2020-网鼎杯-逆向---signal
reverse signal
第一次接触虚拟机逆向,还不太清楚虚拟机逆向的原理等等,如有错误,请指正。
拖进ida查看伪代码:
main函数:
qmemcpy 给v4赋值,赋值内容是unk_403040函数,再看这个函数的内容:
是这一大段数据
再看vm_operad函数:这个函数里用到了403040函数,为了方便,将这个函数称作a1函数。
vm_operad函数里都是witch-case函数
因为v10,v9.。。太难辨认了,把它们分别改成了i、j、k、m、n
看case语句:
case1:
赋值,v4[m]=v5,v4和v5都是定义的未知变量,看下面哪里和v4数组的数据有关:
当a1中的数据的某一位为7的时候,就将v4和数据比较,如果不一样就输出“what a shame”,所以可以推出v4数组的值等于a1中的某些值。
再看case其他值:
case2: 将a1中的某个数和v3中某个数的和相加赋值给v5,
看看哪里有跟给v3赋值的信息:
看看read函数:
read函数就是exe文件运行的时候要求输入的一串字符串,长度为15。
那看来v3就是flag,vm_op函数对flag进行了加密处理,求flag的话就看switch-case函数来进行解密。
接着看case:
case2:对a1和v3进行相加操作
case3:对v3和a1进行相减操作
case4:对a1和v3进行异或操作
case5:对a1和v3进行相乘操作
case6:i变量自增
case8:给v3赋值
case11:v3-1之后的值赋给v5
case12:v3+1之后的值赋给v5
看完了这些函数之后,有一个问题就出现了:
i、j、k、m、n这些变量太多了,容易搞混。看了一下大佬们的wp:
v5是作为中间字符存在的,v9(j) 和 v6(n) 都是v3的下标,所以v9(j) 和 v6(n) 可以视为同一个,v7(m) 是v4的下标,但是由于是顺序加密的,所以 v7(m) 、v6(n) 、v9(j) 的值是相同的。
在a1数据的最后面会存在0xffffff开头的数据,但是ffffff只是填充,并不参与运算,参与运算的只看低八位。
一个个的手算:(这里要注意在hex-view看unk_403040函数的值的时候显示的是16进制的数,算的时候就有点迷糊,差点算错了)
分析的过程中会发现,整个switch-case语句里,只有case 1 这个语句是给v4赋值,而我们最后用来比较的也是v4。
也就是说a1函数里两个 01 之间的数对应的操作,就是对一个字符的操作。
所以遇到一个 01就print一个字符
解密代码:
print(chr((0x22^0x10)),end='')
print(chr(0x3f//3^0x20),end='')
print(chr(0x34+3),end='')
print(chr((0x32^4)-1),end='')
print(chr((0x72+0x21)//3),end='')
print(chr(0x33+2),end='')
print(chr((0x18+0x20)^9),end='')
print(chr((0xA7^0x24)-0x51),end='')
print(1,end='')
print(chr((0xf1-0x25)//2),end='')
print(chr((0x28^0x41)-0x36),end='')
print(chr((0x84-0x20)),end='')
print(chr((0xc1-0x25)//3),end='')
print(chr((0x1e+0x20)^9),end='')
print(chr((0x7a-0x42)),end='')
#757515121x3xx78
#print(chr((0x35+0x51)^0x24))
某位大佬用angr做的这个题,几行代码就解决了。给大家分享一下。(虽然我不会用angr
import angr
proj = angr.Project('./signal.exe',auto_load_libs = False) #载入文件创建镜像
state = proj.factory.entry_state() # 根据镜像创建进程
simgr = proj.factory.simgr(state) # 创建一个模拟器,用来模拟执行求解
simgr.explore(find = 0x40179E,avoid = 0x401539) # 成功的地址和失败的地址
print simgr.found[0].posix.dumps(0) # 把要找的结果输出
部分参考大佬的CSDN:
signal
上一篇: 广告上的
下一篇: 碰到这样的女人,不信你不疯掉