西湖论剑CTF
这个比赛只做了一道题,看了很久确实也没做出来。没有想到程序的执行逻辑可以在32位和64位的不同执行环境下进行切换。
Dual personality
总体来讲该程序
第一次 从
32-> 64 赋值key -> 32第二次 从
32-> 64 循环左移 -> 32第三次 从
32 -> 64 进行了两次加密,一次就是基本的逻辑运算,另一次是异或。-> 32
- 将exe程序送进ida,发现main函数无法被正常反编译。

sub_401120函数会把下面的二进制修改为 EA D0 11 40 00 33 00—–jmp far 33:004011D0h往后面跳转之后程序就变成了执行64位语句了。所以需要把相应的二进制dump下来放到64位ida中进行分析。
这里不要被这个
jmp far ptr loc_4014FE+2给欺骗了,这个语句没有被正确解析。这句话会远跳转到33:4011D0这个地址。远跳转有一个隐形的操作,他会将代码段寄存器CS设置为跳转到的这个段对应的段选择子,这里执行完了远跳转之后CS的值会变为0x33,


- 把4011d0h地址处的二进制dump出来用ida64分析之后。

注意 gs:qword_60 中 qword_60 是指
60 00 00 00而不是 0x00000060地址处的内容,否则人家会写成gs:[qword_60]
- 其实
407000h处存放的是原本call sub_401120下面一句的地址004013E8。当返回32位执行模式之后,刚好回到下面的语句。
这里有一个加密的过程。

- 在加密完成之后,有一个
call fword ptr其实和jmp far是一样的道理切换到 64位模式下执行。

这次跳转的地址为 00401200, 跟之前的操作是一样的, 同样是dump下来放到ida中分析。

注意这里面的 0x40705c – 在第一次跳转到64模式下执行的过程中,将 BeingDebugged的标志位放到了这个地址里面。
__ROL8__是一个循环左移的操作 其中retaddr[1]指向的实际上是用户输入。
执行完成之后返回到32位执行环境中。
- 第三次跳转到64位环境里面

同样dump 0x401290的字节码,使用64位IDA分析,这个函数主要修改了0x407000保存的返回值,然后对0x407014开始 的数组中的常量进行处理,得到新的值。

注意的是 407050h 存放的是0x401467
注意:前两次切换到64位模式后,函数结束就重新切换到32位模式了,但是这次出来后仍然为64位模式,因此main函数之后的代码也都是64位的指令


此时
407000h中存放的实际上是0x004014C5
- 后面就是常见的比较字符串的操作了。

参考资料
win PEB 中BeingDebugged标志位获取—https://blog.csdn.net/Simon798/article/details/100702034
ret 和 retf 的区别 – https://zhuanlan.zhihu.com/p/372398363

