首先对Easy_Re.exe查壳:
并没有壳,是用Visual C++写的控制台程序,然后就把它用IDA打开,用不同把那本的IDA打开对exe的数据解析和反汇编的伪代码是有些差异的,这是7.0版本的伪代码:
这是6.8版本的伪代码:
int sub_401000()
{
int v0; // eax
__int128 v2; // [esp+0h] [ebp-44h]
__int64 v3; // [esp+10h] [ebp-34h]
int v4; // [esp+18h] [ebp-2Ch]
__int16 v5; // [esp+1Ch] [ebp-28h]
char v6; // [esp+20h] [ebp-24h]
_mm_storeu_si128((__m128i *)&v2, _mm_loadu_si128((const __m128i *)&xmmword_413E34));// 将__m128i 变量xmmword_413E34的值存储到v2所指定的变量中去,xmmword_413E34 xmmword '0tem0c1eW{FTCTUD'
v4 = 0;
v3 = qword_413E44; // qword_413E44 dq '}FTCTUD'
v5 = 0;
sub_40127B((int)"欢迎来到DUTCTF呦\n");
sub_40127B((int)&unk_413E60); // 这是一道很可爱很简单的逆向题呦
sub_40127B((int)"输入flag吧:");
sub_4010D1("%s", &v6); // v6:输入的字符串
v0 = strcmp((const char *)&v2, &v6); // >返回正数,=返回0,<返回负数
if ( v0 )
v0 = -(v0 < 0) | 1; // 正数都转化为1,符数都转化为-1,0不变
if ( v0 ) // 非0即真,只要v0不是0就会执行if中的语句,是0就证明正确就会输出flag get√
sub_40127B((int)"flag不太对呦,再试试呗,加油呦\n");
else
sub_40127B((int)"flag get√\n");
sub_401171("pause");
return 0;
}
这就是主要的main函数,我给它加了部分注释,其实不看这些代码也可以。
点击xmmword_413E34和qword_413E44,查看它们的内容:
发现它们的内容是16进制的数字串,这其实是字符串的16进制形式,选中按快捷键‘R’就可以实现16进制数字到字符的互相转化:
其实这就是转置存储的flag,我们可以用IDA的python插件,将它们转换成正常顺序的flag:
得到flag就是DUTCTF{We1c0met0DUTCTF}。
题外话
关于不同版本的IDA对相同exe的数据解析和反汇编的伪代码的差异,都是可以自己修改数据的格式,增加数据和伪代码的可读性。
如下图所示,xmmword_413E34和qword_413E44被IDA解释为不同的数据:
选中这两个数据,直接右键转化为未定义,或者右键转化为数据:
再转化为数组合:
点击确定:
两个数据就都会被转换为一个数组合,变现为每个字符都是按正常顺序排列的:
这时候再右击unk_413E34,发现IDA已经能把它识别为一个完整的字符串了:
也可以直接按快捷键‘A’解释光标的地址为字符串的首地址:
就得到了正确顺序的flag字符串DUTCTF{We1c0met0DUTCTF}。
同样地,其他输出提示信息的字符串也可以修改。如:‘这是一道很可爱很简单的逆向题呦’
先是unk_413E60:未定义的数据
对未定义的数据unk_413E60每四个字节也就是双字一组,按快捷键‘R’转化为dword_413E60字符:
对未定义的数据unk_413E60右键或者按快捷键‘A’转化为字符串asc_413E60:
选中刚刚修改的数据,右键->同步到->伪代码:
可以看到IDA的汇编代码中已经识别我们刚刚的修改。
重启IDA,打开刚刚修改保存之后的idb文件,再对汇编代码按F5反汇编:
可以看到反汇编的代码也识别到了我们修改的数据,相比之前的代码增加了可读性。
sub_40127B函数我们知道它实际上就是printf函数,再IDA7.0中已经能够识别出来,但是6.8中没有识别出来,我们可以右键->重命名全局项目:
把sub_40127B函数改为printf:
这样所有的sub_40127B函数就都被改为printf函数了:
同样地,sub_4010D1函数也可以改为scanf函数,sub_401171函数也可以改为system函数:
只要我们对数据的修改是正确的,这样的修改可以很大程度上提高数据和伪代码的可读性。