下载:
链接: https://pan.baidu.com/s/1namyd7m2SrKpSzNrbCEoYg
提取码: 1234
用ida打开文件,发现一点线索也没有
查一下壳,带着upx壳
用命令脱一下壳
可是我脱完壳之后用ida再打开还是没脱壳的样子,而再查壳是脱壳的状态,于是我拿着没脱壳的文件看了两天/(ㄒoㄒ)/~~,后来知道应该是我最开始用ida打开过了,不知道怎么回事只剩下一个ida打包的文件,把ida打包的文件脱壳之后再打开还是原来的样子,把文件删了再下载重新做就好了
脱完壳用ida打开,找到main函数反汇编,分析一下
part1-4是输入四个数并分别处理过了,然后v12也就是flag就是处理过的四个数,分析后边对v12的操作,发现对v12没有影响,所以直接算四个数就好了
__int64 __fastcall main(int a1, char **a2, char **a3)
{
unsigned __int64 v3; // rax
unsigned int v5; // [rsp+0h] [rbp-110h] BYREF
unsigned int v6; // [rsp+4h] [rbp-10Ch] BYREF
unsigned int v7; // [rsp+8h] [rbp-108h] BYREF
unsigned int v8; // [rsp+Ch] [rbp-104h] BYREF
char v9[96]; // [rsp+10h] [rbp-100h] BYREF
__int64 s2[2]; // [rsp+70h] [rbp-A0h] BYREF
char s[32]; // [rsp+80h] [rbp-90h] BYREF
char v12[104]; // [rsp+A0h] [rbp-70h] BYREF
unsigned __int64 v13; // [rsp+108h] [rbp-8h]
v13 = __readfsqword(0x28u);
v5 = 0;
printf("Part 1: ");
__isoc99_scanf("%u", &v5);
if ( (unsigned int)sub_1229(v5, -1380855784) )// v5==3821413212
goto LABEL_7;
v6 = 0;
printf("Part 2: ");
__isoc99_scanf("%u", &v6);
if ( (unsigned int)sub_1257(v6) ) // v6==98124621
goto LABEL_7;
v7 = 0;
printf("Part 3: ");
__isoc99_scanf("%u", &v7);
if ( (unsigned int)sub_12A4(v7) ) // v7==78769651
goto LABEL_7;
v8 = 0;
printf("Part 4: ");
__isoc99_scanf("%u", &v8);
if ( (unsigned int)sub_1346(v8) ) // v8==4017045635
goto LABEL_7;
memset(s, 0, sizeof(s));
sprintf(v12, "flag{%08x-%08x-%08x-%08x}", v5, v6, v7, v8);// flag{0xe3c6235c-0x5d9434d-0x4b1edf3-0xef6f4083}
// flag{0x-372526695}
//
sub_2481((__int64)v9); // 对v9变换
v3 = strlen(v12);
sub_24D3((__int64)v9, (__int64)v12, v3); // 用flag对v9变换,flag没变
sub_2578((__int64)v9, (__int64)s); // 用v9对s变换
s2[0] = 0x5C338CC28AC3B9C9LL;
s2[1] = 0x4982C83EACACDBE0LL; // s2存的内容
if ( memcmp(s, s2, 0x10uLL) ) // s和s2对比
{
LABEL_7:
puts("Wrong!");
return 0LL;
}
else
{
puts("Right!");
printf("Your flag is: %s\n", v12);
return 0LL;
}
}
四个数的处理就是四个算式
要人工解四个算式的话基本不可能
所以我们要用到python的模块
用python的z3模块就ok了
在这里学习:Z3求解器基础学习 (一) 从例子入门 - 说芬兰语的雪 - 博客园 (cnblogs.com)
from z3 import *
s = Solver() # 设置一个解方程的类Solver(必须要设置)
v5=BitVec('v5',32)
v6=BitVec('v6',32)
v7=BitVec('v7',32)
v8=BitVec('v8',32)
s.add(v5 + 1380855784 == 907301700)
s.add((v6 | 0x8E03BEC3) - 3 * (v6 & 0x71FC413C) + v6 == -1876131848)
s.add(v7<=0x10000000)
s.add(4 * ((~v7 & 0xA8453437) + 2 * ~(~v7 | 0xA8453437))
+ -3 * (~v7 | 0xA8453437)
+ 3 * ~(v7 | 0xA8453437)
- (-10 * (v7 & 0xA8453437)
+ (v7 ^ 0xA8453437)) == 551387557)
s.add(v8<=0x10000000)
s.add(11 * ~(v8 ^ 0xE33B67BD)
+ 4 * ~(~v8 | 0xE33B67BD)
- (6 * (v8& 0xE33B67BD)
+ 12 * ~(v8 | 0xE33B67BD))
+ 3 * (v8 & 0xD2C7FC0C)
+ -5 * v8
- 2 * ~(v8 | 0xD2C7FC0C)
+ ~(v8 | 0x2D3803F3)
+ 4 * (v8 & 0x2D3803F3)
- -2 * (v8 | 0x2D3803F3) == -837785892)
print(s.check())#check是保证有解
answer=s.model()#model是输出运算结果
print(answer)
用z3解完得到4个数,但是提交flag是不对的,我们用devc爆破一下(c语言爆破更快),爆破就是
循环遍历一个范围,来找符合公式的数
爆破完,发现是v8出错了,下面是v8的爆破
得到flag
data=[3821413212,98124621,78769651,67321987]
print('flag{'+'%08x-'%data[0]+'%08x-'%data[1]+'%08x-'%data[2]+'%08x'%data[3]+'}')#flag{e3c6235c-05d9434d-04b1edf3-04034083}
此题用到了python的z3库,z3库主要用来解方程,还用到了爆破,爆破就是在一个数字范围内进行循环,把数字代入公式,直到找到一个数字代入之后与正确结果相同