下载exe文件后先查壳
无壳,32位,所以后续应使用IDA32来进行操作
将文件导入IDA
下面是一个错误方向,也是我们最常想到的思路,即检索字符串、交叉引用、查看伪代码再进行分析
按shift+12检索字符串,检索flag
找到相应的函数并查看伪代码。
这里可以发现伪代码中V4是没有值的,而且其他量也都没有涉及flag,flag涉及的语句仅作为if语序中的一个条件。
int __cdecl _ftbuf(unsigned int a1, _DWORD *a2)
{
int result; // eax
int v3; // eax
char v4; // [esp+0h] [ebp-10h]
if ( a1 >= 2 && _CrtDbgReport(2, (int)"_sftbuf.c", 161, 0, "flag == 0 || flag == 1", v4) == 1 )
__debugbreak();
if ( a1 )
{
result = a2[3] & 0x1000;
if ( result )
{
_flush(a2);
v3 = a2[3];
BYTE1(v3) &= 0xEEu;
a2[3] = v3;
a2[6] = 0;
result = (int)a2;
*a2 = 0;
a2[2] = 0;
}
}
else
{
result = a2[3] & 0x1000;
if ( result )
return _flush(a2);
}
return result;
}
正确方向
我们回到最开始的主函数,发现这里真正的主函数是main_0
查看伪代码
int __cdecl main_0(int argc, const char **argv, const char **envp)
{
char v4[4]; // [esp+4Ch] [ebp-Ch] BYREF
const char *v5; // [esp+50h] [ebp-8h]
int v6; // [esp+54h] [ebp-4h]
v6 = 5;
v5 = "DBAPP{49d3c93df25caad81232130f3d2ebfad}";
while ( v6 >= 0 )
{
printf(&byte_4250EC, v6);
sub_40100A();
--v6;
}
printf(asc_425088);
v4[0] = 1;
scanf("%c", v4);
if ( v4[0] == 89 )
{
printf(aOd);
return sub_40100A();
}
else
{
if ( v4[0] == 78 )
printf(&byte_425034);
else
printf(&byte_42501C);
return sub_40100A();
}
}
分析一下发现v5的大括号里的部分正是flag,而这段伪代码其实与v5没有太大关系,正确的flag就是v5大括号里的字符串。