示例#1
0
def context_ghidra(func=None, target=sys.stdout, with_banner=True, width=None, force_show=False):
    banner = [pwndbg.ui.banner("ghidra decompile", target=target, width=width)]

    if config_context_ghidra == "never" and not force_show:
        return []
    elif config_context_ghidra == "if-no-source" and not force_show:
        try:
            with open(gdb.selected_frame().find_sal().symtab.fullname()) as _:
                pass
        except:         # a lot can go wrong in search of source code.
            return []   # we don't care what, just that it did not work out well...

    filename = gdb.current_progspace().filename
    try:
        r2 = init_radare2(filename)
        # LD         list supported decompilers (e cmd.pdc=?)
        # Outputs for example:: pdc\npdg
        if not "pdg" in r2.cmd("LD").split("\n"):
            return banner + ["radare2 plugin r2ghidra-dec must be installed and available from r2"]
    except ImportError: # no r2pipe present
        return banner + ["r2pipe not available, but required for r2->ghidra-bridge"]
    if func is None:
        try:
            func = hex(pwndbg.regs[pwndbg.regs.current.pc])
        except:
            func = "main"
    src = r2.cmdj("pdgj @" + func)
    source = src.get("code", "")
    curline = None
    try:
        cur = pwndbg.regs[pwndbg.regs.current.pc]
    except AttributeError:
        cur = None # If not running there is no current.pc
    if cur is not None:
        closest = 0
        for off in (a.get("offset", 0) for a in src.get("annotations", [])):
            if abs(cur - closest) > abs(cur - off):
                closest = off
        pos_annotations = sorted([a for a in src.get("annotations", []) if a.get("offset") == closest],
                         key=lambda a: a["start"])
        if pos_annotations:
            curline = source.count("\n", 0, pos_annotations[0]["start"])
    source = source.split("\n")
    # Append --> for the current line if possible
    if curline is not None:
        line = source[curline]
        if line.startswith('    '):
            line = line[4:]
        source[curline] = '--> ' + line
    # Join the source for highlighting
    source = "\n".join(source)
    if pwndbg.config.syntax_highlight:
        # highlighting depends on the file extension to guess the language, so try to get one...
        try: # try to read the source filename from debug information
            src_filename = gdb.selected_frame().find_sal().symtab.fullname()
        except: # if non, take the original filename and maybe append .c (just assuming is was c)
            src_filename = filename+".c" if os.path.basename(filename).find(".") < 0 else filename
        source = H.syntax_highlight(source, src_filename)
    source = source.split("\n")
    return banner + source if with_banner else source
示例#2
0
文件: ghidra.py 项目: saraiva/pwndbg
def decompile(func=None):
    """
    Return the source of the given function decompiled by ghidra.

    If no function is given, decompile the function within the current pc.
    This function requires radare2, r2pipe and r2ghidra.

    Raises Exception if any fatal error occures.
    """
    try:
        r2 = pwndbg.radare2.r2pipe()
    except ImportError:
        raise Exception('r2pipe not available, but required for r2->ghidra bridge')

    # LD -> list supported decompilers (e cmd.pdc=?)
    # Outputs for example: pdc\npdg
    if "pdg" not in r2.cmd("LD").split("\n"):
        raise Exception('radare2 plugin r2ghidra must be installed and available from r2')

    if not func:
        func = hex(pwndbg.regs[pwndbg.regs.current.pc]) if pwndbg.proc.alive else 'main'

    src = r2.cmdj("pdgj @" + func)
    if not src:
        raise Exception("Decompile command failed, check if '{}' is a valid target".format(func))

    current_line_marker = '/*%%PWNDBG_CODE_MARKER%%*/'
    source = src.get("code", "")

    # If not running there is no current pc to mark
    if pwndbg.proc.alive:
        pc = pwndbg.regs[pwndbg.regs.current.pc]

        closest = 0
        for off in (a.get("offset", 0) for a in src.get("annotations", [])):
            if abs(pc - closest) > abs(pc - off):
                closest = off
        pos_annotations = sorted([a for a in src.get("annotations", []) if a.get("offset") == closest], key=lambda a: a["start"])

        # Append code prefix marker for the current line and replace it later
        if pos_annotations:
            curline = source.count("\n", 0, pos_annotations[0]["start"])
            source = source.split("\n")
            line = source[curline]
            if line.startswith('    '):
                line = line[min(4, len(pwndbg.config.code_prefix) + 1):]
            source[curline] = current_line_marker + ' ' + line
            source = "\n".join(source)

    if pwndbg.config.syntax_highlight:
        # highlighting depends on the file extension to guess the language, so try to get one...
        src_filename = pwndbg.symbol.selected_frame_source_absolute_filename()
        if not src_filename:
            filename = gdb.current_progspace().filename
            src_filename = filename + ".c" if os.path.basename(filename).find(".") < 0 else filename
        source = H.syntax_highlight(source, src_filename)

    # Replace code prefix marker after syntax highlighting
    source = source.replace(current_line_marker, C.prefix(pwndbg.config.code_prefix), 1)
    return source
