IDA: Produce typed CustomAttributesCacheGenerator methods

This commit is contained in:
Katy Coe
2020-07-17 03:23:15 +02:00
parent bbfd370f49
commit fc313de0b2
2 changed files with 13 additions and 17 deletions

View File

@@ -223,17 +223,14 @@ namespace Il2CppInspector.Model
} }
// Add custom attribute generators to the model // Add custom attribute generators to the model
foreach (var method in ILModel.AttributesByIndices.Values.Where(m => m.VirtualAddress.HasValue)) { foreach (var cppMethod in ILModel.AttributesByIndices.Values.Where(m => m.VirtualAddress.HasValue)) {
var cppTypeName = declarationGenerator.TypeNamer.GetName(method.AttributeType); var cppMethodName = declarationGenerator.TypeNamer.GetName(cppMethod.AttributeType) + "_CustomAttributesCacheGenerator";
var fnPtrType = CppFnPtrType.FromSignature(CppTypeCollection, $"void (*{cppTypeName}_CustomAttributesCacheGenerator)(CustomAttributesCache *)"); var fnPtrType = CppFnPtrType.FromSignature(CppTypeCollection, $"void (*{cppMethodName})(CustomAttributesCache *)");
fnPtrType.Name = cppMethodName;
fnPtrType.Group = "custom_attribute_generators"; fnPtrType.Group = "custom_attribute_generators";
// Get first constructor for attribute var appMethod = new AppMethod(null, fnPtrType, cppMethod.VirtualAddress.Value.Start) {Group = fnPtrType.Group};
// This is not strictly what the cache generator C++ function is but it'll do CustomAttributeGenerators.Add(cppMethod, appMethod);
var ctor = method.AttributeType.DeclaredConstructors.First();
var appMethod = new AppMethod(ctor, fnPtrType, method.VirtualAddress.Value.Start);
CustomAttributeGenerators.Add(method, appMethod);
} }
// This is to allow this method to be chained after a new expression // This is to allow this method to be chained after a new expression

View File

@@ -104,11 +104,7 @@ typedef __int64 int64_t;
writeMethods(model.GetMethodGroup("types_from_generic_methods")); writeMethods(model.GetMethodGroup("types_from_generic_methods"));
writeSectionHeader("Custom attributes generators"); writeSectionHeader("Custom attributes generators");
foreach (var method in model.ILModel.AttributesByIndices.Values.Where(m => m.VirtualAddress.HasValue)) { writeMethods(model.CustomAttributeGenerators.Values, asRefs: true);
var address = method.VirtualAddress.Value.Start;
writeName(address, $"{method.AttributeType.Name}_CustomAttributesCacheGenerator");
writeComment(address, $"{method.AttributeType.Name}_CustomAttributesCacheGenerator(CustomAttributesCache *)");
}
writeSectionHeader("Method.Invoke thunks"); writeSectionHeader("Method.Invoke thunks");
foreach (var method in model.ILModel.MethodInvokers.Where(m => m != null)) { foreach (var method in model.ILModel.MethodInvokers.Where(m => m != null)) {
@@ -123,11 +119,14 @@ typedef __int64 int64_t;
writeDecls(type.ToString()); writeDecls(type.ToString());
} }
private void writeMethods(IEnumerable<AppMethod> methods) { private void writeMethods(IEnumerable<AppMethod> methods, bool asRefs = false) {
foreach (var method in methods) { foreach (var method in methods) {
var address = method.MethodCodeAddress; var address = asRefs? method.MethodInfoPtrAddress : method.MethodCodeAddress;
writeTypedName(address, method.CppFnPtrType.ToSignatureString(), method.CppFnPtrType.Name); writeTypedName(address, method.CppFnPtrType.ToSignatureString(), method.CppFnPtrType.Name);
writeComment(address, method.Method);
// C++-only methods won't have an IL equivalent, eg. invokers and custom attribute generators
if (method.Method != null)
writeComment(address, method.Method);
} }
} }