public string GetCustomAttribute(Il2CppImageDefinition imageDef, int customAttributeIndex, uint token, string padding = "") { if (il2Cpp.Version < 21) { return(string.Empty); } var attributeIndex = metadata.GetCustomAttributeIndex(imageDef, customAttributeIndex, token); if (attributeIndex >= 0) { if (il2Cpp.Version < 29) { var methodPointer = executor.customAttributeGenerators[attributeIndex]; var fixedMethodPointer = il2Cpp.GetRVA(methodPointer); var attributeTypeRange = metadata.attributeTypeRanges[attributeIndex]; var sb = new StringBuilder(); for (var i = 0; i < attributeTypeRange.count; i++) { var typeIndex = metadata.attributeTypes[attributeTypeRange.start + i]; sb.AppendFormat("{0}[{1}] // RVA: 0x{2:X} Offset: 0x{3:X} VA: 0x{4:X}\n", padding, executor.GetTypeName(il2Cpp.types[typeIndex], false, false), fixedMethodPointer, il2Cpp.MapVATR(methodPointer), methodPointer); } return(sb.ToString()); } else { var startRange = metadata.attributeDataRanges[attributeIndex]; var endRange = metadata.attributeDataRanges[attributeIndex + 1]; metadata.Position = metadata.header.attributeDataOffset + startRange.startOffset; var buff = metadata.ReadBytes((int)(endRange.startOffset - startRange.startOffset)); var reader = new CustomAttributeDataReader(executor, buff); if (reader.Count == 0) { return(string.Empty); } var sb = new StringBuilder(); for (var i = 0; i < reader.Count; i++) { sb.Append(padding); sb.Append(reader.GetStringCustomAttributeData()); sb.Append("\n"); } return(sb.ToString()); } } else { return(string.Empty); } }
private void CreateCustomAttribute(Il2CppImageDefinition imageDef, int customAttributeIndex, uint token, ModuleDefinition moduleDefinition, Collection <CustomAttribute> customAttributes) { var attributeIndex = metadata.GetCustomAttributeIndex(imageDef, customAttributeIndex, token); if (attributeIndex >= 0) { try { if (il2Cpp.Version < 29) { var attributeTypeRange = metadata.attributeTypeRanges[attributeIndex]; for (int i = 0; i < attributeTypeRange.count; i++) { var attributeTypeIndex = metadata.attributeTypes[attributeTypeRange.start + i]; var attributeType = il2Cpp.types[attributeTypeIndex]; var typeDef = executor.GetTypeDefinitionFromIl2CppType(attributeType); var typeDefinition = typeDefinitionDic[typeDef]; if (!TryRestoreCustomAttribute(typeDefinition, moduleDefinition, customAttributes)) { var methodPointer = executor.customAttributeGenerators[attributeIndex]; var fixedMethodPointer = il2Cpp.GetRVA(methodPointer); var customAttribute = new CustomAttribute(moduleDefinition.ImportReference(attributeAttribute)); var name = new CustomAttributeNamedArgument("Name", new CustomAttributeArgument(stringType, typeDefinition.Name)); var rva = new CustomAttributeNamedArgument("RVA", new CustomAttributeArgument(stringType, $"0x{fixedMethodPointer:X}")); var offset = new CustomAttributeNamedArgument("Offset", new CustomAttributeArgument(stringType, $"0x{il2Cpp.MapVATR(methodPointer):X}")); customAttribute.Fields.Add(name); customAttribute.Fields.Add(rva); customAttribute.Fields.Add(offset); customAttributes.Add(customAttribute); } } } else { var startRange = metadata.attributeDataRanges[attributeIndex]; var endRange = metadata.attributeDataRanges[attributeIndex + 1]; metadata.Position = metadata.header.attributeDataOffset + startRange.startOffset; var buff = metadata.ReadBytes((int)(endRange.startOffset - startRange.startOffset)); var reader = new CustomAttributeDataReader(executor, buff); if (reader.Count != 0) { for (var i = 0; i < reader.Count; i++) { var visitor = reader.VisitCustomAttributeData(); var methodDefinition = methodDefinitionDic[visitor.CtorIndex]; var customAttribute = new CustomAttribute(moduleDefinition.ImportReference(methodDefinition)); foreach (var argument in visitor.Arguments) { var parameterDefinition = methodDefinition.Parameters[argument.Index]; var customAttributeArgument = CreateCustomAttributeArgument(parameterDefinition.ParameterType, argument.Value, methodDefinition); customAttribute.ConstructorArguments.Add(customAttributeArgument); } foreach (var field in visitor.Fields) { var fieldDefinition = fieldDefinitionDic[field.Index]; var customAttributeArgument = CreateCustomAttributeArgument(fieldDefinition.FieldType, field.Value, fieldDefinition); var customAttributeNamedArgument = new CustomAttributeNamedArgument(fieldDefinition.Name, customAttributeArgument); customAttribute.Fields.Add(customAttributeNamedArgument); } foreach (var property in visitor.Properties) { var propertyDefinition = propertyDefinitionDic[property.Index]; var customAttributeArgument = CreateCustomAttributeArgument(propertyDefinition.PropertyType, property.Value, propertyDefinition); var customAttributeNamedArgument = new CustomAttributeNamedArgument(propertyDefinition.Name, customAttributeArgument); customAttribute.Properties.Add(customAttributeNamedArgument); } customAttributes.Add(customAttribute); } } } } catch { Console.WriteLine($"ERROR: Error while restoring attributeIndex {attributeIndex}"); } } }