GFSJ0779-【梅津美治郎】
VEH 异常回调
简单看一下main函数 运行一下 考点是第二段密码 所以我们去找相对应的解密函数
int __cdecl main(int argc, const char **argv, const char **envp)
{
const CHAR *v3; // ebx
HMODULE ModuleHandleA; // eax
void (__stdcall *ProcAddress)(HMODULE, LPCSTR); // eax
char Str1[20]; // [esp+1h] [ebp-157h] BYREF
char Str2[11]; // [esp+15h] [ebp-143h] BYREF
int v9; // [esp+20h] [ebp-138h] BYREF
_DWORD v10[6]; // [esp+26h] [ebp-132h] BYREF
__int16 v11; // [esp+3Eh] [ebp-11Ah]
_DWORD v12[7]; // [esp+40h] [ebp-118h] BYREF
_DWORD v13[4]; // [esp+5Ch] [ebp-FCh] BYREF
_DWORD v14[2]; // [esp+6Ch] [ebp-ECh] BYREF
char v15; // [esp+74h] [ebp-E4h]
_DWORD v16[8]; // [esp+75h] [ebp-E3h] BYREF
__int16 v17; // [esp+95h] [ebp-C3h]
_DWORD v18[8]; // [esp+97h] [ebp-C1h] BYREF
char v19; // [esp+B7h] [ebp-A1h]
int v20; // [esp+B8h] [ebp-A0h] BYREF
_DWORD v21[8]; // [esp+BEh] [ebp-9Ah] BYREF
char v22; // [esp+DEh] [ebp-7Ah]
_DWORD v23[8]; // [esp+DFh] [ebp-79h] BYREF
__int16 v24; // [esp+FFh] [ebp-59h]
int v25; // [esp+101h] [ebp-57h]
int v26; // [esp+105h] [ebp-53h]
char v27; // [esp+109h] [ebp-4Fh]
_DWORD v28[4]; // [esp+10Ah] [ebp-4Eh] BYREF
_DWORD v29[7]; // [esp+11Ah] [ebp-3Eh] BYREF
_DWORD v30[6]; // [esp+136h] [ebp-22h] BYREF
__int16 v31; // [esp+14Eh] [ebp-Ah]
int *p_argc; // [esp+150h] [ebp-8h]
p_argc = &argc;
sub_402940();
puts(
" . \n"
" _|_ ROBOTIC AUTHENTICATION SYSTEM\n"
" /\\/\\ (. .) /\n"
" `||' |#| \n"
" ||__.-\"-\"-.___ \n"
" `---| . . |--.\\ \n"
" | : : | ,||,\n"
" `..-..' \\/\\/\n"
" || || \n"
" || || \n"
" |__|__| \n");
v20 = 1337;
qmemcpy(v21, "Qmd`rd!douds!uid!ghsru!Q`rrvnse;", sizeof(v21));
v22 = 1;
qmemcpy(v18, "Qmd`rd!douds!uid!ghsru!Q`rrvnse;", sizeof(v18));
v19 = 1;
qmemcpy(v23, "Qmd`rd!douds!uid!rdbnoe!Q`rrvnse", sizeof(v23));
v24 = 315;
qmemcpy(v16, "Qmd`rd!douds!uid!rdbnoe!Q`rrvnse", sizeof(v16));
v17 = 315;
v25 = 1869557876;
v26 = 1718432615;
v27 = 3;
v14[0] = 1869557876;
v14[1] = 1718432615;
v15 = 3;
qmemcpy(v28, "jdsodm23/emm", 12);
v28[3] = 20906241;
qmemcpy(v13, "jdsodm23/emm", 12);
v13[3] = 20906241;
qmemcpy(v29, "@eeWdbunsdeDybdquhnoI`oe", 24);
v29[6] = 24339565;
qmemcpy(v12, "@eeWdbunsdeDybdquhnoI`oe", 24);
v12[6] = 24339565;
qmemcpy(v30, "Xnt!vho/!Bnofs`utm`uhnor", sizeof(v30));
v31 = 288;
qmemcpy(v10, "Xnt!vho/!Bnofs`utm`uhnor", sizeof(v10));
v11 = 288;
v9 = 1337;
strcpy(Str2, "r0b0RUlez!");
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;
ModuleHandleA = GetModuleHandleA(lpModuleName);
ProcAddress = (void (__stdcall *)(HMODULE, LPCSTR))GetProcAddress(ModuleHandleA, v3);
ProcAddress((HMODULE)1, (LPCSTR)sub_40157F);
puts(dword_40AD8C);
scanf("%20s", Str1);
if ( !strcmp(Str1, Str2) )
{
puts("You passed level1!");
sub_4015EA(0);
}
return 0;
}
sub_20157F 能看到这里出现了第二个scanf
void __cdecl __noreturn sub_40157F(int a1)
{
_BYTE v1[20]; // [esp+18h] [ebp-20h] BYREF
int v2; // [esp+2Ch] [ebp-Ch]
v2 = *(_DWORD *)(*(_DWORD *)(a1 + 4) + 184);
if ( v2 == dword_40ADA8 + 6 )
{
scanf("%20s", v1);
if ( !sub_401547(v1, (_BYTE *)dword_40AD98) )
puts(Buffer);
}
ExitProcess(0);
}
sub_401547 这里是一个简单的^2 所以我们要去找这个dword_40AD98的值是多少 接着往下看 能看到这个
int __cdecl sub_401547(_BYTE *a1, _BYTE *a2)
{
while ( *a2 != 2 )
{
if ( *a1 != (*a2 ^ 2) )
return 1;
++a1;
++a2;
}
return 0;
}
sub_4015EA 能看到这里有一个__debugbreak() 也就是触发异常函数
int __cdecl sub_4015EA(int a1)
{
if ( a1 <= 9 )
return sub_4015EA(a1 + 1);
puts(dword_40AD90);
dword_40ADA8 = 4199961;
__debugbreak();
return 0;
}
总体流程是main 里注册了一个 VEH 异常处理函数:
ProcAddress = GetProcAddress(GetModuleHandleA(lpModuleName), lpProcName);
ProcAddress((HMODULE)1, (LPCSTR)sub_40157F);
这里 lpModuleName 和 lpProcName 经过 sub_401500(0) 解密后分别是
kernel32.dll
AddVectoredExceptionHandler
所以实际上是
AddVectoredExceptionHandler(1, sub_40157F);
第一段密码很明显
strcpy(Str2, "r0b0RUlez!");
所以第一段输入
r0b0RUlez!
输入正确后进入
sub_4015EA(0);
递归到 a1 > 9 后执行
puts(dword_40AD90);
dword_40ADA8 = 4199961;
__debugbreak();
__debugbreak() 会触发异常,从而进入 VEH 回调函数 sub_40157F
所以我们就知道 来动调一下看看吧 到这里就能看到他的值是多少了
u1nnf2lg
异或2可得
w3lld0ne
flag{r0b0RUlez!_w3lld0ne}
评论