1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
| import gdb
import struct
class Opcode: #opcode结构
opcode = ""
val1 = 0
const = 0
src = 0
dest = 0
final = 0
final2 = 0
def __init__(self, opcode):
self.opcode = opcode
test = struct.unpack("<Q", int(opcode, 16).to_bytes(8, byteorder='big'))[0]
self.val1 = test >> 56
self.const = (test >> 48) & 0xff
self.src = (test >> 40) & 0xff
self.dest = (test >> 32) & 0xff
self.final = struct.unpack("<I", ((test & 0xffffffff00) >> 8).to_bytes(4, byteorder='big'))[0]
self.final2 = struct.unpack("<I", (test & 0xffffffff).to_bytes(4, byteorder='big'))[0]
def __repr__(self):
str_out = "-------------------\n"
str_out += "OPCODE : %s | %d\n" % (self.opcode, int(self.opcode, 16) )
str_out += "val1 = %d | const = %d | src = %d | dest = %d\n" % (self.val1, self.const, self.src, self.dest)
str_out += "val1 = %s | const = %s | src = %s | dest = %s\n" % (hex(self.val1), hex(self.const), hex(self.src), hex(self.dest))
str_out += "final = %d | final2 = %d \n" % (self.final, self.final2)
str_out += "-------------------\n"
return str_out
sign = {4: "SIGILL", 5 : "SIGTRAP", 8: "SIGFPE", 0xb: "SIGSEGV" }
mov_ins = {0: "%d: mov r%d r%d\n",1: "%d: mov r%d 0x%x\n" ,2: "%d: mov r%d [r%d]\n", 32: "%d: mov [r%d] r%d\n"}
ops = ["add" , "sub" , "mul" , "div" , "mod" , "or" , "and" , "xor" , "lsh" , "rsh"]
op_sym = ["+", "-", "*", "/", "%", "|", "&", "^", "<<", ">>"]
str_ops = ["%d: %s r%d r%d\n", "%d: %s r%d 0x%x\n"]
jmp = ["", "eq", "neq", "le", "lt", "ge", "gt"]
f = open('ins.out', 'w')
gdb.execute("file signal_vm") # 加载被调试的可执行程序文件
gdb.execute("set pagination off") #gdb会全部输出,中间不暂停
gdb.execute("set follow-fork-mode parent") #fork之后继续调试父进程
gdb.execute("b * 0x400C5B") # 获取子进程内存值的ptrace处
gdb.execute("b * 0x400C67") # signal控制跳转处
gdb.execute("b * 0x401448") # 设置寄存器值的ptrace处
gdb.execute("r < input")
i = 0
while True:
try:
i = int(gdb.execute("p/x $rdx", to_string=True).split("=")[1].strip(),16)
if a == 0:
a = i
i = i % a
gdb.execute("ni") # 执行call ptrace后获取rax中的返回值
except gdb.error:
break
opcode = gdb.execute("p/x $rax", to_string=True).split("=")[1].strip()
gdb.execute("c")
# 将BYTE1(stat_addr[0])保存在al中来控制跳转的,直接获取al的值
sig = gdb.execute("p/x $al", to_string=True).split("=")[1].strip()
gdb.execute("c")
print(sign[int(sig, 16)])
op = Opcode(opcode)
print(op)
# 根据sig和opcode进行翻译
if int(sig, 16) == 4:
if op.const == 1:
f.write(mov_ins[op.const] % (i, op.src, op.final))
else:
f.write(mov_ins[op.const] % (i, op.src, op.dest))
elif int(sig, 16) == 5:
if op.const == 1:
f.write(str_ops[1] % (i, ops[op.val1], op.src, op.final))
else:
f.write(str_ops[0] % (i, ops[op.val1], op.src, op.dest))
elif int(sig, 16) == 8:
if op.src == 1:
f.write("%d: cmp r%d 0x%x\n" % (i, op.dest, op.final2))
else:
f.write("%d: cmp r%d r%d\n" % (i, op.dest, op.final2 & 0xff))
elif int(sig, 16) == 0xb:
f.write("%d: jmp %s 0x%x\n" % (i, jmp[op.src], op.dest))
else:
print("Error")
gdb.execute("c")
i = i + 1
f.close()
|