From f87d22d726720abecf308b771fa19ecb1022eb18 Mon Sep 17 00:00:00 2001 From: Perfare Date: Sun, 13 Dec 2020 04:06:17 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8D=95=E7=8B=AC=E7=9A=84ghidra=E8=84=9A?= =?UTF-8?q?=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Il2CppDumper/Il2CppDumper.csproj | 3 + Il2CppDumper/ghidra.py | 56 ----------- Il2CppDumper/ghidra_with_struct.py | 143 +++++++++++++++++++++++++++++ 3 files changed, 146 insertions(+), 56 deletions(-) create mode 100644 Il2CppDumper/ghidra_with_struct.py diff --git a/Il2CppDumper/Il2CppDumper.csproj b/Il2CppDumper/Il2CppDumper.csproj index 652cf97..5f79586 100644 --- a/Il2CppDumper/Il2CppDumper.csproj +++ b/Il2CppDumper/Il2CppDumper.csproj @@ -25,6 +25,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest diff --git a/Il2CppDumper/ghidra.py b/Il2CppDumper/ghidra.py index b063cde..9e26ded 100644 --- a/Il2CppDumper/ghidra.py +++ b/Il2CppDumper/ghidra.py @@ -1,9 +1,6 @@ # -*- coding: utf-8 -*- import json -from ghidra.app.util.cparser.C import CParserUtils -from ghidra.app.cmd.function import ApplyFunctionSignatureCmd - processFields = [ "ScriptMethod", "ScriptString", @@ -23,54 +20,11 @@ def set_name(addr, name): name = name.replace(' ', '-') createLabel(addr, name, True, USER_DEFINED) -def set_type(addr, type): - # Requires types (il2cpp.h) to be imported first - newType = type.replace("*"," *").replace(" "," ").strip() - dataTypes = getDataTypes(newType) - addrType = None - if len(dataTypes) == 0: - if newType == newType[:-2] + " *": - baseType = newType[:-2] - dataTypes = getDataTypes(baseType) - if len(dataTypes) == 1: - dtm = currentProgram.getDataTypeManager() - pointerType = dtm.getPointer(dataTypes[0]) - addrType = dtm.addDataType(pointerType, None) - elif len(dataTypes) > 1: - print("Conflicting data types found for type " + type + "(parsed as '" + newType + "')") - return - else: - addrType = dataTypes[0] - if addrType is None: - print("Could not identify type " + type + "(parsed as '" + newType + "')") - else: - createData(addr, addrType) - def make_function(start): func = getFunctionAt(start) if func is None: createFunction(start, None) -def set_sig(addr, name, sig): - try: - typeSig = CParserUtils.parseSignature(None, currentProgram, sig, False) - except ghidra.app.util.cparser.C.ParseException: - print("Warning: Unable to parse") - print(sig) - print("Attempting to modify...") - # try to fix by renaming the parameters - try: - newSig = sig.replace(", ","ext, ").replace("\)","ext\)") - typeSig = CParserUtils.parseSignature(None, currentProgram, newSig, False) - except: - print("Warning: also unable to parse") - print(newSig) - print("Skipping.") - return - if typeSig is not None: - typeSig.setName(name) - ApplyFunctionSignatureCmd(addr, typeSig, USER_DEFINED, False, True).applyTo(currentProgram) - f = askFile("script.json from Il2cppdumper", "Open") data = json.loads(open(f.absolutePath, 'rb').read().decode('utf-8')) @@ -108,8 +62,6 @@ if "ScriptMetadata" in data and "ScriptMetadata" in processFields: set_name(addr, name) setEOLComment(addr, name) monitor.incrementProgress(1) - if scriptMetadata["Signature"]: - set_type(addr, scriptMetadata["Signature"].encode("utf-8")) if "ScriptMetadataMethod" in data and "ScriptMetadataMethod" in processFields: scriptMetadataMethods = data["ScriptMetadataMethod"] @@ -132,12 +84,4 @@ if "Addresses" in data and "Addresses" in processFields: make_function(start) monitor.incrementProgress(1) -if "ScriptMethod" in data and "ScriptMethod" in processFields: - scriptMethods = data["ScriptMethod"] - for scriptMethod in scriptMethods: - addr = get_addr(scriptMethod["Address"]) - sig = scriptMethod["Signature"][:-1].encode("utf-8") - name = scriptMethod["Name"].encode("utf-8") - set_sig(addr, name, sig) - print 'Script finished!' diff --git a/Il2CppDumper/ghidra_with_struct.py b/Il2CppDumper/ghidra_with_struct.py new file mode 100644 index 0000000..b063cde --- /dev/null +++ b/Il2CppDumper/ghidra_with_struct.py @@ -0,0 +1,143 @@ +# -*- coding: utf-8 -*- +import json + +from ghidra.app.util.cparser.C import CParserUtils +from ghidra.app.cmd.function import ApplyFunctionSignatureCmd + +processFields = [ + "ScriptMethod", + "ScriptString", + "ScriptMetadata", + "ScriptMetadataMethod", + "Addresses", +] + +functionManager = currentProgram.getFunctionManager() +baseAddress = currentProgram.getImageBase() +USER_DEFINED = ghidra.program.model.symbol.SourceType.USER_DEFINED + +def get_addr(addr): + return baseAddress.add(addr) + +def set_name(addr, name): + name = name.replace(' ', '-') + createLabel(addr, name, True, USER_DEFINED) + +def set_type(addr, type): + # Requires types (il2cpp.h) to be imported first + newType = type.replace("*"," *").replace(" "," ").strip() + dataTypes = getDataTypes(newType) + addrType = None + if len(dataTypes) == 0: + if newType == newType[:-2] + " *": + baseType = newType[:-2] + dataTypes = getDataTypes(baseType) + if len(dataTypes) == 1: + dtm = currentProgram.getDataTypeManager() + pointerType = dtm.getPointer(dataTypes[0]) + addrType = dtm.addDataType(pointerType, None) + elif len(dataTypes) > 1: + print("Conflicting data types found for type " + type + "(parsed as '" + newType + "')") + return + else: + addrType = dataTypes[0] + if addrType is None: + print("Could not identify type " + type + "(parsed as '" + newType + "')") + else: + createData(addr, addrType) + +def make_function(start): + func = getFunctionAt(start) + if func is None: + createFunction(start, None) + +def set_sig(addr, name, sig): + try: + typeSig = CParserUtils.parseSignature(None, currentProgram, sig, False) + except ghidra.app.util.cparser.C.ParseException: + print("Warning: Unable to parse") + print(sig) + print("Attempting to modify...") + # try to fix by renaming the parameters + try: + newSig = sig.replace(", ","ext, ").replace("\)","ext\)") + typeSig = CParserUtils.parseSignature(None, currentProgram, newSig, False) + except: + print("Warning: also unable to parse") + print(newSig) + print("Skipping.") + return + if typeSig is not None: + typeSig.setName(name) + ApplyFunctionSignatureCmd(addr, typeSig, USER_DEFINED, False, True).applyTo(currentProgram) + +f = askFile("script.json from Il2cppdumper", "Open") +data = json.loads(open(f.absolutePath, 'rb').read().decode('utf-8')) + +if "ScriptMethod" in data and "ScriptMethod" in processFields: + scriptMethods = data["ScriptMethod"] + monitor.initialize(len(scriptMethods)) + monitor.setMessage("Methods") + for scriptMethod in scriptMethods: + addr = get_addr(scriptMethod["Address"]) + name = scriptMethod["Name"].encode("utf-8") + set_name(addr, name) + monitor.incrementProgress(1) + +if "ScriptString" in data and "ScriptString" in processFields: + index = 1 + scriptStrings = data["ScriptString"] + monitor.initialize(len(scriptStrings)) + monitor.setMessage("Strings") + for scriptString in scriptStrings: + addr = get_addr(scriptString["Address"]) + value = scriptString["Value"].encode("utf-8") + name = "StringLiteral_" + str(index) + createLabel(addr, name, True, USER_DEFINED) + setEOLComment(addr, value) + index += 1 + monitor.incrementProgress(1) + +if "ScriptMetadata" in data and "ScriptMetadata" in processFields: + scriptMetadatas = data["ScriptMetadata"] + monitor.initialize(len(scriptMetadatas)) + monitor.setMessage("Metadata") + for scriptMetadata in scriptMetadatas: + addr = get_addr(scriptMetadata["Address"]) + name = scriptMetadata["Name"].encode("utf-8") + set_name(addr, name) + setEOLComment(addr, name) + monitor.incrementProgress(1) + if scriptMetadata["Signature"]: + set_type(addr, scriptMetadata["Signature"].encode("utf-8")) + +if "ScriptMetadataMethod" in data and "ScriptMetadataMethod" in processFields: + scriptMetadataMethods = data["ScriptMetadataMethod"] + monitor.initialize(len(scriptMetadataMethods)) + monitor.setMessage("Metadata Methods") + for scriptMetadataMethod in scriptMetadataMethods: + addr = get_addr(scriptMetadataMethod["Address"]) + name = scriptMetadataMethod["Name"].encode("utf-8") + methodAddr = get_addr(scriptMetadataMethod["MethodAddress"]) + set_name(addr, name) + setEOLComment(addr, name) + monitor.incrementProgress(1) + +if "Addresses" in data and "Addresses" in processFields: + addresses = data["Addresses"] + monitor.initialize(len(addresses)) + monitor.setMessage("Addresses") + for index in range(len(addresses) - 1): + start = get_addr(addresses[index]) + make_function(start) + monitor.incrementProgress(1) + +if "ScriptMethod" in data and "ScriptMethod" in processFields: + scriptMethods = data["ScriptMethod"] + for scriptMethod in scriptMethods: + addr = get_addr(scriptMethod["Address"]) + sig = scriptMethod["Signature"][:-1].encode("utf-8") + name = scriptMethod["Name"].encode("utf-8") + set_sig(addr, name, sig) + +print 'Script finished!'