def print_inst(self, i, tab=0, prefix=""): def get_inst_str(): nonlocal i return "%s %s" % (i.mnemonic, i.op_str) if i.address in self.ctx.dis.previous_comments: for comm in self.ctx.dis.previous_comments[i.address]: print_tabbed(color_intern_comment("; %s" % comm), tab) if prefix == "# ": if self.ctx.comments: if i.address in self.ctx.labels: print_label(i.address, tab) print() print_comment_no_end(prefix + hex(i.address) + ": ", tab) else: print_comment_no_end(prefix, tab) print_addr(i.address) self.print_bytes(i, True) print_comment(get_inst_str()) return if i.address in self.ctx.all_fused_inst: return if self.is_symbol(i.address): print_tabbed_no_end("", tab) self.print_symbol(i.address) print() modified = self.__print_inst(i, tab, prefix) if i.address in self.ctx.dis.inline_comments: print_no_end(color_intern_comment(" ; ")) print_no_end( color_intern_comment(self.ctx.dis.inline_comments[i.address])) if modified and self.ctx.comments: print_comment_no_end(" # " + get_inst_str()) print()
def print_inst(self, i, tab=0, prefix=""): def get_inst_str(): nonlocal i return "%s %s" % (i.mnemonic, i.op_str) if i.address in self.ctx.dis.previous_comments: for comm in self.ctx.dis.previous_comments[i.address]: print_tabbed(color_intern_comment("; %s" % comm), tab) if prefix == "# ": if self.ctx.comments: if i.address in self.ctx.labels: print_label(i.address, tab) print() print_comment_no_end(prefix + hex(i.address) + ": ", tab) else: print_comment_no_end(prefix, tab) print_addr(i.address) self.print_bytes(i, True) print_comment(get_inst_str()) return if i.address in self.ctx.all_fused_inst: return if self.is_symbol(i.address): print_tabbed_no_end("", tab) self.print_symbol(i.address) print() modified = self.__print_inst(i, tab, prefix) if i.address in self.ctx.dis.inline_comments: print_no_end(color_intern_comment(" ; ")) print_no_end(color_intern_comment(self.ctx.dis.inline_comments[i.address])) if modified and self.ctx.comments: print_comment_no_end(" # " + get_inst_str()) print()
def print_operand(self, i, num_op, hexa=False, show_deref=True): def inv(n): return n == MIPS_OP_INVALID op = i.operands[num_op] if op.type == MIPS_OP_IMM: imm = op.value.imm sec_name, is_data = self.binary.is_address(imm) if sec_name is not None: modified = False if self.ctx.sectionsname: print_no_end("(" + color_section(sec_name) + ") ") if imm in self.binary.reverse_symbols: self.print_symbol(imm) print_no_end(" ") modified = True if imm in self.ctx.labels: print_label(imm, print_colon=False) print_no_end(" ") modified = True if not modified: print_no_end(hex(imm)) if is_data: s = self.binary.get_string(imm, self.ctx.max_data_size) if s != "\"\"": print_no_end(" " + color_string(s)) return modified elif hexa: print_no_end(hex(imm)) else: print_no_end(str(imm)) if imm > 0: packed = struct.pack("<L", imm) if set(packed).issubset(BYTES_PRINTABLE_SET): print_no_end(color_string(" \"")) print_no_end(color_string("".join(map(chr, packed)))) print_no_end(color_string("\"")) return False # returns True because capstone print immediate in hexa # it will be printed in a comment, sometimes it's better # to have the value in hexa return True return False elif op.type == MIPS_OP_REG: print_no_end("$") print_no_end(i.reg_name(op.value.reg)) return False elif op.type == MIPS_OP_MEM: mm = op.mem printed = False if show_deref: print_no_end("*(") if not inv(mm.base): print_no_end("$%s" % i.reg_name(mm.base)) printed = True if mm.disp != 0: sec_name, is_data = self.binary.is_address(mm.disp) if sec_name is not None: if printed: print_no_end(" + ") if mm.disp in self.binary.reverse_symbols: self.print_symbol(mm.disp) else: print_no_end(hex(mm.disp)) else: if printed: if mm.disp < 0: print_no_end(" - ") print_no_end(-mm.disp) else: print_no_end(" + ") print_no_end(mm.disp) if show_deref: print_no_end(")") return True
def print_inst(self, i, tab=0, prefix=""): def get_inst_str(): nonlocal i return "%s %s" % (i.mnemonic, i.op_str) if isinstance(i, NopInst): return if isinstance(i, PseudoInst): for i2 in i.real_inst_list: self.print_inst(i2, tab, "# ") print_label_and_addr(i.real_inst_list[0].address, tab) print(i.pseudo) return if i.address in self.ctx.dis.previous_comments: for comm in self.ctx.dis.previous_comments[i.address]: print_tabbed(color_intern_comment("; %s" % comm), tab) if prefix == "# ": if self.ctx.comments: if i.address in self.ctx.labels: print_label(i.address, tab) print() print_comment_no_end(prefix, tab) print_addr(i.address) self.print_bytes(i, True) print_comment(get_inst_str()) return if i.address in self.ctx.all_fused_inst: return if self.is_symbol(i.address): print_tabbed_no_end("", tab) self.print_symbol(i.address) print() print_label_and_addr(i.address, tab) self.print_bytes(i) if is_ret(i): print(color_retcall(get_inst_str())) return if is_call(i): print_no_end(color_retcall(i.mnemonic) + " ") modified = self.print_operand(i, 0, hexa=True) if modified and self.ctx.comments: print_comment_no_end(" # " + get_inst_str()) print() return # Here we can have conditional jump with the option --dump if is_jump(i): print_no_end(i.mnemonic + " ") if i.operands[-1].type != MIPS_OP_IMM: print_no_end(i.op_str) if is_uncond_jump(i) and self.ctx.comments and not self.ctx.dump \ and not i.address in self.ctx.dis.jmptables: print_comment_no_end(" # STOPPED") print() return for num in range(len(i.operands)-1): self.print_operand(i, num) print_no_end(", ") addr = i.operands[0].value.imm if addr in self.ctx.addr_color: print_label_or_addr(addr, -1, False) else: print_no_end(hex(addr)) print() return modified = False if i.id in LD_CHECK: self.print_operand(i, 0) print_no_end(" = (") print_no_end(color_type(LD_TYPE[i.id])) print_no_end(") ") self.print_operand(i, 1) modified = True elif i.id in ST_CHECK: self.print_operand(i, 1) print_no_end(" = (") print_no_end(color_type(ST_TYPE[i.id])) print_no_end(") ") self.print_operand(i, 0) modified = True elif i.id in INST_CHECK: if i.id == MIPS_INS_LUI: print_no_end("(load upper) ") self.print_operand(i, 0) print_no_end(" = ") self.print_operand(i, 1) elif i.id == MIPS_INS_MOVE: self.print_operand(i, 0) print_no_end(" = ") if i.operands[1].value.reg == MIPS_REG_ZERO: print_no_end("0") else: self.print_operand(i, 1) else: self.print_operand(i, 0) if i.operands[0].type == i.operands[1].type == MIPS_OP_REG and \ i.operands[0].value.reg == i.operands[1].value.reg: print_no_end(" " + inst_symbol(i) + "= ") else: print_no_end(" = ") self.print_operand(i, 1) print_no_end(" " + inst_symbol(i) + " ") self.print_operand(i, 2) modified = True else: print_no_end("%s " % i.mnemonic) if len(i.operands) > 0: modified = self.print_operand(i, 0) k = 1 while k < len(i.operands): print_no_end(", ") modified |= self.print_operand(i, k) k += 1 if i.address in self.ctx.dis.inline_comments: print_no_end(color_intern_comment(" ; ")) print_no_end(color_intern_comment(self.ctx.dis.inline_comments[i.address])) if modified and self.ctx.comments: print_comment_no_end(" # " + get_inst_str()) print()
def print_inst(self, i, tab=0, prefix=""): def get_inst_str(): nonlocal i return "%s %s" % (i.mnemonic, i.op_str) if i.address in self.ctx.dis.previous_comments: for comm in self.ctx.dis.previous_comments[i.address]: print_tabbed(color_intern_comment("; %s" % comm), tab) if prefix == "# ": if self.ctx.comments: if i.address in self.ctx.labels: print_label(i.address, tab) print() print_comment_no_end(prefix, tab) print_addr(i.address) self.print_bytes(i, True) print_comment(get_inst_str()) return if i.address in self.ctx.all_fused_inst: return if self.is_symbol(i.address): print_tabbed_no_end("", tab) self.print_symbol(i.address) print() print_label_and_addr(i.address, tab) self.print_bytes(i) if is_ret(i): print(color_retcall(get_inst_str())) return if is_call(i): print_no_end(color_retcall(i.mnemonic) + " ") modified = self.print_operand(i, 0, hexa=True) if modified and self.ctx.comments: print_comment_no_end(" # " + get_inst_str()) print() return # Here we can have conditional jump with the option --dump if is_jump(i): print_no_end(i.mnemonic + " ") if i.operands[0].type != ARM_OP_IMM: print_no_end(i.op_str) if is_uncond_jump(i) and self.ctx.comments and not self.ctx.dump \ and not i.address in self.ctx.dis.jmptables: print_comment_no_end(" # STOPPED") print() return addr = i.operands[0].value.imm if addr in self.ctx.addr_color: print_label_or_addr(addr, -1, False) else: print_no_end(hex(addr)) print() return modified = False if i.id in LDR_CHECK: self.print_operand(i, 0) print_no_end(" = (") print_no_end(color_type(LDR_TYPE[i.id])) print_no_end(") ") self.print_operand(i, 1) modified = True elif i.id in STR_CHECK: self.print_operand(i, 1) print_no_end(" = (") print_no_end(color_type(STR_TYPE[i.id])) print_no_end(") ") self.print_operand(i, 0) modified = True elif i.id in INST_CHECK: self.print_operand(i, 0) if i.id == ARM_INS_CMP: print_no_end(" " + inst_symbol(i) + " ") self.print_operand(i, 1) else: print_no_end(" = ") self.print_operand(i, 1) if len(i.operands) == 3: print_no_end(" " + inst_symbol(i) + " ") self.print_operand(i, 2) modified = True else: print_no_end("%s " % i.mnemonic) if len(i.operands) > 0: modified = self.print_operand(i, 0) k = 1 while k < len(i.operands): print_no_end(", ") modified |= self.print_operand(i, k) k += 1 if i.update_flags and i.id != ARM_INS_CMP and i.id != ARM_INS_TST: print_no_end(color_type(" (FLAGS)")) if i.address in self.ctx.dis.inline_comments: print_no_end(color_intern_comment(" ; ")) print_no_end(color_intern_comment(self.ctx.dis.inline_comments[i.address])) if modified and self.ctx.comments: print_comment_no_end(" # " + get_inst_str()) print()
def print_operand(self, i, num_op, hexa=False, show_deref=True): def inv(n): return n == ARM_OP_INVALID op = i.operands[num_op] if op.shift.type: print_no_end("(") if op.type == ARM_OP_IMM: imm = op.value.imm sec_name, is_data = self.binary.is_address(imm) if sec_name is not None: modified = False if self.ctx.sectionsname: print_no_end("(" + color_section(sec_name) + ") ") if imm in self.binary.reverse_symbols: self.print_symbol(imm) print_no_end(" ") modified = True if imm in self.ctx.labels: print_label(imm, print_colon=False) print_no_end(" ") modified = True if not modified: print_no_end(hex(imm)) if is_data: s = self.binary.get_string(imm, self.ctx.max_data_size) if s != "\"\"": print_no_end(" " + color_string(s)) return modified elif hexa: print_no_end(hex(imm)) else: print_no_end(str(imm)) if imm > 0: packed = struct.pack("<L", imm) if set(packed).issubset(BYTES_PRINTABLE_SET): print_no_end(color_string(" \"")) print_no_end(color_string("".join(map(chr, packed)))) print_no_end(color_string("\"")) return False # returns True because capstone print immediate in hexa # it will be printed in a comment, sometimes it's better # to have the value in hexa return True return False elif op.type == ARM_OP_REG: if op.value.reg == ARM_REG_PC and i.reg_read(ARM_REG_PC): print_no_end(hex(i.address)) else: print_no_end(i.reg_name(op.value.reg)) if op.shift.type: self.print_shift(i, op.shift) return False elif op.type == ARM_OP_FP: print_no_end("%f" % op.value.fp) if op.shift.type: self.print_shift(i, op.shift) return False elif op.type == ARM_OP_MEM: mm = op.mem if not inv(mm.base) and mm.disp != 0 and inv(mm.index): # if (mm.base == X86_REG_RBP or mm.base == X86_REG_EBP) and \ # self.var_name_exists(i, num_op): # print_no_end(color_var(self.get_var_name(i, num_op))) # return True if mm.base == ARM_REG_PC: addr = i.address + i.size * 2 + mm.disp print_no_end("*(") if addr in self.binary.reverse_symbols: self.print_symbol(addr) else: print_no_end(hex(addr)) print_no_end(")") return True printed = False if show_deref: print_no_end("*(") if not inv(mm.base): print_no_end("%s" % i.reg_name(mm.base)) printed = True elif not inv(mm.segment): print_no_end("%s" % i.reg_name(mm.segment)) printed = True if not inv(mm.index): if printed: print_no_end(" + ") if mm.scale == 1: print_no_end("%s" % i.reg_name(mm.index)) else: print_no_end("(%s*%d)" % (i.reg_name(mm.index), mm.scale)) if op.shift.type: self.print_shift(i, op.shift) printed = True if mm.disp != 0: sec_name, is_data = self.binary.is_address(mm.disp) if sec_name is not None: if printed: print_no_end(" + ") if mm.disp in self.binary.reverse_symbols: self.print_symbol(mm.disp) else: print_no_end(hex(mm.disp)) else: if printed: if mm.disp < 0: print_no_end(" - ") print_no_end(-mm.disp) else: print_no_end(" + ") print_no_end(mm.disp) if show_deref: print_no_end(")") return True
def print_inst(self, i, tab=0, prefix=""): def get_inst_str(): nonlocal i return "%s %s" % (i.mnemonic, i.op_str) if isinstance(i, NopInst): return if isinstance(i, PseudoInst): for i2 in i.real_inst_list: self.print_inst(i2, tab, "# ") print_label_and_addr(i.real_inst_list[0].address, tab) print(i.pseudo) return if i.address in self.ctx.dis.previous_comments: for comm in self.ctx.dis.previous_comments[i.address]: print_tabbed(color_intern_comment("; %s" % comm), tab) if prefix == "# ": if self.ctx.comments: if i.address in self.ctx.labels: print_label(i.address, tab) print() print_comment_no_end(prefix, tab) print_addr(i.address) self.print_bytes(i, True) print_comment(get_inst_str()) return if i.address in self.ctx.all_fused_inst: return if self.is_symbol(i.address): print_tabbed_no_end("", tab) self.print_symbol(i.address) print() print_label_and_addr(i.address, tab) self.print_bytes(i) if is_ret(i): print(color_retcall(get_inst_str())) return if is_call(i): print_no_end(color_retcall(i.mnemonic) + " ") modified = self.print_operand(i, 0, hexa=True) if modified and self.ctx.comments: print_comment_no_end(" # " + get_inst_str()) print() return # Here we can have conditional jump with the option --dump if is_jump(i): print_no_end(i.mnemonic + " ") if i.operands[-1].type != MIPS_OP_IMM: print_no_end(i.op_str) if is_uncond_jump(i) and self.ctx.comments and not self.ctx.dump \ and not i.address in self.ctx.dis.jmptables: print_comment_no_end(" # STOPPED") print() return for num in range(len(i.operands) - 1): self.print_operand(i, num) print_no_end(", ") addr = i.operands[0].value.imm if addr in self.ctx.addr_color: print_label_or_addr(addr, -1, False) else: print_no_end(hex(addr)) print() return modified = False if i.id in LD_CHECK: self.print_operand(i, 0) print_no_end(" = (") print_no_end(color_type(LD_TYPE[i.id])) print_no_end(") ") self.print_operand(i, 1) modified = True elif i.id in ST_CHECK: self.print_operand(i, 1) print_no_end(" = (") print_no_end(color_type(ST_TYPE[i.id])) print_no_end(") ") self.print_operand(i, 0) modified = True elif i.id in INST_CHECK: if i.id == MIPS_INS_LUI: print_no_end("(load upper) ") self.print_operand(i, 0) print_no_end(" = ") self.print_operand(i, 1) elif i.id == MIPS_INS_MOVE: self.print_operand(i, 0) print_no_end(" = ") if i.operands[1].value.reg == MIPS_REG_ZERO: print_no_end("0") else: self.print_operand(i, 1) else: self.print_operand(i, 0) if i.operands[0].type == i.operands[1].type == MIPS_OP_REG and \ i.operands[0].value.reg == i.operands[1].value.reg: print_no_end(" " + inst_symbol(i) + "= ") else: print_no_end(" = ") self.print_operand(i, 1) print_no_end(" " + inst_symbol(i) + " ") self.print_operand(i, 2) modified = True else: print_no_end("%s " % i.mnemonic) if len(i.operands) > 0: modified = self.print_operand(i, 0) k = 1 while k < len(i.operands): print_no_end(", ") modified |= self.print_operand(i, k) k += 1 if i.address in self.ctx.dis.inline_comments: print_no_end(color_intern_comment(" ; ")) print_no_end( color_intern_comment(self.ctx.dis.inline_comments[i.address])) if modified and self.ctx.comments: print_comment_no_end(" # " + get_inst_str()) print()
def print_inst(self, i, tab=0, prefix=""): def get_inst_str(): nonlocal i return "%s %s" % (i.mnemonic, i.op_str) if prefix == "# ": if self.ctx.comments: if i.address in self.ctx.labels: print_label(i.address, tab) print() print_comment_no_end(prefix, tab) print_addr(i.address) self.print_bytes(i, True) print_comment(get_inst_str()) return if i.address in self.ctx.all_fused_inst: return if self.is_symbol(i.address): print_tabbed_no_end("", tab) self.print_symbol(i.address) print() print_label_and_addr(i.address, tab) self.print_bytes(i) if is_ret(i): print(color_retcall(get_inst_str())) return if is_call(i): print_no_end(color_retcall(i.mnemonic) + " ") modified = self.print_operand(i, 0, hexa=True) if modified and self.ctx.comments: print_comment_no_end(" # " + get_inst_str()) print() return # Here we can have conditional jump with the option --dump if is_jump(i): print_no_end(i.mnemonic + " ") if i.operands[0].type != ARM_OP_IMM: print_no_end(i.op_str) if is_uncond_jump( i) and self.ctx.comments and not self.ctx.dump: print_comment_no_end(" # STOPPED") print() return addr = i.operands[0].value.imm if addr in self.ctx.addr_color: print_label_or_addr(addr, -1, False) else: print_no_end(hex(addr)) print() return modified = False if i.id in LDR_CHECK: self.print_operand(i, 0) print_no_end(" = (") print_no_end(color_type(LDR_TYPE[i.id])) print_no_end(") ") self.print_operand(i, 1) modified = True elif i.id in STR_CHECK: self.print_operand(i, 1) print_no_end(" = (") print_no_end(color_type(STR_TYPE[i.id])) print_no_end(") ") self.print_operand(i, 0) modified = True elif i.id in INST_CHECK: self.print_operand(i, 0) if i.id == ARM_INS_CMP: print_no_end(" " + inst_symbol(i) + " ") self.print_operand(i, 1) else: print_no_end(" = ") self.print_operand(i, 1) if len(i.operands) == 3: print_no_end(" " + inst_symbol(i) + " ") self.print_operand(i, 2) modified = True else: print_no_end("%s " % i.mnemonic) if len(i.operands) > 0: modified = self.print_operand(i, 0) k = 1 while k < len(i.operands): print_no_end(", ") modified |= self.print_operand(i, k) k += 1 if i.update_flags and i.id != ARM_INS_CMP and i.id != ARM_INS_TST: print_no_end(color_type(" (FLAGS)")) if modified and self.ctx.comments: print_comment_no_end(" # " + get_inst_str()) print()
def print_operand(self, i, num_op, hexa=False, show_deref=True): def inv(n): return n == ARM_OP_INVALID op = i.operands[num_op] if op.shift.type: print_no_end("(") if op.type == ARM_OP_IMM: imm = op.value.imm sec_name, is_data = self.binary.is_address(imm) if sec_name is not None: modified = False if self.ctx.sectionsname: print_no_end("(" + color_section(sec_name) + ") ") if imm in self.binary.reverse_symbols: self.print_symbol(imm) print_no_end(" ") modified = True if imm in self.ctx.labels: print_label(imm, print_colon=False) print_no_end(" ") modified = True if not modified: print_no_end(hex(imm)) if is_data: s = self.binary.get_string(imm, self.ctx.max_data_size) if s != "\"\"": print_no_end(" " + color_string(s)) return modified elif hexa: print_no_end(hex(imm)) else: print_no_end(str(imm)) if imm > 0: packed = struct.pack("<L", imm) if set(packed).issubset(BYTES_PRINTABLE_SET): print_no_end(color_string(" \"")) print_no_end(color_string("".join(map(chr, packed)))) print_no_end(color_string("\"")) return False # returns True because capstone print immediate in hexa # it will be printed in a comment, sometimes it's better # to have the value in hexa return True return False elif op.type == ARM_OP_REG: if op.value.reg == ARM_REG_PC and i.reg_read(ARM_REG_PC): print_no_end(hex(i.address)) else: print_no_end(i.reg_name(op.value.reg)) if op.shift.type: self.print_shift(i, op.shift) return False elif op.type == ARM_OP_FP: print_no_end("%f" % op.value.fp) if op.shift.type: self.print_shift(i, op.shift) return False elif op.type == ARM_OP_MEM: mm = op.mem if not inv(mm.base) and mm.disp != 0 and inv(mm.index): # if (mm.base == X86_REG_RBP or mm.base == X86_REG_EBP) and \ # self.var_name_exists(i, num_op): # print_no_end(color_var(self.get_var_name(i, num_op))) # return True if mm.base == ARM_REG_PC: addr = i.address + i.size + mm.disp print_no_end("*({0})".format( self.binary.reverse_symbols.get(addr, hex(addr)))) return True printed = False if show_deref: print_no_end("*(") if not inv(mm.base): print_no_end("%s" % i.reg_name(mm.base)) printed = True elif not inv(mm.segment): print_no_end("%s" % i.reg_name(mm.segment)) printed = True if not inv(mm.index): if printed: print_no_end(" + ") if mm.scale == 1: print_no_end("%s" % i.reg_name(mm.index)) else: print_no_end("(%s*%d)" % (i.reg_name(mm.index), mm.scale)) if op.shift.type: self.print_shift(i, op.shift) printed = True if mm.disp != 0: sec_name, is_data = self.binary.is_address(mm.disp) if sec_name is not None: if printed: print_no_end(" + ") if mm.disp in self.binary.reverse_symbols: self.print_symbol(mm.disp) else: print_no_end(hex(mm.disp)) else: if printed: if mm.disp < 0: print_no_end(" - ") print_no_end(-mm.disp) else: print_no_end(" + ") print_no_end(mm.disp) if show_deref: print_no_end(")") return True