|   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()  
 |