ciscn 2020 reverse hyperthreading
程序员文章站
2022-05-12 14:01:53
...
hyperthreading
Start
搜索字符串找到关键函数:
int sub_401270()
{
signed int v0; // eax
HANDLE Handles; // [esp+8h] [ebp-Ch]
HANDLE v3; // [esp+Ch] [ebp-8h]
printf("plz input your flag:");
scanf("%42s", byte_40336C);
Handles = CreateThread(0, 0, StartAddress, 0, 0, 0);
v3 = CreateThread(0, 0, loc_401200, 0, 0, 0);
CreateThread(0, 0, sub_401240, 0, 0, 0);
WaitForMultipleObjects(2u, &Handles, 1, 0xFFFFFFFF);
v0 = 0;
do
{
if ( byte_40336C[v0] != byte_402150[v0] )
{
printf("error");
exit(0);
}
++v0;
}
while ( v0 < 42 );
printf("win");
getchar();
return 0;
}
看到关键句:byte_40336C[v0] != byte_402150[v0]
找到加密后的字符串
这里创建了一堆线程:
跟进sub_401240
发现,这里用到了IsDebuggerPresent
反调试函数
void __stdcall __noreturn sub_401240(LPVOID lpThreadParameter)
{
while ( !IsDebuggerPresent() )
;
printf("debug!\n");
exit(0);
}
根据题名可以猜测,加密的线程被加密了,无法直接看到加密过程
将进程载入OD,在输入处下断点
运行,单步到007F1296
,此时要求输入flag,随便输点东西
之后一直单步,走到WaitForMultipleObjects
,往下程序就会卡在这个位置,因为前面判断了程序处于调试模式,所以线程会一直占用,出不来。
这里先按下暂停,然后再点运行,会发现程序就过了WaitForMultipleObject
这个函数,上面那个判断反调式的线程没有占用资源了
之后看到关键比较dd 7f336c
dd 7f2150
通过比较后,发现7f2150
开始的位置就是byte_402150
而7f336c
就是我们输入的flag经过处理后的结果。
经过多次尝试发现,对于每个字符,每一次的加密结果是固定的,那么就可以通过遍历有可能是flag的字符,查看每个字符加密后的结果,与真正flag加密后的结果进行逐一比较,最终可以得到flag
exp.py
encrypt = [0xDD,0x5B,0x9E,0x1D,0x20,0x9E,0x90,0x91,0x90,0x90,0x91,0x92,0xDE,0x8B,0x11,0xD1,0x1E,0x9E,0x8B,0x51,0x11,0x50,0x51,0x8B,0x9E,0x5D,0x5D,0x11,0x8B,0x90,0x12,0x91,0x50,0x12,0xD2,0x91,0x92,0x1E,0x9E,0x90,0xD2,0x9F]
key_dic = {'a':0x9E,'b':0xDE,'c':0x1E,'d':0x5D,'e':0x9D,'f':0xDD,'g':0x1D,'h':0x5C,'i':0x9C,'j':0xDC,'k':0x1C,'l':0x5B,'m':0x9B,'n':0xDB,'o':0x1B,'p':0x62,'q':0xA2,'r':0xE2,'s':0x22,'t':0x61,'u':0xA1,'v':0xE1,'w':0x21,'x':0x60,'y':0x0A,'z':0xE0,'_':0x17,'{':0x20,'}':0x9F,'0':0x52,'1':0x92,'2':0xD2,'3':0x12,'4':0x51,'5':0x91,'6':0xD1,'7':0x11,'8':0x50,'9':0x90,'-':0x8B}
flag = ''
for i in encrypt:
for j in key_dic:
if key_dic[j] == i:
flag += j
print(flag)
# flag{a959951b-76ca-4784-add7-93583251ca92}
ps: 这道题的思路应该就是考的绕过isDebuggerPresent函数
这里可以发现,当EIP处于WaitForMultipleObjects
之前时,0x0087336c
的值还是我们输入的字符串,并没有进行处理。(这里是我之后补充的,所以基地址不同)
End
上一篇: 记录一道C语言题目