代码清理

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
{
private List<MachoSection> sections = new List<MachoSection>();
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 ulong vmaddr;
private readonly List<MachoSection> sections = new();
private readonly ulong vmaddr;
public Macho(Stream stream) : base(stream)
{

View File

@ -9,10 +9,10 @@ namespace Il2CppDumper
{
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[] 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)
{

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -10,7 +10,7 @@ namespace Il2CppDumper
{
var start = reader.BaseStream.Position;
// 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.
reader.BaseStream.Position = start;
reader.ReadBytes(Encoding.UTF8.GetByteCount(str));

View File

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

View File

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

View File

@ -16,15 +16,15 @@ namespace Il2CppDumper
public Il2CppMethodDefinition[] methodDefs;
public Il2CppParameterDefinition[] parameterDefs;
public Il2CppFieldDefinition[] fieldDefs;
private Dictionary<int, Il2CppFieldDefaultValue> fieldDefaultValuesDic;
private Dictionary<int, Il2CppParameterDefaultValue> parameterDefaultValuesDic;
private readonly Dictionary<int, Il2CppFieldDefaultValue> fieldDefaultValuesDic;
private readonly Dictionary<int, Il2CppParameterDefaultValue> parameterDefaultValuesDic;
public Il2CppPropertyDefinition[] propertyDefs;
public Il2CppCustomAttributeTypeRange[] attributeTypeRanges;
public Il2CppCustomAttributeDataRange[] attributeDataRanges;
private Dictionary<Il2CppImageDefinition, Dictionary<uint, int>> attributeTypeRangesDic;
private readonly Dictionary<Il2CppImageDefinition, Dictionary<uint, int>> attributeTypeRangesDic;
public Il2CppStringLiteral[] stringLiterals;
private Il2CppMetadataUsageList[] metadataUsageLists;
private Il2CppMetadataUsagePair[] metadataUsagePairs;
private readonly Il2CppMetadataUsageList[] metadataUsageLists;
private readonly Il2CppMetadataUsagePair[] metadataUsagePairs;
public int[] attributeTypes;
public int[] interfaceIndices;
public Dictionary<Il2CppMetadataUsage, SortedDictionary<uint, uint>> metadataUsageDic;
@ -38,7 +38,7 @@ namespace Il2CppDumper
public uint[] vtableMethods;
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)
{
@ -239,7 +239,7 @@ namespace Il2CppDumper
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;
}
@ -286,19 +286,14 @@ namespace Il2CppDumper
}
return size;
int GetPrimitiveTypeSize(string name)
static int GetPrimitiveTypeSize(string name)
{
switch (name)
return name switch
{
case "Int32":
case "UInt32":
return 4;
case "Int16":
case "UInt16":
return 2;
default:
return 0;
}
"Int32" or "UInt32" => 4,
"Int16" or "UInt16" => 2,
_ => 0,
};
}
}
}

View File

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

View File

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

View File

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

View File

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

View File

@ -8,10 +8,10 @@ namespace Il2CppDumper
public string TypeName;
public bool IsValueType;
public string Parent;
public List<StructFieldInfo> Fields = new List<StructFieldInfo>();
public List<StructFieldInfo> StaticFields = new List<StructFieldInfo>();
public List<StructFieldInfo> Fields = new();
public List<StructFieldInfo> StaticFields = new();
public StructVTableMethodInfo[] VTableMethod = Array.Empty<StructVTableMethodInfo>();
public List<StructRGCTXInfo> RGCTXs = new List<StructRGCTXInfo>();
public List<StructRGCTXInfo> RGCTXs = new();
}
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 (il2cppPath == null)
{
var ofd = new OpenFileDialog();
ofd.Filter = "Il2Cpp binary file|*.*";
var ofd = new OpenFileDialog
{
Filter = "Il2Cpp binary file|*.*"
};
if (ofd.ShowDialog())
{
il2cppPath = ofd.FileName;

View File

@ -14,7 +14,7 @@ namespace Il2CppDumper
public static ulong DecodeAdr(ulong pc, byte[] inst)
{
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]);
return pc + Convert.ToUInt64(uint64, 2);
}
@ -23,7 +23,7 @@ namespace Il2CppDumper
{
pc &= 0xFFFFFFFFFFFFF000;
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]);
return pc + Convert.ToUInt64(uint64, 2);
}

