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)
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 ")
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