| 
 | 1 | +# -*- coding: utf-8 -*-  | 
 | 2 | +import json  | 
 | 3 | + | 
 | 4 | +from ghidra.app.util.cparser.C import CParserUtils  | 
 | 5 | +from ghidra.app.cmd.function import ApplyFunctionSignatureCmd  | 
 | 6 | + | 
 | 7 | +processFields = [  | 
 | 8 | +	"ScriptMethod",  | 
 | 9 | +	"ScriptString",  | 
 | 10 | +	"ScriptMetadata",  | 
 | 11 | +	"ScriptMetadataMethod",  | 
 | 12 | +	"Addresses",  | 
 | 13 | +]  | 
 | 14 | + | 
 | 15 | +functionManager = currentProgram.getFunctionManager()  | 
 | 16 | +baseAddress = currentProgram.getImageBase()  | 
 | 17 | +USER_DEFINED = ghidra.program.model.symbol.SourceType.USER_DEFINED  | 
 | 18 | + | 
 | 19 | +def get_addr(addr):  | 
 | 20 | +	return baseAddress.add(addr)  | 
 | 21 | + | 
 | 22 | +def set_name(addr, name):  | 
 | 23 | +	name = name.replace(' ', '-')  | 
 | 24 | +	createLabel(addr, name, True, USER_DEFINED)  | 
 | 25 | + | 
 | 26 | +def set_type(addr, type):  | 
 | 27 | +	# Requires types (il2cpp.h) to be imported first  | 
 | 28 | +	newType = type.replace("*"," *").replace("  "," ").strip()  | 
 | 29 | +	dataTypes = getDataTypes(newType)  | 
 | 30 | +	addrType = None  | 
 | 31 | +	if len(dataTypes) == 0:  | 
 | 32 | +		if newType == newType[:-2] + " *":  | 
 | 33 | +			baseType = newType[:-2]  | 
 | 34 | +			dataTypes = getDataTypes(baseType)  | 
 | 35 | +			if len(dataTypes) == 1:  | 
 | 36 | +				dtm = currentProgram.getDataTypeManager()  | 
 | 37 | +				pointerType = dtm.getPointer(dataTypes[0])  | 
 | 38 | +				addrType = dtm.addDataType(pointerType, None)  | 
 | 39 | +	elif len(dataTypes) > 1:  | 
 | 40 | +		print("Conflicting data types found for type " + type + "(parsed as '" + newType + "')")  | 
 | 41 | +		return  | 
 | 42 | +	else:  | 
 | 43 | +		addrType = dataTypes[0]  | 
 | 44 | +	if addrType is None:  | 
 | 45 | +		print("Could not identify type " + type + "(parsed as '" + newType + "')")  | 
 | 46 | +	else:  | 
 | 47 | +		createData(addr, addrType)  | 
 | 48 | + | 
 | 49 | +def make_function(start):  | 
 | 50 | +	func = getFunctionAt(start)  | 
 | 51 | +	if func is None:  | 
 | 52 | +		createFunction(start, None)  | 
 | 53 | + | 
 | 54 | +def set_sig(addr, name, sig):  | 
 | 55 | +	try:   | 
 | 56 | +		typeSig = CParserUtils.parseSignature(None, currentProgram, sig, False)  | 
 | 57 | +	except ghidra.app.util.cparser.C.ParseException:  | 
 | 58 | +		print("Warning: Unable to parse")  | 
 | 59 | +		print(sig)  | 
 | 60 | +		print("Attempting to modify...")  | 
 | 61 | +		# try to fix by renaming the parameters  | 
 | 62 | +		try:  | 
 | 63 | +			newSig = sig.replace(", ","ext, ").replace("\)","ext\)")  | 
 | 64 | +			typeSig = CParserUtils.parseSignature(None, currentProgram, newSig, False)  | 
 | 65 | +		except:  | 
 | 66 | +			print("Warning: also unable to parse")  | 
 | 67 | +			print(newSig)  | 
 | 68 | +			print("Skipping.")  | 
 | 69 | +			return  | 
 | 70 | +	if typeSig is not None:  | 
 | 71 | +		typeSig.setName(name)  | 
 | 72 | +		ApplyFunctionSignatureCmd(addr, typeSig, USER_DEFINED, False, True).applyTo(currentProgram)  | 
 | 73 | + | 
 | 74 | +f = askFile("script.json from Il2cppdumper", "Open")  | 
 | 75 | +data = json.loads(open(f.absolutePath, 'rb').read().decode('utf-8'))  | 
 | 76 | + | 
 | 77 | +if "ScriptMethod" in data and "ScriptMethod" in processFields:  | 
 | 78 | +	scriptMethods = data["ScriptMethod"]  | 
 | 79 | +	monitor.initialize(len(scriptMethods))  | 
 | 80 | +	monitor.setMessage("Methods")  | 
 | 81 | +	for scriptMethod in scriptMethods:  | 
 | 82 | +		addr = get_addr(scriptMethod["Address"])  | 
 | 83 | +		name = scriptMethod["Name"].encode("utf-8")  | 
 | 84 | +		set_name(addr, name)  | 
 | 85 | +		monitor.incrementProgress(1)  | 
 | 86 | + | 
 | 87 | +if "ScriptString" in data and "ScriptString" in processFields:  | 
 | 88 | +	index = 1  | 
 | 89 | +	scriptStrings = data["ScriptString"]  | 
 | 90 | +	monitor.initialize(len(scriptStrings))  | 
 | 91 | +	monitor.setMessage("Strings")  | 
 | 92 | +	for scriptString in scriptStrings:  | 
 | 93 | +		addr = get_addr(scriptString["Address"])  | 
 | 94 | +		value = scriptString["Value"].encode("utf-8")  | 
 | 95 | +		name = "StringLiteral_" + str(index)  | 
 | 96 | +		createLabel(addr, name, True, USER_DEFINED)  | 
 | 97 | +		setEOLComment(addr, value)  | 
 | 98 | +		index += 1  | 
 | 99 | +		monitor.incrementProgress(1)  | 
 | 100 | + | 
 | 101 | +if "ScriptMetadata" in data and "ScriptMetadata" in processFields:  | 
 | 102 | +	scriptMetadatas = data["ScriptMetadata"]  | 
 | 103 | +	monitor.initialize(len(scriptMetadatas))  | 
 | 104 | +	monitor.setMessage("Metadata")  | 
 | 105 | +	for scriptMetadata in scriptMetadatas:  | 
 | 106 | +		addr = get_addr(scriptMetadata["Address"])  | 
 | 107 | +		name = scriptMetadata["Name"].encode("utf-8")  | 
 | 108 | +		set_name(addr, name)  | 
 | 109 | +		setEOLComment(addr, name)  | 
 | 110 | +		monitor.incrementProgress(1)  | 
 | 111 | +		if scriptMetadata["Signature"]:  | 
 | 112 | +			set_type(addr, scriptMetadata["Signature"].encode("utf-8"))  | 
 | 113 | + | 
 | 114 | +if "ScriptMetadataMethod" in data and "ScriptMetadataMethod" in processFields:  | 
 | 115 | +	scriptMetadataMethods = data["ScriptMetadataMethod"]  | 
 | 116 | +	monitor.initialize(len(scriptMetadataMethods))  | 
 | 117 | +	monitor.setMessage("Metadata Methods")  | 
 | 118 | +	for scriptMetadataMethod in scriptMetadataMethods:  | 
 | 119 | +		addr = get_addr(scriptMetadataMethod["Address"])  | 
 | 120 | +		name = scriptMetadataMethod["Name"].encode("utf-8")  | 
 | 121 | +		methodAddr = get_addr(scriptMetadataMethod["MethodAddress"])  | 
 | 122 | +		set_name(addr, name)  | 
 | 123 | +		setEOLComment(addr, name)  | 
 | 124 | +		monitor.incrementProgress(1)  | 
 | 125 | + | 
 | 126 | +if "Addresses" in data and "Addresses" in processFields:  | 
 | 127 | +	addresses = data["Addresses"]  | 
 | 128 | +	monitor.initialize(len(addresses))  | 
 | 129 | +	monitor.setMessage("Addresses")  | 
 | 130 | +	for index in range(len(addresses) - 1):  | 
 | 131 | +		start = get_addr(addresses[index])  | 
 | 132 | +		make_function(start)  | 
 | 133 | +		monitor.incrementProgress(1)  | 
 | 134 | + | 
 | 135 | +if "ScriptMethod" in data and "ScriptMethod" in processFields:  | 
 | 136 | +	scriptMethods = data["ScriptMethod"]  | 
 | 137 | +	for scriptMethod in scriptMethods:  | 
 | 138 | +		addr = get_addr(scriptMethod["Address"])  | 
 | 139 | +		sig = scriptMethod["Signature"][:-1].encode("utf-8")  | 
 | 140 | +		name = scriptMethod["Name"].encode("utf-8")  | 
 | 141 | +		set_sig(addr, name, sig)  | 
 | 142 | + | 
 | 143 | +print 'Script finished!'  | 
0 commit comments