diff --git a/Il2CppDumper/Il2CppDumper.cs b/Il2CppDumper/Il2CppDumper.cs index b0b67c4..deb3cc8 100644 --- a/Il2CppDumper/Il2CppDumper.cs +++ b/Il2CppDumper/Il2CppDumper.cs @@ -1,13 +1,13 @@ -// Copyright (c) 2017 Katy Coe - https://www.djkaty.com - https://github.com/djkaty +// Copyright (c) 2017-2019 Katy Coe - https://www.djkaty.com - https://github.com/djkaty // All rights reserved using System.Collections.Generic; using System.IO; using System.Linq; -using System.Reflection; -using System.Security.Cryptography.X509Certificates; + using System.Text; using Il2CppInspector.Reflection; +using ParameterInfo = Il2CppInspector.Reflection.ParameterInfo; namespace Il2CppInspector { @@ -183,6 +183,18 @@ namespace Il2CppInspector if (type.DeclaredEvents.Count > 0) writer.Write("\n"); + // Constructors + if (type.DeclaredConstructors.Any()) + writer.Write("\t// Constructors\n"); + + foreach (var method in type.DeclaredConstructors) { + writer.Write($"\t{method.GetModifierString()}{method.DeclaringType.Name}("); + writer.Write(getParametersString(method.DeclaredParameters)); + writer.Write(");" + (method.VirtualAddress != 0 ? $" // {formatAddress(method.VirtualAddress)}" : "") + "\n"); + } + if (type.DeclaredConstructors.Any()) + writer.Write("\n"); + // Methods if (type.DeclaredMethods.Except(usedMethods).Any()) writer.Write("\t// Methods\n"); @@ -190,23 +202,29 @@ namespace Il2CppInspector // Don't re-output methods for constructors, properties, events etc. foreach (var method in type.DeclaredMethods.Except(usedMethods)) { writer.Write($"\t{method.GetModifierString()}{method.ReturnType.CSharpName} {method.Name}("); - - bool first = true; - foreach (var param in method.DeclaredParameters) { - if (!first) - writer.Write(", "); - first = false; - if (param.IsOptional) - writer.Write("optional "); - if (param.IsOut) - writer.Write("out "); - writer.Write($"{param.ParameterType.CSharpName} {param.Name}"); - } + writer.Write(getParametersString(method.DeclaredParameters)); writer.Write(");" + (method.VirtualAddress != 0? $" // {formatAddress(method.VirtualAddress)}" : "") + "\n"); } writer.Write("}\n"); } } } + + private string getParametersString(List @params) { + StringBuilder sb = new StringBuilder(); + + bool first = true; + foreach (var param in @params) { + if (!first) + sb.Append(", "); + first = false; + if (param.IsOptional) + sb.Append("optional "); + if (param.IsOut) + sb.Append("out "); + sb.Append($"{param.ParameterType.CSharpName} {param.Name}"); + } + return sb.ToString(); + } } } diff --git a/Il2CppInspector/Reflection/ConstructorInfo.cs b/Il2CppInspector/Reflection/ConstructorInfo.cs new file mode 100644 index 0000000..66ce82b --- /dev/null +++ b/Il2CppInspector/Reflection/ConstructorInfo.cs @@ -0,0 +1,26 @@ +/* + Copyright 2017-2019 Katy Coe - http://www.hearthcode.org - http://www.djkaty.com + + All rights reserved. +*/ + +using System.Linq; +using System.Reflection; + +namespace Il2CppInspector.Reflection +{ + public class ConstructorInfo : MethodBase + { + // IL names of constructor and static constructor + public static readonly string ConstructorName = ".ctor"; + + public static readonly string TypeConstructorName = ".cctor"; + + // TODO + public override MemberTypes MemberType => MemberTypes.Constructor; + + public ConstructorInfo(Il2CppInspector pkg, int methodIndex, TypeInfo declaringType) : base(pkg, methodIndex, declaringType) { } + + public override string ToString() => DeclaringType.Name + "(" + string.Join(", ", DeclaredParameters.Select(x => x.ParameterType.Name)) + ")"; + } +} \ No newline at end of file diff --git a/Il2CppInspector/Reflection/EventInfo.cs b/Il2CppInspector/Reflection/EventInfo.cs index f89ecf1..fbda0eb 100644 --- a/Il2CppInspector/Reflection/EventInfo.cs +++ b/Il2CppInspector/Reflection/EventInfo.cs @@ -4,6 +4,7 @@ All rights reserved. */ +using System.Linq; using System.Reflection; namespace Il2CppInspector.Reflection @@ -44,11 +45,11 @@ namespace Il2CppInspector.Reflection // NOTE: This relies on methods being added to TypeInfo.DeclaredMethods in the same order they are defined in the Il2Cpp metadata // add, remove and raise are method indices from the first method of the declaring type if (Definition.add >= 0) - AddMethod = declaringType.DeclaredMethods[Definition.add]; + AddMethod = declaringType.DeclaredMethods.First(x => x.Index == declaringType.Definition.methodStart + Definition.add); if (Definition.remove >= 0) - RemoveMethod = declaringType.DeclaredMethods[Definition.remove]; + RemoveMethod = declaringType.DeclaredMethods.First(x => x.Index == declaringType.Definition.methodStart + Definition.remove); if (Definition.raise >= 0) - RaiseMethod = declaringType.DeclaredMethods[Definition.raise]; + RaiseMethod = declaringType.DeclaredMethods.First(x => x.Index == declaringType.Definition.methodStart + Definition.raise); } } } \ No newline at end of file diff --git a/Il2CppInspector/Reflection/MethodBase.cs b/Il2CppInspector/Reflection/MethodBase.cs index d0b9876..9c0bc71 100644 --- a/Il2CppInspector/Reflection/MethodBase.cs +++ b/Il2CppInspector/Reflection/MethodBase.cs @@ -1,5 +1,5 @@ /* - Copyright 2017 Katy Coe - http://www.hearthcode.org - http://www.djkaty.com + Copyright 2017-2019 Katy Coe - http://www.hearthcode.org - http://www.djkaty.com All rights reserved. */ @@ -30,7 +30,7 @@ namespace Il2CppInspector.Reflection public bool IsAbstract => (Attributes & MethodAttributes.Abstract) == MethodAttributes.Abstract; public bool IsAssembly => (Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Assembly; - public bool IsConstructor => throw new NotImplementedException(); + public bool IsConstructor => MemberType == MemberTypes.Constructor; public bool IsFamily => (Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Family; public bool IsFamilyAndAssembly => (Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.FamANDAssem; public bool IsFamilyOrAssembly => (Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.FamORAssem; diff --git a/Il2CppInspector/Reflection/PropertyInfo.cs b/Il2CppInspector/Reflection/PropertyInfo.cs index d35b6a9..a3943ff 100644 --- a/Il2CppInspector/Reflection/PropertyInfo.cs +++ b/Il2CppInspector/Reflection/PropertyInfo.cs @@ -4,6 +4,7 @@ All rights reserved. */ +using System.Linq; using System.Reflection; namespace Il2CppInspector.Reflection { @@ -29,12 +30,11 @@ namespace Il2CppInspector.Reflection { Name = pkg.Strings[prop.nameIndex]; - // NOTE: This relies on methods being added to TypeInfo.DeclaredMethods in the same order they are defined in the Il2Cpp metadata // prop.get and prop.set are method indices from the first method of the declaring type if (prop.get >= 0) - GetMethod = declaringType.DeclaredMethods[prop.get]; + GetMethod = declaringType.DeclaredMethods.First(x => x.Index == declaringType.Definition.methodStart + prop.get); if (prop.set >= 0) - SetMethod = declaringType.DeclaredMethods[prop.set]; + SetMethod = declaringType.DeclaredMethods.First(x => x.Index == declaringType.Definition.methodStart + prop.set); } } } \ No newline at end of file diff --git a/Il2CppInspector/Reflection/ReflectionClasses.cs b/Il2CppInspector/Reflection/ReflectionClasses.cs index db95245..e28378c 100644 --- a/Il2CppInspector/Reflection/ReflectionClasses.cs +++ b/Il2CppInspector/Reflection/ReflectionClasses.cs @@ -4,23 +4,8 @@ All rights reserved. */ -using System.Reflection; - namespace Il2CppInspector.Reflection { - public class ConstructorInfo : MethodBase - { - // IL names of constructor and static constructor - public static readonly string ConstructorName = ".ctor"; - - public static readonly string TypeConstructorName = ".cctor"; - - // TODO - public override MemberTypes MemberType => MemberTypes.Constructor; - - public ConstructorInfo(Il2CppInspector pkg, int methodIndex, TypeInfo declaringType) : base(pkg, methodIndex, declaringType) { } - } - public class CustomAttributeData { // TODO diff --git a/Il2CppInspector/Reflection/TypeInfo.cs b/Il2CppInspector/Reflection/TypeInfo.cs index c4eefe8..0366e5b 100644 --- a/Il2CppInspector/Reflection/TypeInfo.cs +++ b/Il2CppInspector/Reflection/TypeInfo.cs @@ -40,7 +40,7 @@ namespace Il2CppInspector.Reflection { } } - public List DeclaredConstructors => throw new NotImplementedException(); + public List DeclaredConstructors { get; } = new List(); public List DeclaredEvents { get; } = new List(); public List DeclaredFields { get; } = new List(); public List DeclaredMembers => throw new NotImplementedException(); @@ -137,7 +137,7 @@ namespace Il2CppInspector.Reflection { Definition = pkg.TypeDefinitions[typeIndex]; Index = typeIndex; Namespace = pkg.Strings[Definition.namespaceIndex]; - Name = pkg.Strings[pkg.TypeDefinitions[typeIndex].nameIndex]; + Name = pkg.Strings[Definition.nameIndex]; if (Definition.parentIndex >= 0) baseType = pkg.TypeUsages[Definition.parentIndex]; @@ -189,8 +189,13 @@ namespace Il2CppInspector.Reflection { DeclaredFields.Add(new FieldInfo(pkg, f, this)); // Add all methods - for (var m = Definition.methodStart; m < Definition.methodStart + Definition.method_count; m++) - DeclaredMethods.Add(new MethodInfo(pkg, m, this)); + for (var m = Definition.methodStart; m < Definition.methodStart + Definition.method_count; m++) { + var method = new MethodInfo(pkg, m, this); + if (method.Name == ConstructorInfo.ConstructorName || method.Name == ConstructorInfo.TypeConstructorName) + DeclaredConstructors.Add(new ConstructorInfo(pkg, m, this)); + else + DeclaredMethods.Add(method); + } // Add all properties for (var p = Definition.propertyStart; p < Definition.propertyStart + Definition.property_count; p++)