0.前言
这题早就做出来了,一直拖着不想写wp,来学校才能静下心来写点东西。
1.简单分析
下载运行,随便输入一些字符串,结果如下图
提示长度错误。 然后查一下壳,结果如下:
UPX壳,直接使用peid的插件脱掉upx壳
2.ida分析
将脱壳后的软件拖入ida,查看程序大致流程。 具体的追踪流程为:winmain窗口——>调用DialogBoxParamA函数——>调用DialogFunc函数,看一下DialogFunc函数
2.1 DialogFunc
BOOL __stdcall DialogFunc(HWND hWnd, UINT a2, WPARAM a3, LPARAM a4)
{
BOOL result; // eax@6
if ( a2 == 272 )
{
::hWnd = hWnd;
SendMessageA(hWnd, 0x80u, 1u, 0);
SendMessageA(hWnd, 0x80u, 0, 0);
result = 1;
}
else
{
if ( a2 != 273 )
return 0;
if ( (unsigned __int16)a3 == 1 )
{
sub_401170(); // 这里对输入进行了验证
result = 1;
}
else if ( (unsigned __int16)a3 == 2 )
{
EndDialog(0, 2);
result = 1;
}
else
{
if ( (unsigned __int16)a3 != 1003 )
return 0;
WinExec("explorer.exe \"https://www.52pojie.cn/home.php?mod=task&do=view&id=14\"", 5u); //在这里弹窗,跳到领取红包的页面
result = 1;
}
}
return result;
}
2.2 sub_401170()
核心验证函数,这个函数中,首先对通过GetWindowTextLengthA函数对输入sn的长度进行验证,必须使16个字符。然后以’udhYssdHzhNb9102’为初始字符串,让它经过change函数变换后与sn比较,相同则正确。关键就是经过change函数后变成了什么,change就是一系列变换,因为考虑使用了strcmp函数,所以判断寄存器中应该有相应的值,所以使用动态调试。
HWND sub_401170()
{
HWND result; // eax@1
_DWORD *sn; // esi@4
_DWORD *v2; // edi@4
int v3; // [sp+0h] [bp-14h]@4
int v4; // [sp+4h] [bp-10h]@4
int v5; // [sp+8h] [bp-Ch]@4
int v6; // [sp+Ch] [bp-8h]@4
char v7; // [sp+10h] [bp-4h]@4
result = GetDlgItem(0, 1000);
if ( result )
{
if ( GetWindowTextLengthA(result) == 16 )
{
sn = malloc(0x11u); // 分配空间
v2 = malloc(0x11u);
*sn = 0;
sn[1] = 0;
sn[2] = 0;
sn[3] = 0;
*((_BYTE *)sn + 16) = 0;
*v2 = 0;
v2[1] = 0;
v2[2] = 0;
v2[3] = 0;
*((_BYTE *)v2 + 16) = 0;
GetDlgItemTextA(0, 1000, (LPSTR)sn, 17);
v5 = 'udhY';
v3 = 'ssdH';
v4 = 'zhNb';
v6 = '9102';
v7 = 0;
change((const char *)&v3, (int)v2, 3);
if ( !strcmp((const char *)v2, (const char *)sn) )
result = (HWND)MessageBoxA(0, "正确!!!回复你输入的内容到吾爱破解论坛公众号,即可获取通关口令!", Caption, 0);
else
result = (HWND)MessageBoxA(0, "内容错误", Caption, 0);
}
else
{
result = (HWND)MessageBoxA(0, "长度错误", Caption, 0);
}
}
return result;
}
3. 动态调试
在以下位置下断点
if ( !strcmp((const char *)v2, (const char *)sn) )
输入16个字符,例如1234567890123456,然后检测密码。然后f9让程序运行,最终查看eax的值,发现就是sn
验证结果如下: