Skip to content

Commit d0eeb82

Browse files
committed
Merge branch 'master' of https://github.com/Perfare/Il2CppDumper
2 parents f73d1ac + 4428601 commit d0eeb82

File tree

6 files changed

+179
-0
lines changed

6 files changed

+179
-0
lines changed

Il2CppDumper/Il2CppDumper.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@
2525
<None Update="ghidra.py">
2626
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
2727
</None>
28+
<None Update="ghidra_wasm.py">
29+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
30+
</None>
2831
<None Update="ghidra_with_struct.py">
2932
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
3033
</None>

Il2CppDumper/Outputs/ScriptJson.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ public class ScriptMethod
2121
public ulong Address;
2222
public string Name;
2323
public string Signature;
24+
public string TypeSignature;
2425
}
2526

2627
public class ScriptString

Il2CppDumper/Outputs/StructGenerator.cs

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ public void WriteScript(string outputDir)
8989
var methodPointer = il2Cpp.GetMethodPointer(imageName, methodDef);
9090
if (methodPointer > 0)
9191
{
92+
var methodTypeSignature = new List<Il2CppTypeEnum>();
9293
var scriptMethod = new ScriptMethod();
9394
json.ScriptMethod.Add(scriptMethod);
9495
scriptMethod.Address = il2Cpp.GetRVA(methodPointer);
@@ -101,15 +102,18 @@ public void WriteScript(string outputDir)
101102
{
102103
returnType += "*";
103104
}
105+
methodTypeSignature.Add(methodReturnType.byref == 1 ? Il2CppTypeEnum.IL2CPP_TYPE_PTR : methodReturnType.type);
104106
var signature = $"{returnType} {FixName(methodFullName)} (";
105107
var parameterStrs = new List<string>();
106108
if ((methodDef.flags & METHOD_ATTRIBUTE_STATIC) == 0)
107109
{
108110
var thisType = ParseType(il2Cpp.types[typeDef.byvalTypeIndex]);
111+
methodTypeSignature.Add(il2Cpp.types[typeDef.byvalTypeIndex].type);
109112
parameterStrs.Add($"{thisType} __this");
110113
}
111114
else if (il2Cpp.Version <= 24)
112115
{
116+
methodTypeSignature.Add(Il2CppTypeEnum.IL2CPP_TYPE_PTR);
113117
parameterStrs.Add($"Il2CppObject* __this");
114118
}
115119
for (var j = 0; j < methodDef.parameterCount; j++)
@@ -122,12 +126,15 @@ public void WriteScript(string outputDir)
122126
{
123127
parameterCType += "*";
124128
}
129+
methodTypeSignature.Add(parameterType.byref == 1 ? Il2CppTypeEnum.IL2CPP_TYPE_PTR : parameterType.type);
125130
parameterStrs.Add($"{parameterCType} {FixName(parameterName)}");
126131
}
132+
methodTypeSignature.Add(Il2CppTypeEnum.IL2CPP_TYPE_PTR);
127133
parameterStrs.Add("const MethodInfo* method");
128134
signature += string.Join(", ", parameterStrs);
129135
signature += ");";
130136
scriptMethod.Signature = signature;
137+
scriptMethod.TypeSignature = GetMethodTypeSignature(methodTypeSignature);
131138
}
132139
//泛型实例函数
133140
if (il2Cpp.methodDefinitionMethodSpecs.TryGetValue(i, out var methodSpecs))
@@ -137,6 +144,7 @@ public void WriteScript(string outputDir)
137144
var genericMethodPointer = il2Cpp.methodSpecGenericMethodPointers[methodSpec];
138145
if (genericMethodPointer > 0)
139146
{
147+
var methodTypeSignature = new List<Il2CppTypeEnum>();
140148
var scriptMethod = new ScriptMethod();
141149
json.ScriptMethod.Add(scriptMethod);
142150
scriptMethod.Address = il2Cpp.GetRVA(genericMethodPointer);
@@ -158,6 +166,7 @@ public void WriteScript(string outputDir)
158166
{
159167
returnType += "*";
160168
}
169+
methodTypeSignature.Add(methodReturnType.byref == 1 ? Il2CppTypeEnum.IL2CPP_TYPE_PTR : methodReturnType.type);
161170
var signature = $"{returnType} {FixName(methodFullName)} (";
162171
var parameterStrs = new List<string>();
163172
if ((methodDef.flags & METHOD_ATTRIBUTE_STATIC) == 0)
@@ -172,21 +181,25 @@ public void WriteScript(string outputDir)
172181
if (nameGenericClassDic.TryGetValue(typeStructName, out var il2CppType))
173182
{
174183
thisType = ParseType(il2CppType);
184+
methodTypeSignature.Add(il2CppType.type);
175185
}
176186
else
177187
{
178188
//没有单独的泛型实例类
179189
thisType = ParseType(il2Cpp.types[typeDef.byvalTypeIndex]);
190+
methodTypeSignature.Add(il2Cpp.types[typeDef.byvalTypeIndex].type);
180191
}
181192
}
182193
else
183194
{
184195
thisType = ParseType(il2Cpp.types[typeDef.byvalTypeIndex]);
196+
methodTypeSignature.Add(il2Cpp.types[typeDef.byvalTypeIndex].type);
185197
}
186198
parameterStrs.Add($"{thisType} __this");
187199
}
188200
else if (il2Cpp.Version <= 24)
189201
{
202+
methodTypeSignature.Add(Il2CppTypeEnum.IL2CPP_TYPE_PTR);
190203
parameterStrs.Add($"Il2CppObject* __this");
191204
}
192205
for (var j = 0; j < methodDef.parameterCount; j++)
@@ -199,12 +212,15 @@ public void WriteScript(string outputDir)
199212
{
200213
parameterCType += "*";
201214
}
215+
methodTypeSignature.Add(parameterType.byref == 1 ? Il2CppTypeEnum.IL2CPP_TYPE_PTR : parameterType.type);
202216
parameterStrs.Add($"{parameterCType} {FixName(parameterName)}");
203217
}
218+
methodTypeSignature.Add(Il2CppTypeEnum.IL2CPP_TYPE_PTR);
204219
parameterStrs.Add($"const {methodInfoName}* method");
205220
signature += string.Join(", ", parameterStrs);
206221
signature += ");";
207222
scriptMethod.Signature = signature;
223+
scriptMethod.TypeSignature = GetMethodTypeSignature(methodTypeSignature);
208224
}
209225
}
210226
}
@@ -644,6 +660,57 @@ private string ParseType(Il2CppType il2CppType, Il2CppGenericContext context = n
644660
throw new NotSupportedException();
645661
}
646662
}
663+
public string GetMethodTypeSignature(List<Il2CppTypeEnum> types)
664+
{
665+
string signature = string.Empty;
666+
foreach (Il2CppTypeEnum type in types)
667+
{
668+
switch (type)
669+
{
670+
case Il2CppTypeEnum.IL2CPP_TYPE_VOID:
671+
signature += "v";
672+
break;
673+
case Il2CppTypeEnum.IL2CPP_TYPE_BOOLEAN:
674+
case Il2CppTypeEnum.IL2CPP_TYPE_CHAR:
675+
case Il2CppTypeEnum.IL2CPP_TYPE_I1:
676+
case Il2CppTypeEnum.IL2CPP_TYPE_U1:
677+
case Il2CppTypeEnum.IL2CPP_TYPE_I2:
678+
case Il2CppTypeEnum.IL2CPP_TYPE_U2:
679+
case Il2CppTypeEnum.IL2CPP_TYPE_I4:
680+
case Il2CppTypeEnum.IL2CPP_TYPE_U4:
681+
signature += "i";
682+
break;
683+
case Il2CppTypeEnum.IL2CPP_TYPE_I8:
684+
case Il2CppTypeEnum.IL2CPP_TYPE_U8:
685+
signature += "j";
686+
break;
687+
case Il2CppTypeEnum.IL2CPP_TYPE_R4:
688+
signature += "f";
689+
break;
690+
case Il2CppTypeEnum.IL2CPP_TYPE_R8:
691+
signature += "d";
692+
break;
693+
case Il2CppTypeEnum.IL2CPP_TYPE_STRING:
694+
case Il2CppTypeEnum.IL2CPP_TYPE_PTR:
695+
case Il2CppTypeEnum.IL2CPP_TYPE_VALUETYPE:
696+
case Il2CppTypeEnum.IL2CPP_TYPE_CLASS:
697+
case Il2CppTypeEnum.IL2CPP_TYPE_VAR:
698+
case Il2CppTypeEnum.IL2CPP_TYPE_ARRAY:
699+
case Il2CppTypeEnum.IL2CPP_TYPE_GENERICINST:
700+
case Il2CppTypeEnum.IL2CPP_TYPE_TYPEDBYREF:
701+
case Il2CppTypeEnum.IL2CPP_TYPE_I:
702+
case Il2CppTypeEnum.IL2CPP_TYPE_U:
703+
case Il2CppTypeEnum.IL2CPP_TYPE_OBJECT:
704+
case Il2CppTypeEnum.IL2CPP_TYPE_SZARRAY:
705+
case Il2CppTypeEnum.IL2CPP_TYPE_MVAR:
706+
signature += "i";
707+
break;
708+
default:
709+
throw new NotSupportedException();
710+
}
711+
}
712+
return signature;
713+
}
647714

