Beispiel #1
0
def add_decompiler_func_info(cu, func_die, func, file_index, func_line):
    # https://ghidra.re/ghidra_docs/api/ghidra/app/decompiler/DecompileResults.html
    # print func.allVariables
    decomp = get_decompiled_function(func)
    for name, datatype, addr, storage in get_decompiled_variables(decomp):
        add_variable(cu, func_die, name, datatype, addr, storage)

    cmarkup = decomp.CCodeMarkup
    # TODO: implement our own pretty printer?
    # https://github.com/NationalSecurityAgency/ghidra/blob/master/Ghidra/Features/Decompiler/src/main/java/ghidra/app/decompiler/PrettyPrinter.java
    lines = DecompilerUtils.toLines(cmarkup)
    for l in lines:
        # TODO: multiple lines might have the same lowest address
        addresses = [
            get_real_address(t.minAddress) for t in l.allTokens if t.minAddress
        ]
        # TODO: We need to use max or min? In some cases with min we have incorrect offset
        best_addr = addresses[0] if addresses else None

        if best_addr:
            # TODO: is this call to dwarf_lne_set_address needed?
            # dwarf_lne_set_address(dbg, lowest_line_addr, 0)
            # https://nxmnpg.lemoda.net/3/dwarf_add_line_entry
            dwarf_add_line_entry(dbg, file_index, best_addr,
                                 l.lineNumber + func_line - 1, 0, True, False)
def add_decompiler_func_info(cu, func_die, func, file_index, linecount):
    # https://ghidra.re/ghidra_docs/api/ghidra/app/decompiler/DecompileResults.html
    # print func.allVariables
    decomp = get_decompiled_function(func)
    for name, datatype, addr, storage in get_decompiled_variables(decomp):
        add_variable(cu, func_die, name, datatype, addr, storage)

    cmarkup = decomp.CCodeMarkup
    # TODO: implement our own pretty printer?
    # https://github.com/NationalSecurityAgency/ghidra/blob/master/Ghidra/Features/Decompiler/src/main/java/ghidra/app/decompiler/PrettyPrinter.java
    lines = DecompilerUtils.toLines(cmarkup)
    for l in lines:
        # TODO: multiple lines might have the same lowest address
        addresses = [t.minAddress for t in l.allTokens if t.minAddress]
        lowest_addr = min(addresses) if addresses else None
        # print lowest_addr, l
        # TODO: is this call to dwarf_lne_set_address needed?
        # dwarf_lne_set_address(dbg, lowest_line_addr, 0, &err)
        # https://nxmnpg.lemoda.net/3/dwarf_add_line_entry
        if lowest_addr:
            dwarf_add_line_entry(dbg, file_index, lowest_addr.offset,
                                 l.lineNumber + linecount - MAGIC_OFFSET, 0,
                                 True, False, err)
Beispiel #3
0
        logger.error("Put the cursor in the decompiler window")
        raise Exception
    

    cl = currentLocation
    dc = cl.getDecompile()
    addr = cl.getAddress()
    """
    tokenAtCursor = cl.getToken();
    print type(tokenAtCursor)
    print  tokenAtCursor.getPcodeOp()
    print tokenAtCursor.getVarnode()
    print tokenAtCursor.getHighVariable().getName(),tokenAtCursor.getHighVariable().getDataType()
    """
    tokenAtCursor = cl.getToken();
    var = DecompilerUtils.getVarnodeRef(tokenAtCursor);
    if var == None:
        print "[-] Cannot get the varnode "
        raise Exception("Varnode error")
    
    desc = var.getDescendants()

    varhigh = var.getHigh()

    if varhigh == None:
        raise Exception("Could not get High variable")

    varname = varhigh.getName()
    vartype = varhigh.getDataType()
    if varname == None or vartype == None:
        raise Exception("No name/type found ")
Beispiel #4
0
def get_tl_dr_api_table(dispatcher):
    """Retrieves function tables for TL/DR API calls

    :param dispatcher: Dispatcher of the TL/DR calls
    :type dispatcher: int
    :return: Driver API function table and Trustlet API function table
    :rtype: (int, int)
    """

    def get_table_addr_and_type(table_pcode_op_ast):
        """Retrives address and type of a given table

        :param table_pcode_op_ast: pcodeOpAST associated with the given table load instruction
        :type pcode_op_ast: ghidra.program.model.pcode.PcodeOpAST
        :return: Address and type of the given table
        :rtype: (int, Optional[bool])
        """
        memory_varnode = table_pcode_op_ast.getInput(0)
        if memory_varnode.isAddress():
            table = read_dword(memory_varnode.getAddress())
            basicBlock = table_pcode_op_ast.getParent()
            for pcodeop in basicBlock.getIterator():
                opcode = pcodeop.getOpcode()
                if opcode == PcodeOp.INT_SUB and \
                        pcodeop.getInput(1).isConstant and \
                        pcodeop.getInput(1).getOffset() == 0x1000:
                    return table, True
 
                elif opcode == PcodeOp.INT_AND and \
                        pcodeop.getInput(1).isConstant() and \
                        pcodeop.getInput(1).getOffset() == 0x7FFFFFFF:
                    return table, None
            return table, False

    dr_table, tl_table = None, None

    function = functionManager.getFunctionAt(dispatcher)
    if function is None:
        function = createFunction(mclib_jumper, None)

    # First forward slice the first argument of the function until we find the
    # address where the API number is used to get the function pointer and retrieve
    # the base varnode (register) where is stored the table pointer
    decompileResults = decompInterface.decompileFunction(function, 30, monitor)
    hfunction = decompileResults.getHighFunction()
    varnode = hfunction.getFunctionPrototype().getParam(0).getRepresentative()

    forward_slices = DecompilerUtils.getForwardSlice(varnode)
    for forward_slice in forward_slices:
        pcode_op_ast = forward_slice.getDef()
        if not pcode_op_ast:
            continue
        if pcode_op_ast.getOpcode() == PcodeOp.PTRADD:
            array_varnode = pcode_op_ast.getInput(0)
            break

    # Second, backward slice the varnode used to store the base of the function pointer
    # table to get the values
    backward_slices = DecompilerUtils.getBackwardSlice(array_varnode)
    for backward_slice in backward_slices:
        pcode_op_ast = backward_slice.getDef()
        if not pcode_op_ast:
            continue
        if pcode_op_ast.getOpcode() == PcodeOp.COPY:
            table, table_type = get_table_addr_and_type(pcode_op_ast)
            if table_type is not None and table_type:
                dr_table = table
            elif table_type is not None and not table_type:
                tl_table = table

    return dr_table, tl_table