先感谢up的详细讲解
32位无壳exe 运行了啥也没有
查看字符串 跟进f5查看伪代码,提示
往上翻可以看到两断一样的汇编指令 逐步交叉引用找到函数的调用位置可以发现 jz+jnz=>无条件跳转 导致了下面的jmp无法执行
然后回到最开始变红的地方 按p键定义函数 就可以正常按F5查看伪代码了
LRESULT __stdcall sub_401640(HWND hWndParent, UINT Msg, WPARAM wParam, LPARAM lParam)
{
int v5;
size_t v6;
DWORD v7;
HWND v8;
int v9;
int v10;
const CHAR *v11;
const CHAR *v12;
UINT v13;
int v14;
UINT v15;
CHAR v16;
CHAR v17[2];
int v18;
__int16 v19;
char v20;
char v21;
char v22;
__int16 v23;
char v24;
CHAR v25;
CHAR String[4];
int v27;
__int16 v28;
CHAR Text;
struct tagRECT Rect;
CHAR Buffer;
HDC hdc;
struct tagPAINTSTRUCT Paint;
WPARAM v34;
int v35;
LoadStringA(hInstance, 0x6Au, &Buffer, 100);
v15 = Msg;
if ( Msg > 0x111 )
{
if ( v15 == 517 )
{
if ( strlen((const char *)String1) > 6 )
ExitProcess(0);
if ( strlen((const char *)String1) )
{
memset(&v25, 0, 0x100u);
v6 = strlen((const char *)String1);
memcpy(&v25, String1, v6);
v7 = strlen((const char *)String1);
v8 = (HWND)sub_40101E(String1, v7, (LPSTR)String1);
if ( &v11 && !&v11 )
MessageBoxA(v8, v11, v12, v13);
strcpy(&v21, "0kk`d1a`55k222k2a776jbfgd`06cjjb");
memset(&v22, 0, 0xDCu);
v23 = 0;
v24 = 0;
strcpy(v17, "SS");
v18 = 0;
v19 = 0;
v20 = 0;
v9 = strlen(&v21);
sub_401005(v17, (int)&v21, v9);
if ( _strcmpi((const char *)String1, &v21) )
{
SetWindowTextA(hWndParent, "flag{}");
MessageBoxA(hWndParent, "Are you kidding me?", "^_^", 0);
ExitProcess(0);
}
memcpy(&v16, &unk_423030, 0x32u);
v10 = strlen(&v16);
sub_401005(&v25, (int)&v16, v10);
MessageBoxA(hWndParent, &v16, 0, 0x32u);
}
++dword_428D54;
}
else
{
if ( v15 != 520 )
return DefWindowProcA(hWndParent, Msg, wParam, lParam);
if ( dword_428D54 == 16 )
{
strcpy(String, "ctf");
v27 = 0;
v28 = 0;
SetWindowTextA(hWndParent, String);
strcpy(&Text, "Are you kidding me?");
MessageBoxA(hWndParent, &Text, &Buffer, 0);
}
++dword_428D54;
}
}
else
{
switch ( v15 )
{
case 0x111u:
v35 = (unsigned __int16)wParam;
v34 = wParam >> 16;
v14 = (unsigned __int16)wParam;
if ( (unsigned __int16)wParam == 104 )
{
DialogBoxParamA(hInstance, (LPCSTR)0x67, hWndParent, (DLGPROC)DialogFunc, 0);
}
else
{
if ( v14 != 105 )
return DefWindowProcA(hWndParent, Msg, wParam, lParam);
DestroyWindow(hWndParent);
}
break;
case 2u:
PostQuitMessage(0);
break;
case 0xFu:
hdc = BeginPaint(hWndParent, &Paint);
GetClientRect(hWndParent, &Rect);
v5 = strlen(&Buffer);
DrawTextA(hdc, &Buffer, v5, &Rect, 1u);
EndPaint(hWndParent, &Paint);
break;
default:
return DefWindowProcA(hWndParent, Msg, wParam, lParam);
}
}
return 0;
}
有两个关键函数,跟进一下 v8 = (HWND)sub_40101E(String1, v7, (LPSTR)String1); 之前有讲,md5加密String 官方文档里有 下一个 sub_401005(v17, (int)&v21, v9);
unsigned int __cdecl sub_401590(LPCSTR lpString, int a2, int a3)
{
unsigned int result;
unsigned int i;
unsigned int v5;
v5 = lstrlenA(lpString);
for ( i = 0; ; ++i )
{
result = i;
if ( i >= a3 )
break;
*(_BYTE *)(i + a2) ^= lpString[i % v5];
}
return result;
}
第一次调用: 将0kk`d1a`55k222k2a776jbfgd`06cjjb 与SS 按一定规律异或 “SS"不管下标是啥都是"S”,直接无视
v21=list('0kk`d1a`55k222k2a776jbfgd`06cjjb')
for i in range(len(v21)):
v21[i]=ord(v21[i])^ord('S')
print(chr(v21[i]),end='')
输出 c8837b23ff8aaa8a2dde915473ce0991 解密得到123321 第二次调用:
memcpy(&v16, &unk_423030, 0x32u);
sub_401005(&v25, (int)&v16, v10);
将String与unk_423030异或 shift+E快捷键获取unk_423030的值
v21=list('0kk`d1a`55k222k2a776jbfgd`06cjjb')
for i in range(len(v21)):
v21[i]=ord(v21[i])^ord('S')
print(chr(v21[i]),end='')
print()
String = list('123321')
unk_423030=[0x57, 0x5E, 0x52, 0x54, 0x49, 0x5F, 0x01, 0x6D, 0x69, 0x46,
0x02, 0x6E, 0x5F, 0x02, 0x6C, 0x57, 0x5B, 0x54, 0x4C]
flag=[]
for i in range(len(unk_423030)):
flag.append(unk_423030[i]^ord(String[i%len(String)]))
print(chr(flag[i]),end='')
flag{n0_Zu0_n0_die}
|