648715
private void AddStruct(Il2CppTypeDefinition typeDef)
649716
{

Il2CppDumper/ghidra_wasm.py

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
# -*- coding: utf-8 -*-
2+
import json
3+
4+
from wasm import WasmLoader
5+
from wasm.analysis import WasmAnalysis
6+
from ghidra.util.task import ConsoleTaskMonitor
7+
8+
monitor = ConsoleTaskMonitor()
9+
WasmLoader.loadElementsToTable(currentProgram, WasmAnalysis.getState(currentProgram).module, 0, 0, 0, monitor)
10+
11+
runScript("analyze_dyncalls.py")
12+
13+
processFields = [
14+
"ScriptMethod",
15+
"ScriptString",
16+
"ScriptMetadata",
17+
"ScriptMetadataMethod",
18+
"Addresses",
19+
]
20+
21+
functionManager = currentProgram.getFunctionManager()
22+
progspace = currentProgram.addressFactory.getAddressSpace("ram")
23+
USER_DEFINED = ghidra.program.model.symbol.SourceType.USER_DEFINED
24+
25+
def get_addr(addr):
26+
return progspace.getAddress(addr)
27+
28+
def set_name(addr, name):
29+
name = name.replace(' ', '-')
30+
createLabel(addr, name, True, USER_DEFINED)
31+
32+
def make_function(start):
33+
func = getFunctionAt(start)
34+
if func is None:
35+
createFunction(start, None)
36+
37+
f = askFile("script.json from Il2cppdumper", "Open")
38+
data = json.loads(open(f.absolutePath, 'rb').read().decode('utf-8'))
39+
40+
41+
if "ScriptMethod" in data and "ScriptMethod" in processFields:
42+
scriptMethods = data["ScriptMethod"]
43+
dynCallNamespace = currentProgram.symbolTable.getNamespace("dynCall", None)
44+
monitor.initialize(len(scriptMethods))
45+
monitor.setMessage("Methods")
46+
for scriptMethod in scriptMethods:
47+
offset = scriptMethod["Address"]
48+
sig = scriptMethod["TypeSignature"]
49+
symbolName = "func_%s_%d" % (sig, offset)
50+
symbol = currentProgram.symbolTable.getSymbol(symbolName, dynCallNamespace)
51+
if symbol:
52+
addr = symbol.address
53+
name = scriptMethod["Name"].encode("utf-8")
54+
set_name(addr, name)
55+
else:
56+
print "Warning at %s:" % scriptMethod["Name"]
57+
print "Symbol %s not found!" % symbolName
58+
monitor.incrementProgress(1)
59+
60+
if "ScriptString" in data and "ScriptString" in processFields:
61+
index = 1
62+
scriptStrings = data["ScriptString"]
63+
monitor.initialize(len(scriptStrings))
64+
monitor.setMessage("Strings")
65+
for scriptString in scriptStrings:
66+
addr = get_addr(scriptString["Address"])
67+
value = scriptString["Value"].encode("utf-8")
68+
name = "StringLiteral_" + str(index)
69+
createLabel(addr, name, True, USER_DEFINED)
70+
setEOLComment(addr, value)
71+
index += 1
72+
monitor.incrementProgress(1)
73+
74+
if "ScriptMetadata" in data and "ScriptMetadata" in processFields:
75+
scriptMetadatas = data["ScriptMetadata"]
76+
monitor.initialize(len(scriptMetadatas))
77+
monitor.setMessage("Metadata")
78+
for scriptMetadata in scriptMetadatas:
79+
addr = get_addr(scriptMetadata["Address"])
80+
name = scriptMetadata["Name"].encode("utf-8")
81+
set_name(addr, name)
82+
setEOLComment(addr, name)
83+
monitor.incrementProgress(1)
84+
85+
if "ScriptMetadataMethod" in data and "ScriptMetadataMethod" in processFields:
86+
scriptMetadataMethods = data["ScriptMetadataMethod"]
87+
monitor.initialize(len(scriptMetadataMethods))
88+
monitor.setMessage("Metadata Methods")
89+
for scriptMetadataMethod in scriptMetadataMethods:
90+
addr = get_addr(scriptMetadataMethod["Address"])
91+
name = scriptMetadataMethod["Name"].encode("utf-8")
92+
methodAddr = get_addr(scriptMetadataMethod["MethodAddress"])
93+
set_name(addr, name)
94+
setEOLComment(addr, name)
95+
monitor.incrementProgress(1)
96+
97+
if "Addresses" in data and "Addresses" in processFields:
98+
pass
99+
100+
print 'Script finished!'

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@ structure information header file
5454

5555
For Ghidra
5656

57+
#### ghidra_wasm.py
58+
59+
For Ghidra, work with [ghidra-wasm-plugin](https://github.com/nneonneo/ghidra-wasm-plugin)
60+
5761
#### script.json
5862

5963
For ida.py and ghidra.py

README.zh-CN.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@ Il2CppDumper.exe <executable-file> <global-metadata> <output-directory>
5252

5353
用于Ghidra
5454

55+
#### ghidra_wasm.py
56+
57+
用于Ghidra, 和[ghidra-wasm-plugin](https://github.com/nneonneo/ghidra-wasm-plugin)一起工作
58+
5559
#### script.json
5660

5761
用于IDA和Ghidra脚本

0 commit comments

Comments
 (0)