查看反编译代码
strcpy(Str2, "r0b0RUlez!"); // first Password
dword_40AD94 = (int)&v9;
dword_40ADA0 = (int)&v20;
dword_40AD8C = (char *)v18;
dword_40AD90 = (char *)v16;
dword_40AD98 = (int)v14;
lpProcName = (LPCSTR)v12;
lpModuleName = (LPCSTR)v13;
Buffer = (char *)v10;
sub_401500(0);
v3 = lpProcName;
v4 = GetModuleHandleA(lpModuleName);
v5 = (void (__stdcall *)(HMODULE, LPCSTR))GetProcAddress(v4, v3);
v5((HMODULE)1, (LPCSTR)sub_40157F);
puts(dword_40AD8C);
scanf("%20s", Str1);
if ( !strcmp(Str1, Str2) )
{
puts("You passed level1!");
sub_4015EA(0);
}
第一部分直接能看出来passwordr0b0RUlez!
int __cdecl sub_4015EA(int a1)
{
if ( a1 <= 9 )
return sub_4015EA(a1 + 1);
puts(dword_40AD90);
dword_40ADA8 = 4199961;
__debugbreak(); // 相当于int 3指令
return 0;
}
动态调试
发现AddVectoredExceptionHandler()
函数,功能是在异常前执行指定函数
void __cdecl __noreturn sub_40157F(int a1)
{
char v1[20]; // [esp+18h] [ebp-20h] BYREF
int v2; // [esp+2Ch] [ebp-Ch]
v2 = *(_DWORD *)(*(_DWORD *)(a1 + 4) + 184);
if ( v2 == dword_40ADA8 + 6 ) // dword_40ADA8在debugbreak()附近出现过
{
scanf("%20s", v1);
if ( !sub_401547(v1, (_BYTE *)dword_40AD98) )
puts(Buffer);
}
ExitProcess(0);
}
通过调试得知执行的是起始地址为0x40175F的函数
在0x40175F下断点后,继续执行
Exp
s = [0x75, 0x31, 0x6E, 0x6E, 0x66, 0x32, 0x6C, 0x67]
flag = ''
for i in s:
flag += chr(i ^ 0x2)
print(flag)
得到second Password w3lld0ne
flag{r0b0RUlez!_w3lld0ne}