def __init__(self, verbose, api_db): self.verbose = verbose self.api_db_path = api_db if os.path.isfile(api_db) else None self.api_db = None symbol_table = currentProgram.getSymbolTable() gpa = symbol_table.getExternalSymbol("GetProcAddress") self.gpa_refs = gpa.getReferences() if gpa else [] # list of references (code or data) to GetProcAddress if len(self.gpa_refs) > 0 and self.gpa_refs[0].getReferenceType().isData(): self.gpa_refs.extend(getReferencesTo(self.gpa_refs[0].getFromAddress())) # List of references (code or data) to LoadLibrary (and similar functions) ll_refs = [] ll_symbols = ["LoadLibraryA", "LoadLibraryW", "LoadLibraryExA", "LoadLibraryExW", "GetModuleHandleA", "GetModuleHandleW"] for symbol in ll_symbols: ext_symbol = symbol_table.getExternalSymbol(symbol) if ext_symbol: ll_refs.extend(ext_symbol.getReferences()) self.load_lib_functions = DynamicImportsEnumerator.__get_functions_containing_refs(ll_refs) # Regex for matching GetProcAddress arguments self.getprocaddress_regex = re.compile(r"GetProcAddress[ \t]?\(" r"[ \t]?(.+?)[ \t]?," # 1st parameter (hModule) r"[ \t]?(?:\(.+?\))?[ \t]?(.+?)[ \t]?[),]") # 2nd parameter (lpProcName) # Regex for matching LoadLibrary (et similia) first argument (i.e. the name of the dll) self.loadlibrary_regex = \ r"{}\s?=\s?(?:LoadLibrary(?:Ex)?|GetModuleHandle)(?:[AW])?\s?\(\s?(?:\(.+?\))?\s?(.+?)\s?[),]" # Regex for handling wrong hmodule bug in Ghidra decompiler self.wrong_hmodule_regex = r"hModule(_[0-9]*)" # Regex for matching C function call and their arguments self.function_call_regex = r"{}[ \t]?\([ \t]?(.*)[ \t]?\)" # Regex for matching casts to HMODULE self.hmodule_cast_regex = r"(?:\*[ \t]?\([ \t]?HMODULE[ \t]?\*\))?\(?(?:\(.*\))?{}\)?" # Regex for matching variable alias assignments self.alias_regex = r"([a-zA-Z_][a-zA-Z0-9_]*)[ \t]?=[ \t]?(?:\(.+?\)\s*)?{}[ \t]*;" self.alias_regex2 = r"{}[ \t]?=[ \t]?([a-zA-Z_][a-zA-Z0-9_]*)[ \t]*;" # Regex for matching internal functions self.internal_function_regex = r"((?:FUN|UndefinedFunction)\_[a-fA-F0-9]+)" self.internal_call_regex = re.compile(self.function_call_regex.format(self.internal_function_regex)) # Regex for matching names of both internal functions and string/memory copy/move API functions self.call_regex = r"((?:FUN|UndefinedFunction)\_[a-fA-F0-9]+|" \ r"str(?:n)?cpy(?:_s)?|w?mem(?:cpy|move)(?:_s)?|basic_string<>)" self.call_regex = re.compile(self.function_call_regex.format(self.call_regex)) # Initializing the decompiler self.flat_program = FlatProgramAPI(currentProgram) self.flat_decompiler = FlatDecompilerAPI(self.flat_program) decompiler_options = DecompileOptions() # Decompilation of some programs requires more memory than the default 50 MiB payload size. decompiler_options.setMaxPayloadMBytes(200) self.flat_decompiler.initialize() # Explicit initialization is required for setting the options self.flat_decompiler.getDecompiler().setOptions(decompiler_options) self.decompiled_functions = {}
def _decompiler(): ifc = DecompInterface() DecOptions = DecompileOptions() service = state.getTool().getService(OptionsService) opt = service.getOptions("Decompiler") DecOptions.grabFromToolAndProgram(None, opt, currentProgram) ifc.setOptions(DecOptions) ifc.toggleCCode(True) ifc.toggleSyntaxTree(True) ifc.setSimplificationStyle("decompile") ifc.openProgram(currentProgram) return ifc
def get_decompile_interface(): # type: () -> DecompInterface interface = DecompInterface() options = DecompileOptions() interface.setOptions(options) interface.openProgram(currentProgram) interface.setSimplificationStyle("decompile") return interface
def generate_decomp_interface(): decompiler = DecompInterface() opts = DecompileOptions() opts.grabFromProgram(curr) decompiler.setOptions(opts) decompiler.toggleCCode(True) decompiler.toggleSyntaxTree(True) # - decompile -- The main decompiler action # - normalize -- Decompilation tuned for normalization # - jumptable -- Simplify just enough to recover a jump-table # - paramid -- Simplify enough to recover function parameters # - register -- Perform one analysis pass on registers, without stack variables # - firstpass -- Construct the initial raw syntax tree, with no simplification decompiler.setSimplificationStyle("decompile") decompiler.openProgram(curr) return decompiler
def get_decompiler(state, program): tool = state.getTool() options = DecompileOptions() decomp = DecompInterface() if tool is not None: service = tool.getService(OptionsService) if service is not None: opt = service.getOptions("Decompiler") options.grabFromToolAndProgram(None, opt, program) decomp.setOptions(options) decomp.toggleCCode(True) decomp.toggleSyntaxTree(True) decomp.setSimplificationStyle("decompile") return decomp
def get_high_function(func): options = DecompileOptions() monitor = ConsoleTaskMonitor() ifc = DecompInterface() ifc.setOptions(options) ifc.openProgram(getCurrentProgram()) res = ifc.decompileFunction(func, 60, monitor) return res.getHighFunction()
sym = getDataAt(refs[0].toAddress).symbols[0] if sym.name == u'__vt' and sym.parentNamespace.name.startswith( u'TParamT'): newTypeName = sym.parentNamespace.getName(True) newTypeName = newTypeName[:newTypeName.find( '<')].replace( u'::', u'/') + newTypeName[newTypeName.find('<'):] newType = currentProgram.getDataTypeManager( ).getDataType("boot.dol/Demangler/" + newTypeName) print offset, newTypeName, newType thisType.replaceAtOffset(offset.value, newType, 0, None, None) inst = inst.next options = DecompileOptions() monitor = ConsoleTaskMonitor() ifc = DecompInterface() ifc.setOptions(options) ifc.openProgram(currentFunction.program) res = ifc.decompileFunction(currentFunction, 60, monitor) high_func = res.getHighFunction() inst = getInstructionAt(currentAddress) while inst.address < currentFunction.body.maxAddress: callConstructor = None if inst.getFlowType().isCall() and \ inst.getFlows()[0] == baseParamConstructor.entryPoint: callConstructor = inst print "Constructor is called at", callConstructor.address
# quit if we did not get even number of hex values is_hex = all(c in string.hexdigits for c in instr_bytes) is_even = len(instr_bytes) % 2 == 0 if not is_hex or not is_even: print "Error: Please only enter hex values." exit() instr_bytes = "".join( ["\\x" + instr_bytes[i:i + 2] for i in range(0, len(instr_bytes), 2)]) decompInterface = DecompInterface() decompInterface.openProgram(currentProgram) # ghidra options newOptions = DecompileOptions() # Current decompiler options newOptions.setMaxPayloadMBytes(max_payload_mbytes) decompInterface.setOptions(newOptions) listing = currentProgram.getListing() fpapi = FlatProgramAPI(currentProgram) address_factory = fpapi.getAddressFactory() psedu_disassembler = PseudoDisassembler(currentProgram) # search for the specified bytes minAddress = currentProgram.getMinAddress() instr_addresses = fpapi.findBytes(minAddress, instr_bytes, matchLimit) fixed = 0 for target_address in instr_addresses: # check if ghidra got this one right disassembled_instr = fpapi.getInstructionAt(target_address)
import re import os # to decompile from ghidra.app.decompiler import DecompileOptions from ghidra.app.decompiler import DecompInterface # to rename function from ghidra.program.model.symbol import SourceType # to trace basic blocks from ghidra.program.model.block import BasicBlockModel from ghidra.program.model.pcode import HighFunctionDBUtil # logic to find and rename the main function ifc = DecompInterface() ifc.setOptions(DecompileOptions()) ifc.openProgram(currentProgram) try: entryfunction = getGlobalFunctions("entry")[0] except: # if binary has symbols if getGlobalFunctions("_start"): entryfunction = getGlobalFunctions("_start")[0] else: exit() res = ifc.decompileFunction(entryfunction, 60, monitor) m = re.search("__libc_start_main\((.+?),", res.getCCodeMarkup().toString()) if m.group(1)[0] != "main": getGlobalFunctions(m.group(1))[0].setName("main", SourceType.ANALYSIS) # for static blocks blockiterator = BasicBlockModel(currentProgram).getCodeBlocks(monitor) fun_blocks = {}
def get_hf(iface, func): iface.setOptions(DecompileOptions()) iface.setSimplificationStyle("normalize") func_decompiled = iface.decompileFunction(func, 60, ConsoleTaskMonitor()) highFunction = func_decompiled.getHighFunction() return highFunction