Ejemplo n.º 1
0
    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
Ejemplo n.º 2
0
    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