首先将下载的文件打开运行
确实如题目描述所说运行可以得到flag,但是却为乱码
那就先用Exeinfo PE查看信息
这次为c++编写的32位程序,直接用ida32打开
进入后直接查看主函数的伪代码
这个主函数看起来还是比较复杂的
先查看开头的HeapCreate()函数和heapAlloc()函数的作用,百度了解到这两个函数实际上就是申请了内存空间的(https://www.cnblogs.com/lancidie/archive/2011/02/12/1952356.html)
然后看一下memcpy_s()函数,实际作用就是进行的字符串的拷贝
代码中的作用就是将 unk_409B10 中的字符串拷贝到IpMem
跟进后查看
接下来到了 if 条件处
if ( sub_40102A() || IsDebuggerPresent() )
{
__debugbreak();
sub_401000(v3 + 4, lpMem);
ExitProcess(0xFFFFFFFF);
}
先查看if判断的两个条件
int sub_40102A()
{
char v0; // t1
v0 = *(_BYTE *)(*(_DWORD *)(__readfsdword(0x18u) + 48) + 2);
return 0;
}
第一个条件返回值为0,就不用看了
第二个条件 IsDebuggerPresent 百度了解到这个函数是用于反调试,当检测到程序被调试时,就会结束其进程或不按正常流程运行,而达到反调试的作用
先不看 if 中的语句,继续往后看
MessageBoxA(0, lpMem + 1, "Flag", 2u);
HeapFree(hHeap, 0, lpMem);
HeapDestroy(hHeap);
MessageBoxA函数作用是进行一个输出,进行输出flag
我们猜测 IpMem 中有我们要的 flag
先将之前 unk_409B10 中的数据导出
写脚本进行输出
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main()
{
int lpMem[]=
{
0xBB, 0xCC, 0xA0, 0xBC, 0xDC, 0xD1, 0xBE, 0xB8, 0xCD, 0xCF,
0xBE, 0xAE, 0xD2, 0xC4, 0xAB, 0x82, 0xD2, 0xD9, 0x93, 0xB3,
0xD4, 0xDE, 0x93, 0xA9, 0xD3, 0xCB, 0xB8, 0x82, 0xD3, 0xCB,
0xBE, 0xB9, 0x9A, 0xD7, 0xCC, 0xDD
};
for (int i = 0; i < 36; i++)
{
printf("%c", lpMem[i]);
}
return 0;
}
运行出来还是乱码,毕竟不可能让我们这么容易出结果
sub_401000(v3 + 4, lpMem);
此时退回之前没看的 if 条件内部,其实sub_401000调用了lpMem
跟进去查看
unsigned int __fastcall sub_401000(int a1, int a2)
{
int v2; // esi
unsigned int v3; // eax
unsigned int v4; // ecx
unsigned int result; // eax
v2 = dword_409B38;
v3 = a2 + 1 + strlen((const char *)(a2 + 1)) + 1;
v4 = 0;
result = ((v3 - (a2 + 2)) >> 2) + 1;
if ( result )
{
do
*(_DWORD *)(a2 + 4 * v4++) ^= v2;
while ( v4 < result );
}
return result;
}
这里对 v2 进行了赋值,继续跟进去查看 dword_409B38
后面发现这个可以转变为数据
分析这段代码,是lpMem进行依次异或v2中的数,根据这个写出脚本
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main()
{
int lpMem[]=
{
0xBB, 0xCC, 0xA0, 0xBC, 0xDC, 0xD1, 0xBE, 0xB8, 0xCD, 0xCF,
0xBE, 0xAE, 0xD2, 0xC4, 0xAB, 0x82, 0xD2, 0xD9, 0x93, 0xB3,
0xD4, 0xDE, 0x93, 0xA9, 0xD3, 0xCB, 0xB8, 0x82, 0xD3, 0xCB,
0xBE, 0xB9, 0x9A, 0xD7, 0xCC, 0xDD
};
int v2[]=
{
0xBB, 0xAA, 0xCC, 0xDD
};
for (int i = 0; i < 36; i++)
{
printf("%c", lpMem[i] ^ v2[i % 4]);
}
return 0;
}
运行得出本题flag
其实本题还可以用动态调试,但由于汇编了解并不多,这里并没有进行动态分析,等之后汇编了解差不多,再用动态调试去解这道题