ida打开,main函数是sub_5B4270,没加混淆,但是main函数调用的其他计算函数都加了混淆(大概看了下,与Archaia战队在前几次比赛中用的差不多,难搞)
main函数没有混淆,验证逻辑很容易看出来,大概是对name和serial各做一些计算分别得到两个8字节的值,然后比较两个值是否相等。
比较好的一点是程序没有加壳与反调试,直接动态调试main函数,发现修改中间值的一个bit也会对结果产生巨大的影响,所以似乎只能分析算法逆推。
看了一个小时题目,先去睡觉了(实在不想硬刚代码混淆,再加上昨晚写第十题的wp没怎么睡)
晚上起来发现一血只用了一个半小时,果断开始找非预期。
main函数调用的其他函数由于被混淆了,导致ida识别的函数签名很乱,main函数的F5伪代码观感很差。
还是先修正所有函数的类型,根据汇编里调用函数前的push个数确定参数个数。
修正之后的main函数看上去清爽多了,摘抄如下:("..."中间的代码与前后相同(除了数组偏移),在此略去)
修正函数签名后,交叉引用的查找也会变得更准。“登录成功”的条件是v395和v365相等,对v365查找交叉引用可以定位到上面的sprintf,是从name计算出来的一个值;v395则是从serial计算出来的一个值。
观察代码,发现v70变量贯穿了大部分代码。
在输入serial之前以v365为初始值正向遍历v70进行了22次迭代计算得到v391;在输入serial之后以serial为初始值反向遍历v70进行了22次迭代计算得到v395。
这两块计算给人感觉很像互逆的。输入公开的name,尝试在0x5B6364下断点查看正向迭代22次后的v391,发现此处的v391正好就是公开的serial。
所以最终获得答案的方法很简单,输入KCTF作为name,提取正向迭代22次后的v391,即为对应的serial。
验证通过
/
/
bad sp value at call has been detected, the output may be wrong!
int
__cdecl main(
int
argc, const char
*
*
argv, const char
*
*
envp)
{
/
/
[COLLAPSED LOCAL DECLARATIONS. PRESS KEYPAD CTRL
-
"+"
TO EXPAND]
memset(v70,
0
,
0x1C2u
);
memset(v69,
0
, sizeof(v69));
qmemcpy(v116,
"abcdefgh"
, sizeof(v116));
memset(name,
0
,
0x32u
);
*
(_DWORD
*
)
Buffer
=
0
;
v406
=
0
;
v207
=
0
;
v208
=
0
;
v209
=
0
;
v210
=
0
;
v326
=
0
;
v327
=
0
;
v328
=
0
;
printf(&
Format
);
/
/
"请输入用户名:\n"
gets((
int
)name);
v390
=
name;
v293
=
&name[
1
];
v390
+
=
strlen(v390);
v289
=
+
+
v390
-
&name[
1
];
Value
=
sub_5AE2D3(name, v390
-
&name[
1
]);
itoa(Value,
Buffer
,
16
);
sub_5AD9F9(v116,
Buffer
, &v207, &v326);
*
(_DWORD
*
)v70
=
v207;
*
(_DWORD
*
)&v70[
4
]
=
v208;
*
(_DWORD
*
)v69
=
v326;
*
(_DWORD
*
)&v69[
4
]
=
v327;
qmemcpy(v115,
"ijklmnop"
, sizeof(v115));
v231
=
0
;
v232
=
0
;
v233
=
0
;
v234
=
0
;
v323
=
0
;
v324
=
0
;
v325
=
0
;
...
sub_593D03(v126,
Buffer
, v77, v277);
qmemcpy(v127,
"abcdefgh"
, sizeof(v127));
memset(v76,
0
, sizeof(v76));
v275[
0
]
=
0
;
v275[
1
]
=
0
;
v276
=
0
;
sub_5937B3(v127,
Buffer
, v76, v275);
memset(v365,
0
, sizeof(v365));
v366
=
0
;
v3
=
sub_5AE2D3(v69,
192
);
sprintf(v365,
"%08x"
, v3);
/
/
v365
v401[
0
]
=
0
;
v401[
1
]
=
0
;
v402
=
0
;
v403
=
0
;
v404
=
0
;
v391[
0
]
=
0
;
v391[
1
]
=
0
;
v392
=
0
;
v393
=
0
;
v394
=
0
;
sub_592CB9(v70, v365, v401);
v368
=
malloc(
8u
);
v4
=
v368;
v5
=
v403;
*
v368
=
v402;
v4[
1
]
=
v5;
sub_592CB9(&v70[
9
], v401, v391);
...
v44
=
malloc(
8u
);
v387
=
v44;
v45
=
v403;
*
v44
=
v402;
v44[
1
]
=
v45;
sub_592CB9(&v70[
189
], v401, v391);
/
/
here, v391
is
the correct serial
v44
=
malloc(
8u
);
v387
=
v44;
v45
=
v403;
*
v44
=
v402;
v44[
1
]
=
v45;
sub_592CB9(&v70[
189
], v401, v391);
memset(serial,
0
, sizeof(serial));
v288
=
0
;
memset(v399,
0
, sizeof(v399));
v400
=
0
;
memset(v395,
0
, sizeof(v395));
v396
=
0
;
v397
=
0
;
v398
=
0
;
printf(&byte_5D0848);
/
/
"请输入序列号:\n"
gets((
int
)serial);
v389
=
serial;
v291
=
&serial[
1
];
v389
+
=
strlen(v389);
v292
=
+
+
v389
-
&serial[
1
];
if
( v389
-
&serial[
1
]
=
=
16
)
{
sub_592C10(&v70[
189
], v399, serial);
v47
=
v387[
1
];
*
(_DWORD
*
)&v399[
8
]
=
*
v387;
*
(_DWORD
*
)&v399[
12
]
=
v47;
...
sub_592C10(&v70[
9
], v399, v395);
v67
=
v368[
1
];
*
(_DWORD
*
)&v399[
8
]
=
*
v368;
*
(_DWORD
*
)&v399[
12
]
=
v67;
sub_592C10(v70, v395, v399);
for
( i
=
0
; i <
8
;
+
+
i )
{
if
( v395[i] !
=
v365[i] )
{
printf(&fail_1);
/
/
"登录失败!\n"
system(aPause_0);
return
0
;
}
}
printf(&success);
/
/
"登录成功!\n"
system(aPause_1);
return
0
;
}
else
{
printf(&fail_2);
/
/
"登录失败!\n"
system(Command);
return
0
;
}
}
/
/
bad sp value at call has been detected, the output may be wrong!
int
__cdecl main(
int
argc, const char
*
*
argv, const char
*
*
envp)
{
/
/
[COLLAPSED LOCAL DECLARATIONS. PRESS KEYPAD CTRL
-
"+"
TO EXPAND]
memset(v70,
0
,
0x1C2u
);
memset(v69,
0
, sizeof(v69));
qmemcpy(v116,
"abcdefgh"
, sizeof(v116));
memset(name,
0
,
0x32u
);
*
(_DWORD
*
)
Buffer
=
0
;
v406
=
0
;
v207
=
0
;
v208
=
0
;
v209
=
0
;
v210
=
0
;
v326
=
0
;
v327
=
0
;
v328
=
0
;
printf(&
Format
);
/
/
"请输入用户名:\n"
gets((
int
)name);
v390
=
name;
v293
=
&name[
1
];
v390
+
=
strlen(v390);
v289
=
+
+
v390
-
&name[
1
];
Value
=
sub_5AE2D3(name, v390
-
&name[
1
]);
itoa(Value,
Buffer
,
16
);
sub_5AD9F9(v116,
Buffer
, &v207, &v326);
*
(_DWORD
*
)v70
=
v207;
*
(_DWORD
*
)&v70[
4
]
=
v208;
*
(_DWORD
*
)v69
=
v326;
*
(_DWORD
*
)&v69[
4
]
=
v327;
qmemcpy(v115,
"ijklmnop"
, sizeof(v115));
v231
=
0
;
v232
=
0
;
v233
=
0
;
v234
=
0
;
v323
=
0
;
v324
=
0
;
v325
=
0
;
...
sub_593D03(v126,
Buffer
, v77, v277);
qmemcpy(v127,
"abcdefgh"
, sizeof(v127));
memset(v76,
0
, sizeof(v76));
v275[
0
]
=
0
;
v275[
1
]
=
0
;
v276
=
0
;
sub_5937B3(v127,
Buffer
, v76, v275);
memset(v365,
0
, sizeof(v365));
v366
=
0
;
v3
=
sub_5AE2D3(v69,
192
);
sprintf(v365,
"%08x"
, v3);
/
/
v365
v401[
0
]
=
0
;
v401[
1
]
=
0
;
v402
=
0
;
v403
=
0
;
v404
=
0
;
v391[
0
]
=
0
;
v391[
1
]
=
0
;
v392
=
0
;
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
最后于 2022-12-12 02:02
被mb_mgodlfyn编辑
,原因: