代码清理

This commit is contained in:
Perfare 2023-03-05 01:49:15 +08:00
parent 101f3c62ef
commit 217f1d4737
23 changed files with 219 additions and 259 deletions

View file

@ -9,10 +9,10 @@ namespace Il2CppDumper
{ {
public sealed class Macho : Il2Cpp public sealed class Macho : Il2Cpp
{ {
private List<MachoSection> sections = new List<MachoSection>();
private static readonly byte[] FeatureBytes1 = { 0x0, 0x22 };//MOVS R2, #0 private static readonly byte[] FeatureBytes1 = { 0x0, 0x22 };//MOVS R2, #0
private static readonly byte[] FeatureBytes2 = { 0x78, 0x44, 0x79, 0x44 };//ADD R0, PC and ADD R1, PC private static readonly byte[] FeatureBytes2 = { 0x78, 0x44, 0x79, 0x44 };//ADD R0, PC and ADD R1, PC
private ulong vmaddr; private readonly List<MachoSection> sections = new();
private readonly ulong vmaddr;
public Macho(Stream stream) : base(stream) public Macho(Stream stream) : base(stream)
{ {

View file

@ -9,10 +9,10 @@ namespace Il2CppDumper
{ {
public sealed class Macho64 : Il2Cpp public sealed class Macho64 : Il2Cpp
{ {
private List<MachoSection64Bit> sections = new List<MachoSection64Bit>();
private static readonly byte[] FeatureBytes1 = { 0x2, 0x0, 0x80, 0xD2 };//MOV X2, #0 private static readonly byte[] FeatureBytes1 = { 0x2, 0x0, 0x80, 0xD2 };//MOV X2, #0
private static readonly byte[] FeatureBytes2 = { 0x3, 0x0, 0x80, 0x52 };//MOV W3, #0 private static readonly byte[] FeatureBytes2 = { 0x3, 0x0, 0x80, 0x52 };//MOV W3, #0
private ulong vmaddr; private readonly List<MachoSection64Bit> sections = new();
private readonly ulong vmaddr;
public Macho64(Stream stream) : base(stream) public Macho64(Stream stream) : base(stream)
{ {

View file

@ -1,6 +1,5 @@
using System; using System.Buffers.Binary;
using System.IO; using System.IO;
using System.Linq;
namespace Il2CppDumper namespace Il2CppDumper
{ {
@ -10,16 +9,17 @@ namespace Il2CppDumper
public MachoFat(Stream stream) : base(stream) public MachoFat(Stream stream) : base(stream)
{ {
//BigEndian
Position += 4; Position += 4;
var size = BitConverter.ToInt32(ReadBytes(4).Reverse().ToArray(), 0); var size = BinaryPrimitives.ReadInt32BigEndian(ReadBytes(4));
fats = new Fat[size]; fats = new Fat[size];
for (var i = 0; i < size; i++) for (var i = 0; i < size; i++)
{ {
Position += 8; Position += 8;
fats[i] = new Fat(); fats[i] = new Fat
fats[i].offset = BitConverter.ToUInt32(ReadBytes(4).Reverse().ToArray(), 0); {
fats[i].size = BitConverter.ToUInt32(ReadBytes(4).Reverse().ToArray(), 0); offset = BinaryPrimitives.ReadUInt32BigEndian(ReadBytes(4)),
size = BinaryPrimitives.ReadUInt32BigEndian(ReadBytes(4))
};
Position += 4; Position += 4;
} }
for (var i = 0; i < size; i++) for (var i = 0; i < size; i++)

View file

@ -8,23 +8,25 @@ namespace Il2CppDumper
{ {
public sealed class NSO : Il2Cpp public sealed class NSO : Il2Cpp
{ {
private NSOHeader header; private readonly NSOHeader header;
private bool isTextCompressed; private readonly bool isTextCompressed;
private bool isRoDataCompressed; private readonly bool isRoDataCompressed;
private bool isDataCompressed; private readonly bool isDataCompressed;
private List<NSOSegmentHeader> segments = new List<NSOSegmentHeader>(); private readonly List<NSOSegmentHeader> segments = new();
private Elf64_Sym[] symbolTable; private Elf64_Sym[] symbolTable;
private List<Elf64_Dyn> dynamicSection = new List<Elf64_Dyn>(); private readonly List<Elf64_Dyn> dynamicSection = new();
private bool isCompressed => isTextCompressed || isRoDataCompressed || isDataCompressed; private bool IsCompressed => isTextCompressed || isRoDataCompressed || isDataCompressed;
public NSO(Stream stream) : base(stream) public NSO(Stream stream) : base(stream)
{ {
header = new NSOHeader(); header = new NSOHeader
header.Magic = ReadUInt32(); {
header.Version = ReadUInt32(); Magic = ReadUInt32(),
header.Reserved = ReadUInt32(); Version = ReadUInt32(),
header.Flags = ReadUInt32(); Reserved = ReadUInt32(),
Flags = ReadUInt32()
};
isTextCompressed = (header.Flags & 1) != 0; isTextCompressed = (header.Flags & 1) != 0;
isRoDataCompressed = (header.Flags & 2) != 0; isRoDataCompressed = (header.Flags & 2) != 0;
isDataCompressed = (header.Flags & 4) != 0; isDataCompressed = (header.Flags & 4) != 0;
@ -76,7 +78,7 @@ namespace Il2CppDumper
header.RoDataHash = ReadBytes(0x20); header.RoDataHash = ReadBytes(0x20);
header.DataHash = ReadBytes(0x20); header.DataHash = ReadBytes(0x20);
if (!isCompressed) if (!IsCompressed)
{ {
Position = header.TextSegment.FileOffset + 4; Position = header.TextSegment.FileOffset + 4;
var modOffset = ReadUInt32(); var modOffset = ReadUInt32();

View file

@ -7,7 +7,7 @@ namespace Il2CppDumper
{ {
public sealed class PE : Il2Cpp public sealed class PE : Il2Cpp
{ {
private SectionHeader[] sections; private readonly SectionHeader[] sections;
public PE(Stream stream) : base(stream) public PE(Stream stream) : base(stream)
{ {

View file

@ -5,7 +5,7 @@ namespace Il2CppDumper
{ {
public sealed class WebAssembly : BinaryStream public sealed class WebAssembly : BinaryStream
{ {
private DataSection[] dataSections; private readonly DataSection[] dataSections;
public WebAssembly(Stream stream) : base(stream) public WebAssembly(Stream stream) : base(stream)
{ {
@ -46,7 +46,7 @@ namespace Il2CppDumper
public WebAssemblyMemory CreateMemory() public WebAssemblyMemory CreateMemory()
{ {
var last = dataSections[dataSections.Length - 1]; var last = dataSections[^1];
var bssStart = last.Offset + (uint)last.Data.Length; var bssStart = last.Offset + (uint)last.Data.Length;
var stream = new MemoryStream(new byte[Length]); var stream = new MemoryStream(new byte[Length]);
foreach (var dataSection in dataSections) foreach (var dataSection in dataSections)

View file

@ -4,7 +4,7 @@ namespace Il2CppDumper
{ {
public sealed class WebAssemblyMemory : Il2Cpp public sealed class WebAssemblyMemory : Il2Cpp
{ {
private uint bssStart; private readonly uint bssStart;
public WebAssemblyMemory(Stream stream, uint bssStart) : base(stream) public WebAssemblyMemory(Stream stream, uint bssStart) : base(stream)
{ {

View file

@ -10,7 +10,7 @@ namespace Il2CppDumper
{ {
var start = reader.BaseStream.Position; var start = reader.BaseStream.Position;
// UTF8 takes up to 4 bytes per character // UTF8 takes up to 4 bytes per character
var str = Encoding.UTF8.GetString(reader.ReadBytes(numChars * 4)).Substring(0, numChars); var str = Encoding.UTF8.GetString(reader.ReadBytes(numChars * 4))[..numChars];
// make our position what it would have been if we'd known the exact number of bytes needed. // make our position what it would have been if we'd known the exact number of bytes needed.
reader.BaseStream.Position = start; reader.BaseStream.Position = start;
reader.ReadBytes(Encoding.UTF8.GetByteCount(str)); reader.ReadBytes(Encoding.UTF8.GetByteCount(str));

View file

@ -12,13 +12,13 @@ namespace Il2CppDumper
public double Version; public double Version;
public bool Is32Bit; public bool Is32Bit;
public ulong ImageBase; public ulong ImageBase;
private Stream stream; private readonly Stream stream;
private BinaryReader reader; private readonly BinaryReader reader;
private BinaryWriter writer; private readonly BinaryWriter writer;
private MethodInfo readClass; private readonly MethodInfo readClass;
private MethodInfo readClassArray; private readonly MethodInfo readClassArray;
private Dictionary<Type, MethodInfo> genericMethodCache = new Dictionary<Type, MethodInfo>(); private readonly Dictionary<Type, MethodInfo> genericMethodCache;
private Dictionary<FieldInfo, VersionAttribute[]> attributeCache = new Dictionary<FieldInfo, VersionAttribute[]>(); private readonly Dictionary<FieldInfo, VersionAttribute[]> attributeCache;
public BinaryStream(Stream input) public BinaryStream(Stream input)
{ {
@ -27,6 +27,8 @@ namespace Il2CppDumper
writer = new BinaryWriter(stream, Encoding.UTF8, true); writer = new BinaryWriter(stream, Encoding.UTF8, true);
readClass = GetType().GetMethod("ReadClass", Type.EmptyTypes); readClass = GetType().GetMethod("ReadClass", Type.EmptyTypes);
readClassArray = GetType().GetMethod("ReadClassArray", new[] { typeof(long) }); readClassArray = GetType().GetMethod("ReadClassArray", new[] { typeof(long) });
genericMethodCache = new();
attributeCache = new();
} }
public bool ReadBoolean() => reader.ReadBoolean(); public bool ReadBoolean() => reader.ReadBoolean();
@ -91,26 +93,17 @@ namespace Il2CppDumper
private object ReadPrimitive(Type type) private object ReadPrimitive(Type type)
{ {
var typename = type.Name; return type.Name switch
switch (typename)
{ {
case "Int32": "Int32" => ReadInt32(),
return ReadInt32(); "UInt32" => ReadUInt32(),
case "UInt32": "Int16" => ReadInt16(),
return ReadUInt32(); "UInt16" => ReadUInt16(),
case "Int16": "Byte" => ReadByte(),
return ReadInt16(); "Int64" => ReadIntPtr(),
case "UInt16": "UInt64" => ReadUIntPtr(),
return ReadUInt16(); _ => throw new NotSupportedException()
case "Byte": };
return ReadByte();
case "Int64":
return ReadIntPtr();
case "UInt64":
return ReadUIntPtr();
default:
throw new NotSupportedException();
}
} }
public T ReadClass<T>(ulong addr) where T : new() public T ReadClass<T>(ulong addr) where T : new()
@ -243,8 +236,8 @@ namespace Il2CppDumper
{ {
if (disposing) if (disposing)
{ {
reader.Close(); reader.Dispose();
writer.Close(); writer.Dispose();
stream.Close(); stream.Close();
} }
} }
@ -252,6 +245,7 @@ namespace Il2CppDumper
public void Dispose() public void Dispose()
{ {
Dispose(true); Dispose(true);
GC.SuppressFinalize(this);
} }
} }
} }

View file

@ -17,14 +17,14 @@ namespace Il2CppDumper
public ulong[] unresolvedVirtualCallPointers; public ulong[] unresolvedVirtualCallPointers;
private ulong[] fieldOffsets; private ulong[] fieldOffsets;
public Il2CppType[] types; public Il2CppType[] types;
private Dictionary<ulong, Il2CppType> typeDic = new Dictionary<ulong, Il2CppType>(); private readonly Dictionary<ulong, Il2CppType> typeDic = new();
public ulong[] metadataUsages; public ulong[] metadataUsages;
private Il2CppGenericMethodFunctionsDefinitions[] genericMethodTable; private Il2CppGenericMethodFunctionsDefinitions[] genericMethodTable;
public ulong[] genericInstPointers; public ulong[] genericInstPointers;
public Il2CppGenericInst[] genericInsts; public Il2CppGenericInst[] genericInsts;
public Il2CppMethodSpec[] methodSpecs; public Il2CppMethodSpec[] methodSpecs;
public Dictionary<int, List<Il2CppMethodSpec>> methodDefinitionMethodSpecs = new Dictionary<int, List<Il2CppMethodSpec>>(); public Dictionary<int, List<Il2CppMethodSpec>> methodDefinitionMethodSpecs = new();
public Dictionary<Il2CppMethodSpec, ulong> methodSpecGenericMethodPointers = new Dictionary<Il2CppMethodSpec, ulong>(); public Dictionary<Il2CppMethodSpec, ulong> methodSpecGenericMethodPointers = new();
private bool fieldOffsetsArePointers; private bool fieldOffsetsArePointers;
protected long metadataUsagesCount; protected long metadataUsagesCount;
public Dictionary<string, Il2CppCodeGenModule> codeGenModules; public Dictionary<string, Il2CppCodeGenModule> codeGenModules;

View file

@ -16,15 +16,15 @@ namespace Il2CppDumper
public Il2CppMethodDefinition[] methodDefs; public Il2CppMethodDefinition[] methodDefs;
public Il2CppParameterDefinition[] parameterDefs; public Il2CppParameterDefinition[] parameterDefs;
public Il2CppFieldDefinition[] fieldDefs; public Il2CppFieldDefinition[] fieldDefs;
private Dictionary<int, Il2CppFieldDefaultValue> fieldDefaultValuesDic; private readonly Dictionary<int, Il2CppFieldDefaultValue> fieldDefaultValuesDic;
private Dictionary<int, Il2CppParameterDefaultValue> parameterDefaultValuesDic; private readonly Dictionary<int, Il2CppParameterDefaultValue> parameterDefaultValuesDic;
public Il2CppPropertyDefinition[] propertyDefs; public Il2CppPropertyDefinition[] propertyDefs;
public Il2CppCustomAttributeTypeRange[] attributeTypeRanges; public Il2CppCustomAttributeTypeRange[] attributeTypeRanges;
public Il2CppCustomAttributeDataRange[] attributeDataRanges; public Il2CppCustomAttributeDataRange[] attributeDataRanges;
private Dictionary<Il2CppImageDefinition, Dictionary<uint, int>> attributeTypeRangesDic; private readonly Dictionary<Il2CppImageDefinition, Dictionary<uint, int>> attributeTypeRangesDic;
public Il2CppStringLiteral[] stringLiterals; public Il2CppStringLiteral[] stringLiterals;
private Il2CppMetadataUsageList[] metadataUsageLists; private readonly Il2CppMetadataUsageList[] metadataUsageLists;
private Il2CppMetadataUsagePair[] metadataUsagePairs; private readonly Il2CppMetadataUsagePair[] metadataUsagePairs;
public int[] attributeTypes; public int[] attributeTypes;
public int[] interfaceIndices; public int[] interfaceIndices;
public Dictionary<Il2CppMetadataUsage, SortedDictionary<uint, uint>> metadataUsageDic; public Dictionary<Il2CppMetadataUsage, SortedDictionary<uint, uint>> metadataUsageDic;
@ -38,7 +38,7 @@ namespace Il2CppDumper
public uint[] vtableMethods; public uint[] vtableMethods;
public Il2CppRGCTXDefinition[] rgctxEntries; public Il2CppRGCTXDefinition[] rgctxEntries;
private Dictionary<uint, string> stringCache = new Dictionary<uint, string>(); private readonly Dictionary<uint, string> stringCache = new();
public Metadata(Stream stream) : base(stream) public Metadata(Stream stream) : base(stream)
{ {
@ -239,7 +239,7 @@ namespace Il2CppDumper
metadataUsagesCount = metadataUsageDic.Max(x => x.Value.Select(y => y.Key).DefaultIfEmpty().Max()) + 1; metadataUsagesCount = metadataUsageDic.Max(x => x.Value.Select(y => y.Key).DefaultIfEmpty().Max()) + 1;
} }
public uint GetEncodedIndexType(uint index) public static uint GetEncodedIndexType(uint index)
{ {
return (index & 0xE0000000) >> 29; return (index & 0xE0000000) >> 29;
} }
@ -286,19 +286,14 @@ namespace Il2CppDumper
} }
return size; return size;
int GetPrimitiveTypeSize(string name) static int GetPrimitiveTypeSize(string name)
{ {
switch (name) return name switch
{ {
case "Int32": "Int32" or "UInt32" => 4,
case "UInt32": "Int16" or "UInt16" => 2,
return 4; _ => 0,
case "Int16": };
case "UInt16":
return 2;
default:
return 0;
}
} }
} }
} }

View file

@ -14,12 +14,10 @@ namespace Il2CppDumper
var dummy = new DummyAssemblyGenerator(il2CppExecutor, addToken); var dummy = new DummyAssemblyGenerator(il2CppExecutor, addToken);
foreach (var assembly in dummy.Assemblies) foreach (var assembly in dummy.Assemblies)
{ {
using (var stream = new MemoryStream()) using var stream = new MemoryStream();
{
assembly.Write(stream); assembly.Write(stream);
File.WriteAllBytes(assembly.MainModule.Name, stream.ToArray()); File.WriteAllBytes(assembly.MainModule.Name, stream.ToArray());
} }
} }
} }
}
} }

View file

@ -9,16 +9,17 @@ namespace Il2CppDumper
{ {
public class Il2CppDecompiler public class Il2CppDecompiler
{ {
private Il2CppExecutor executor; private readonly Il2CppExecutor executor;
private Metadata metadata; private readonly Metadata metadata;
private Il2Cpp il2Cpp; private readonly Il2Cpp il2Cpp;
private Dictionary<Il2CppMethodDefinition, string> methodModifiers = new Dictionary<Il2CppMethodDefinition, string>(); private readonly Dictionary<Il2CppMethodDefinition, string> methodModifiers;
public Il2CppDecompiler(Il2CppExecutor il2CppExecutor) public Il2CppDecompiler(Il2CppExecutor il2CppExecutor)
{ {
executor = il2CppExecutor; executor = il2CppExecutor;
metadata = il2CppExecutor.metadata; metadata = il2CppExecutor.metadata;
il2Cpp = il2CppExecutor.il2Cpp; il2Cpp = il2CppExecutor.il2Cpp;
methodModifiers = new();
} }
public void Decompile(Config config, string outputDir) public void Decompile(Config config, string outputDir)
@ -436,7 +437,7 @@ namespace Il2CppDumper
{ {
sb.Append(padding); sb.Append(padding);
sb.Append(reader.GetStringCustomAttributeData()); sb.Append(reader.GetStringCustomAttributeData());
sb.Append("\n"); sb.Append('\n');
} }
return sb.ToString(); return sb.ToString();
} }

View file

@ -4,10 +4,10 @@ namespace Il2CppDumper
{ {
public class ScriptJson public class ScriptJson
{ {
public List<ScriptMethod> ScriptMethod = new List<ScriptMethod>(); public List<ScriptMethod> ScriptMethod = new();
public List<ScriptString> ScriptString = new List<ScriptString>(); public List<ScriptString> ScriptString = new();
public List<ScriptMetadata> ScriptMetadata = new List<ScriptMetadata>(); public List<ScriptMetadata> ScriptMetadata = new();
public List<ScriptMetadataMethod> ScriptMetadataMethod = new List<ScriptMetadataMethod>(); public List<ScriptMetadataMethod> ScriptMetadataMethod = new();
public ulong[] Addresses; public ulong[] Addresses;
} }

View file

@ -11,25 +11,25 @@ namespace Il2CppDumper
{ {
public class StructGenerator public class StructGenerator
{ {
private Il2CppExecutor executor; private readonly Il2CppExecutor executor;
private Metadata metadata; private readonly Metadata metadata;
private Il2Cpp il2Cpp; private readonly Il2Cpp il2Cpp;
private Dictionary<Il2CppTypeDefinition, string> typeDefImageNames = new Dictionary<Il2CppTypeDefinition, string>(); private readonly Dictionary<Il2CppTypeDefinition, string> typeDefImageNames = new();
private HashSet<string> structNameHashSet = new HashSet<string>(StringComparer.Ordinal); private readonly HashSet<string> structNameHashSet = new(StringComparer.Ordinal);
private List<StructInfo> structInfoList = new List<StructInfo>(); private readonly List<StructInfo> structInfoList = new();
private Dictionary<string, StructInfo> structInfoWithStructName = new Dictionary<string, StructInfo>(); private readonly Dictionary<string, StructInfo> structInfoWithStructName = new();
private HashSet<StructInfo> structCache = new HashSet<StructInfo>(); private readonly HashSet<StructInfo> structCache = new();
private Dictionary<Il2CppTypeDefinition, string> structNameDic = new Dictionary<Il2CppTypeDefinition, string>(); private readonly Dictionary<Il2CppTypeDefinition, string> structNameDic = new();
private Dictionary<ulong, string> genericClassStructNameDic = new Dictionary<ulong, string>(); private readonly Dictionary<ulong, string> genericClassStructNameDic = new();
private Dictionary<string, Il2CppType> nameGenericClassDic = new Dictionary<string, Il2CppType>(); private readonly Dictionary<string, Il2CppType> nameGenericClassDic = new();
private List<ulong> genericClassList = new List<ulong>(); private readonly List<ulong> genericClassList = new();
private StringBuilder arrayClassHeader = new StringBuilder(); private readonly StringBuilder arrayClassHeader = new();
private StringBuilder methodInfoHeader = new StringBuilder(); private readonly StringBuilder methodInfoHeader = new();
private static HashSet<ulong> methodInfoCache = new HashSet<ulong>(); private static readonly HashSet<ulong> methodInfoCache = new();
private static HashSet<string> keyword = new HashSet<string>(StringComparer.Ordinal) private static readonly HashSet<string> keyword = new(StringComparer.Ordinal)
{ "klass", "monitor", "register", "_cs", "auto", "friend", "template", "flat", "default", "_ds", "interrupt", { "klass", "monitor", "register", "_cs", "auto", "friend", "template", "flat", "default", "_ds", "interrupt",
"unsigned", "signed", "asm", "if", "case", "break", "continue", "do", "new", "_", "short", "union", "class", "namespace"}; "unsigned", "signed", "asm", "if", "case", "break", "continue", "do", "new", "_", "short", "union", "class", "namespace"};
private static HashSet<string> specialKeywords = new HashSet<string>(StringComparer.Ordinal) private static readonly HashSet<string> specialKeywords = new(StringComparer.Ordinal)
{ "inline", "near", "far" }; { "inline", "near", "far" };
public StructGenerator(Il2CppExecutor il2CppExecutor) public StructGenerator(Il2CppExecutor il2CppExecutor)
@ -278,7 +278,7 @@ namespace Il2CppDumper
if (metadataValue < uint.MaxValue) if (metadataValue < uint.MaxValue)
{ {
var encodedToken = (uint)metadataValue; var encodedToken = (uint)metadataValue;
var usage = metadata.GetEncodedIndexType(encodedToken); var usage = Metadata.GetEncodedIndexType(encodedToken);
if (usage > 0 && usage <= 6) if (usage > 0 && usage <= 6)
{ {
var decodedIndex = metadata.GetDecodedMethodIndex(encodedToken); var decodedIndex = metadata.GetDecodedMethodIndex(encodedToken);
@ -674,54 +674,21 @@ namespace Il2CppDumper
throw new NotSupportedException(); throw new NotSupportedException();
} }
} }
public string GetMethodTypeSignature(List<Il2CppTypeEnum> types) public static string GetMethodTypeSignature(List<Il2CppTypeEnum> types)
{ {
string signature = string.Empty; string signature = string.Empty;
foreach (Il2CppTypeEnum type in types) foreach (Il2CppTypeEnum type in types)
{ {
switch (type) signature += type switch
{ {
case Il2CppTypeEnum.IL2CPP_TYPE_VOID: Il2CppTypeEnum.IL2CPP_TYPE_VOID => "v",
signature += "v"; Il2CppTypeEnum.IL2CPP_TYPE_BOOLEAN or Il2CppTypeEnum.IL2CPP_TYPE_CHAR or Il2CppTypeEnum.IL2CPP_TYPE_I1 or Il2CppTypeEnum.IL2CPP_TYPE_U1 or Il2CppTypeEnum.IL2CPP_TYPE_I2 or Il2CppTypeEnum.IL2CPP_TYPE_U2 or Il2CppTypeEnum.IL2CPP_TYPE_I4 or Il2CppTypeEnum.IL2CPP_TYPE_U4 => "i",
break; Il2CppTypeEnum.IL2CPP_TYPE_I8 or Il2CppTypeEnum.IL2CPP_TYPE_U8 => "j",
case Il2CppTypeEnum.IL2CPP_TYPE_BOOLEAN: Il2CppTypeEnum.IL2CPP_TYPE_R4 => "f",
case Il2CppTypeEnum.IL2CPP_TYPE_CHAR: Il2CppTypeEnum.IL2CPP_TYPE_R8 => "d",
case Il2CppTypeEnum.IL2CPP_TYPE_I1: Il2CppTypeEnum.IL2CPP_TYPE_STRING or Il2CppTypeEnum.IL2CPP_TYPE_PTR or Il2CppTypeEnum.IL2CPP_TYPE_VALUETYPE or Il2CppTypeEnum.IL2CPP_TYPE_CLASS or Il2CppTypeEnum.IL2CPP_TYPE_VAR or Il2CppTypeEnum.IL2CPP_TYPE_ARRAY or Il2CppTypeEnum.IL2CPP_TYPE_GENERICINST or Il2CppTypeEnum.IL2CPP_TYPE_TYPEDBYREF or Il2CppTypeEnum.IL2CPP_TYPE_I or Il2CppTypeEnum.IL2CPP_TYPE_U or Il2CppTypeEnum.IL2CPP_TYPE_OBJECT or Il2CppTypeEnum.IL2CPP_TYPE_SZARRAY or Il2CppTypeEnum.IL2CPP_TYPE_MVAR => "i",
case Il2CppTypeEnum.IL2CPP_TYPE_U1: _ => throw new NotSupportedException(),
case Il2CppTypeEnum.IL2CPP_TYPE_I2: };
case Il2CppTypeEnum.IL2CPP_TYPE_U2:
case Il2CppTypeEnum.IL2CPP_TYPE_I4:
case Il2CppTypeEnum.IL2CPP_TYPE_U4:
signature += "i";
break;
case Il2CppTypeEnum.IL2CPP_TYPE_I8:
case Il2CppTypeEnum.IL2CPP_TYPE_U8:
signature += "j";
break;
case Il2CppTypeEnum.IL2CPP_TYPE_R4:
signature += "f";
break;
case Il2CppTypeEnum.IL2CPP_TYPE_R8:
signature += "d";
break;
case Il2CppTypeEnum.IL2CPP_TYPE_STRING:
case Il2CppTypeEnum.IL2CPP_TYPE_PTR:
case Il2CppTypeEnum.IL2CPP_TYPE_VALUETYPE:
case Il2CppTypeEnum.IL2CPP_TYPE_CLASS:
case Il2CppTypeEnum.IL2CPP_TYPE_VAR:
case Il2CppTypeEnum.IL2CPP_TYPE_ARRAY:
case Il2CppTypeEnum.IL2CPP_TYPE_GENERICINST:
case Il2CppTypeEnum.IL2CPP_TYPE_TYPEDBYREF:
case Il2CppTypeEnum.IL2CPP_TYPE_I:
case Il2CppTypeEnum.IL2CPP_TYPE_U:
case Il2CppTypeEnum.IL2CPP_TYPE_OBJECT:
case Il2CppTypeEnum.IL2CPP_TYPE_SZARRAY:
case Il2CppTypeEnum.IL2CPP_TYPE_MVAR:
signature += "i";
break;
default:
throw new NotSupportedException();
}
} }
return signature; return signature;
} }
@ -780,8 +747,10 @@ namespace Il2CppDumper
{ {
continue; continue;
} }
var structFieldInfo = new StructFieldInfo(); var structFieldInfo = new StructFieldInfo
structFieldInfo.FieldTypeName = ParseType(fieldType, context); {
FieldTypeName = ParseType(fieldType, context)
};
var fieldName = FixName(metadata.GetStringFromIndex(fieldDef.nameIndex)); var fieldName = FixName(metadata.GetStringFromIndex(fieldDef.nameIndex));
if (!cache.Add(fieldName)) if (!cache.Add(fieldName))
{ {
@ -809,7 +778,7 @@ namespace Il2CppDumper
{ {
var vTableIndex = typeDef.vtableStart + i; var vTableIndex = typeDef.vtableStart + i;
var encodedMethodIndex = metadata.vtableMethods[vTableIndex]; var encodedMethodIndex = metadata.vtableMethods[vTableIndex];
var usage = metadata.GetEncodedIndexType(encodedMethodIndex); var usage = Metadata.GetEncodedIndexType(encodedMethodIndex);
var index = metadata.GetDecodedMethodIndex(encodedMethodIndex); var index = metadata.GetDecodedMethodIndex(encodedMethodIndex);
Il2CppMethodDefinition methodDef; Il2CppMethodDefinition methodDef;
if (usage == 6) //kIl2CppMetadataUsageMethodRef if (usage == 6) //kIl2CppMetadataUsageMethodRef

View file

@ -8,10 +8,10 @@ namespace Il2CppDumper
public string TypeName; public string TypeName;
public bool IsValueType; public bool IsValueType;
public string Parent; public string Parent;
public List<StructFieldInfo> Fields = new List<StructFieldInfo>(); public List<StructFieldInfo> Fields = new();
public List<StructFieldInfo> StaticFields = new List<StructFieldInfo>(); public List<StructFieldInfo> StaticFields = new();
public StructVTableMethodInfo[] VTableMethod = Array.Empty<StructVTableMethodInfo>(); public StructVTableMethodInfo[] VTableMethod = Array.Empty<StructVTableMethodInfo>();
public List<StructRGCTXInfo> RGCTXs = new List<StructRGCTXInfo>(); public List<StructRGCTXInfo> RGCTXs = new();
} }
public class StructFieldInfo public class StructFieldInfo

View file

@ -53,16 +53,15 @@ namespace Il2CppDumper
} }
} }
} }
if (outputDir == null) outputDir ??= AppDomain.CurrentDomain.BaseDirectory;
{
outputDir = AppDomain.CurrentDomain.BaseDirectory;
}
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{ {
if (il2cppPath == null) if (il2cppPath == null)
{ {
var ofd = new OpenFileDialog(); var ofd = new OpenFileDialog
ofd.Filter = "Il2Cpp binary file|*.*"; {
Filter = "Il2Cpp binary file|*.*"
};
if (ofd.ShowDialog()) if (ofd.ShowDialog())
{ {
il2cppPath = ofd.FileName; il2cppPath = ofd.FileName;

View file

@ -14,7 +14,7 @@ namespace Il2CppDumper
public static ulong DecodeAdr(ulong pc, byte[] inst) public static ulong DecodeAdr(ulong pc, byte[] inst)
{ {
var bin = inst.HexToBin(); var bin = inst.HexToBin();
var uint64 = bin.Substring(8, 19) + bin.Substring(1, 2); var uint64 = string.Concat(bin.AsSpan(8, 19), bin.AsSpan(1, 2));
uint64 = uint64.PadLeft(64, uint64[0]); uint64 = uint64.PadLeft(64, uint64[0]);
return pc + Convert.ToUInt64(uint64, 2); return pc + Convert.ToUInt64(uint64, 2);
} }
@ -23,7 +23,7 @@ namespace Il2CppDumper
{ {
pc &= 0xFFFFFFFFFFFFF000; pc &= 0xFFFFFFFFFFFFF000;
var bin = inst.HexToBin(); var bin = inst.HexToBin();
var uint64 = bin.Substring(8, 19) + bin.Substring(1, 2) + new string('0', 12); var uint64 = string.Concat(bin.AsSpan(8, 19), bin.AsSpan(1, 2), new string('0', 12));
uint64 = uint64.PadLeft(64, uint64[0]); uint64 = uint64.PadLeft(64, uint64[0]);
return pc + Convert.ToUInt64(uint64, 2); return pc + Convert.ToUInt64(uint64, 2);
} }

View file

@ -5,9 +5,8 @@ namespace Il2CppDumper
{ {
public class CustomAttributeDataReader : BinaryReader public class CustomAttributeDataReader : BinaryReader
{ {
private Il2CppExecutor executor; private readonly Il2CppExecutor executor;
private Metadata metadata; private readonly Metadata metadata;
private Il2Cpp il2Cpp;
private long ctorBuffer; private long ctorBuffer;
private long dataBuffer; private long dataBuffer;
@ -17,7 +16,6 @@ namespace Il2CppDumper
{ {
this.executor = executor; this.executor = executor;
metadata = executor.metadata; metadata = executor.metadata;
il2Cpp = executor.il2Cpp;
Count = this.ReadCompressedUInt32(); Count = this.ReadCompressedUInt32();
ctorBuffer = BaseStream.Position; ctorBuffer = BaseStream.Position;
dataBuffer = BaseStream.Position + Count * 4; dataBuffer = BaseStream.Position + Count * 4;

View file

@ -10,19 +10,19 @@ namespace Il2CppDumper
{ {
public class DummyAssemblyGenerator public class DummyAssemblyGenerator
{ {
public List<AssemblyDefinition> Assemblies = new List<AssemblyDefinition>(); public List<AssemblyDefinition> Assemblies = new();
private Il2CppExecutor executor; private readonly Il2CppExecutor executor;
private Metadata metadata; private readonly Metadata metadata;
private Il2Cpp il2Cpp; private readonly Il2Cpp il2Cpp;
private Dictionary<Il2CppTypeDefinition, TypeDefinition> typeDefinitionDic = new Dictionary<Il2CppTypeDefinition, TypeDefinition>(); private readonly Dictionary<Il2CppTypeDefinition, TypeDefinition> typeDefinitionDic = new();
private Dictionary<Il2CppGenericParameter, GenericParameter> genericParameterDic = new Dictionary<Il2CppGenericParameter, GenericParameter>(); private readonly Dictionary<Il2CppGenericParameter, GenericParameter> genericParameterDic = new();
private MethodDefinition attributeAttribute; private readonly MethodDefinition attributeAttribute;
private TypeReference stringType; private readonly TypeReference stringType;
private TypeSystem typeSystem; private readonly TypeSystem typeSystem;
private Dictionary<int, FieldDefinition> fieldDefinitionDic = new Dictionary<int, FieldDefinition>(); private readonly Dictionary<int, FieldDefinition> fieldDefinitionDic = new();
private Dictionary<int, PropertyDefinition> propertyDefinitionDic = new Dictionary<int, PropertyDefinition>(); private readonly Dictionary<int, PropertyDefinition> propertyDefinitionDic = new();
private Dictionary<int, MethodDefinition> methodDefinitionDic = new Dictionary<int, MethodDefinition>(); private readonly Dictionary<int, MethodDefinition> methodDefinitionDic = new();
public DummyAssemblyGenerator(Il2CppExecutor il2CppExecutor, bool addToken) public DummyAssemblyGenerator(Il2CppExecutor il2CppExecutor, bool addToken)
{ {
@ -221,8 +221,10 @@ namespace Il2CppDumper
{ {
var methodDef = metadata.methodDefs[i]; var methodDef = metadata.methodDefs[i];
var methodName = metadata.GetStringFromIndex(methodDef.nameIndex); var methodName = metadata.GetStringFromIndex(methodDef.nameIndex);
var methodDefinition = new MethodDefinition(methodName, (MethodAttributes)methodDef.flags, typeDefinition.Module.ImportReference(typeSystem.Void)); var methodDefinition = new MethodDefinition(methodName, (MethodAttributes)methodDef.flags, typeDefinition.Module.ImportReference(typeSystem.Void))
methodDefinition.ImplAttributes = (MethodImplAttributes)methodDef.iflags; {
ImplAttributes = (MethodImplAttributes)methodDef.iflags
};
typeDefinition.Methods.Add(methodDefinition); typeDefinition.Methods.Add(methodDefinition);
//genericParameter //genericParameter
if (methodDef.genericContainerIndex >= 0) if (methodDef.genericContainerIndex >= 0)
@ -336,8 +338,7 @@ namespace Il2CppDumper
if (propertyDef.set >= 0) if (propertyDef.set >= 0)
{ {
SetMethod = methodDefinitionDic[typeDef.methodStart + propertyDef.set]; SetMethod = methodDefinitionDic[typeDef.methodStart + propertyDef.set];
if (propertyType == null) propertyType ??= SetMethod.Parameters[0].ParameterType;
propertyType = SetMethod.Parameters[0].ParameterType;
} }
var propertyDefinition = new PropertyDefinition(propertyName, (PropertyAttributes)propertyDef.attrs, propertyType) var propertyDefinition = new PropertyDefinition(propertyName, (PropertyAttributes)propertyDef.attrs, propertyType)
{ {
@ -554,7 +555,7 @@ namespace Il2CppDumper
return new PointerType(GetTypeReference(memberReference, oriType)); return new PointerType(GetTypeReference(memberReference, oriType));
} }
default: default:
throw new ArgumentOutOfRangeException(); throw new NotSupportedException();
} }
} }
@ -635,7 +636,7 @@ namespace Il2CppDumper
} }
} }
private bool TryRestoreCustomAttribute(TypeDefinition attributeType, ModuleDefinition moduleDefinition, Collection<CustomAttribute> customAttributes) private static bool TryRestoreCustomAttribute(TypeDefinition attributeType, ModuleDefinition moduleDefinition, Collection<CustomAttribute> customAttributes)
{ {
if (attributeType.Methods.Count == 1 && attributeType.Name != "CompilerGeneratedAttribute") if (attributeType.Methods.Count == 1 && attributeType.Name != "CompilerGeneratedAttribute")
{ {
@ -655,8 +656,10 @@ namespace Il2CppDumper
if (!genericParameterDic.TryGetValue(param, out var genericParameter)) if (!genericParameterDic.TryGetValue(param, out var genericParameter))
{ {
var genericName = metadata.GetStringFromIndex(param.nameIndex); var genericName = metadata.GetStringFromIndex(param.nameIndex);
genericParameter = new GenericParameter(genericName, iGenericParameterProvider); genericParameter = new GenericParameter(genericName, iGenericParameterProvider)
genericParameter.Attributes = (GenericParameterAttributes)param.flags; {
Attributes = (GenericParameterAttributes)param.flags
};
genericParameterDic.Add(param, genericParameter); genericParameterDic.Add(param, genericParameter);
for (int i = 0; i < param.constraintsCount; ++i) for (int i = 0; i < param.constraintsCount; ++i)
{ {
@ -709,8 +712,10 @@ namespace Il2CppDumper
{ {
return GetTypeReference(memberReference, blobValue.EnumType); return GetTypeReference(memberReference, blobValue.EnumType);
} }
var il2CppType = new Il2CppType(); var il2CppType = new Il2CppType
il2CppType.type = blobValue.il2CppTypeEnum; {
type = blobValue.il2CppTypeEnum
};
return GetTypeReference(memberReference, il2CppType); return GetTypeReference(memberReference, il2CppType);
} }
} }

View file

@ -10,7 +10,7 @@ namespace Il2CppDumper
{ {
public Metadata metadata; public Metadata metadata;
public Il2Cpp il2Cpp; public Il2Cpp il2Cpp;
private static readonly Dictionary<int, string> TypeString = new Dictionary<int, string> private static readonly Dictionary<int, string> TypeString = new()
{ {
{1,"void"}, {1,"void"},
{2,"bool"}, {2,"bool"},
@ -118,7 +118,7 @@ namespace Il2CppDumper
var index = typeName.IndexOf("`"); var index = typeName.IndexOf("`");
if (index != -1) if (index != -1)
{ {
str += typeName.Substring(0, index); str += typeName[..index];
} }
else else
{ {
@ -167,7 +167,7 @@ namespace Il2CppDumper
var index = typeName.IndexOf("`"); var index = typeName.IndexOf("`");
if (index != -1) if (index != -1)
{ {
typeName = typeName.Substring(0, index); typeName = typeName[..index];
} }
if (genericParameter) if (genericParameter)
{ {
@ -342,8 +342,10 @@ namespace Il2CppDumper
public bool GetConstantValueFromBlob(Il2CppTypeEnum type, BinaryReader reader, out BlobValue value) public bool GetConstantValueFromBlob(Il2CppTypeEnum type, BinaryReader reader, out BlobValue value)
{ {
value = new BlobValue(); value = new BlobValue
value.il2CppTypeEnum = type; {
il2CppTypeEnum = type
};
switch (type) switch (type)
{ {
case Il2CppTypeEnum.IL2CPP_TYPE_BOOLEAN: case Il2CppTypeEnum.IL2CPP_TYPE_BOOLEAN:

View file

@ -1,7 +1,6 @@
using System; using System;
using System.ComponentModel; using System.ComponentModel;
using System.IO; using System.IO;
using System.Linq;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Text; using System.Text;
@ -9,14 +8,13 @@ namespace Il2CppDumper
{ {
public class PELoader public class PELoader
{ {
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)] [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
private extern static IntPtr LoadLibrary(string path); private extern static IntPtr LoadLibrary(string path);
public static PE Load(string fileName) public static PE Load(string fileName)
{ {
var buff = File.ReadAllBytes(fileName); var buff = File.ReadAllBytes(fileName);
using (var reader = new BinaryStream(new MemoryStream(buff))) using var reader = new BinaryStream(new MemoryStream(buff));
{
var dosHeader = reader.ReadClass<DosHeader>(); var dosHeader = reader.ReadClass<DosHeader>();
if (dosHeader.Magic != 0x5A4D) if (dosHeader.Magic != 0x5A4D)
{ {
@ -39,7 +37,7 @@ namespace Il2CppDumper
var pos = reader.Position; var pos = reader.Position;
reader.Position = pos + fileHeader.SizeOfOptionalHeader; reader.Position = pos + fileHeader.SizeOfOptionalHeader;
var sections = reader.ReadClassArray<SectionHeader>(fileHeader.NumberOfSections); var sections = reader.ReadClassArray<SectionHeader>(fileHeader.NumberOfSections);
var last = sections.Last(); var last = sections[^1];
var size = last.VirtualAddress + last.VirtualSize; var size = last.VirtualAddress + last.VirtualSize;
var peBuff = new byte[size]; var peBuff = new byte[size];
var handle = LoadLibrary(fileName); var handle = LoadLibrary(fileName);
@ -72,5 +70,4 @@ namespace Il2CppDumper
return pe; return pe;
} }
} }
}
} }

View file

@ -9,11 +9,11 @@ namespace Il2CppDumper
private List<SearchSection> exec; private List<SearchSection> exec;
private List<SearchSection> data; private List<SearchSection> data;
private List<SearchSection> bss; private List<SearchSection> bss;
private Il2Cpp il2Cpp; private readonly Il2Cpp il2Cpp;
private int methodCount; private readonly int methodCount;
private int typeDefinitionsCount; private readonly int typeDefinitionsCount;
private long metadataUsagesCount; private readonly long metadataUsagesCount;
private int imageCount; private readonly int imageCount;
private bool pointerInExec; private bool pointerInExec;
public List<SearchSection> Exec => exec; public List<SearchSection> Exec => exec;