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 = {}
Esempio n. 2
0
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
Esempio n. 3
0
def get_decompile_interface():  # type: () -> DecompInterface
    interface = DecompInterface()
    options = DecompileOptions()
    interface.setOptions(options)
    interface.openProgram(currentProgram)
    interface.setSimplificationStyle("decompile")
    return interface
Esempio n. 4
0
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
Esempio n. 5
0
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
Esempio n. 6
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()
Esempio n. 7
0
                    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)
Esempio n. 9
0
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 = {}
Esempio n. 10
0
def get_hf(iface, func):
    iface.setOptions(DecompileOptions())
    iface.setSimplificationStyle("normalize")
    func_decompiled = iface.decompileFunction(func, 60, ConsoleTaskMonitor())
    highFunction = func_decompiled.getHighFunction()
    return highFunction