目录
题目
一个c++写的64位无壳程序
ida64打开,main函数f5
输入长度28,然后进行简单的异或,func1像是又加密了,进去看看
base64,再进func2康康
_cxa_throw函数是c++在抛出异常时被调用的函数,在这个函数中可以捕获栈信息
第一次在逆向题目里见到try catch呢wwww所以说在这个func2的地方抛出异常,那func1的主要作用大概就是引出这个异常了吧。前面那个base64求出来也会发现是个假的flag,所以纯纯就是用来迷惑人的www这样的话func1就不用进了
在主函数里找到catch块
在地址0000000000401C9B捏,然后找到try里抛出异常的地方
在这个call _Z5func1Pc指令的地方,把他patch成jmp catch块地址
然后再点f5就可以显示出完整的伪代码啦
还有一种更好的找catch块的方法,在所有的call __cxa_begin_catch指令上下个断点,main函数里的call __cxa_begin_catch有两个,然后通过动态调试判断触发哪个断点来分析catch块所在位置
然后就可以安心的分析代码啦,这里的base64是做了点变化的
把所有的结果都加了1
代码如下
import base64
# a = "GUw\D~UHG#kYG~\x7FBA#{QJT(\\A {BG~$BG~$BGz//"
str2 = "UGeNVlGZU1yKUlmPS1iCXF:NS2iPUl6PUl6PUh=="
str1 = 'TFdMUkFYT0xJTklOR0hBWE9MR1hOTk5OTk5OTg=='
# for i in range(len(str2)):
# str1 += chr(ord(str2[i]) - 1)
# print(str1)
b = base64.b64decode(str1)
print('Hexadecimal: ', b.hex())
f = [0x4c, 0x57, 0x4c, 0x52, 0x41, 0x58, 0x4f, 0x4c, 0x49, 0x4e, 0x49, 0x4e, 0x47, 0x48, 0x41, 0x58, 0x4f, 0x4c,
0x47, 0x58, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e]
flag = ''
for i in range(len(f)):
flag += chr((f[i] - 1) ^ 0x22)
print(flag)
小芝士
try catch
try catch这种逻辑直接拿ida看不出来,f5直接看到的伪代码是错误的, try里代码抛出的异常会先被操作系统捕获,然后通过操作系统的异常处理机制处理后再跳转到对应的catch块代码来运行,如果想用ida的f5得到正确的伪代码,就需要patch一下程序,思路就是先找到抛出异常的指令,然后patch成jmp catch块地址。(学长原话嘻嘻)