网鼎杯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
评论区