def print_section_meta(self, name, start, end): print_no_end(color_section(name.ljust(20))) print_no_end(" [") print_no_end(hex(start)) print_no_end(" - ") print_no_end(hex(end)) print("]")
def print_rep_begin(): nonlocal tab if i.prefix[0] in REP_PREFIX: print_tabbed_no_end(color_keyword("while"), tab) # TODO: for 16 and 32 bits print_no_end(" (!rcx)") print(") {") tab += 1
def print(self, o, tab=0): o.print_commented_jump(self.orig_jump, self.fused_inst, tab) if self.prefetch is not None: o.print_inst(self.prefetch, tab) print_tabbed_no_end(color_keyword("if "), tab) o.print_if_cond(self.cond_id, self.fused_inst) print_no_end(color_keyword(" goto ")) print(color_addr(self.addr_jump, False))
def print_rep_end(): nonlocal tab if i.prefix[0] in REP_PREFIX: print() print_label_or_addr(i.address, tab) print("rcx--") if i.prefix[0] == X86_PREFIX_REPNE: print_tabbed_no_end(color_keyword("if"), tab) print_no_end(" (!Z) ") print(color_keyword("break")) tab -= 1 print_tabbed_no_end("}", tab)
def print_symbols(self, print_sections, sym_filter=None): if sym_filter is not None: sym_filter = sym_filter.lower() for addr in self.binary.reverse_symbols: sy = self.binary.reverse_symbols[addr] if sym_filter is None or sym_filter in sy.lower(): sec_name, _ = self.binary.is_address(addr) print_no_end(color_addr(addr) + " " + color_symbol("<" + sy + ">")) if print_sections and sec_name is not None: print_no_end(" (" + color_section(sec_name) + ")") print()
def print_symbols(self, print_sections, sym_filter=None): if sym_filter is not None: sym_filter = sym_filter.lower() for addr in self.binary.reverse_symbols: sy = self.binary.reverse_symbols[addr] if sym_filter is None or sym_filter in sy.lower(): sec_name, _ = self.binary.is_address(addr) if sy: print_no_end(color_addr(addr) + " " + sy) if print_sections and sec_name is not None: print_no_end(" (" + color_section(sec_name) + ")") print()
def print(self, o, tab=0): o.print_commented_jump(None, self.fused_inst, tab) print_tabbed_no_end(color_keyword("if "), tab) o.print_if_cond(self.cond_id, self.fused_inst) # If it contains only one instruction if self.fused_inst == None and len(self.br.nodes) == 1 and \ len(self.br.nodes[0]) == 1 and isinstance(self.br.nodes[0], list): print_no_end(" : ") o.print_inst(self.br.nodes[0][0], 0) else: print(" {") self.br.print(o, tab+1) print_tabbed("}", tab)
def print(self, o, tab=0): o.print_commented_jump(None, self.fused_inst, tab) print_tabbed_no_end(color_keyword("if "), tab) o.print_if_cond(self.cond_id, self.fused_inst) # If it contains only one instruction if self.fused_inst == None and len(self.br.nodes) == 1 and \ len(self.br.nodes[0]) == 1 and isinstance(self.br.nodes[0], list): print_no_end(" : ") o.print_inst(self.br.nodes[0][0], 0) else: print(" {") self.br.print(o, tab + 1) print_tabbed("}", tab)
def __exec_info(self, args): if self.ctx.filename is None: print("no file loaded") return print("File:", self.ctx.filename) statinfo = os.stat(self.ctx.filename) print("Size: %.2f ko" % (statinfo.st_size / 1024.)) print_no_end("Type: ") ty = self.ctx.dis.binary.type if ty == T_BIN_PE: print("PE") elif ty == T_BIN_ELF: print("ELF") elif ty == T_BIN_RAW: print("RAW") import capstone as CAPSTONE arch, mode = self.ctx.dis.binary.get_arch() print_no_end("Arch: ") if arch == CAPSTONE.CS_ARCH_X86: if mode & CAPSTONE.CS_MODE_32: print("x86") elif mode & CAPSTONE.CS_MODE_64: print("x64") elif arch == CAPSTONE.CS_ARCH_ARM: print("arm") elif arch == CAPSTONE.CS_ARCH_MIPS: if mode & CAPSTONE.CS_MODE_32: print("mips") elif mode & CAPSTONE.CS_MODE_64: print("mips64 (octeon)") else: print("not supported") if mode & CAPSTONE.CS_MODE_BIG_ENDIAN: print("Endianess: big endian") else: print("Endianess: little endian")
def __exec_info(self, args): if self.ctx.filename is None: print("no file loaded") return print("File:", self.ctx.filename) statinfo = os.stat(self.ctx.filename) print("Size: %.2f ko" % (statinfo.st_size/1024.)) print_no_end("Type: ") ty = self.ctx.dis.binary.type if ty == T_BIN_PE: print("PE") elif ty == T_BIN_ELF: print("ELF") elif ty == T_BIN_RAW: print("RAW") import capstone as CAPSTONE arch, mode = self.ctx.dis.binary.get_arch() print_no_end("Arch: ") if arch == CAPSTONE.CS_ARCH_X86: if mode & CAPSTONE.CS_MODE_32: print("x86") elif mode & CAPSTONE.CS_MODE_64: print("x64") elif arch == CAPSTONE.CS_ARCH_ARM: print("arm") elif arch == CAPSTONE.CS_ARCH_MIPS: if mode & CAPSTONE.CS_MODE_32: print("mips") elif mode & CAPSTONE.CS_MODE_64: print("mips64 (octeon)") else: print("not supported") if mode & CAPSTONE.CS_MODE_BIG_ENDIAN: print("Endianess: big endian") else: print("Endianess: little endian")
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 prefix == "# ": if self.ctx.comments: print_comment_no_end(prefix, tab) print_no_end(color_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 INTERN_COMMENTS: print_no_end(color_intern_comment(" ; ")) print_no_end(color_intern_comment(INTERN_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_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: print_comment_no_end(prefix, tab) print_no_end(color_addr(i.address)) print_comment(get_inst_str()) return if i.address in self.ctx.all_fused_inst: return if i.address != self.ctx.addr and \ i.address in self.ctx.dis.binary.reverse_symbols: print_tabbed_no_end("", tab) self.print_symbol(i.address) print() modified = self.__print_inst(i, tab, prefix) if i.address in INTERN_COMMENTS: print_no_end(color_intern_comment(" ; ")) print_no_end(color_intern_comment(INTERN_COMMENTS[i.address])) if modified and self.ctx.comments: print_comment_no_end(" # " + get_inst_str()) print()
def dump_data_ascii(self, ctx, lines): N = 128 # read by block of 128 bytes addr = ctx.entry_addr s_name, s_start, s_end = self.binary.get_section_meta(ctx.entry_addr) self.print_section_meta(s_name, s_start, s_end) l = 0 ascii_str = [] addr_str = -1 while l < lines: buf = self.binary.section_stream_read(addr, N) if not buf: break i = 0 while i < len(buf): if addr > s_end: return j = i while j < len(buf): c = buf[j] if c not in BYTES_PRINTABLE_SET: break if addr_str == -1: addr_str = addr ascii_str.append(c) j += 1 if c != 0 and j == len(buf): addr += j - i break if c == 0 and len(ascii_str) >= 2: print_no_end(color_addr(addr_str)) print_no_end( color_string("\"" + "".join(map(get_char, ascii_str)) + "\"")) print(", 0") addr += j - i i = j else: print_no_end(color_addr(addr)) print("0x%.2x " % buf[i]) addr += 1 i += 1 addr_str = -1 ascii_str = [] l += 1 if l >= lines: return
def dump_data_ascii(self, ctx, lines): N = 128 # read by block of 128 bytes addr = ctx.entry_addr s_name, s_start, s_end = self.binary.get_section_meta(ctx.entry_addr) self.print_section_meta(s_name, s_start, s_end) l = 0 ascii_str = [] addr_str = -1 while l < lines: buf = self.binary.section_stream_read(addr, N) if not buf: break i = 0 while i < len(buf): if addr >= s_end: return j = i while j < len(buf): c = buf[j] if c not in BYTES_PRINTABLE_SET: break if addr_str == -1: addr_str = addr ascii_str.append(c) j += 1 if c != 0 and j == len(buf): addr += j - i break if c == 0 and len(ascii_str) >= 2: print_no_end(color_addr(addr_str)) print_no_end(color_string( "\"" + "".join(map(get_char, ascii_str)) + "\"")) print(", 0") addr += j - i i = j else: print_no_end(color_addr(addr)) print("0x%.2x " % buf[i]) addr += 1 i += 1 addr_str = -1 ascii_str = [] l += 1 if l >= lines: return
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_if_cond(self, cond, fused_inst): if fused_inst is None: print_no_end(cond_symbol(cond)) if cond in COND_ADD_ZERO: print_no_end(" 0") return assignment = fused_inst.id in ASSIGNMENT_OPS if assignment: print_no_end("(") print_no_end("(") self.print_operand(fused_inst, 0) print_no_end(" ") print_no_end(cond_symbol(cond)) print_no_end(" ") self.print_operand(fused_inst, 1) # if (fused_inst.id != ARM_INS_CMP and \ # (cond in COND_ADD_ZERO or assignment)): # print_no_end(" 0") print_no_end(")")
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: print_comment_no_end(prefix, tab) print_no_end(color_addr(i.address)) print_comment(get_inst_str()) return if i.address in self.ctx.all_fused_inst: return if i.address != self.ctx.addr and \ i.address in self.ctx.dis.binary.reverse_symbols: print_tabbed_no_end("", tab) self.print_symbol(i.address) print() print_tabbed_no_end(color_addr(i.address), tab) if is_ret(i): print(color_retcall(get_inst_str())) return if is_call(i): print_no_end(color_retcall(i.mnemonic) + " ") self.print_operand(i, 0, hexa=True) print() return # Here we can have conditional jump with the option --dump if is_jump(i): if i.operands[0].type != ARM_OP_IMM: print_no_end(i.mnemonic + " ") print_no_end(i.op_str) if is_uncond_jump(i) and self.ctx.comments: print_comment_no_end(" # STOPPED") print() return try: addr = i.operands[0].value.imm print(i.mnemonic + " " + color(hex(addr), self.ctx.addr_color[addr])) except KeyError: print(i.mnemonic + " " + hex(addr)) 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_shift(self, i, shift): if shift.type == ARM_SFT_LSL: print_no_end(" << %d)" % shift.value) elif shift.type == ARM_SFT_LSR: print_no_end(" >> %d)" % shift.value) elif shift.type == ARM_SFT_ROR: print_no_end(" rot>> %d)" % shift.value) elif shift.type == ARM_SFT_ASR: print_no_end(" arith>> %d)" % shift.value) elif shift.type == ARM_SFT_RRX: print_no_end(" rrx>> %s)" % shift.value) elif shift.type == ARM_SFT_LSL_REG: print_no_end(" << %s)" % i.reg_name(shift.value)) elif shift.type == ARM_SFT_LSR_REG: print_no_end(" >> %s)" % i.reg_name(shift.value)) elif shift.type == ARM_SFT_ROR_REG: print_no_end(" rot>> %s)" % i.reg_name(shift.value)) elif shift.type == ARM_SFT_ASR_REG: print_no_end(" arith>> %s)" % i.reg_name(shift.value)) elif shift.type == ARM_SFT_RRX_REG: print_no_end(" rrx>> %s)" % i.reg_name(shift.value))
def print_if_cond(self, jump_cond, fused_inst): if fused_inst is None: print_no_end(cond_symbol(jump_cond)) if jump_cond in JMP_ADD_ZERO: print_no_end(" 0") return assignment = fused_inst.id in ASSIGNMENT_OPS if assignment: print_no_end("(") print_no_end("(") self.print_operand(fused_inst, 0) print_no_end(" ") if fused_inst.id == X86_INS_TEST: print_no_end(cond_symbol(jump_cond)) elif assignment: print_no_end(inst_symbol(fused_inst)) print_no_end(" ") self.print_operand(fused_inst, 1) print_no_end(") ") print_no_end(cond_symbol(jump_cond)) else: print_no_end(cond_symbol(jump_cond)) print_no_end(" ") self.print_operand(fused_inst, 1) if fused_inst.id == X86_INS_TEST or \ (fused_inst.id != X86_INS_CMP and \ (jump_cond in JMP_ADD_ZERO or assignment)): print_no_end(" 0") print_no_end(")")
def __print_inst(self, i, tab=0, prefix=""): def get_inst_str(): nonlocal i return "%s %s" % (i.mnemonic, i.op_str) def print_rep_begin(): nonlocal tab if i.prefix[0] in REP_PREFIX: print_tabbed_no_end(color_keyword("while"), tab) # TODO: for 16 and 32 bits print_no_end(" (!rcx)") print(") {") tab += 1 def print_rep_end(): nonlocal tab if i.prefix[0] in REP_PREFIX: print() print_label_or_addr(i.address, tab) print("rcx--") if i.prefix[0] == X86_PREFIX_REPNE: print_tabbed_no_end(color_keyword("if"), tab) print_no_end(" (!Z) ") print(color_keyword("break")) tab -= 1 print_tabbed_no_end("}", tab) print_rep_begin() print_label_and_addr(i.address, tab) self.print_bytes(i) if is_ret(i): print_no_end(color_retcall(get_inst_str())) return if is_call(i): print_no_end(color_retcall(i.mnemonic) + " ") return self.print_operand(i, 0, hexa=True) # Here we can have conditional jump with the option --dump if is_jump(i): print_no_end(i.mnemonic + " ") if i.operands[0].type != X86_OP_IMM: self.print_operand(i, 0) 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") 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)) return modified = False if i.id in INST_CHECK: if (i.id == X86_INS_OR and i.operands[1].type == X86_OP_IMM and i.operands[1].value.imm == -1): self.print_operand(i, 0) print_no_end(" = -1") elif (i.id == X86_INS_AND and i.operands[1].type == X86_OP_IMM and i.operands[1].value.imm == 0): self.print_operand(i, 0) print_no_end(" = 0") elif (all(op.type == X86_OP_REG for op in i.operands) and len(set(op.value.reg for op in i.operands)) == 1 and i.id == X86_INS_XOR): self.print_operand(i, 0) print_no_end(" = 0") elif i.id == X86_INS_INC or i.id == X86_INS_DEC: self.print_operand(i, 0) print_no_end(inst_symbol(i)) elif i.id == X86_INS_LEA: self.print_operand(i, 0) print_no_end(" = &(") self.print_operand(i, 1) print_no_end(")") elif i.id == X86_INS_MOVZX: self.print_operand(i, 0) print_no_end(" = (zero ext) ") self.print_operand(i, 1) elif i.id == X86_INS_IMUL: if len(i.operands) == 3: self.print_operand(i, 0) print_no_end(" = ") self.print_operand(i, 1) print_no_end(" " + inst_symbol(i).rstrip('=') + " ") self.print_operand(i, 2) elif len(i.operands) == 2: self.print_operand(i, 0) print_no_end(" " + inst_symbol(i) + " ") self.print_operand(i, 1) elif len(i.operands) == 1: sz = i.operands[0].size if sz == 1: print_no_end("ax = al * ") elif sz == 2: print_no_end("dx:ax = ax * ") elif sz == 4: print_no_end("edx:eax = eax * ") elif sz == 8: print_no_end("rdx:rax = rax * ") self.print_operand(i, 0) else: self.print_operand(i, 0) print_no_end(" " + inst_symbol(i) + " ") self.print_operand(i, 1) modified = True elif i.id == X86_INS_CDQE: print_no_end("rax = eax") modified = True elif i.id == X86_INS_IDIV: print_no_end('eax = edx:eax / ') self.print_operand(i, 0) print_no_end('; edx = edx:eax % ') self.print_operand(i, 0) modified = True elif i.id == X86_INS_MUL: lut = {1: ("al", "ax"), 2: ("ax", "dx:ax"), 4: ("eax", "edx:eax"), 8: ("rax", "rdx:rax")} src, dst = lut[i.operands[0].size] print_no_end('{0} = {1} * '.format(dst, src)) self.print_operand(i, 0) modified = True elif i.id == X86_INS_NOT: self.print_operand(i, 0) print_no_end(' ^= -1') modified = True elif i.id in INST_SCAS: self.print_operand(i, 0) print_no_end(" cmp ") self.print_operand(i, 1) print() print_label_or_addr(i.address, tab) self.print_operand(i, 1, show_deref=False) print_no_end(" += D") modified = True elif i.id in INST_STOS: self.print_operand(i, 0) print_no_end(" = ") self.print_operand(i, 1) print() print_label_or_addr(i.address, tab) self.print_operand(i, 0, show_deref=False) print_no_end(" += D") modified = True elif i.id in INST_LODS: self.print_operand(i, 0) print_no_end(" = ") self.print_operand(i, 1) print() print_label_or_addr(i.address, tab) self.print_operand(i, 1, show_deref=False) print_no_end(" += D") modified = True elif i.id in INST_CMPS: self.print_operand(i, 0) print_no_end(" cmp ") self.print_operand(i, 1) print() print_label_or_addr(i.address, tab) self.print_operand(i, 0, show_deref=False) print(" += D") print_label_or_addr(i.address, tab) self.print_operand(i, 1, show_deref=False) print_no_end("' += D") modified = True elif i.id in INST_MOVS: self.print_operand(i, 0) print_no_end(" = ") self.print_operand(i, 1) print() print_label_or_addr(i.address, tab) self.print_operand(i, 0, show_deref=False) print(" += D") print_label_or_addr(i.address, tab) self.print_operand(i, 1, show_deref=False) print_no_end(" += D") 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 print_rep_end() return modified
def dump_data(self, ctx, lines, size_word): _, mode = self.binary.get_arch() if mode & self.capstone.CS_MODE_BIG_ENDIAN: endian = ">" else: endian = "<" if size_word == 1: unpack_str = endian + "B" elif size_word == 2: unpack_str = endian + "H" elif size_word == 4: unpack_str = endian + "L" elif size_word == 8: unpack_str = endian + "Q" N = size_word * 64 addr = ctx.entry_addr s_name, s_start, s_end = self.binary.get_section_meta(ctx.entry_addr) self.print_section_meta(s_name, s_start, s_end) l = 0 while l < lines: buf = self.binary.section_stream_read(addr, N) if not buf: break i = 0 while i < len(buf): b = buf[i:i + size_word] if addr >= s_end: return if len(b) != size_word: for c in buf: print_no_end(color_addr(addr)) print("0x%.2x" % c) return if addr in self.binary.reverse_symbols: print(color_symbol(self.binary.reverse_symbols[addr])) print_no_end(color_addr(addr)) w = struct.unpack(unpack_str, b)[0] print_no_end("0x%.2x" % w) sec_name, is_data = self.binary.is_address(w) if sec_name is not None and \ sec_name not in [".comment", ".shstrtab"]: print_no_end(" (") print_no_end(color_section(sec_name)) print_no_end(")") if size_word >= 4 and w in self.binary.reverse_symbols: print_no_end(" ") print_no_end(color_symbol(self.binary.reverse_symbols[w])) print() addr += size_word i += size_word l += 1 if l >= lines: return
def __print_inst(self, i, tab=0, prefix=""): def get_inst_str(): nonlocal i return "%s %s" % (i.mnemonic, i.op_str) def print_rep_begin(): nonlocal tab if i.prefix[0] in REP_PREFIX: print_tabbed_no_end(color_keyword("while"), tab) # TODO: for 16 and 32 bits print_no_end(" (!rcx)") print(") {") tab += 1 def print_rep_end(): nonlocal tab if i.prefix[0] in REP_PREFIX: print() print_label_or_addr(i.address, tab) print("rcx--") if i.prefix[0] == X86_PREFIX_REPNE: print_tabbed_no_end(color_keyword("if"), tab) print_no_end(" (!Z) ") print(color_keyword("break")) tab -= 1 print_tabbed_no_end("}", tab) print_rep_begin() print_label_and_addr(i.address, tab) self.print_bytes(i) if is_ret(i): print_no_end(color_retcall(get_inst_str())) return if is_call(i): print_no_end(color_retcall(i.mnemonic) + " ") return self.print_operand(i, 0, hexa=True) # Here we can have conditional jump with the option --dump if is_jump(i): print_no_end(i.mnemonic + " ") if i.operands[0].type != X86_OP_IMM: self.print_operand(i, 0) if is_uncond_jump( i) and self.ctx.comments and not self.ctx.dump: print_comment_no_end(" # STOPPED") 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)) return modified = False if i.id in INST_CHECK: if (i.id == X86_INS_OR and i.operands[1].type == X86_OP_IMM and i.operands[1].value.imm == -1): self.print_operand(i, 0) print_no_end(" = -1") elif (i.id == X86_INS_AND and i.operands[1].type == X86_OP_IMM and i.operands[1].value.imm == 0): self.print_operand(i, 0) print_no_end(" = 0") elif (all(op.type == X86_OP_REG for op in i.operands) and len(set(op.value.reg for op in i.operands)) == 1 and i.id == X86_INS_XOR): self.print_operand(i, 0) print_no_end(" = 0") elif i.id == X86_INS_INC or i.id == X86_INS_DEC: self.print_operand(i, 0) print_no_end(inst_symbol(i)) elif i.id == X86_INS_LEA: self.print_operand(i, 0) print_no_end(" = &(") self.print_operand(i, 1) print_no_end(")") elif i.id == X86_INS_MOVZX: self.print_operand(i, 0) print_no_end(" = (zero ext) ") self.print_operand(i, 1) elif i.id == X86_INS_IMUL: if len(i.operands) == 3: self.print_operand(i, 0) print_no_end(" = ") self.print_operand(i, 1) print_no_end(" " + inst_symbol(i).rstrip('=') + " ") self.print_operand(i, 2) elif len(i.operands) == 2: self.print_operand(i, 0) print_no_end(" " + inst_symbol(i) + " ") self.print_operand(i, 1) elif len(i.operands) == 1: sz = i.operands[0].size if sz == 1: print_no_end("ax = al * ") elif sz == 2: print_no_end("dx:ax = ax * ") elif sz == 4: print_no_end("edx:eax = eax * ") elif sz == 8: print_no_end("rdx:rax = rax * ") self.print_operand(i, 0) else: self.print_operand(i, 0) print_no_end(" " + inst_symbol(i) + " ") self.print_operand(i, 1) modified = True elif i.id == X86_INS_CDQE: print_no_end("rax = eax") modified = True elif i.id == X86_INS_IDIV: print_no_end('eax = edx:eax / ') self.print_operand(i, 0) print_no_end('; edx = edx:eax % ') self.print_operand(i, 0) modified = True elif i.id == X86_INS_MUL: lut = { 1: ("al", "ax"), 2: ("ax", "dx:ax"), 4: ("eax", "edx:eax"), 8: ("rax", "rdx:rax") } src, dst = lut[i.operands[0].size] print_no_end('{0} = {1} * '.format(dst, src)) self.print_operand(i, 0) modified = True elif i.id == X86_INS_NOT: self.print_operand(i, 0) print_no_end(' ^= -1') modified = True elif i.id in INST_SCAS: self.print_operand(i, 0) print_no_end(" cmp ") self.print_operand(i, 1) print() print_label_or_addr(i.address, tab) self.print_operand(i, 1, show_deref=False) print_no_end(" += D") modified = True elif i.id in INST_STOS: self.print_operand(i, 0) print_no_end(" = ") self.print_operand(i, 1) print() print_label_or_addr(i.address, tab) self.print_operand(i, 0, show_deref=False) print_no_end(" += D") modified = True elif i.id in INST_LODS: self.print_operand(i, 0) print_no_end(" = ") self.print_operand(i, 1) print() print_label_or_addr(i.address, tab) self.print_operand(i, 1, show_deref=False) print_no_end(" += D") modified = True elif i.id in INST_CMPS: self.print_operand(i, 0) print_no_end(" cmp ") self.print_operand(i, 1) print() print_label_or_addr(i.address, tab) self.print_operand(i, 0, show_deref=False) print(" += D") print_label_or_addr(i.address, tab) self.print_operand(i, 1, show_deref=False) print_no_end("' += D") modified = True elif i.id in INST_MOVS: self.print_operand(i, 0) print_no_end(" = ") self.print_operand(i, 1) print() print_label_or_addr(i.address, tab) self.print_operand(i, 0, show_deref=False) print(" += D") print_label_or_addr(i.address, tab) self.print_operand(i, 1, show_deref=False) print_no_end(" += D") 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 print_rep_end() return modified
def __print_inst(self, i, tab=0, prefix=""): def get_inst_str(): nonlocal i return "%s %s" % (i.mnemonic, i.op_str) print_tabbed_no_end(color_addr(i.address), tab) if is_ret(i): print_no_end(color_retcall(get_inst_str())) return if is_call(i): print_no_end(color_retcall(i.mnemonic) + " ") self.print_operand(i, 0, hexa=True) return # Here we can have conditional jump with the option --dump if is_jump(i): if i.operands[0].type != X86_OP_IMM: print_no_end(i.mnemonic + " ") self.print_operand(i, 0) if is_uncond_jump(i) and self.ctx.comments: print_comment_no_end(" # STOPPED") return try: addr = i.operands[0].value.imm print_no_end(i.mnemonic + " " + color(hex(addr), self.ctx.addr_color[addr])) except KeyError: print_no_end(i.mnemonic + " " + hex(addr)) return modified = False if i.id in INST_CHECK: if (i.id == X86_INS_OR and i.operands[1].type == X86_OP_IMM and i.operands[1].value.imm == -1): self.print_operand(i, 0) print_no_end(" = -1") elif (i.id == X86_INS_AND and i.operands[1].type == X86_OP_IMM and i.operands[1].value.imm == 0): self.print_operand(i, 0) print_no_end(" = 0") elif (all(op.type == X86_OP_REG for op in i.operands) and len(set(op.value.reg for op in i.operands)) == 1 and i.id == X86_INS_XOR): self.print_operand(i, 0) print_no_end(" = 0") elif i.id == X86_INS_INC or i.id == X86_INS_DEC: self.print_operand(i, 0) print_no_end(inst_symbol(i)) elif i.id == X86_INS_LEA: self.print_operand(i, 0) print_no_end(" = &(") self.print_operand(i, 1) print_no_end(")") elif i.id == X86_INS_IMUL: if len(i.operands) == 3: self.print_operand(i, 0) print_no_end(" = ") self.print_operand(i, 1) print_no_end(" " + inst_symbol(i).rstrip('=') + " ") self.print_operand(i, 2) elif len(i.operands) == 2: self.print_operand(i, 0) print_no_end(" " + inst_symbol(i) + " ") self.print_operand(i, 1) elif len(i.operands) == 1: sz = i.operands[0].size if sz == 1: print_no_end("ax = al * ") elif sz == 2: print_no_end("dx:ax = ax * ") elif sz == 4: print_no_end("edx:eax = eax * ") elif sz == 8: print_no_end("rdx:rax = rax * ") self.print_operand(i, 0) else: self.print_operand(i, 0) print_no_end(" " + inst_symbol(i) + " ") self.print_operand(i, 1) modified = True elif i.id == X86_INS_CDQE: print_no_end("rax = eax") modified = True elif i.id == X86_INS_IDIV: print_no_end('eax = edx:eax / ') self.print_operand(i, 0) print_no_end('; edx = edx:eax % ') self.print_operand(i, 0) modified = True elif i.id == X86_INS_MUL: lut = {1: ("al", "ax"), 2: ("ax", "dx:ax"), 4: ("eax", "edx:eax"), 8: ("rax", "rdx:rax")} src, dst = lut[i.operands[0].size] print_no_end('{0} = {1} * '.format(dst, src)) self.print_operand(i, 0) modified = True elif i.id == X86_INS_NOT: self.print_operand(i, 0) print_no_end(' ^= -1') modified = True elif i.id == X86_INS_SCASB and i.prefix[0] == X86_PREFIX_REPNE: print_no_end('while (') self.print_operand(i, 1) print_no_end(' != ') self.print_operand(i, 0) print_no_end(') { ') self.print_operand(i, 1, show_deref=False) print_no_end('++; cx--; } ') self.print_operand(i, 1, show_deref=False) print_no_end('++; cx--;') 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 return modified
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: print_no_end(hex(imm)) if self.ctx.sectionsname: print_no_end(" (" + color_section(sec_name) + ")") if is_data: s = self.binary.get_string(imm, self.ctx.max_data_size) print_no_end(" " + color_string(s)) if imm in self.binary.reverse_symbols: print_no_end(" ") self.print_symbol(imm) 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 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: if mm.disp < 0: if printed: print_no_end(" - ") print_no_end(-mm.disp) else: if printed: print_no_end(" + ") print_no_end(mm.disp) else: if mm.disp in self.binary.reverse_symbols: print_no_end(hex(mm.disp) + " ") self.print_symbol(mm.disp) else: print_no_end(hex(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) print_tabbed_no_end(color_addr(i.address), tab) self.print_bytes(i) if is_ret(i): print_no_end(color_retcall(get_inst_str())) return if is_call(i): print_no_end(color_retcall(i.mnemonic) + " ") self.print_operand(i, 0, hexa=True) return # Here we can have conditional jump with the option --dump if is_jump(i): if i.operands[0].type != X86_OP_IMM: print_no_end(i.mnemonic + " ") self.print_operand(i, 0) if is_uncond_jump( i) and self.ctx.comments and not self.ctx.dump: print_comment_no_end(" # STOPPED") return try: addr = i.operands[0].value.imm print_no_end(i.mnemonic + " " + color(hex(addr), self.ctx.addr_color[addr])) except KeyError: print_no_end(i.mnemonic + " " + hex(addr)) return modified = False if i.id in INST_CHECK: if (i.id == X86_INS_OR and i.operands[1].type == X86_OP_IMM and i.operands[1].value.imm == -1): self.print_operand(i, 0) print_no_end(" = -1") elif (i.id == X86_INS_AND and i.operands[1].type == X86_OP_IMM and i.operands[1].value.imm == 0): self.print_operand(i, 0) print_no_end(" = 0") elif (all(op.type == X86_OP_REG for op in i.operands) and len(set(op.value.reg for op in i.operands)) == 1 and i.id == X86_INS_XOR): self.print_operand(i, 0) print_no_end(" = 0") elif i.id == X86_INS_INC or i.id == X86_INS_DEC: self.print_operand(i, 0) print_no_end(inst_symbol(i)) elif i.id == X86_INS_LEA: self.print_operand(i, 0) print_no_end(" = &(") self.print_operand(i, 1) print_no_end(")") elif i.id == X86_INS_IMUL: if len(i.operands) == 3: self.print_operand(i, 0) print_no_end(" = ") self.print_operand(i, 1) print_no_end(" " + inst_symbol(i).rstrip('=') + " ") self.print_operand(i, 2) elif len(i.operands) == 2: self.print_operand(i, 0) print_no_end(" " + inst_symbol(i) + " ") self.print_operand(i, 1) elif len(i.operands) == 1: sz = i.operands[0].size if sz == 1: print_no_end("ax = al * ") elif sz == 2: print_no_end("dx:ax = ax * ") elif sz == 4: print_no_end("edx:eax = eax * ") elif sz == 8: print_no_end("rdx:rax = rax * ") self.print_operand(i, 0) else: self.print_operand(i, 0) print_no_end(" " + inst_symbol(i) + " ") self.print_operand(i, 1) modified = True elif i.id == X86_INS_CDQE: print_no_end("rax = eax") modified = True elif i.id == X86_INS_IDIV: print_no_end('eax = edx:eax / ') self.print_operand(i, 0) print_no_end('; edx = edx:eax % ') self.print_operand(i, 0) modified = True elif i.id == X86_INS_MUL: lut = { 1: ("al", "ax"), 2: ("ax", "dx:ax"), 4: ("eax", "edx:eax"), 8: ("rax", "rdx:rax") } src, dst = lut[i.operands[0].size] print_no_end('{0} = {1} * '.format(dst, src)) self.print_operand(i, 0) modified = True elif i.id == X86_INS_NOT: self.print_operand(i, 0) print_no_end(' ^= -1') modified = True elif i.id == X86_INS_SCASB and i.prefix[0] == X86_PREFIX_REPNE: print_no_end('while (') self.print_operand(i, 1) print_no_end(' != ') self.print_operand(i, 0) print_no_end(') { ') self.print_operand(i, 1, show_deref=False) print_no_end('++; cx--; } ') self.print_operand(i, 1, show_deref=False) print_no_end('++; cx--;') 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 return modified
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 dump_data(self, ctx, lines): N = 128 addr = ctx.entry_addr s_name, s_start, s_end = self.binary.get_section_meta(ctx.entry_addr) self.print_section_meta(s_name, s_start, s_end) addr_ascii_str = -1 ascii_str = [] l = 0 is_new_line = True while l < lines: buf = self.binary.section_stream_read(addr, N) if not buf: break i = 0 while i < len(buf): c = buf[i] if c in BYTES_PRINTABLE_SET: if addr_ascii_str == -1: addr_ascii_str = addr ascii_str.append(c) addr += 1 i += 1 continue stack_char = [] if addr_ascii_str != -1: if c == 0 and len(ascii_str) >= 2: if not is_new_line: print() l += 1 if l >= lines: return print_no_end(color_addr(addr_ascii_str)) print_no_end(color_string("\"" + "".join(map(get_char, ascii_str)) + "\"")) print(", 0") is_new_line = True l += 1 if l >= lines: return ascii_str = [] addr_ascii_str = -1 addr += 1 i += 1 continue stack_char = ascii_str i -= len(ascii_str) addr -= len(ascii_str) stack_char.append(c) for c in stack_char: if is_new_line: print_no_end(color_addr(addr)) elif addr % 4 == 0 and addr != ctx.entry_addr: print() is_new_line = True l += 1 if l >= lines: return print_no_end(color_addr(addr)) print_no_end("%.2x " % c) addr += 1 i += 1 is_new_line = False ascii_str = [] addr_ascii_str = -1 if not is_new_line: print()
def print(self, tab=0): print_cmp_jump_commented(self.cmp_inst, self.orig_jump, tab) print_tabbed_no_end(color_keyword("if "), tab) print_if_cond(self.cmp_inst, self.cond_id) print_no_end(color_keyword(" goto ")) print_addr(self.addr_jump)
def dump_data(self, ctx, lines, size_word): s_name, s_start, s_end = self.binary.get_section_meta(ctx.entry_addr) self.print_section_meta(s_name, s_start, s_end) ad = ctx.entry_addr for w in self.read_array(ctx.entry_addr, lines, size_word): if ad in self.binary.reverse_symbols: print(color_symbol(self.binary.reverse_symbols[ad])) print_no_end(color_addr(ad)) print_no_end("0x%.2x" % w) sec_name, is_data = self.binary.is_address(w) if sec_name is not None: print_no_end(" (") print_no_end(color_section(sec_name)) print_no_end(")") if size_word >= 4 and w in self.binary.reverse_symbols: print_no_end(" ") print_no_end(color_symbol(self.binary.reverse_symbols[w])) ad += size_word 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_if_cond(self, cond, fused_inst): if fused_inst is None: print_no_end(cond_symbol(cond)) if cond in COND_ADD_ZERO: print_no_end(" 0") return assignment = fused_inst.id in ASSIGNMENT_OPS if assignment: print_no_end("(") print_no_end("(") self.print_operand(fused_inst, 0) print_no_end(" ") print_no_end(cond_symbol(cond)) print_no_end(" ") self.print_operand(fused_inst, 1) if (fused_inst.id != ARM_INS_CMP and \ (cond in COND_ADD_ZERO or assignment)): print_no_end(" 0") print_no_end(")")
def print_operand(self, i, num_op, hexa=False, show_deref=True): def inv(n): return n == X86_OP_INVALID op = i.operands[num_op] if op.type == X86_OP_IMM: imm = op.value.imm sec_name, is_data = self.binary.is_address(imm) if sec_name is not None: print_no_end(hex(imm)) if self.ctx.sectionsname: print_no_end(" (" + color_section(sec_name) + ")") if is_data: s = self.binary.get_string(imm, self.ctx.max_data_size) print_no_end(" " + color_string(s)) if imm in self.binary.reverse_symbols: print_no_end(" ") self.print_symbol(imm) elif op.size == 1: print_no_end(color_string("'%s'" % get_char(imm))) 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 better # to have the value in hexa return True return False elif op.type == X86_OP_REG: print_no_end(i.reg_name(op.value.reg)) return False elif op.type == X86_OP_FP: print_no_end("%f" % op.value.fp) return False elif op.type == X86_OP_MEM: mm = op.mem if not inv(mm.base) and mm.disp != 0 \ and inv(mm.segment) 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 elif mm.base == X86_REG_RIP or mm.base == X86_REG_EIP: 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)) printed = True if mm.disp != 0: if mm.disp < 0: if printed: print_no_end(" - ") print_no_end(-mm.disp) else: if printed: print_no_end(" + ") print_no_end(mm.disp) else: if mm.disp in self.binary.reverse_symbols: print_no_end(hex(mm.disp) + " ") self.print_symbol(mm.disp) else: print_no_end(hex(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 prefix == "# ": if self.ctx.comments: print_comment_no_end(prefix, tab) print_no_end(color_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_tabbed_no_end(color_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) + " ") self.print_operand(i, 0, hexa=True) print() return # Here we can have conditional jump with the option --dump if is_jump(i): if i.operands[0].type != ARM_OP_IMM: print_no_end(i.mnemonic + " ") 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 try: addr = i.operands[0].value.imm print(i.mnemonic + " " + color(hex(addr), self.ctx.addr_color[addr])) except KeyError: print(i.mnemonic + " " + hex(addr)) 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_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: print_comment_no_end(prefix, tab) print_no_end(color_addr(i.address)) print_comment(get_inst_str()) return if i.address in self.ctx.all_fused_inst: return if i.address != self.ctx.addr and \ i.address in self.ctx.dis.binary.reverse_symbols: print_tabbed_no_end("", tab) self.print_symbol(i.address) print() print_tabbed_no_end(color_addr(i.address), tab) if is_ret(i): print(color_retcall(get_inst_str())) return if is_call(i): print_no_end(color_retcall(i.mnemonic) + " ") self.print_operand(i, 0, hexa=True) 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: 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[-1].value.imm if addr in self.ctx.addr_color: print(color(hex(addr), self.ctx.addr_color[addr])) else: print(hex(addr)) 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 modified and self.ctx.comments: print_comment_no_end(" # " + get_inst_str()) print()