mirror of
https://github.com/Perfare/Il2CppDumper.git
synced 2025-01-24 09:57:44 -03:00
代码清理
This commit is contained in:
parent
101f3c62ef
commit
217f1d4737
23 changed files with 219 additions and 259 deletions
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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++)
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -7,7 +7,7 @@ namespace Il2CppDumper
|
|||
{
|
||||
public sealed class PE : Il2Cpp
|
||||
{
|
||||
private SectionHeader[] sections;
|
||||
private readonly SectionHeader[] sections;
|
||||
|
||||
public PE(Stream stream) : base(stream)
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue