网鼎杯Re694
题目附件
查壳
UPX壳,试试自动脱壳工具 这时候就要意识到,要手动脱壳了。
寻找程序入口点EP(用x64dbg打开)
按下F8,单步步过
寻找原程序入口点OEP
发现右边寄存器窗口RSP寄存器变为红色,即可使用平衡堆栈法(又称ESP定律) 继续跳过直到彻底跳出push指令后,在RSP寄存器处右键,点击“在内存窗口中转到” 在下面内存窗口中,右击与RSP地址相同处,添加硬件断点。之后F9运行。
看到pop指令时,就离原始OEP不远了,因为执行完pop指令意味着壳代码告一段落了(即解压代码结束)。 看到后面有个jump函数,jump后跟的地址大概率就是原程序的OPE了。我们给jump指令打上断点,F9运行,直到到达jump指令处。 按下F7单步步入,就能看见函数和代码段了。
使用Scylla进行脱壳
此时,使用x64dbg带的插件Scylla进行脱壳。
用IDA64打开,就能发现脱壳完毕。
IDA64打开dump后的exe
很明显v7就是flag。 我们先进入函数sub_7FF734801235再进入1230函数,最后再到1840函数。 很明显,a1指向v7,并且在倒数第二行,对v7进行了一个异或操作。
接下来继续分析,1005明显是个比较函数。 把里面的函数都逛了一圈,并没有什么线索。于是将注意力放在了11E5上。 a1依旧指向v7函数。关键又在1276函数处。我们继续跟进。 函数的逻辑即将v7数组加上10后的结果再异或0x50,再与D000的数据进行比较。 联系到之前的加密,我们可以写出解题脚本
x=[0x4B,0x48,0x79,0x13,0x45,0x30,0x5C,0x49,0X5A,0X79,0X13,0x70,0x6D,0x78,0x13,0x6F,0x48,0x5D,0x64,0x64]
y={}
for i in range(len(x)):
y[i]=((x[i]^0x50)-10)^0x66
for i in range(len(x)):
print(chr(y[i]),end="")
得到结果
赛后总结
第一次手脱UPX的壳,其实当时都已经找到OEP了,但是在使用插件的时候,没dump反而直接fix dump,最后肯定是打不开了。(没了解原理的痛。。。)最后发现自己猪鼻时,距离比赛结束也不久了。。。 参考文章 脱UPX的三种方法 upx原理 upx原理 ESP定律 手脱UPX
评论区