def run(): monitor = ConsoleTaskMonitor() emuHelper = EmulatorHelper(currentProgram) emuHelper.enableMemoryWriteTracking(True) fnManager = currentProgram.getFunctionManager() beg = currentSelection.getFirstRange().getMinAddress() end = currentSelection.getLastRange().getMaxAddress() function = fnManager.getFunctionContaining(beg) varsFn = function.getAllVariables() setVarsFn = {} for var in varsFn: stackOffset = var.getStackOffset() print(stackOffset) setVarsFn[-stackOffset] = var emulate(emuHelper, beg, end) mems = emuHelper.getTrackedMemoryWriteSet().getAddresses(True) for addr in mems: try: decrStr = emuHelper.readNullTerminatedString(addr, 0xffff) offset = addr.getOffset() print("{:#018x} => {}".format(offset, decrStr)) name = "local_" + decrStr # because 0x0 - offset is annoying in python... var = setVarsFn[0xffffffff - offset + 1] var.setName(name, USER_DEFINED) except: continue emuHelper.dispose()
def renameFunctionsBasedOnstringRefrencesUsingTheDecompiler(): monitor.setMessage("Rename Functions Based on string refrences ") function = getFirstFunction() decompinterface = DecompInterface() decompinterface.openProgram(currentProgram) uniqueList = [] while function is not None and not monitor.isCancelled(): try: tokengrp = decompinterface.decompileFunction(function, 0, ConsoleTaskMonitor()) code = tokengrp.getDecompiledFunction().getC() pattern1 = r"\"[a-zA-Z0-9 .,\-\*\/\[\]\{\}\!\@\#\$\%\^\&\(\)\=\~\:\"\'\\\+\?\>\<\`\_\;]+\"" pattern2 = r'[ .,\-\*\/\[\]\{\}\!\@\#\$\%\^\&\(\)\=\~\:\"\'\\\+\?\>\<\`]+' stringList = re.findall(pattern1,code) if not stringList == []: for unique in stringList: if unique not in uniqueList: uniqueList.append(unique) name = re.sub(pattern2,"","_".join(uniqueList)) if len(name) > 15: name = name[:15] functionName = "rep_s_fun_" + str(function.getEntryPoint()) + "_" + name print functionName function.setName(functionName,USER_DEFINED) except: pass function = getFunctionAfter(function) return 0
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()
def get_decompilation(calle_addr, func_name): program = getCurrentProgram() ifc = DecompInterface() ifc.openProgram(program) # here we assume there is only one function named `main` function = getGlobalFunctions(func_name)[0] # decompile the function and print the pseudo C results = ifc.decompileFunction(function, 0, ConsoleTaskMonitor()) print(results.getDecompiledFunction().getC()) return results.getDecompiledFunction().getC()
def __createRefTable(self, dataTypes): global glb_offset, glb_datatype jc=java_consumer(AddReftoTable) finders = ClassSearcher.getInstances(DataTypeReferenceFinder); for dt in dataTypes: glb_datatype=dt components=dt.getComponents() for cmp in components: fieldName, glb_offset=cmp.getFieldName(), cmp.getOffset() for finder in finders: finder.findReferences(currentProgram, dt, fieldName, jc, ConsoleTaskMonitor()) glb_offset=None glb_datatype=None print "Table of references is created successfully."
def observe_function(func): # decompile the function and print the pseudo C results = ifc.decompileFunction(func, 0, ConsoleTaskMonitor()) decomp_func = results.getDecompiledFunction() if decomp_func is None: # No decompilation available print("Failed to decompile {} ({})".format(func.getName(), func)) return c_code = decomp_func.getC() # print(c_code) for param in func.getParameters(): data_type = param.getDataType() try: data_type = data_type.getDataType() except Exception as e: # We only care about pointers return # We don't care about builtins if type(data_type) is not StructureDB: return observation_list = records.get(data_type, list()) # Look for accesses into the 'this' ptr. # NOTE: This properly skips the vtable (1st field), because there's no ptr offset. # *(float *)(this + 0xc40) regex = '\*\((\w+ \*+)\)\({} \+ ((0x[0-9a-f]+)|(\d+))\)' regex = regex.format(param.getName()) regex = re.compile(regex) for match in regex.finditer(c_code): field_type = match.group(1) field_offset = int(match.group(2), 0) # print("{0}[{2}]: {1}".format(data_type.getName(),field_type, field_offset)) observation_list.append((field_offset, field_type[:-1].rstrip())) # (byte)param_1[0x6c] regex = '\((\w+ ?\**)\){}\[((0x[0-9a-f]+)|(\d+))\]' regex = regex.format(param.getName()) regex = re.compile(regex) for match in regex.finditer(c_code): field_type = match.group(1) field_offset = int(match.group(2), 0) # print("{0}[{2}]: {1}".format(data_type.getName(),field_type, field_offset)) observation_list.append((field_offset, field_type)) # Record what offset and type was used. records[data_type] = observation_list
def fixUndefinedDataTypes(): monitor.setMessage("Fixing Undefined Data Types") function = getFirstFunction() decompinterface = DecompInterface() decompinterface.openProgram(currentProgram) # get var list from decompilation while function is not None: prt = False varList = [] try: tokengrp = decompinterface.decompileFunction(function, 0, ConsoleTaskMonitor()) code = tokengrp.getDecompiledFunction().getC() for line in code.split("\n"): if line == " \r": break if prt: varList.append(filter(None,line.split(";")[0].split(" "))) if line.startswith("{"): prt = True except: pass for var in function.getAllVariables(): varMsg = str(var) dt = str(var.getDataType()) inx = 0 if "undefined" in dt: for decVar in varList: if len(decVar) > 1: arr = False if len(decVar) == 3: arr = True inx = int(decVar[2].split("[")[1].split("]")[0]) if decVar[1].replace("*","") == var.getName(): if not "undefined" in decVar[0]: if '*' in decVar[1]: dt = getDataType("/" + decVar[0] + " " + ('*' * decVar[1].count("*")),arr,inx) else: dt = getDataType("/" + decVar[0],arr,inx) else: if '*' in decVar[1]: dtlen = decVar[0].replace("undefined","") if dtlen == "": dtlen = "1" dt = getDataTypeWrap(dtlen + ('*' * decVar[1].count("*")),arr,inx) else: dt = getDataTypeWrap(decVar[0],arr,inx) if type(dt) == str: dt = str(var.getDataType()) dt = dt.replace("undefined","") dt = getDataTypeWrap(dt) if dt: try: var.setDataType(dt,USER_DEFINED) print "[+] " + str(function.getName()) + ": " + varMsg + " -> " + str(dt) except: pass function = getFunctionAfter(function) return 0
from ghidra.app.decompiler import DecompInterface from ghidra.util.task import ConsoleTaskMonitor # get the current program # here currentProgram is predefined program = currentProgram decompinterface = DecompInterface() decompinterface.openProgram(program) functions = program.getFunctionManager().getFunctions(True) for function in list(functions): print(function) # decompile each function tokengrp = decompinterface.decompileFunction(function, 0, ConsoleTaskMonitor()) print(tokengrp.getDecompiledFunction().getC())
monitor.initialize(len(xrefs)) for xref in xrefs: monitor.checkCanceled() monitor.setMessage(str(xref)) # let's find the function that is calling us, # and decompile it. func = fm.getFunctionContaining(xref.getFromAddress()) if func is None: print("No function found for xref at address " + str(xref.getFromAddress())) continue if func in hit_funcs: stat_skip += 1 continue hit_funcs.add(func) results = ifc.decompileFunction(func, 0, ConsoleTaskMonitor()) decomp_func = results.getDecompiledFunction() if decomp_func is None: # No decompilation available print("Failed to decompile {} ({})".format(func.getName(), func)) stat_no_decomp += 1 continue c_code = decomp_func.getC() for match in regex.finditer(c_code): typename = match.group(1) typesize = int(match.group(2), 0) hit = hit_types.get(typename) if hit is not None: stat_skip_type += 1 if hit != typesize: stat_mismatch_size += 1
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 fieldOffset = None
def main(): fm = currentProgram.getFunctionManager() functions = [func for func in fm.getFunctions(True)] # ==================================================================== # Step 1. Check if our target has at least one source and one sink we care about function_names = [func.name for func in functions] if (set(sources) & set(function_names)) and (set(sinks) & set(function_names)): print( "This target contains interesting source(s) and sink(s). Continuing analysis..." ) else: print( "This target does not contain interesting source(s) and sink(s). Done." ) return # ==================================================================== # Step 2. Find functions that calls at least one source and one sink interesting_functions = [] for func in functions: monitor = ConsoleTaskMonitor() called_functions = func.getCalledFunctions(monitor) called_function_names = [cf.name for cf in called_functions] source_callers = set(called_function_names) & set(sources) sink_callers = set(called_function_names) & set(sinks) if source_callers and sink_callers: interesting_functions.append(func) # Show any interesting functions found if len(interesting_functions) <= 0: print("\nNo interesting functions found to analyze. Done.") return else: print("\nFound {} interesting functions to analyze:".format( len(interesting_functions))) for func in interesting_functions: print(" {}".format(func.name)) # ==================================================================== # Step 3. Dig into interesting functions for func in interesting_functions: print("\nAnalyzing function: {}".format(func.name)) source_args = [] sink_args = [] hf = get_high_function(func) opiter = hf.getPcodeOps() while opiter.hasNext(): op = opiter.next() mnemonic = op.getMnemonic() if mnemonic == "CALL": opinputs = op.getInputs() call_target = opinputs[0] call_target_addr = call_target.getAddress() call_target_name = fm.getFunctionAt(call_target_addr).getName() if call_target_name == "system": arg = opinputs[1] sv = get_stack_var_from_varnode(func, arg) if sv: addr = op.getSeqnum().getTarget() sink_args.append(sv.getName()) print(" >> {} : system({})".format( addr, sv.getName())) elif call_target_name == "sprintf": arg = opinputs[1] sv = get_stack_var_from_varnode(func, arg) if sv: addr = op.getSeqnum().getTarget() source_args.append(sv.getName()) print(" >> {} : sprintf({}, ...)".format( addr, sv.getName())) elif call_target_name == "snprintf": arg = opinputs[1] sv = get_stack_var_from_varnode(func, arg) if sv: addr = op.getSeqnum().getTarget() source_args.append(sv.getName()) print(" >> {} : snprintf({}, ...)".format( addr, sv.getName())) if len(set(sink_args) & set(source_args)) > 0: print( " [!] Alert: Function {} appears to contain a vulnerable `system` call pattern!" .format(func.name))
# -*- coding: utf-8 -*- import json from wasm import WasmLoader from wasm.analysis import WasmAnalysis from ghidra.util.task import ConsoleTaskMonitor monitor = ConsoleTaskMonitor() WasmLoader.loadElementsToTable(currentProgram, WasmAnalysis.getState(currentProgram).module, 0, 0, 0, monitor) runScript("analyze_dyncalls.py") processFields = [ "ScriptMethod", "ScriptString", "ScriptMetadata", "ScriptMetadataMethod", "Addresses", ] functionManager = currentProgram.getFunctionManager() progspace = currentProgram.addressFactory.getAddressSpace("ram") USER_DEFINED = ghidra.program.model.symbol.SourceType.USER_DEFINED def get_addr(addr): return progspace.getAddress(addr)
def get_calling_function(func): monitor = ConsoleTaskMonitor() called_funcs = func.getCallingFunctions(monitor) return called_funcs
def get_hf(iface, func): iface.setOptions(DecompileOptions()) iface.setSimplificationStyle("normalize") func_decompiled = iface.decompileFunction(func, 60, ConsoleTaskMonitor()) highFunction = func_decompiled.getHighFunction() return highFunction
""" Usage: ./analyzeHeadless [GHIDRA WORKING DIR] [PROJECT NAME] -import [BINARY] -overwrite \ -postscript decompile_func.py [FUNCTION] [OUTPUT DIR] """ import os from ghidra.app.decompiler import DecompInterface from ghidra.util.task import ConsoleTaskMonitor args = getScriptArgs() print("[+] Decompiling '{}' now...".format(args[0])) program = getCurrentProgram() decompiface = DecompInterface() decompiface.openProgram(program) func = getGlobalFunctions(args[0])[0] res = decompiface.decompileFunction(func, 0, ConsoleTaskMonitor()) if not os.path.exists(args[1]): os.makedirs(args[1]) fname = "{}/{}.c".format(args[1], args[0]) f = open(fname, 'w') f.write(res.getDecompiledFunction().getC()) f.close()
emuHelper.writeRegister(emuHelper.getPCRegister(), 0x0) return True return False D_HOOKS = { 0x400e3120: { "name": "good_serial", "callback": hook_good_serial, }, } if __name__ == '__main__': emuHelper = EmulatorHelper(currentProgram) monitor = ConsoleTaskMonitor() bbm = BasicBlockModel(currentProgram) ctx = {} ctx = libAFL.init_ctx(ctx, monitor, bbm) res, ctx = libAFL.run_bridge_server_api(ctx, port=PORT) if not res: print("Error on listen on %d tcp port", PORT) exit(1) start_addr = 0x400e30ab stop_addr = toAddr(0x400e3120) # Add new memory section to store emulate values addr_section_emu = 0x20000000
""" Usage: ./analyzeHeadless [GHIDRA WORKING DIR] [PROJECT NAME] -import [BINARY] -overwrite \ -postscript decompile_all.py [OUTPUT PATH] """ import os from ghidra.app.decompiler import DecompInterface from ghidra.util.task import ConsoleTaskMonitor args = getScriptArgs() program = currentProgram decompinterface = DecompInterface() decompinterface.openProgram(program); functions = program.getFunctionManager().getFunctions(True) for function in list(functions): print("[+] Decompiling '{}' now...".format(function)) if not os.path.exists(args[0]): os.makedirs(args[0]) tokengrp = decompinterface.decompileFunction(function, 0, ConsoleTaskMonitor()) fname = "{}/{}.c".format(args[0], str(function)) f = open(fname, 'w') f.write(tokengrp.getDecompiledFunction().getC()) f.close()