示例#3
0
文件: context.py 项目: 0xfocu5/tools
def get_highlight_source(filename):
    # Notice that the code is cached
    with open(filename, encoding='utf-8') as f:
        source = f.read()

    if pwndbg.config.syntax_highlight:
        source = H.syntax_highlight(source, filename)

    source_lines = source.splitlines()
    source_lines = tuple(line.rstrip() for line in source_lines)
    return source_lines
示例#4
0
def get_highlight_source(filename):
    # Notice that the code is cached
    with open(filename, encoding='utf-8') as f:
        source = f.read()

    if pwndbg.config.syntax_highlight:
        source = H.syntax_highlight(source, filename)

    source_lines = source.splitlines()
    source_lines = tuple(line.rstrip() for line in source_lines)
    return source_lines
示例#5
0
文件: disasm.py 项目: pwndbg/pwndbg
def syntax_highlight(ins):
    return H.syntax_highlight(ins, filename='.asm')
示例#6
0
def enhance(value, code=True):
    """
    Given the last pointer in a chain, attempt to characterize

    Note that 'the last pointer in a chain' may not at all actually be a pointer.

    Additionally, optimizations are made based on various sources of data for
    'value'. For example, if it is set to RWX, we try to get information on whether
    it resides on the stack, or in a RW section that *happens* to be RWX, to
    determine which order to print the fields.

    Arguments:
        value(obj): Value to enhance
        code(bool): Hint that indicates the value may be an instruction
    """
    value = int(value)

    name = pwndbg.symbol.get(value) or None
    page = pwndbg.vmmap.find(value)

    # If it's not in a page we know about, try to dereference
    # it anyway just to test.
    can_read = True
    if not page or None == pwndbg.memory.peek(value):
        can_read = False

    if not can_read:
        return E.integer(int_str(value))

    # It's mapped memory, or we can at least read it.
    # Try to find out if it's a string.
    instr = None
    exe = page and page.execute
    rwx = page and page.rwx

    # For the purpose of following pointers, don't display
    # anything on the stack or heap as 'code'
    if '[stack' in page.objfile or '[heap' in page.objfile:
        rwx = exe = False

    # If IDA doesn't think it's in a function, don't display it as code.
    if pwndbg.ida.available() and not pwndbg.ida.GetFunctionName(value):
        rwx = exe = False

    if exe:
        instr = pwndbg.disasm.one(value)
        if instr:
            instr = "%-6s %s" % (instr.mnemonic, instr.op_str)
            if pwndbg.config.syntax_highlight:
                instr = syntax_highlight(instr)

    szval = pwndbg.strings.get(value) or None
    szval0 = szval
    if szval:
        szval = E.string(repr(szval))

    intval = int(pwndbg.memory.poi(pwndbg.typeinfo.pvoid, value))
    intval0 = intval
    if 0 <= intval < 10:
        intval = E.integer(str(intval))
    else:
        intval = E.integer('%#x' % int(intval & pwndbg.arch.ptrmask))

    retval = []

    # print([instr,intval0,szval])
    if not code:
        instr = None

    # If it's on the stack, don't display it as code in a chain.
    if instr and 'stack' in page.objfile:
        retval = [intval, szval]

    # If it's RWX but a small value, don't display it as code in a chain.
    elif instr and rwx and intval0 < 0x1000:
        retval = [intval, szval]

    # If it's an instruction and *not* RWX, display it unconditionally
    elif instr and exe:
        if not rwx:
            if szval:
                retval = [instr, szval]
            else:
                retval = [instr]
        else:
            retval = [instr, intval, szval]

    # Otherwise strings have preference
    elif szval:
        if len(szval0) < pwndbg.arch.ptrsize:
            retval = [intval, szval]
        else:
            retval = [szval]

    # And then integer
    else:
        return E.integer(int_str(intval0))

    retval = tuple(filter(lambda x: x is not None, retval))

    if len(retval) == 0:
        return E.unknown("???")

    if len(retval) == 1:
        return retval[0]

    return retval[0] + E.comment(
        color.strip(' /* {} */'.format('; '.join(retval[1:]))))
