--这是我的第一个博客--如有错误希望大佬能指出---
进来之后看到第8行和第12行有不知道的函数,分别是sub_140001000,sub_1400010B0。
进入第8行的sub_140001000看看。
再进入sub_140001060。
会发现初始化了一些以a1为基地址的数据。
vm逆向,即虚拟机逆向。这里的虚拟机类似java虚拟机,python虚拟机,能够解释一系列自研的指令。
而这里对a1的初始化,很可能是对自研的指令系统的寄存器初始化。
建一个结构体方便下面的分析。
在Structure窗口右键,点击add struct type或者按快捷键insert可以新建一个结构体。
我命名为了VM。
在ends处点击d可以新建结构体成员。
根据上上上个图,会发现也许可以这样建结构体。
不过这个题有提示怎么建结构体。
右键想转为结构体的变量可以转为指定结构体,这里转a1。
会发现这个函数需要返回0才算成功。
然后进入这个函数看看。
这也是a1,把它转成结构体。
会发现如果这个数组指定下标的值如果不是255,就执行下面的函数。返回值是zzz。那么zzz必须是0。
byte_140005360数组里也许就是这道题的加密过程的指令了。进入sub_140001940函数看看。
又有a1,把a1转成结构体。
看到很多case。这个数组也是上面说到的数组,进去看看。
果然是一堆。那么可以把数组重命名为opcode。
回到之前的函数,每个case下面的函数就是根据不同指令 [opcode数组] 做出的不同处理。
并且数组的下标是结构体a1的成员xxx,那么xxx就是指令寄存器ip。
把每个case里面的函数的a1都转成结构体。
进入case 0,发现根据opcode的ip的下一个数据执行不同赋值操作。
如果在main函数里重命名了,会发现数组dword_140005040就是存放用户输入的flag的数组。
下面是重命名后的。
会发现里面涉及到opcode[ip~ip+3],一共4字节的数据。函数的后面ip也进行了+4。
看外层函数的case 1,会发现把寄存器的值复制到了一个什么数组。
再看外层函数的case 2,把同样的数组的值赋给寄存器。
这个函数代表内存区域的那部分呢?我们会发现yyy进行了自增自减。可以猜测是栈。而yyy代表sp。
那么这两个函数分别是入栈和出栈。
看这个函数,会发现是一些有关寄存器的运算。
在这个函数,会发现zzz代表reg[0]和reg[1]相不相等。相等则是0。相当于汇编语言的cmp,比较之后给zzz赋值。
这个函数相当于jmp ip+1即jmp opcode[ip+1]。
这个函数即je opcode[ip+1]。
这个函数即jne opcode[ip+1]。
下面是我的代码。
python脚本
opcode = [0x00, 0x03, 0x02, 0x00, 0x03, 0x00, 0x02, 0x03, 0x00, 0x00,0x00, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00, 0x03, 0x02, 0x32,0x03, 0x00, 0x02, 0x03, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00,0x01, 0x00, 0x00, 0x03, 0x02, 0x64, 0x03, 0x00, 0x02, 0x03,0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x01, 0x00, 0x00, 0x03,0x00, 0x08, 0x00, 0x02, 0x02, 0x01, 0x03, 0x04, 0x01, 0x00,0x03, 0x05, 0x02, 0x00, 0x03, 0x00, 0x01, 0x02, 0x00, 0x02,0x00, 0x01, 0x01, 0x00, 0x00, 0x03, 0x00, 0x01, 0x03, 0x00,0x03, 0x00, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x01, 0x28,0x04, 0x06, 0x5F, 0x05, 0x00, 0x00, 0x03, 0x03, 0x00, 0x02,0x01, 0x00, 0x03, 0x02, 0x96, 0x03, 0x00, 0x02, 0x03, 0x00,0x00, 0x00, 0x00, 0x04, 0x07, 0x88, 0x00, 0x03, 0x00, 0x01,0x03, 0x00, 0x03, 0x00, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03,0x01, 0x28, 0x04, 0x07, 0x63, 0xFF, 0xFF]
ip = 0
while opcode[ip] != 255:print(f"{str(ip)+':':<8}",end='')match opcode[ip]:case 0:match opcode[ip+1]:case 0:print("mov reg[0] input[reg[2]]")case 1:print("mov input[reg[2]] reg[0]")case 2:print(f"mov reg[{opcode[ip+2]}] reg[{opcode[ip+3]}]")case 3:print(f"mov reg[{opcode[ip+2]}] {opcode[ip+3]}")ip+=4case 1:match opcode[ip+1]:case 0:print("push reg[0]")case 1:print("push reg[0]")case 2:print("push reg[2]")case 3:print("push reg[3]")ip+=2case 2:match opcode[ip+1]:case 0:print("pop reg[0]")case 1:print("pop reg[1]")case 2:print("pop reg[2]")case 3:print("pop reg[3]")ip+=2case 3:match opcode[ip+1]:case 0:print(f"add reg[{opcode[ip+2]}] reg[{opcode[ip+3]}]")case 1:print(f"sub reg[{opcode[ip+2]}] reg[{opcode[ip+3]}]")case 2:print(f"mul reg[{opcode[ip+2]}] reg[{opcode[ip+3]}]")case 3:print(f"xor reg[{opcode[ip+2]}] reg[{opcode[ip+3]}]")case 4:print(f"shl reg[{opcode[ip+2]}] reg[{opcode[ip+3]}]")# print(f" and reg[{opcode[ip+2]}] 0xFF00")case 5:print(f"shr reg[{opcode[ip+2]}] reg[{opcode[ip+3]}]")ip+=4case 4:print("cmp reg[0] reg[1]")ip+=1case 5:print(f"jmp {opcode[ip+1]}")ip+=2case 6:print(f"je {opcode[ip+1]}")ip+=2case 7:print(f"jne {opcode[ip+1]}")ip+=2
下面是得出的结果。
伪汇编代码
0: mov reg[2] 0
4: add reg[2] reg[3]
8: mov reg[0] input[reg[2]]
12: mov reg[1] reg[0]
16: mov reg[2] 50
20: add reg[2] reg[3]
24: mov reg[0] input[reg[2]]
28: add reg[1] reg[0]
32: mov reg[2] 100
36: add reg[2] reg[3]
40: mov reg[0] input[reg[2]]
44: xor reg[1] reg[0]
48: mov reg[0] 8
52: mov reg[2] reg[1]
56: shl reg[1] reg[0]and reg[1] 0xFF00
60: shr reg[2] reg[0]
64: add reg[1] reg[2]
68: mov reg[0] reg[1]
72: push reg[0]
74: mov reg[0] 1
78: add reg[3] reg[0]
82: mov reg[0] reg[3]
86: mov reg[1] 40
90: cmp reg[0] reg[1]
91: je 95
93: jmp 0
95: mov reg[3] 0
99: pop reg[1]
101: mov reg[2] 150
105: add reg[2] reg[3]
109: mov reg[0] input[reg[2]]
113: cmp reg[0] reg[1]
114: jne 136
116: mov reg[0] 1
120: add reg[3] reg[0]
124: mov reg[0] reg[3]
128: mov reg[1] 40
132: cmp reg[0] reg[1]
133: jne 99
然后不会了呢。