View File

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

View File

@ -10,19 +10,19 @@ namespace Il2CppDumper
{
public class DummyAssemblyGenerator
{
public List<AssemblyDefinition> Assemblies = new List<AssemblyDefinition>();
public List<AssemblyDefinition> Assemblies = new();
private Il2CppExecutor executor;
private Metadata metadata;
private Il2Cpp il2Cpp;
private Dictionary<Il2CppTypeDefinition, TypeDefinition> typeDefinitionDic = new Dictionary<Il2CppTypeDefinition, TypeDefinition>();
private Dictionary<Il2CppGenericParameter, GenericParameter> genericParameterDic = new Dictionary<Il2CppGenericParameter, GenericParameter>();
private MethodDefinition attributeAttribute;
private TypeReference stringType;
private TypeSystem typeSystem;
private Dictionary<int, FieldDefinition> fieldDefinitionDic = new Dictionary<int, FieldDefinition>();
private Dictionary<int, PropertyDefinition> propertyDefinitionDic = new Dictionary<int, PropertyDefinition>();
private Dictionary<int, MethodDefinition> methodDefinitionDic = new Dictionary<int, MethodDefinition>();
private readonly Il2CppExecutor executor;
private readonly Metadata metadata;
private readonly Il2Cpp il2Cpp;
private readonly Dictionary<Il2CppTypeDefinition, TypeDefinition> typeDefinitionDic = new();
private readonly Dictionary<Il2CppGenericParameter, GenericParameter> genericParameterDic = new();
private readonly MethodDefinition attributeAttribute;
private readonly TypeReference stringType;
private readonly TypeSystem typeSystem;
private readonly Dictionary<int, FieldDefinition> fieldDefinitionDic = new();
private readonly Dictionary<int, PropertyDefinition> propertyDefinitionDic = new();
private readonly Dictionary<int, MethodDefinition> methodDefinitionDic = new();
public DummyAssemblyGenerator(Il2CppExecutor il2CppExecutor, bool addToken)
{
@ -221,8 +221,10 @@ namespace Il2CppDumper
{
var methodDef = metadata.methodDefs[i];
var methodName = metadata.GetStringFromIndex(methodDef.nameIndex);
var methodDefinition = new MethodDefinition(methodName, (MethodAttributes)methodDef.flags, typeDefinition.Module.ImportReference(typeSystem.Void));
methodDefinition.ImplAttributes = (MethodImplAttributes)methodDef.iflags;
var methodDefinition = new MethodDefinition(methodName, (MethodAttributes)methodDef.flags, typeDefinition.Module.ImportReference(typeSystem.Void))
{
ImplAttributes = (MethodImplAttributes)methodDef.iflags
};
typeDefinition.Methods.Add(methodDefinition);
//genericParameter
if (methodDef.genericContainerIndex >= 0)
@ -336,8 +338,7 @@ namespace Il2CppDumper
if (propertyDef.set >= 0)
{
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)
{
@ -554,7 +555,7 @@ namespace Il2CppDumper
return new PointerType(GetTypeReference(memberReference, oriType));
}
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")
{
@ -655,8 +656,10 @@ namespace Il2CppDumper
if (!genericParameterDic.TryGetValue(param, out var genericParameter))
{
var genericName = metadata.GetStringFromIndex(param.nameIndex);
genericParameter = new GenericParameter(genericName, iGenericParameterProvider);
genericParameter.Attributes = (GenericParameterAttributes)param.flags;
genericParameter = new GenericParameter(genericName, iGenericParameterProvider)
{
Attributes = (GenericParameterAttributes)param.flags
};
genericParameterDic.Add(param, genericParameter);
for (int i = 0; i < param.constraintsCount; ++i)
{
@ -709,8 +712,10 @@ namespace Il2CppDumper
{
return GetTypeReference(memberReference, blobValue.EnumType);
}
var il2CppType = new Il2CppType();
il2CppType.type = blobValue.il2CppTypeEnum;
var il2CppType = new Il2CppType
{
type = blobValue.il2CppTypeEnum
};
return GetTypeReference(memberReference, il2CppType);
}
}

View File

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

View File

@ -1,7 +1,6 @@
using System;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
@ -9,68 +8,66 @@ namespace Il2CppDumper
{
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);
public static PE Load(string 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>();
if (dosHeader.Magic != 0x5A4D)
{
var dosHeader = reader.ReadClass<DosHeader>();
if (dosHeader.Magic != 0x5A4D)
{
throw new InvalidDataException("ERROR: Invalid PE file");
}
reader.Position = dosHeader.Lfanew;
if (reader.ReadUInt32() != 0x4550u) //Signature
{
throw new InvalidDataException("ERROR: Invalid PE file");
}
var fileHeader = reader.ReadClass<FileHeader>();
if (fileHeader.Machine == 0x14c && Environment.Is64BitProcess) //64bit process can't load 32bit dll
{
throw new InvalidOperationException("The file is a 32-bit file, please try to load it with Il2CppDumper-x86.exe");
}
if (fileHeader.Machine == 0x8664 && !Environment.Is64BitProcess) //32bit process can't load 64bit dll
{
throw new InvalidOperationException("The file is a 64-bit file, please try to load it with Il2CppDumper.exe");
}
var pos = reader.Position;
reader.Position = pos + fileHeader.SizeOfOptionalHeader;
var sections = reader.ReadClassArray<SectionHeader>(fileHeader.NumberOfSections);
var last = sections.Last();
var size = last.VirtualAddress + last.VirtualSize;
var peBuff = new byte[size];
var handle = LoadLibrary(fileName);
if (handle == IntPtr.Zero)
{
throw new Win32Exception(Marshal.GetLastWin32Error());
}
foreach (var section in sections)
{
switch (section.Characteristics)
{
case 0x60000020:
case 0x40000040:
case 0xC0000040:
Marshal.Copy(new IntPtr(handle.ToInt64() + section.VirtualAddress), peBuff, (int)section.VirtualAddress, (int)section.VirtualSize);
break;
}
}
var peMemory = new MemoryStream(peBuff);
var writer = new BinaryWriter(peMemory, Encoding.UTF8, true);
var headerSize = reader.Position;
reader.Position = 0;
var buff2 = reader.ReadBytes((int)headerSize);
writer.Write(buff2);
writer.Flush();
writer.Close();
peMemory.Position = 0;
var pe = new PE(peMemory);
pe.LoadFromMemory((ulong)handle.ToInt64());
return pe;
throw new InvalidDataException("ERROR: Invalid PE file");
}
reader.Position = dosHeader.Lfanew;
if (reader.ReadUInt32() != 0x4550u) //Signature
{
throw new InvalidDataException("ERROR: Invalid PE file");
}
var fileHeader = reader.ReadClass<FileHeader>();
if (fileHeader.Machine == 0x14c && Environment.Is64BitProcess) //64bit process can't load 32bit dll
{
throw new InvalidOperationException("The file is a 32-bit file, please try to load it with Il2CppDumper-x86.exe");
}
if (fileHeader.Machine == 0x8664 && !Environment.Is64BitProcess) //32bit process can't load 64bit dll
{
throw new InvalidOperationException("The file is a 64-bit file, please try to load it with Il2CppDumper.exe");
}
var pos = reader.Position;
reader.Position = pos + fileHeader.SizeOfOptionalHeader;
var sections = reader.ReadClassArray<SectionHeader>(fileHeader.NumberOfSections);
var last = sections[^1];
var size = last.VirtualAddress + last.VirtualSize;
var peBuff = new byte[size];
var handle = LoadLibrary(fileName);
if (handle == IntPtr.Zero)
{
throw new Win32Exception(Marshal.GetLastWin32Error());
}
foreach (var section in sections)
{
switch (section.Characteristics)
{
case 0x60000020:
case 0x40000040:
case 0xC0000040:
Marshal.Copy(new IntPtr(handle.ToInt64() + section.VirtualAddress), peBuff, (int)section.VirtualAddress, (int)section.VirtualSize);
break;
}
}
var peMemory = new MemoryStream(peBuff);
var writer = new BinaryWriter(peMemory, Encoding.UTF8, true);
var headerSize = reader.Position;
reader.Position = 0;
var buff2 = reader.ReadBytes((int)headerSize);
writer.Write(buff2);
writer.Flush();
writer.Close();
peMemory.Position = 0;
var pe = new PE(peMemory);
pe.LoadFromMemory((ulong)handle.ToInt64());
return pe;
}
}
}

View File

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