示例#7
0
文件: disasm.py 项目: cebrusfs/217gdb
def syntax_highlight(ins):
    return H.syntax_highlight(ins, filename='.asm')
示例#8
0
def enhance(value, code = True):
    """
    Given the last pointer in a chain, attempt to characterize

    Note that 'the last pointer in a chain' may not at all actually be a pointer.

    Additionally, optimizations are made based on various sources of data for
    'value'. For example, if it is set to RWX, we try to get information on whether
    it resides on the stack, or in a RW section that *happens* to be RWX, to
    determine which order to print the fields.

    Arguments:
        value(obj): Value to enhance
        code(bool): Hint that indicates the value may be an instruction
    """
    value = int(value)

    name = pwndbg.symbol.get(value) or None
    page = pwndbg.vmmap.find(value)

    # If it's not in a page we know about, try to dereference
    # it anyway just to test.
    can_read = True
    if not page or None == pwndbg.memory.peek(value):
        can_read = False

    if not can_read:
        return E.integer(int_str(value))

    # It's mapped memory, or we can at least read it.
    # Try to find out if it's a string.
    instr  = None
    exe    = page and page.execute
    rwx    = page and page.rwx

    # For the purpose of following pointers, don't display
    # anything on the stack or heap as 'code'
    if '[stack' in page.objfile or '[heap' in page.objfile:
        rwx = exe = False

    # If IDA doesn't think it's in a function, don't display it as code.
    if pwndbg.ida.available() and not pwndbg.ida.GetFunctionName(value):
        rwx = exe = False

    if exe:
        instr = pwndbg.disasm.one(value)
        if instr:
            instr = "%-6s %s" % (instr.mnemonic, instr.op_str)
            if pwndbg.config.syntax_highlight:
                instr = syntax_highlight(instr)

    szval = pwndbg.strings.get(value) or None
    szval0 = szval
    if szval:
        szval = E.string(repr(szval))

    intval  = int(pwndbg.memory.poi(pwndbg.typeinfo.pvoid, value))
    intval0 = intval
    if 0 <= intval < 10:
        intval = E.integer(str(intval))
    else:
        intval = E.integer('%#x' % int(intval & pwndbg.arch.ptrmask))

    retval = []

    # print([instr,intval0,szval])
    if not code:
        instr = None

    # If it's on the stack, don't display it as code in a chain.
    if instr and 'stack' in page.objfile:
        retval = [intval, szval]



    # If it's RWX but a small value, don't display it as code in a chain.
    elif instr and rwx and intval0 < 0x1000:
        retval = [intval, szval]

    # If it's an instruction and *not* RWX, display it unconditionally
    elif instr and exe:
        if not rwx:
            if szval:
                retval = [instr, szval]
            else:
                retval = [instr]
        else:
            retval = [instr, intval, szval]

    # Otherwise strings have preference
    elif szval:
        if len(szval0) < pwndbg.arch.ptrsize:
            retval = [intval, szval]
        else:
            retval = [szval]

    # And then integer
    else:
        return E.integer(int_str(intval0))

    retval = tuple(filter(lambda x: x is not None, retval))

    if len(retval) == 0:
        return E.unknown("???")

    if len(retval) == 1:
        return retval[0]

    return retval[0] + E.comment(color.strip(' /* {} */'.format('; '.join(retval[1:]))))