def context_source(self): try: pc = pwngef.arch.CURRENT_ARCH.pc symtabline = gdb.find_pc_line(pc) symtab = symtabline.symtab line_num = symtabline.line - 1 # we substract one because line number returned by gdb start at 1 if not symtab.is_valid(): return None fpath = symtab.fullname() with open(fpath, "r") as f: lines = [l.rstrip() for l in f.readlines()] except Exception: return None nb_line = self.get_setting("nb_lines_code") fn = symtab.filename if len(fn) > 20: fn = "{}[...]{}".format(fn[:15], os.path.splitext(fn)[1]) title = "source:{}+{}".format(fn, line_num + 1) cur_line_color = pwngef.config.get("theme.source_current_line") self.context_title(title) for i in range(line_num - nb_line + 1, line_num + nb_line): if i < 0: continue if i < line_num: print( Color.grayify(" {:4d}\t {:s}".format( i + 1, lines[i], ))) if i == line_num: extra_info = self.get_pc_context_info(pc, lines[i]) prefix = "{}{:4d}\t ".format(config_arrow_right, i + 1) leading = len(lines[i]) - len(lines[i].lstrip()) if extra_info: print("{}{}".format(" " * (len(prefix) + leading), extra_info)) print( Color.colorify("{}{:s}".format(prefix, lines[i]), cur_line_color)) if i > line_num: try: print(" {:4d}\t {:s}".format( i + 1, lines[i], )) except IndexError: break return None
def context_code(self): nb_insn = self.get_setting("nb_lines_code") nb_insn_prev = self.get_setting("nb_lines_code_prev") use_capstone = self.has_setting("use_capstone") and self.get_setting( "use_capstone") use_ida = self.get_setting("use_ida") cur_insn_color = pwngef.config.get( "theme.disassemble_current_instruction") pc = int(pwngef.arch.CURRENT_ARCH.pc) frame = gdb.selected_frame() arch_name = "{}:{}".format(pwngef.arch.CURRENT_ARCH.arch.lower(), pwngef.arch.CURRENT_ARCH.mode) self.context_title("code:{}".format(arch_name)) try: instruction_iterator = disass.capstone_disassemble if use_capstone else disass.gef_disassemble instruction_iterator = disass.ida_disassemble if use_ida else instruction_iterator for insn in instruction_iterator(pc, nb_insn, nb_prev=nb_insn_prev): line = [] is_taken = False target = None text = str(insn) if insn.address < pc: line += Color.grayify(" {}".format(text)) elif insn.address == pc: line += Color.colorify( "{:s}{:s}".format(config_arrow_right.rjust(3), text), cur_insn_color) if pwngef.arch.CURRENT_ARCH.is_conditional_branch(insn): is_taken, reason = pwngef.arch.CURRENT_ARCH.is_branch_taken( insn) if is_taken: target = insn.operands[-1].split()[0] reason = "[Reason: {:s}]".format( reason) if reason else "" line += Color.colorify( "\tTAKEN {:s}".format(reason), "bold green") else: reason = "[Reason: !({:s})]".format( reason) if reason else "" line += Color.colorify( "\tNOT taken {:s}".format(reason), "bold red") elif pwngef.arch.CURRENT_ARCH.is_call( insn) and self.get_setting("peek_calls") is True: target = insn.operands[-1].split()[0] elif pwngef.arch.CURRENT_ARCH.is_ret( insn) and self.get_setting("peek_ret") is True: target = int( pwngef.arch.CURRENT_ARCH.get_ra(insn, frame)) else: line += " {}".format(text) print("".join(line)) if target: try: target = int(target, 0) except TypeError: # Already an int pass except ValueError: # If the operand isn't an address right now we can't parse it continue for i, tinsn in enumerate( instruction_iterator(target, nb_insn)): text = " {} {}".format( pwngef.config.DOWN_ARROW if i == 0 else " ", str(tinsn)) print(text) break except gdb.MemoryError: message.error("Cannot disassemble from $PC") except Exception: import traceback print(traceback.format_exc()) return None