mirror of
https://github.com/Perfare/Il2CppDumper.git
synced 2025-01-26 02:33:01 -03:00
完善头文件输出
This commit is contained in:
parent
1b89455c95
commit
cfa4037d23
4 changed files with 137 additions and 41 deletions
|
@ -9,9 +9,7 @@ namespace Il2CppDumper
|
||||||
public static class HeaderConstants
|
public static class HeaderConstants
|
||||||
{
|
{
|
||||||
public readonly static string HeaderV242 =
|
public readonly static string HeaderV242 =
|
||||||
@"#define ALIGN_TYPE(val) __attribute__((aligned(val)))
|
@"struct VirtualInvokeData
|
||||||
|
|
||||||
struct VirtualInvokeData
|
|
||||||
{
|
{
|
||||||
uintptr_t methodPtr;
|
uintptr_t methodPtr;
|
||||||
void* method;
|
void* method;
|
||||||
|
@ -20,11 +18,7 @@ struct VirtualInvokeData
|
||||||
struct Il2CppType
|
struct Il2CppType
|
||||||
{
|
{
|
||||||
void* data;
|
void* data;
|
||||||
unsigned int attrs : 16;
|
unsigned int bits;
|
||||||
unsigned int type : 8;
|
|
||||||
unsigned int num_mods : 6;
|
|
||||||
unsigned int byref : 1;
|
|
||||||
unsigned int pinned : 1;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Il2CppClass;
|
struct Il2CppClass;
|
||||||
|
@ -62,7 +56,7 @@ struct Il2CppClass_2
|
||||||
uint32_t initializationExceptionGCHandle;
|
uint32_t initializationExceptionGCHandle;
|
||||||
uint32_t cctor_started;
|
uint32_t cctor_started;
|
||||||
uint32_t cctor_finished;
|
uint32_t cctor_finished;
|
||||||
ALIGN_TYPE(8) size_t cctor_thread;
|
size_t cctor_thread;
|
||||||
int32_t genericContainerIndex;
|
int32_t genericContainerIndex;
|
||||||
uint32_t instance_size;
|
uint32_t instance_size;
|
||||||
uint32_t actualSize;
|
uint32_t actualSize;
|
||||||
|
@ -89,20 +83,8 @@ struct Il2CppClass_2
|
||||||
uint8_t minimumAlignment;
|
uint8_t minimumAlignment;
|
||||||
uint8_t naturalAligment;
|
uint8_t naturalAligment;
|
||||||
uint8_t packingSize;
|
uint8_t packingSize;
|
||||||
uint8_t initialized_and_no_error : 1;
|
uint8_t bitflags1;
|
||||||
uint8_t valuetype : 1;
|
uint8_t bitflags2;
|
||||||
uint8_t initialized : 1;
|
|
||||||
uint8_t enumtype : 1;
|
|
||||||
uint8_t is_generic : 1;
|
|
||||||
uint8_t has_references : 1;
|
|
||||||
uint8_t init_pending : 1;
|
|
||||||
uint8_t size_inited : 1;
|
|
||||||
uint8_t has_finalize : 1;
|
|
||||||
uint8_t has_cctor : 1;
|
|
||||||
uint8_t is_blittable : 1;
|
|
||||||
uint8_t is_import_or_windows_runtime : 1;
|
|
||||||
uint8_t is_vtable_initialized : 1;
|
|
||||||
uint8_t has_initialization_error : 1;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Il2CppClass
|
struct Il2CppClass
|
||||||
|
|
|
@ -99,6 +99,15 @@ namespace Il2CppDumper
|
||||||
json.ScriptMetadata.Add(scriptMetadata);
|
json.ScriptMetadata.Add(scriptMetadata);
|
||||||
scriptMetadata.Address = il2Cpp.GetRVA(il2Cpp.metadataUsages[i.Key]);
|
scriptMetadata.Address = il2Cpp.GetRVA(il2Cpp.metadataUsages[i.Key]);
|
||||||
scriptMetadata.Name = "Class$" + typeName;
|
scriptMetadata.Name = "Class$" + typeName;
|
||||||
|
var signature = GetIl2CppTypeSignature(type);
|
||||||
|
if (signature == "Il2CppArray*")
|
||||||
|
{
|
||||||
|
scriptMetadata.Signature = signature;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
scriptMetadata.Signature = FixName(signature) + "_c*";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
foreach (var i in metadata.metadataUsageDic[2]) //kIl2CppMetadataUsageIl2CppType
|
foreach (var i in metadata.metadataUsageDic[2]) //kIl2CppMetadataUsageIl2CppType
|
||||||
{
|
{
|
||||||
|
@ -108,6 +117,15 @@ namespace Il2CppDumper
|
||||||
json.ScriptMetadata.Add(scriptMetadata);
|
json.ScriptMetadata.Add(scriptMetadata);
|
||||||
scriptMetadata.Address = il2Cpp.GetRVA(il2Cpp.metadataUsages[i.Key]);
|
scriptMetadata.Address = il2Cpp.GetRVA(il2Cpp.metadataUsages[i.Key]);
|
||||||
scriptMetadata.Name = "Class$" + typeName;
|
scriptMetadata.Name = "Class$" + typeName;
|
||||||
|
var signature = GetIl2CppTypeSignature(type);
|
||||||
|
if (signature == "Il2CppArray*")
|
||||||
|
{
|
||||||
|
scriptMetadata.Signature = signature;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
scriptMetadata.Signature = FixName(signature) + "_t*";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
foreach (var i in metadata.metadataUsageDic[3]) //kIl2CppMetadataUsageMethodDef
|
foreach (var i in metadata.metadataUsageDic[3]) //kIl2CppMetadataUsageMethodDef
|
||||||
{
|
{
|
||||||
|
@ -226,32 +244,25 @@ namespace Il2CppDumper
|
||||||
var headerClass = new StringBuilder();
|
var headerClass = new StringBuilder();
|
||||||
foreach (var info in StructInfo)
|
foreach (var info in StructInfo)
|
||||||
{
|
{
|
||||||
|
preHeader.Append($"struct {info.TypeName}_t;\n");
|
||||||
|
|
||||||
if (info.IsValueType)
|
if (info.IsValueType)
|
||||||
{
|
{
|
||||||
preHeader.Append($"struct {info.TypeName}_t;\n");
|
|
||||||
headerStruct.Append(RecursionStructInfo(info));
|
headerStruct.Append(RecursionStructInfo(info));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
preHeader.Append($"struct {info.TypeName}_t;\n");
|
|
||||||
|
|
||||||
headerClass.Append($"struct {info.TypeName}_StaticFields {{\n");
|
headerClass.Append($"struct {info.TypeName}_StaticFields {{\n");
|
||||||
if (info.StaticFields.Count > 0)
|
foreach (var field in info.StaticFields)
|
||||||
{
|
{
|
||||||
foreach (var field in info.StaticFields)
|
headerClass.Append($"\t{field.FieldTypeName} {field.FieldName};\n");
|
||||||
{
|
|
||||||
headerClass.Append($"\t{field.FieldTypeName} {field.FieldName};\n");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
headerClass.Append("};\n");
|
headerClass.Append("};\n");
|
||||||
|
|
||||||
headerClass.Append($"struct {info.TypeName}_VTable {{\n");
|
headerClass.Append($"struct {info.TypeName}_VTable {{\n");
|
||||||
if (info.VTableMethod.Count > 0)
|
foreach (var method in info.VTableMethod)
|
||||||
{
|
{
|
||||||
foreach (var method in info.VTableMethod)
|
headerClass.Append($"\tVirtualInvokeData {method.MethodName};\n");
|
||||||
{
|
|
||||||
headerClass.Append($"\tVirtualInvokeData {method.MethodName};\n");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
headerClass.Append("};\n");
|
headerClass.Append("};\n");
|
||||||
|
|
||||||
|
@ -395,7 +406,7 @@ namespace Il2CppDumper
|
||||||
return "intptr_t";
|
return "intptr_t";
|
||||||
case Il2CppTypeEnum.IL2CPP_TYPE_U:
|
case Il2CppTypeEnum.IL2CPP_TYPE_U:
|
||||||
return "uintptr_t";
|
return "uintptr_t";
|
||||||
case Il2CppTypeEnum.IL2CPP_TYPE_OBJECT:
|
case Il2CppTypeEnum.IL2CPP_TYPE_OBJECT: //TODO
|
||||||
return "Il2CppObject*";
|
return "Il2CppObject*";
|
||||||
case Il2CppTypeEnum.IL2CPP_TYPE_SZARRAY: //TODO
|
case Il2CppTypeEnum.IL2CPP_TYPE_SZARRAY: //TODO
|
||||||
return "Il2CppArray*";
|
return "Il2CppArray*";
|
||||||
|
@ -579,14 +590,14 @@ namespace Il2CppDumper
|
||||||
}
|
}
|
||||||
|
|
||||||
var sb = new StringBuilder();
|
var sb = new StringBuilder();
|
||||||
sb.Append($"struct {info.TypeName}_t {{\n");
|
|
||||||
|
|
||||||
|
sb.Append($"struct {info.TypeName}_t {{\n");
|
||||||
foreach (var field in info.Fields)
|
foreach (var field in info.Fields)
|
||||||
{
|
{
|
||||||
if (!field.FieldTypeName.EndsWith("*"))
|
if (!field.FieldTypeName.EndsWith("*")) //hack
|
||||||
{
|
{
|
||||||
var fieldTypeName = field.FieldTypeName.Substring(0, field.FieldTypeName.Length - 2);
|
var fieldTypeName = field.FieldTypeName.Substring(0, field.FieldTypeName.Length - 2);
|
||||||
var fieldInfo = StructInfo.Find(x => x.TypeName == fieldTypeName); //hack
|
var fieldInfo = StructInfo.Find(x => x.TypeName == fieldTypeName);
|
||||||
if (fieldInfo != null)
|
if (fieldInfo != null)
|
||||||
{
|
{
|
||||||
sb.Insert(0, RecursionStructInfo(fieldInfo));
|
sb.Insert(0, RecursionStructInfo(fieldInfo));
|
||||||
|
@ -595,7 +606,102 @@ namespace Il2CppDumper
|
||||||
sb.Append($"\t{field.FieldTypeName} {field.FieldName};\n");
|
sb.Append($"\t{field.FieldTypeName} {field.FieldName};\n");
|
||||||
}
|
}
|
||||||
sb.Append("};\n");
|
sb.Append("};\n");
|
||||||
|
|
||||||
|
sb.Append($"struct {info.TypeName}_StaticFields {{\n");
|
||||||
|
foreach (var field in info.StaticFields)
|
||||||
|
{
|
||||||
|
if (!field.FieldTypeName.EndsWith("*")) //hack
|
||||||
|
{
|
||||||
|
var fieldTypeName = field.FieldTypeName.Substring(0, field.FieldTypeName.Length - 2);
|
||||||
|
var fieldInfo = StructInfo.Find(x => x.TypeName == fieldTypeName);
|
||||||
|
if (fieldInfo != null)
|
||||||
|
{
|
||||||
|
sb.Insert(0, RecursionStructInfo(fieldInfo));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sb.Append($"\t{field.FieldTypeName} {field.FieldName};\n");
|
||||||
|
}
|
||||||
|
sb.Append("};\n");
|
||||||
|
|
||||||
|
sb.Append($"struct {info.TypeName}_VTable {{\n");
|
||||||
|
foreach (var method in info.VTableMethod)
|
||||||
|
{
|
||||||
|
sb.Append($"\tVirtualInvokeData {method.MethodName};\n");
|
||||||
|
}
|
||||||
|
sb.Append("};\n");
|
||||||
|
|
||||||
|
sb.Append($"struct {info.TypeName}_c {{\n" +
|
||||||
|
$"\tIl2CppClass_1 _1;\n" +
|
||||||
|
$"\t{info.TypeName}_StaticFields* static_fields;\n" +
|
||||||
|
$"\tIl2CppClass_2 _2;\n" +
|
||||||
|
$"\t{info.TypeName}_VTable vtable;\n" +
|
||||||
|
$"}};\n");
|
||||||
|
|
||||||
return sb.ToString();
|
return sb.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private string GetIl2CppTypeSignature(Il2CppType il2CppType)
|
||||||
|
{
|
||||||
|
switch (il2CppType.type)
|
||||||
|
{
|
||||||
|
case Il2CppTypeEnum.IL2CPP_TYPE_VOID:
|
||||||
|
case Il2CppTypeEnum.IL2CPP_TYPE_BOOLEAN:
|
||||||
|
case Il2CppTypeEnum.IL2CPP_TYPE_CHAR:
|
||||||
|
case Il2CppTypeEnum.IL2CPP_TYPE_I1:
|
||||||
|
case Il2CppTypeEnum.IL2CPP_TYPE_U1:
|
||||||
|
case Il2CppTypeEnum.IL2CPP_TYPE_I2:
|
||||||
|
case Il2CppTypeEnum.IL2CPP_TYPE_U2:
|
||||||
|
case Il2CppTypeEnum.IL2CPP_TYPE_I4:
|
||||||
|
case Il2CppTypeEnum.IL2CPP_TYPE_U4:
|
||||||
|
case Il2CppTypeEnum.IL2CPP_TYPE_I8:
|
||||||
|
case Il2CppTypeEnum.IL2CPP_TYPE_U8:
|
||||||
|
case Il2CppTypeEnum.IL2CPP_TYPE_R4:
|
||||||
|
case Il2CppTypeEnum.IL2CPP_TYPE_R8:
|
||||||
|
case Il2CppTypeEnum.IL2CPP_TYPE_STRING:
|
||||||
|
case Il2CppTypeEnum.IL2CPP_TYPE_TYPEDBYREF:
|
||||||
|
case Il2CppTypeEnum.IL2CPP_TYPE_I:
|
||||||
|
case Il2CppTypeEnum.IL2CPP_TYPE_U:
|
||||||
|
case Il2CppTypeEnum.IL2CPP_TYPE_VALUETYPE:
|
||||||
|
case Il2CppTypeEnum.IL2CPP_TYPE_CLASS:
|
||||||
|
case Il2CppTypeEnum.IL2CPP_TYPE_OBJECT:
|
||||||
|
{
|
||||||
|
var typeDef = metadata.typeDefs[il2CppType.data.klassIndex];
|
||||||
|
if (typeDef.IsEnum)
|
||||||
|
{
|
||||||
|
return GetIl2CppTypeSignature(il2Cpp.types[typeDef.elementTypeIndex]);
|
||||||
|
}
|
||||||
|
return StructNameDic[typeDef];
|
||||||
|
}
|
||||||
|
case Il2CppTypeEnum.IL2CPP_TYPE_PTR:
|
||||||
|
{
|
||||||
|
var oriType = il2Cpp.GetIl2CppType(il2CppType.data.type);
|
||||||
|
return GetIl2CppTypeSignature(oriType);
|
||||||
|
}
|
||||||
|
case Il2CppTypeEnum.IL2CPP_TYPE_ARRAY: //TODO
|
||||||
|
case Il2CppTypeEnum.IL2CPP_TYPE_SZARRAY: //TODO
|
||||||
|
return "Il2CppArray*";
|
||||||
|
case Il2CppTypeEnum.IL2CPP_TYPE_GENERICINST:
|
||||||
|
{
|
||||||
|
//TODO Enum ValueType
|
||||||
|
if (!GenericClassStructNameDic.TryGetValue(il2CppType.data.generic_class, out var typeStructName))
|
||||||
|
{
|
||||||
|
var genericClass = il2Cpp.MapVATR<Il2CppGenericClass>(il2CppType.data.generic_class);
|
||||||
|
var typeDef = metadata.typeDefs[genericClass.typeDefinitionIndex];
|
||||||
|
var typeOriName = StructNameDic[typeDef];
|
||||||
|
var typeToReplaceName = FixName(executor.GetTypeDefName(typeDef, true, true));
|
||||||
|
var typeReplaceName = FixName(executor.GetTypeName(il2CppType, true, false));
|
||||||
|
typeStructName = typeOriName.Replace(typeToReplaceName, typeReplaceName);
|
||||||
|
GenericClassStructNameDic.Add(il2CppType.data.generic_class, typeStructName);
|
||||||
|
if (StructNameHashSet.Add(typeStructName))
|
||||||
|
{
|
||||||
|
GenericClass.Add(il2CppType.data.generic_class);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return typeStructName;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
throw new NotSupportedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,7 @@ namespace Il2CppDumper
|
||||||
{
|
{
|
||||||
public ulong Address;
|
public ulong Address;
|
||||||
public string Name;
|
public string Name;
|
||||||
|
public string Signature;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ScriptMetadataMethod
|
public class ScriptMetadataMethod
|
||||||
|
|
|
@ -21,6 +21,8 @@ def make_function(start, end):
|
||||||
ida_funcs.add_func(start, end)
|
ida_funcs.add_func(start, end)
|
||||||
|
|
||||||
path = idaapi.ask_file(False, '*.json', 'script.json from Il2cppdumper')
|
path = idaapi.ask_file(False, '*.json', 'script.json from Il2cppdumper')
|
||||||
|
hpath = idaapi.ask_file(False, '*.h', 'il2cpp.h from Il2cppdumper')
|
||||||
|
parse_decls(open(hpath, 'rb').read(), 0)
|
||||||
data = json.loads(open(path, 'rb').read().decode('utf-8'))
|
data = json.loads(open(path, 'rb').read().decode('utf-8'))
|
||||||
scriptMethods = data["ScriptMethod"]
|
scriptMethods = data["ScriptMethod"]
|
||||||
for scriptMethod in scriptMethods:
|
for scriptMethod in scriptMethods:
|
||||||
|
@ -28,7 +30,7 @@ for scriptMethod in scriptMethods:
|
||||||
name = scriptMethod["Name"].encode("utf-8")
|
name = scriptMethod["Name"].encode("utf-8")
|
||||||
set_name(addr, name)
|
set_name(addr, name)
|
||||||
signature = scriptMethod["Signature"].encode("utf-8")
|
signature = scriptMethod["Signature"].encode("utf-8")
|
||||||
if not apply_type(addr, parse_decl(signature, 0), 1):
|
if apply_type(addr, parse_decl(signature, 0), 1) == False:
|
||||||
print "apply_type failed:", hex(addr), signature
|
print "apply_type failed:", hex(addr), signature
|
||||||
index = 1
|
index = 1
|
||||||
scriptStrings = data["ScriptString"]
|
scriptStrings = data["ScriptString"]
|
||||||
|
@ -45,6 +47,11 @@ for scriptMetadata in scriptMetadatas:
|
||||||
name = scriptMetadata["Name"].encode("utf-8")
|
name = scriptMetadata["Name"].encode("utf-8")
|
||||||
set_name(addr, name)
|
set_name(addr, name)
|
||||||
idc.set_cmt(addr, name, 1)
|
idc.set_cmt(addr, name, 1)
|
||||||
|
if scriptMetadata["Signature"] is not None:
|
||||||
|
signature = scriptMetadata["Signature"].encode("utf-8")
|
||||||
|
if apply_type(addr, parse_decl(signature, 0), 1) == False:
|
||||||
|
print "apply_type failed:", hex(addr), signature
|
||||||
|
|
||||||
scriptMetadataMethods = data["ScriptMetadataMethod"]
|
scriptMetadataMethods = data["ScriptMetadataMethod"]
|
||||||
for scriptMetadataMethod in scriptMetadataMethods:
|
for scriptMetadataMethod in scriptMetadataMethods:
|
||||||
addr = get_addr(scriptMetadataMethod["Address"])
|
addr = get_addr(scriptMetadataMethod["Address"])
|
||||||
|
|
Loading…
Add table
Reference in a new issue