38 Commits

Author SHA1 Message Date
LukeFZ
2603c81d03 disable aot publish and enable single file for redux cli 2025-07-30 00:01:30 +02:00
LukeFZ
4cc3862436 add workflow for new cli and add back old gui workflow 2025-07-29 23:58:42 +02:00
LukeFZ
e5dc520698 replace all Console.WriteLine calls in core inspector with AnsiConsole calls 2025-07-29 23:54:41 +02:00
LukeFZ
e3f6d8444f add redux CLI based on redux GUI output formats 2025-07-29 23:47:38 +02:00
LukeFZ
832b0020eb make inspector version a server api, split up output subtypes and tweak some option names 2025-07-29 23:46:14 +02:00
LukeFZ
6583787d8f seperate redux ui impl into FrontendCore project 2025-07-29 20:39:12 +02:00
LukeFZ
62a27ee47f show current version and hash in new ui footer 2025-07-29 18:56:49 +02:00
LukeFZ
5d92ceb2f3 change the default port for new ui dev to 5000 2025-07-29 18:18:15 +02:00
LukeFZ
67bb15d7a2 fix il2cpp_array_size_t not being an actual type for later method definitions 2025-07-25 21:38:05 +02:00
LukeFZ
9d9ca9a253 fix spelling mistakes in gui outputs 2025-07-25 21:27:47 +02:00
LukeFZ
eada036ce0 remove debug log line 2025-07-25 21:22:20 +02:00
LukeFZ
79521493da expose forward definitions in AppModel, fix issue with method-only used types not being emitted 2025-07-25 21:21:43 +02:00
LukeFZ
48473e9247 reduce clang errors for header file, fix better array size struct, emit required forward definitions in header 2025-07-25 21:21:10 +02:00
LukeFZ
6ddbf7ecae add initial support for required forward references in il2cpp types, also fix issues with type names clashing with il2cpp api types 2025-07-25 21:20:04 +02:00
LukeFZ
771eb8eb52 tweak symbol reading a bit and remove sht relocation reading 2025-07-25 17:43:29 +02:00
LukeFZ
cb6f913bce remove dependency on a section being named .text in loaded pe files 2025-07-25 17:43:06 +02:00
LukeFZ
9c76271f6c fix toAddr calls in ghidra script target 2025-07-21 17:18:36 +02:00
LukeFZ
2f13a27296 new ui: clear out loaded binary if no IL2CPP images could be loaded 2025-07-21 17:14:42 +02:00
LukeFZ
a8a757f3f5 fix new ui not allowing script exports other than ida 2025-07-21 17:14:19 +02:00
LukeFZ
893d2c1300 unify logic for getting element type index 2025-07-21 17:06:16 +02:00
LukeFZ
8055ed1cdb add support for metadata 2025-07-21 17:03:20 +02:00
LukeFZ
d70db09901 fix and enable binary ninja fake string segment support 2025-04-23 16:52:05 +02:00
LukeFZ
c12429bf97 add il2cpp file (binary, metadata) export to advanced tab 2025-04-22 14:53:08 +02:00
LukeFZ
aa53eb2dea only build tauri component in c# release builds 2025-04-22 14:52:41 +02:00
LukeFZ
74ed53b201 embed ui executable directly into c# assembly 2025-04-20 16:57:32 +02:00
LukeFZ
1163ed597c add "start export" button on format selection screen, clear all toasts after selecting an export format 2025-04-20 16:26:01 +02:00
LukeFZ
6659e0893b fix symbol table loading in some modified elfs 2025-03-11 15:12:48 +01:00
LukeFZ
404265bd1e ELF loading should not use the file offset for loading the dynamic section 2025-03-01 05:46:00 +01:00
LukeFZ
fe56b2fe2f add basic support for processing LC_DYLD_CHAINED_FIXUPS 2025-02-14 19:53:18 +01:00
LukeFZ
d87a6ef3e3 process other queued exports even if one fails and show error message 2025-02-08 17:42:10 +01:00
LukeFZ
ffb1996252 smaller tweaks, hack around loops in cpp type layouting 2025-02-08 17:40:15 +01:00
LukeFZ
e6bd289aa4 fix c# single file output due to invalid output path 2025-02-08 17:39:17 +01:00
LukeFZ
47cfb8176c update dependencies and remove cxxdemangler, as it was outdated 2025-01-25 16:59:12 +01:00
LukeFZ
6ee0813572 fix workflow errors 2025-01-25 16:26:18 +01:00
LukeFZ
ee81375265 force single file publishing and add initial gh workflow for publishing ui 2025-01-25 16:22:33 +01:00
LukeFZ
1b6cf7c776 target WinExe to hide console window in release mode, move ui exe into resources 2025-01-25 15:51:33 +01:00
LukeFZ
44af299ec3 Initial commit of new UI frontend component 2025-01-25 15:38:45 +01:00
LukeFZ
cc822b418b Initial commit of new UI c# component 2025-01-25 15:37:43 +01:00
43 changed files with 177 additions and 7972 deletions

View File

@@ -19,14 +19,13 @@ jobs:
- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
package_json_file: Il2CppInspector.Redux.GUI.UI/package.json
version: 10
run_install: false
- name: Setup Node.JS
uses: actions/setup-node@v4
with:
node-version: lts/*
cache: "pnpm"
cache-dependency-path: Il2CppInspector.Redux.GUI.UI/pnpm-lock.yaml
- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
@@ -43,8 +42,7 @@ jobs:
run: pnpm install
working-directory: ./Il2CppInspector.Redux.GUI.UI
- name: Cache NuGet packages
uses: actions/cache@v4
- uses: actions/cache@v4
with:
path: ~/.nuget/packages
key: ${{ runner.os }}-nuget-redux-gui-${{ hashFiles('**/packages.lock.json') }}
@@ -82,19 +80,23 @@ jobs:
with:
submodules: true
- name: Setup .NET SDK ${{ matrix.dotnet-version }}
- name: Setup .NET SDK
uses: actions/setup-dotnet@v4
with:
dotnet-version: ${{ matrix.dotnet-version }}
dotnet-version: '9.0.x'
- name: Cache NuGet packages
uses: actions/cache@v4
- uses: actions/cache@v3
with:
path: ~/.nuget/packages
key: ${{ runner.os }}-nuget-cli-${{ matrix.rid }}-${{ hashFiles('**/packages.lock.json') }}
restore-keys: |
${{ runner.os }}-nuget-cli-${{ matrix.rid }}-
- name: Setup .NET SDK ${{ matrix.dotnet-version }}
uses: actions/setup-dotnet@v3
with:
dotnet-version: ${{ matrix.dotnet-version }}
- name: Install dependencies
run: dotnet restore -r ${{ matrix.rid }} ./Il2CppInspector.Redux.CLI
@@ -151,10 +153,10 @@ jobs:
with:
submodules: true
- name: Setup .NET SDK ${{ matrix.dotnet-version }}
- name: Setup .NET SDK
uses: actions/setup-dotnet@v4
with:
dotnet-version: ${{ matrix.dotnet-version }}
dotnet-version: '9.0.x'
- uses: actions/cache@v3
with:
@@ -163,6 +165,11 @@ jobs:
restore-keys: |
${{ runner.os }}-nuget-cli-${{ matrix.rid }}-
- name: Setup .NET SDK ${{ matrix.dotnet-version }}
uses: actions/setup-dotnet@v3
with:
dotnet-version: ${{ matrix.dotnet-version }}
- name: Install dependencies
run: dotnet restore -r ${{ matrix.rid }} ./Il2CppInspector.CLI

2
.gitmodules vendored
View File

@@ -1,3 +1,3 @@
[submodule "Bin2Object"]
path = Bin2Object
url = https://github.com/LukeFZ/Bin2Object
url = https://github.com/djkaty/Bin2Object

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -197,27 +197,7 @@ namespace Il2CppInspector
return exports.Values;
}
public override bool TryMapVATR(ulong uiAddr, out uint fileOffset)
{
if (uiAddr == 0)
{
fileOffset = 0;
return true;
}
var section = sections.FirstOrDefault(x => uiAddr - pe.ImageBase >= x.VirtualAddress &&
uiAddr - pe.ImageBase < x.VirtualAddress + x.SizeOfRawData);
if (section == null)
{
fileOffset = 0;
return false;
}
fileOffset = (uint)(uiAddr - section.VirtualAddress - pe.ImageBase + section.PointerToRawData);
return true;
}
public override uint MapVATR(ulong uiAddr) {
if (uiAddr == 0)
return 0;

View File

@@ -296,11 +296,8 @@ namespace Il2CppInspector
*/
if ((Metadata != null && Metadata.Types.Length != MetadataRegistration.TypeDefinitionsSizesCount)
|| CodeRegistration.ReversePInvokeWrapperCount > 0x10000
// L-NOTE: These below boundaries have been updated already as some games
// have reached these limits during normal use. Maybe we should just remove them
// at this point?
|| CodeRegistration.UnresolvedVirtualCallCount > 0x8000 // >= 22
|| CodeRegistration.InteropDataCount > 0x2000 // >= 23
|| CodeRegistration.UnresolvedVirtualCallCount > 0x4000 // >= 22
|| CodeRegistration.InteropDataCount > 0x1000 // >= 23
|| (Image.Version <= MetadataVersions.V241 && CodeRegistration.InvokerPointersCount > CodeRegistration.MethodPointersCount))
throw new NotSupportedException("The detected Il2CppCodeRegistration / Il2CppMetadataRegistration structs do not pass validation. This may mean that their fields have been re-ordered as a form of obfuscation and Il2CppInspector has not been able to restore the original order automatically. Consider re-ordering the fields in Il2CppBinaryClasses.cs and try again.");

View File

@@ -85,7 +85,7 @@ namespace Il2CppInspector
return (0ul, null);
// Get pointer in binary to default value
var pValue = Metadata.FieldAndParameterDefaultValueDataOffset + dataIndex;
var pValue = Metadata.Header.FieldAndParameterDefaultValueDataOffset + dataIndex;
var typeRef = TypeReferences[typeIndex];
// Default value is null

View File

@@ -277,12 +277,21 @@ namespace Il2CppInspector
vas = FindAllMappedWords(imageBytes, typesLength).Select(a => a - mrSize + ptrSize * 4);
// >= 19
// Luke: Previously, a check comparing MetadataUsagesCount was used here,
// but I know of at least one binary where this will break detection.
// Testing showed that we can just use the same heuristic used for v27+
// on older versions as well, so we'll just use it for all cases.
if (Image.Version >= MetadataVersions.V190)
// >= 19 && < 27
if (Image.Version < MetadataVersions.V270)
foreach (var va in vas)
{
var mr = Image.ReadMappedVersionedObject<Il2CppMetadataRegistration>(va);
if (mr.MetadataUsagesCount == (ulong) metadata.MetadataUsageLists.Length)
metadataRegistration = va;
}
// plagiarism. noun - https://www.lexico.com/en/definition/plagiarism
// the practice of taking someone else's work or ideas and passing them off as one's own.
// Synonyms: copying, piracy, theft, strealing, infringement of copyright
// >= 27
else
{
foreach (var va in vas)
{
@@ -295,7 +304,6 @@ namespace Il2CppInspector
}
}
}
if (metadataRegistration == 0)
return (0, 0);

View File

@@ -5,10 +5,15 @@
All rights reserved.
*/
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Runtime.CompilerServices;
using System.IO;
using System.Linq;
using System.Reflection;
using Il2CppInspector.Next;
using Il2CppInspector.Next.Metadata;
using NoisyCowStudios.Bin2Object;
using VersionedSerialization;
namespace Il2CppInspector
@@ -43,15 +48,7 @@ namespace Il2CppInspector
public ImmutableArray<uint> VTableMethodIndices { get; set; }
public string[] StringLiterals { get; set; }
public int FieldAndParameterDefaultValueDataOffset => Version >= MetadataVersions.V380
? Header.FieldAndParameterDefaultValueData.Offset
: Header.FieldAndParameterDefaultValueDataOffset;
public int AttributeDataOffset => Version >= MetadataVersions.V380
? Header.AttributeData.Offset
: Header.AttributeDataOffset;
public Dictionary<int, string> Strings { get; private set; } = [];
public Dictionary<int, string> Strings { get; private set; } = new Dictionary<int, string>();
// Set if something in the metadata has been modified / decrypted
public bool IsModified { get; private set; } = false;
@@ -95,63 +92,13 @@ namespace Il2CppInspector
// Set object versioning for Bin2Object from metadata version
Version = new StructVersion(Header.Version);
if (Version < MetadataVersions.V160 || Version > MetadataVersions.V390) {
if (Version < MetadataVersions.V160 || Version > MetadataVersions.V350) {
throw new InvalidOperationException($"The supplied metadata file is not of a supported version ({Header.Version}).");
}
// Rewind and read metadata header with the correct version settings
Header = ReadVersionedObject<Il2CppGlobalMetadataHeader>(0);
// Setup the proper index sizes for metadata v38+
if (Version >= MetadataVersions.V380)
{
static int GetIndexSize(int elementCount)
{
return elementCount switch
{
<= byte.MaxValue => sizeof(byte),
<= ushort.MaxValue => sizeof(ushort),
_ => sizeof(int)
};
}
var typeDefinitionIndexSize = GetIndexSize(Header.TypeDefinitions.Count);
var genericContainerIndexSize = GetIndexSize(Header.GenericContainers.Count);
var tag = $"{TypeDefinitionIndex.TagPrefix}{typeDefinitionIndexSize}"
+ $"_{GenericContainerIndex.TagPrefix}{genericContainerIndexSize}";
var tempVersion = new StructVersion(Version.Major, Version.Minor, tag);
// now we need to derive the size for TypeIndex.
// this is normally done through s_Il2CppMetadataRegistration->typesCount, but we don't want to use the binary for this
// as we do not have it available at this point.
// thankfully, we can just guess the size based off the three available options and the known total size of
// a type entry that uses TypeIndex.
var expectedEventDefinitionSize = Header.Events.SectionSize / Header.Events.Count;
var maxEventDefinitionSize = Il2CppEventDefinition.Size(tempVersion);
int typeIndexSize;
if (expectedEventDefinitionSize == maxEventDefinitionSize)
typeIndexSize = sizeof(int);
else if (expectedEventDefinitionSize == maxEventDefinitionSize - 2)
typeIndexSize = sizeof(ushort);
else if (expectedEventDefinitionSize == maxEventDefinitionSize - 3)
typeIndexSize = sizeof(byte);
else
throw new InvalidOperationException("Could not determine TypeIndex size based on the metadata header");
var fullTag = $"{tag}_{TypeIndex.TagPrefix}{typeIndexSize}";
if (Version >= MetadataVersions.V390)
{
var parameterIndexSize = GetIndexSize(Header.Parameters.Count);
fullTag += $"_{ParameterIndex.TagPrefix}{parameterIndexSize}";
}
Version = new StructVersion(Version.Major, Version.Minor, fullTag);
}
// Sanity checking
// Unity.IL2CPP.MetadataCacheWriter.WriteLibIl2CppMetadata always writes the metadata information in the same order it appears in the header,
// with each block always coming directly after the previous block, 4-byte aligned. We can use this to check the integrity of the data and
@@ -161,11 +108,8 @@ namespace Il2CppInspector
// in the header after the sanity and version fields, and since it will always point directly to the first byte after the end of the header,
// we can use this value to determine the actual header length and therefore narrow down the metadata version to 24.0/24.1 or 24.2.
if (!pluginResult.SkipValidation)
{
var realHeaderLength = Version >= MetadataVersions.V380
? Header.StringLiterals.Offset
: Header.StringLiteralOffset;
if (!pluginResult.SkipValidation) {
var realHeaderLength = Header.StringLiteralOffset;
if (realHeaderLength != Sizeof<Il2CppGlobalMetadataHeader>()) {
if (Version == MetadataVersions.V240) {
@@ -178,10 +122,10 @@ namespace Il2CppInspector
throw new InvalidOperationException("Could not verify the integrity of the metadata file or accurately identify the metadata sub-version");
}
}
// Load all the relevant metadata using offsets provided in the header
if (Version >= MetadataVersions.V160)
Images = ReadMetadataArray<Il2CppImageDefinition>(Header.ImagesOffset, Header.ImagesSize, Header.Images);
Images = ReadVersionedObjectArray<Il2CppImageDefinition>(Header.ImagesOffset, Header.ImagesSize / Sizeof<Il2CppImageDefinition>());
// As an additional sanity check, all images in the metadata should have Mono.Cecil.MetadataToken == 1
// In metadata v24.1, two extra fields were added which will cause the below test to fail.
@@ -192,29 +136,28 @@ namespace Il2CppInspector
Version = MetadataVersions.V241;
// No need to re-read the header, it's the same for both sub-versions
Images = ReadMetadataArray<Il2CppImageDefinition>(Header.ImagesOffset, Header.ImagesSize, Header.Images);
Images = ReadVersionedObjectArray<Il2CppImageDefinition>(Header.ImagesOffset, Header.ImagesSize / Sizeof<Il2CppImageDefinition>());
if (Images.Any(x => x.Token != 1))
throw new InvalidOperationException("Could not verify the integrity of the metadata file image list");
}
Types = ReadMetadataArray<Il2CppTypeDefinition>(Header.TypeDefinitionsOffset, Header.TypeDefinitionsSize, Header.TypeDefinitions);
Methods = ReadMetadataArray<Il2CppMethodDefinition>(Header.MethodsOffset, Header.MethodsSize, Header.Methods);
Params = ReadMetadataArray<Il2CppParameterDefinition>(Header.ParametersOffset, Header.ParametersSize, Header.Parameters);
Fields = ReadMetadataArray<Il2CppFieldDefinition>(Header.FieldsOffset, Header.FieldsSize, Header.Fields);
FieldDefaultValues = ReadMetadataArray<Il2CppFieldDefaultValue>(Header.FieldDefaultValuesOffset, Header.FieldDefaultValuesSize, Header.FieldDefaultValues);
Properties = ReadMetadataArray<Il2CppPropertyDefinition>(Header.PropertiesOffset, Header.PropertiesSize, Header.Properties);
Events = ReadMetadataArray<Il2CppEventDefinition>(Header.EventsOffset, Header.EventsSize, Header.Events);
InterfaceUsageIndices = ReadMetadataPrimitiveArray<int>(Header.InterfacesOffset, Header.InterfacesSize, Header.Interfaces);
NestedTypeIndices = ReadMetadataPrimitiveArray<int>(Header.NestedTypesOffset, Header.NestedTypesSize, Header.NestedTypes);
GenericContainers = ReadMetadataArray<Il2CppGenericContainer>(Header.GenericContainersOffset, Header.GenericContainersSize, Header.GenericContainers);
GenericParameters = ReadMetadataArray<Il2CppGenericParameter>(Header.GenericParametersOffset, Header.GenericParametersSize, Header.GenericParameters);
GenericConstraintIndices = ReadMetadataPrimitiveArray<int>(Header.GenericParameterConstraintsOffset, Header.GenericParameterConstraintsSize, Header.GenericParameterConstraints);
InterfaceOffsets = ReadMetadataArray<Il2CppInterfaceOffsetPair>(Header.InterfaceOffsetsOffset, Header.InterfaceOffsetsSize, Header.InterfaceOffsets);
VTableMethodIndices = ReadMetadataPrimitiveArray<uint>(Header.VTableMethodsOffset, Header.VTableMethodsSize, Header.VtableMethods);
Types = ReadVersionedObjectArray<Il2CppTypeDefinition>(Header.TypeDefinitionsOffset, Header.TypeDefinitionsSize / Sizeof<Il2CppTypeDefinition>());
Methods = ReadVersionedObjectArray<Il2CppMethodDefinition>(Header.MethodsOffset, Header.MethodsSize / Sizeof<Il2CppMethodDefinition>());
Params = ReadVersionedObjectArray<Il2CppParameterDefinition>(Header.ParametersOffset, Header.ParametersSize / Sizeof<Il2CppParameterDefinition>());
Fields = ReadVersionedObjectArray<Il2CppFieldDefinition>(Header.FieldsOffset, Header.FieldsSize / Sizeof<Il2CppFieldDefinition>());
FieldDefaultValues = ReadVersionedObjectArray<Il2CppFieldDefaultValue>(Header.FieldDefaultValuesOffset, Header.FieldDefaultValuesSize / Sizeof<Il2CppFieldDefaultValue>());
Properties = ReadVersionedObjectArray<Il2CppPropertyDefinition>(Header.PropertiesOffset, Header.PropertiesSize / Sizeof<Il2CppPropertyDefinition>());
Events = ReadVersionedObjectArray<Il2CppEventDefinition>(Header.EventsOffset, Header.EventsSize / Sizeof<Il2CppEventDefinition>());
InterfaceUsageIndices = ReadPrimitiveArray<int>(Header.InterfacesOffset, Header.InterfacesSize / sizeof(int));
NestedTypeIndices = ReadPrimitiveArray<int>(Header.NestedTypesOffset, Header.NestedTypesSize / sizeof(int));
GenericContainers = ReadVersionedObjectArray<Il2CppGenericContainer>(Header.GenericContainersOffset, Header.GenericContainersSize / Sizeof<Il2CppGenericContainer>());
GenericParameters = ReadVersionedObjectArray<Il2CppGenericParameter>(Header.GenericParametersOffset, Header.GenericParametersSize / Sizeof<Il2CppGenericParameter>());
GenericConstraintIndices = ReadPrimitiveArray<int>(Header.GenericParameterConstraintsOffset, Header.GenericParameterConstraintsSize / sizeof(int));
InterfaceOffsets = ReadVersionedObjectArray<Il2CppInterfaceOffsetPair>(Header.InterfaceOffsetsOffset, Header.InterfaceOffsetsSize / Sizeof<Il2CppInterfaceOffsetPair>());
VTableMethodIndices = ReadPrimitiveArray<uint>(Header.VTableMethodsOffset, Header.VTableMethodsSize / sizeof(uint));
if (Version >= MetadataVersions.V160)
{
if (Version >= MetadataVersions.V160) {
// In v24.4 hashValueIndex was removed from Il2CppAssemblyNameDefinition, which is a field in Il2CppAssemblyDefinition
// The number of images and assemblies should be the same. If they are not, we deduce that we are using v24.4
// Note the version comparison matches both 24.2 and 24.3 here since 24.3 is tested for during binary loading
@@ -224,39 +167,32 @@ namespace Il2CppInspector
{
if (Version == MetadataVersions.V241)
changedAssemblyDefStruct = true;
Version = MetadataVersions.V244;
}
Assemblies = ReadMetadataArray<Il2CppAssemblyDefinition>(Header.AssembliesOffset, Header.AssembliesSize, Header.Assemblies);
Assemblies = ReadVersionedObjectArray<Il2CppAssemblyDefinition>(Header.AssembliesOffset, Images.Length);
if (changedAssemblyDefStruct)
Version = MetadataVersions.V241;
ParameterDefaultValues = ReadMetadataArray<Il2CppParameterDefaultValue>(Header.ParameterDefaultValuesOffset, Header.ParameterDefaultValuesSize, Header.ParameterDefaultValues);
ParameterDefaultValues = ReadVersionedObjectArray<Il2CppParameterDefaultValue>(Header.ParameterDefaultValuesOffset, Header.ParameterDefaultValuesSize / Sizeof<Il2CppParameterDefaultValue>());
}
if (Version >= MetadataVersions.V190 && Version < MetadataVersions.V270)
{
MetadataUsageLists = ReadMetadataArray<Il2CppMetadataUsageList>(Header.MetadataUsageListsOffset, Header.MetadataUsageListsCount, default);
MetadataUsagePairs = ReadMetadataArray<Il2CppMetadataUsagePair>(Header.MetadataUsagePairsOffset, Header.MetadataUsagePairsCount, default);
if (Version >= MetadataVersions.V190 && Version < MetadataVersions.V270) {
MetadataUsageLists = ReadVersionedObjectArray<Il2CppMetadataUsageList>(Header.MetadataUsageListsOffset, Header.MetadataUsageListsCount / Sizeof<Il2CppMetadataUsageList>());
MetadataUsagePairs = ReadVersionedObjectArray<Il2CppMetadataUsagePair>(Header.MetadataUsagePairsOffset, Header.MetadataUsagePairsCount / Sizeof<Il2CppMetadataUsagePair>());
}
if (Version >= MetadataVersions.V190)
{
FieldRefs = ReadMetadataArray<Il2CppFieldRef>(Header.FieldRefsOffset, Header.FieldRefsSize, Header.FieldRefs);
if (Version >= MetadataVersions.V190) {
FieldRefs = ReadVersionedObjectArray<Il2CppFieldRef>(Header.FieldRefsOffset, Header.FieldRefsSize / Sizeof<Il2CppFieldRef>());
}
if (Version >= MetadataVersions.V210 && Version < MetadataVersions.V290)
{
AttributeTypeIndices = ReadMetadataPrimitiveArray<int>(Header.AttributesTypesOffset, Header.AttributesTypesCount, default);
AttributeTypeRanges = ReadMetadataArray<Il2CppCustomAttributeTypeRange>(Header.AttributesInfoOffset, Header.AttributesInfoCount, default);
if (Version >= MetadataVersions.V210 && Version < MetadataVersions.V290) {
AttributeTypeIndices = ReadPrimitiveArray<int>(Header.AttributesTypesOffset, Header.AttributesTypesCount / sizeof(int));
AttributeTypeRanges = ReadVersionedObjectArray<Il2CppCustomAttributeTypeRange>(Header.AttributesInfoOffset, Header.AttributesInfoCount / Sizeof<Il2CppCustomAttributeTypeRange>());
}
if (Version >= MetadataVersions.V290)
{
AttributeDataRanges = ReadMetadataArray<Il2CppCustomAttributeDataRange>(Header.AttributeDataRangeOffset,
Header.AttributeDataRangeSize, Header.AttributeDataRanges);
AttributeDataRanges = ReadVersionedObjectArray<Il2CppCustomAttributeDataRange>(Header.AttributeDataRangeOffset,
Header.AttributeDataRangeSize / Sizeof<Il2CppCustomAttributeDataRange>());
}
// Get all metadata strings
@@ -265,17 +201,10 @@ namespace Il2CppInspector
Strings = pluginGetStringsResult.Strings;
else {
var stringOffset = Version >= MetadataVersions.V380
? Header.Strings.Offset
: Header.StringOffset;
var stringLength = Version >= MetadataVersions.V380
? Header.Strings.SectionSize
: Header.StringSize;
Position = Header.StringOffset;
Position = stringOffset;
while (Position < stringOffset + stringLength)
Strings.Add((int)Position - stringOffset, ReadNullTerminatedString());
while (Position < Header.StringOffset + Header.StringSize)
Strings.Add((int) Position - Header.StringOffset, ReadNullTerminatedString());
}
// Get all string literals
@@ -283,65 +212,40 @@ namespace Il2CppInspector
if (pluginGetStringLiteralsResult.IsDataModified)
StringLiterals = pluginGetStringLiteralsResult.StringLiterals.ToArray();
else
{
var stringLiteralList = ReadMetadataArray<Il2CppStringLiteral>(Header.StringLiteralOffset,
Header.StringLiteralSize, Header.StringLiterals);
var dataOffset = Version >= MetadataVersions.V380
? Header.StringLiteralData.Offset
: Header.StringLiteralDataOffset;
else {
var stringLiteralList = ReadVersionedObjectArray<Il2CppStringLiteral>(Header.StringLiteralOffset, Header.StringLiteralSize / Sizeof<Il2CppStringLiteral>());
if (Version >= MetadataVersions.V350)
{
var literals = new string[stringLiteralList.Length - 1];
for (var i = 0; i < literals.Length; i++)
StringLiterals = new string[stringLiteralList.Length - 1];
for (var i = 0; i < stringLiteralList.Length; i++)
{
var currentStringDataIndex = stringLiteralList[i].DataIndex;
var nextStringDataIndex = stringLiteralList[i + 1].DataIndex;
var stringLength = nextStringDataIndex - currentStringDataIndex;
literals[i] = ReadFixedLengthString(dataOffset + currentStringDataIndex, stringLength);
StringLiterals[i] = ReadFixedLengthString(Header.StringLiteralDataOffset + currentStringDataIndex, stringLength);
}
StringLiterals = literals;
}
else
{
StringLiterals = new string[stringLiteralList.Length];
for (var i = 0; i < stringLiteralList.Length; i++)
StringLiterals[i] = ReadFixedLengthString(dataOffset + stringLiteralList[i].DataIndex,
(int)stringLiteralList[i].Length);
StringLiterals[i] = ReadFixedLengthString(Header.StringLiteralDataOffset + stringLiteralList[i].DataIndex, (int)stringLiteralList[i].Length);
}
}
// Post-processing hook
IsModified |= PluginHooks.PostProcessMetadata(this).IsStreamModified;
return;
}
public ImmutableArray<T> ReadMetadataPrimitiveArray<T>(int oldOffset, int oldSize, Il2CppSectionMetadata newMetadata)
where T : unmanaged
{
return Version >= MetadataVersions.V380
? ReadPrimitiveArray<T>(newMetadata.Offset, newMetadata.Count)
: ReadPrimitiveArray<T>(oldOffset, oldSize / Unsafe.SizeOf<T>());
}
public ImmutableArray<T> ReadMetadataArray<T>(int oldOffset, int oldSize, Il2CppSectionMetadata newMetadata)
where T : IReadable, new()
{
return Version >= MetadataVersions.V380
? ReadVersionedObjectArray<T>(newMetadata.Offset, newMetadata.Count)
: ReadVersionedObjectArray<T>(oldOffset, oldSize / Sizeof<T>());
}
// Save metadata to file, overwriting if necessary
public void SaveToFile(string pathname) {
Position = 0;
using var outFile = new FileStream(pathname, FileMode.Create, FileAccess.Write);
CopyTo(outFile);
using (var outFile = new FileStream(pathname, FileMode.Create, FileAccess.Write))
CopyTo(outFile);
}
public int Sizeof<T>() where T : IReadable => T.Size(Version, Is32Bit);

View File

@@ -1,45 +0,0 @@
using VersionedSerialization;
namespace Il2CppInspector.Next.Metadata;
public struct GenericContainerIndex(int value) : IIndexType<GenericContainerIndex>, IReadable, IEquatable<GenericContainerIndex>
{
public const string TagPrefix = nameof(GenericContainerIndex);
static string IIndexType<GenericContainerIndex>.TagPrefix => TagPrefix;
static StructVersion IIndexType<GenericContainerIndex>.AddedVersion => MetadataVersions.V390;
private int _value = value;
public static int Size(in StructVersion version = default, bool is32Bit = false)
=> IIndexType<GenericContainerIndex>.IndexSize(version, is32Bit);
public void Read<TReader>(ref TReader reader, in StructVersion version = default) where TReader : IReader, allows ref struct
{
_value = IIndexType<GenericContainerIndex>.ReadIndex(ref reader, in version);
}
#region Operators + ToString
public static implicit operator int(GenericContainerIndex idx) => idx._value;
public static implicit operator GenericContainerIndex(int idx) => new(idx);
public static bool operator ==(GenericContainerIndex left, GenericContainerIndex right)
=> left._value == right._value;
public static bool operator !=(GenericContainerIndex left, GenericContainerIndex right)
=> !(left == right);
public readonly override bool Equals(object obj)
=> obj is GenericContainerIndex other && Equals(other);
public readonly bool Equals(GenericContainerIndex other)
=> this == other;
public readonly override int GetHashCode()
=> HashCode.Combine(_value);
public readonly override string ToString() => _value.ToString();
#endregion
}

View File

@@ -1,55 +0,0 @@
using VersionedSerialization;
namespace Il2CppInspector.Next.Metadata;
public interface IIndexType<T> where T
: IIndexType<T>, allows ref struct
{
public static abstract string TagPrefix { get; }
public static abstract StructVersion AddedVersion { get; }
private static string TagSize4 => $"{T.TagPrefix}4";
private static string TagSize2 => $"{T.TagPrefix}2";
private static string TagSize1 => $"{T.TagPrefix}1";
private static bool HasCustomSize(in StructVersion version)
=> version >= T.AddedVersion
&& version.Tag != null
&& version.Tag.Contains(T.TagPrefix)
&& !version.Tag.Contains(TagSize4);
public static int IndexSize(in StructVersion version = default, bool is32Bit = false)
{
if (version.Tag != null && HasCustomSize(version))
{
if (version.Tag.Contains(TagSize2))
return sizeof(ushort);
if (version.Tag.Contains(TagSize1))
return sizeof(byte);
}
return sizeof(int);
}
public static int ReadIndex<TReader>(ref TReader reader, in StructVersion version = default) where TReader : IReader, allows ref struct
{
if (version.Tag != null && HasCustomSize(version))
{
if (version.Tag.Contains(TagSize2))
{
var value = reader.ReadPrimitive<ushort>();
return value == ushort.MaxValue ? -1 : value;
}
if (version.Tag.Contains(TagSize1))
{
var value = reader.ReadPrimitive<byte>();
return value == byte.MaxValue ? -1 : value;
}
}
return reader.ReadPrimitive<int>();
}
}

View File

@@ -20,10 +20,6 @@ public partial record struct Il2CppAssemblyDefinition
[VersionCondition(GreaterThan = "24.1")]
public uint Token;
[FieldOffset(20 + 52)]
[VersionCondition(GreaterThan = "38.0")]
public uint ModuleToken;
[FieldOffset(8)]
[VersionCondition(LessThan = "24.0")]
public int CustomAttributeIndex;

View File

@@ -1,6 +1,7 @@
namespace Il2CppInspector.Next.Metadata;
using StringIndex = int;
using TypeIndex = int;
using MethodIndex = int;
using VersionedSerialization.Attributes;

View File

@@ -3,6 +3,7 @@
namespace Il2CppInspector.Next.Metadata;
using FieldIndex = int;
using TypeIndex = int;
using DefaultValueDataIndex = int;
[VersionedStruct]

View File

@@ -2,6 +2,7 @@
using VersionedSerialization.Attributes;
using StringIndex = int;
using TypeIndex = int;
[VersionedStruct]
public partial record struct Il2CppFieldDefinition

View File

@@ -2,6 +2,7 @@
using VersionedSerialization.Attributes;
using FieldIndex = int;
using TypeIndex = int;
[VersionedStruct]
public partial record struct Il2CppFieldMarshaledSize

View File

@@ -3,6 +3,7 @@
namespace Il2CppInspector.Next.Metadata;
using FieldIndex = int;
using TypeIndex = int;
[VersionedStruct]
public partial record struct Il2CppFieldRef

View File

@@ -3,6 +3,7 @@ using VersionedSerialization.Attributes;
namespace Il2CppInspector.Next.Metadata;
using GenericContainerIndex = int;
using StringIndex = int;
using GenericParameterConstraintIndex = short;

View File

@@ -29,127 +29,55 @@ public partial record struct Il2CppGlobalMetadataHeader
{
public int Sanity { get; private set; }
public int Version { get; private set; }
[VersionCondition(LessThan = "35.0")]
public int StringLiteralOffset { get; private set; }
[VersionCondition(LessThan = "35.0")]
public int StringLiteralSize { get; private set; }
[VersionCondition(LessThan = "35.0")]
public int StringLiteralDataOffset { get; private set; }
[VersionCondition(LessThan = "35.0")]
public int StringLiteralDataSize { get; private set; }
[VersionCondition(LessThan = "35.0")]
public int StringOffset { get; private set; }
[VersionCondition(LessThan = "35.0")]
public int StringSize { get; private set; }
[VersionCondition(LessThan = "35.0")]
public int EventsOffset { get; private set; }
[VersionCondition(LessThan = "35.0")]
public int EventsSize { get; private set; }
[VersionCondition(LessThan = "35.0")]
public int PropertiesOffset { get; private set; }
[VersionCondition(LessThan = "35.0")]
public int PropertiesSize { get; private set; }
[VersionCondition(LessThan = "35.0")]
public int MethodsOffset { get; private set; }
[VersionCondition(LessThan = "35.0")]
public int MethodsSize { get; private set; }
[VersionCondition(GreaterThan = "16.0", LessThan = "35.0")]
[VersionCondition(GreaterThan = "16.0")]
[VersionCondition(EqualTo = "16.0")]
public int ParameterDefaultValuesOffset { get; private set; }
[VersionCondition(GreaterThan = "16.0", LessThan = "35.0")]
[VersionCondition(GreaterThan = "16.0")]
[VersionCondition(EqualTo = "16.0")]
public int ParameterDefaultValuesSize { get; private set; }
[VersionCondition(LessThan = "35.0")]
public int FieldDefaultValuesOffset { get; private set; }
[VersionCondition(LessThan = "35.0")]
public int FieldDefaultValuesSize { get; private set; }
[VersionCondition(LessThan = "35.0")]
public int FieldAndParameterDefaultValueDataOffset { get; private set; }
[VersionCondition(LessThan = "35.0")]
public int FieldAndParameterDefaultValueDataSize { get; private set; }
[VersionCondition(GreaterThan = "16.0", LessThan = "35.0")]
[VersionCondition(GreaterThan = "16.0")]
public int FieldMarshaledSizesOffset { get; private set; }
[VersionCondition(GreaterThan = "16.0", LessThan = "35.0")]
[VersionCondition(GreaterThan = "16.0")]
public int FieldMarshaledSizesSize { get; private set; }
[VersionCondition(LessThan = "35.0")]
public int ParametersOffset { get; private set; }
[VersionCondition(LessThan = "35.0")]
public int ParametersSize { get; private set; }
[VersionCondition(LessThan = "35.0")]
public int FieldsOffset { get; private set; }
[VersionCondition(LessThan = "35.0")]
public int FieldsSize { get; private set; }
[VersionCondition(LessThan = "35.0")]
public int GenericParametersOffset { get; private set; }
[VersionCondition(LessThan = "35.0")]
public int GenericParametersSize { get; private set; }
[VersionCondition(LessThan = "35.0")]
public int GenericParameterConstraintsOffset { get; private set; }
[VersionCondition(LessThan = "35.0")]
public int GenericParameterConstraintsSize { get; private set; }
[VersionCondition(LessThan = "35.0")]
public int GenericContainersOffset { get; private set; }
[VersionCondition(LessThan = "35.0")]
public int GenericContainersSize { get; private set; }
[VersionCondition(LessThan = "35.0")]
public int NestedTypesOffset { get; private set; }
[VersionCondition(LessThan = "35.0")]
public int NestedTypesSize { get; private set; }
[VersionCondition(LessThan = "35.0")]
public int InterfacesOffset { get; private set; }
[VersionCondition(LessThan = "35.0")]
public int InterfacesSize { get; private set; }
[VersionCondition(LessThan = "35.0")]
public int VTableMethodsOffset { get; private set; }
[VersionCondition(LessThan = "35.0")]
public int VTableMethodsSize { get; private set; }
[VersionCondition(LessThan = "35.0")]
public int InterfaceOffsetsOffset { get; private set; }
[VersionCondition(LessThan = "35.0")]
public int InterfaceOffsetsSize { get; private set; }
[VersionCondition(LessThan = "35.0")]
public int TypeDefinitionsOffset { get; private set; }
[VersionCondition(LessThan = "35.0")]
public int TypeDefinitionsSize { get; private set; }
[VersionCondition(LessThan = "24.1")]
@@ -158,16 +86,16 @@ public partial record struct Il2CppGlobalMetadataHeader
[VersionCondition(LessThan = "24.1")]
public int RgctxEntriesCount { get; private set; }
[VersionCondition(GreaterThan = "16.0", LessThan = "35.0")]
[VersionCondition(GreaterThan = "16.0")]
public int ImagesOffset { get; private set; }
[VersionCondition(GreaterThan = "16.0", LessThan = "35.0")]
[VersionCondition(GreaterThan = "16.0")]
public int ImagesSize { get; private set; }
[VersionCondition(GreaterThan = "16.0", LessThan = "35.0")]
[VersionCondition(GreaterThan = "16.0")]
public int AssembliesOffset { get; private set; }
[VersionCondition(GreaterThan = "16.0", LessThan = "35.0")]
[VersionCondition(GreaterThan = "16.0")]
public int AssembliesSize { get; private set; }
[VersionCondition(GreaterThan = "19.0", LessThan = "24.5")]
@@ -182,16 +110,16 @@ public partial record struct Il2CppGlobalMetadataHeader
[VersionCondition(GreaterThan = "19.0", LessThan = "24.5")]
public int MetadataUsagePairsCount { get; private set; }
[VersionCondition(GreaterThan = "19.0", LessThan = "35.0")]
[VersionCondition(GreaterThan = "19.0")]
public int FieldRefsOffset { get; private set; }
[VersionCondition(GreaterThan = "19.0", LessThan = "35.0")]
[VersionCondition(GreaterThan = "19.0")]
public int FieldRefsSize { get; private set; }
[VersionCondition(GreaterThan = "20.0", LessThan = "35.0")]
[VersionCondition(GreaterThan = "20.0")]
public int ReferencedAssembliesOffset { get; private set; }
[VersionCondition(GreaterThan = "20.0", LessThan = "35.0")]
[VersionCondition(GreaterThan = "20.0")]
public int ReferencedAssembliesSize { get; private set; }
[VersionCondition(GreaterThan = "21.0", LessThan = "27.2")]
@@ -206,143 +134,48 @@ public partial record struct Il2CppGlobalMetadataHeader
[VersionCondition(GreaterThan = "21.0", LessThan = "27.2")]
public int AttributesTypesCount { get; private set; }
[VersionCondition(GreaterThan = "29.0", LessThan = "35.0")]
[VersionCondition(GreaterThan = "29.0")]
public int AttributeDataOffset { get; private set; }
[VersionCondition(GreaterThan = "29.0", LessThan = "35.0")]
[VersionCondition(GreaterThan = "29.0")]
public int AttributeDataSize { get; private set; }
[VersionCondition(GreaterThan = "29.0", LessThan = "35.0")]
[VersionCondition(GreaterThan = "29.0")]
public int AttributeDataRangeOffset { get; private set; }
[VersionCondition(GreaterThan = "29.0", LessThan = "35.0")]
[VersionCondition(GreaterThan = "29.0")]
public int AttributeDataRangeSize { get; private set; }
[VersionCondition(GreaterThan = "22.0", LessThan = "35.0")]
[VersionCondition(GreaterThan = "22.0")]
public int UnresolvedIndirectCallParameterTypesOffset { get; private set; }
[VersionCondition(GreaterThan = "22.0", LessThan = "35.0")]
[VersionCondition(GreaterThan = "22.0")]
public int UnresolvedIndirectCallParameterTypesSize { get; private set; }
[VersionCondition(GreaterThan = "22.0", LessThan = "35.0")]
[VersionCondition(GreaterThan = "22.0")]
public int UnresolvedIndirectCallParameterRangesOffset { get; private set; }
[VersionCondition(GreaterThan = "22.0", LessThan = "35.0")]
[VersionCondition(GreaterThan = "22.0")]
public int UnresolvedIndirectCallParameterRangesSize { get; private set; }
[VersionCondition(GreaterThan = "23.0", LessThan = "35.0")]
[VersionCondition(GreaterThan = "23.0")]
public int WindowsRuntimeTypeNamesOffset { get; private set; }
[VersionCondition(GreaterThan = "23.0", LessThan = "35.0")]
[VersionCondition(GreaterThan = "23.0")]
public int WindowsRuntimeTypeNamesSize { get; private set; }
[VersionCondition(GreaterThan = "27.0", LessThan = "35.0")]
[VersionCondition(GreaterThan = "27.0")]
public int WindowsRuntimeStringsOffset { get; private set; }
[VersionCondition(GreaterThan = "27.0", LessThan = "35.0")]
[VersionCondition(GreaterThan = "27.0")]
public int WindowsRuntimeStringsSize { get; private set; }
[VersionCondition(GreaterThan = "24.0", LessThan = "35.0")]
[VersionCondition(GreaterThan = "24.0")]
public int ExportedTypeDefinitionsOffset { get; private set; }
[VersionCondition(GreaterThan = "24.0", LessThan = "35.0")]
[VersionCondition(GreaterThan = "24.0")]
public int ExportedTypeDefinitionsSize { get; private set; }
// new, v38 metadata sections
[VersionCondition(GreaterThan = "38.0")]
public Il2CppSectionMetadata StringLiterals { get; private set; }
[VersionCondition(GreaterThan = "38.0")]
public Il2CppSectionMetadata StringLiteralData { get; private set; }
[VersionCondition(GreaterThan = "38.0")]
public Il2CppSectionMetadata Strings { get; private set; }
[VersionCondition(GreaterThan = "38.0")]
public Il2CppSectionMetadata Events { get; private set; }
[VersionCondition(GreaterThan = "38.0")]
public Il2CppSectionMetadata Properties { get; private set; }
[VersionCondition(GreaterThan = "38.0")]
public Il2CppSectionMetadata Methods { get; private set; }
[VersionCondition(GreaterThan = "38.0")]
public Il2CppSectionMetadata ParameterDefaultValues { get; private set; }
[VersionCondition(GreaterThan = "38.0")]
public Il2CppSectionMetadata FieldDefaultValues { get; private set; }
[VersionCondition(GreaterThan = "38.0")]
public Il2CppSectionMetadata FieldAndParameterDefaultValueData { get; private set; }
[VersionCondition(GreaterThan = "38.0")]
public Il2CppSectionMetadata FieldMarshaledSizes { get; private set; }
[VersionCondition(GreaterThan = "38.0")]
public Il2CppSectionMetadata Parameters { get; private set; }
[VersionCondition(GreaterThan = "38.0")]
public Il2CppSectionMetadata Fields { get; private set; }
[VersionCondition(GreaterThan = "38.0")]
public Il2CppSectionMetadata GenericParameters { get; private set; }
[VersionCondition(GreaterThan = "38.0")]
public Il2CppSectionMetadata GenericParameterConstraints { get; private set; }
[VersionCondition(GreaterThan = "38.0")]
public Il2CppSectionMetadata GenericContainers { get; private set; }
[VersionCondition(GreaterThan = "38.0")]
public Il2CppSectionMetadata NestedTypes { get; private set; }
[VersionCondition(GreaterThan = "38.0")]
public Il2CppSectionMetadata Interfaces { get; private set; }
[VersionCondition(GreaterThan = "38.0")]
public Il2CppSectionMetadata VtableMethods { get; private set; }
[VersionCondition(GreaterThan = "38.0")]
public Il2CppSectionMetadata InterfaceOffsets { get; private set; }
[VersionCondition(GreaterThan = "38.0")]
public Il2CppSectionMetadata TypeDefinitions { get; private set; }
[VersionCondition(GreaterThan = "38.0")]
public Il2CppSectionMetadata Images { get; private set; }
[VersionCondition(GreaterThan = "38.0")]
public Il2CppSectionMetadata Assemblies { get; private set; }
[VersionCondition(GreaterThan = "38.0")]
public Il2CppSectionMetadata FieldRefs { get; private set; }
[VersionCondition(GreaterThan = "38.0")]
public Il2CppSectionMetadata ReferencedAssemblies { get; private set; }
[VersionCondition(GreaterThan = "38.0")]
public Il2CppSectionMetadata AttributeData { get; private set; }
[VersionCondition(GreaterThan = "38.0")]
public Il2CppSectionMetadata AttributeDataRanges { get; private set; }
[VersionCondition(GreaterThan = "38.0")]
public Il2CppSectionMetadata UnresolvedIndirectCallParameterTypes { get; private set; }
[VersionCondition(GreaterThan = "38.0")]
public Il2CppSectionMetadata UnresolvedIndirectCallParameterRanges { get; private set; }
[VersionCondition(GreaterThan = "38.0")]
public Il2CppSectionMetadata WindowsRuntimeTypeNames { get; private set; }
[VersionCondition(GreaterThan = "38.0")]
public Il2CppSectionMetadata WindowsRuntimeStrings { get; private set; }
[VersionCondition(GreaterThan = "38.0")]
public Il2CppSectionMetadata ExportedTypeDefinitions { get; private set; }
public const int ExpectedSanity = unchecked((int)0xFAB11BAF);
public readonly bool SanityValid => Sanity == ExpectedSanity;

View File

@@ -2,6 +2,7 @@
using StringIndex = int;
using AssemblyIndex = int;
using TypeDefinitionIndex = int;
using MethodIndex = int;
using CustomAttributeIndex = int;
using VersionedSerialization.Attributes;

View File

@@ -2,6 +2,8 @@
namespace Il2CppInspector.Next.Metadata;
using TypeIndex = int;
[VersionedStruct]
public partial record struct Il2CppInterfaceOffsetPair
{

View File

@@ -4,6 +4,10 @@ using VersionedSerialization.Attributes;
namespace Il2CppInspector.Next.Metadata;
using StringIndex = int;
using TypeDefinitionIndex = int;
using TypeIndex = int;
using ParameterIndex = int;
using GenericContainerIndex = int;
[VersionedStruct]
public partial record struct Il2CppMethodDefinition

View File

@@ -1,5 +1,7 @@
namespace Il2CppInspector.Next.Metadata;
using ParameterIndex = int;
using TypeIndex = int;
using DefaultValueDataIndex = int;
using VersionedSerialization.Attributes;

View File

@@ -2,6 +2,7 @@
using VersionedSerialization.Attributes;
using StringIndex = int;
using TypeIndex = int;
[VersionedStruct]
public partial record struct Il2CppParameterDefinition

View File

@@ -1,11 +0,0 @@
using VersionedSerialization.Attributes;
namespace Il2CppInspector.Next.Metadata;
[VersionedStruct]
public partial record struct Il2CppSectionMetadata
{
public int Offset { get; private set; }
public int SectionSize { get; private set; }
public int Count { get; private set; }
}

View File

@@ -5,6 +5,8 @@ using VersionedSerialization.Attributes;
namespace Il2CppInspector.Next.Metadata;
using StringIndex = int;
using TypeIndex = int;
using GenericContainerIndex = int;
using FieldIndex = int;
using MethodIndex = int;
using EventIndex = int;
@@ -16,7 +18,7 @@ using VTableIndex = int;
[VersionedStruct]
public partial record struct Il2CppTypeDefinition
{
public static readonly TypeIndex InvalidTypeIndex = -1;
public const TypeIndex InvalidTypeIndex = -1;
public StringIndex NameIndex { get; private set; }
public StringIndex NamespaceIndex { get; private set; }

View File

@@ -2,6 +2,7 @@
using VersionedSerialization.Attributes;
using StringIndex = int;
using TypeIndex = int;
[VersionedStruct]
public partial record struct Il2CppWindowsRuntimeTypeNamePair

View File

@@ -1,46 +0,0 @@
using NoisyCowStudios.Bin2Object;
using VersionedSerialization;
namespace Il2CppInspector.Next.Metadata;
public struct ParameterIndex(int value) : IIndexType<ParameterIndex>, IReadable, IEquatable<ParameterIndex>
{
public const string TagPrefix = nameof(ParameterIndex);
static string IIndexType<ParameterIndex>.TagPrefix => TagPrefix;
static StructVersion IIndexType<ParameterIndex>.AddedVersion => MetadataVersions.V390;
private int _value = value;
public static int Size(in StructVersion version = default, bool is32Bit = false)
=> IIndexType<ParameterIndex>.IndexSize(version, is32Bit);
public void Read<TReader>(ref TReader reader, in StructVersion version = default) where TReader : IReader, allows ref struct
{
_value = IIndexType<ParameterIndex>.ReadIndex(ref reader, in version);
}
#region Operators + ToString
public static implicit operator int(ParameterIndex idx) => idx._value;
public static implicit operator ParameterIndex(int idx) => new(idx);
public static bool operator ==(ParameterIndex left, ParameterIndex right)
=> left._value == right._value;
public static bool operator !=(ParameterIndex left, ParameterIndex right)
=> !(left == right);
public readonly override bool Equals(object obj)
=> obj is ParameterIndex other && Equals(other);
public readonly bool Equals(ParameterIndex other)
=> this == other;
public readonly override int GetHashCode()
=> HashCode.Combine(_value);
public readonly override string ToString() => _value.ToString();
#endregion
}

View File

@@ -1,45 +0,0 @@
using VersionedSerialization;
namespace Il2CppInspector.Next.Metadata;
public struct TypeDefinitionIndex(int value) : IIndexType<TypeDefinitionIndex>, IReadable, IEquatable<TypeDefinitionIndex>
{
public const string TagPrefix = nameof(TypeDefinitionIndex);
static string IIndexType<TypeDefinitionIndex>.TagPrefix => TagPrefix;
static StructVersion IIndexType<TypeDefinitionIndex>.AddedVersion => MetadataVersions.V390;
private int _value = value;
public static int Size(in StructVersion version = default, bool is32Bit = false)
=> IIndexType<TypeDefinitionIndex>.IndexSize(version, is32Bit);
public void Read<TReader>(ref TReader reader, in StructVersion version = default) where TReader : IReader, allows ref struct
{
_value = IIndexType<TypeDefinitionIndex>.ReadIndex(ref reader, in version);
}
#region Operators + ToString
public static implicit operator int(TypeDefinitionIndex idx) => idx._value;
public static implicit operator TypeDefinitionIndex(int idx) => new(idx);
public static bool operator ==(TypeDefinitionIndex left, TypeDefinitionIndex right)
=> left._value == right._value;
public static bool operator !=(TypeDefinitionIndex left, TypeDefinitionIndex right)
=> !(left == right);
public readonly override bool Equals(object obj)
=> obj is TypeDefinitionIndex other && Equals(other);
public readonly bool Equals(TypeDefinitionIndex other)
=> this == other;
public readonly override int GetHashCode()
=> HashCode.Combine(_value);
public readonly override string ToString() => _value.ToString();
#endregion
}

View File

@@ -1,45 +0,0 @@
using VersionedSerialization;
namespace Il2CppInspector.Next.Metadata;
public struct TypeIndex(int value) : IIndexType<TypeIndex>, IReadable, IEquatable<TypeIndex>
{
public const string TagPrefix = nameof(TypeIndex);
static string IIndexType<TypeIndex>.TagPrefix => TagPrefix;
static StructVersion IIndexType<TypeIndex>.AddedVersion => MetadataVersions.V390;
private int _value = value;
public static int Size(in StructVersion version = default, bool is32Bit = false)
=> IIndexType<TypeIndex>.IndexSize(version, is32Bit);
public void Read<TReader>(ref TReader reader, in StructVersion version = default) where TReader : IReader, allows ref struct
{
_value = IIndexType<TypeIndex>.ReadIndex(ref reader, in version);
}
#region Operators + ToString
public static implicit operator int(TypeIndex idx) => idx._value;
public static implicit operator TypeIndex(int idx) => new(idx);
public static bool operator ==(TypeIndex left, TypeIndex right)
=> left._value == right._value;
public static bool operator !=(TypeIndex left, TypeIndex right)
=> !(left == right);
public readonly override bool Equals(object obj)
=> obj is TypeIndex other && Equals(other);
public readonly bool Equals(TypeIndex other)
=> this == other;
public readonly override int GetHashCode()
=> HashCode.Combine(_value);
public readonly override string ToString() => _value.ToString();
#endregion
}

View File

@@ -31,12 +31,4 @@ public static class MetadataVersions
// Unity 6000.3.0a2
public static readonly StructVersion V350 = new(35);
// Unity 6000.3.0a5
public static readonly StructVersion V380 = new(38);
// NOTE: This version uses tags to specify the size of TypeIndex, TypeDefinitionIndex, and GenericContainerIndex.
// Unity 6000.3.0b1
public static readonly StructVersion V390 = new(39);
// NOTE This version additionally uses a tag to specify the size of ParameterIndex.
}

View File

@@ -298,10 +298,6 @@ namespace Il2CppInspector.Outputs
private PropertyDef AddProperty(ModuleDef module, TypeDef mType, PropertyInfo prop) {
PropertySig s;
// Example: ZstdSharp MEM_32Bit which gets inlined using weaving and all accessors removed
if (prop.GetMethod == null && prop.SetMethod == null)
return null;
// Static or instance
if (prop.GetMethod?.IsStatic ?? prop.SetMethod.IsStatic)
s = PropertySig.CreateStatic(GetTypeSig(module, prop.PropertyType));

View File

@@ -71,7 +71,7 @@ class BinaryNinjaDisassemblerInterface(BaseDisassemblerInterface):
self._type_cache[type] = parsed
return parsed
def _parse_type_source(self, types: str, filename: Union[str, None] = None):
def _parse_type_source(self, types: str, filename: str | None = None):
parsed_types, errors = TypeParser.default.parse_types_from_source(
types,
filename if filename else "types.hpp",
@@ -127,7 +127,7 @@ class BinaryNinjaDisassemblerInterface(BaseDisassemblerInterface):
self._view.set_analysis_hold(False)
self._view.update_analysis()
def define_function(self, address: int, end: Union[int, None] = None):
def define_function(self, address: int, end: int | None = None):
if self._view.get_function_at(address) is not None:
return

View File

@@ -51,7 +51,7 @@ class GhidraDisassemblerInterface(BaseDisassemblerInterface):
def on_finish(self):
pass
def define_function(self, address: int, end: Union[int, None] = None):
def define_function(self, address: int, end: int | None = None):
address = self._to_address(address)
# Don't override existing functions
fn = getFunctionAt(address)

View File

@@ -83,8 +83,8 @@ class IDADisassemblerInterface(BaseDisassemblerInterface):
ida_ida.inf_set_genflags(self._cached_genflags & ~ida_ida.INFFL_AUTO)
# Unload type libraries we know to cause issues - like the c++ linux one
PLATFORMS = ["x86", "x64", "arm", "arm64", "win7"]
PROBLEMATIC_TYPELIBS = ["gnulnx", "mssdk64"]
PLATFORMS = ["x86", "x64", "arm", "arm64"]
PROBLEMATIC_TYPELIBS = ["gnulnx"]
for lib in PROBLEMATIC_TYPELIBS:
for platform in PLATFORMS:
@@ -118,7 +118,7 @@ class IDADisassemblerInterface(BaseDisassemblerInterface):
def on_finish(self):
ida_ida.inf_set_genflags(self._cached_genflags)
def define_function(self, address: int, end: Union[int, None] = None):
def define_function(self, address: int, end: int | None = None):
if self._skip_function_creation:
return

View File

@@ -1,13 +1,9 @@
#@runtime PyGhidra
# ^-- required for ghidra, ignored by all others
# Generated script file by Il2CppInspectorRedux - https://github.com/LukeFZ (Original Il2CppInspector by http://www.djkaty.com - https://github.com/djkaty)
# Target Unity version: %TARGET_UNITY_VERSION%
import json
import os
from datetime import datetime
from typing import Union
import abc
class BaseStatusHandler(abc.ABC):
@@ -32,7 +28,7 @@ class BaseDisassemblerInterface(abc.ABC):
def on_finish(self): pass
@abc.abstractmethod
def define_function(self, address: int, end: Union[int, None] = None): pass
def define_function(self, address: int, end: int | None = None): pass
@abc.abstractmethod
def define_data_array(self, address: int, type: str, count: int): pass
@@ -112,7 +108,7 @@ class ScriptContext:
self._backend.set_data_name(addr, definition['name'])
self._backend.set_data_comment(addr, definition['string'])
def define_field(self, addr: str, name: str, type: str, il_type: Union[str, None] = None):
def define_field(self, addr: str, name: str, type: str, il_type: str | None = None):
address = self.from_hex(addr)
self._backend.set_data_type(address, type)
self._backend.set_data_name(address, name)

View File

@@ -118,8 +118,8 @@ namespace Il2CppInspector.Reflection
var range = pkg.Metadata.AttributeDataRanges[customAttributeIndex];
var next = pkg.Metadata.AttributeDataRanges[customAttributeIndex + 1];
var startOffset = (uint)pkg.Metadata.AttributeDataOffset + range.StartOffset;
var endOffset = (uint)pkg.Metadata.AttributeDataOffset + next.StartOffset;
var startOffset = (uint)pkg.Metadata.Header.AttributeDataOffset + range.StartOffset;
var endOffset = (uint)pkg.Metadata.Header.AttributeDataOffset + next.StartOffset;
var reader = new CustomAttributeDataReader(pkg, asm, pkg.Metadata, startOffset, endOffset);
if (reader.Count == 0)

View File

@@ -14,16 +14,16 @@
"license": "MIT",
"dependencies": {
"@microsoft/signalr": "^8.0.7",
"@tauri-apps/api": "^2.2.0",
"@tauri-apps/plugin-dialog": "~2.2.0",
"@tauri-apps/plugin-opener": "^2.2.5"
"@tauri-apps/api": "^2",
"@tauri-apps/plugin-dialog": "~2",
"@tauri-apps/plugin-opener": "^2"
},
"devDependencies": {
"@sveltejs/adapter-static": "^3.0.8",
"@sveltejs/kit": "^2.16.0",
"@sveltejs/vite-plugin-svelte": "^5.0.3",
"@sveltejs/adapter-static": "^3.0.6",
"@sveltejs/kit": "^2.9.0",
"@sveltejs/vite-plugin-svelte": "^5.0.0",
"@tailwindcss/typography": "^0.5.16",
"@tauri-apps/cli": "^2.2.5",
"@tauri-apps/cli": "^2",
"autoprefixer": "^10.4.20",
"bits-ui": "1.0.0-next.78",
"clsx": "^2.1.1",
@@ -32,15 +32,15 @@
"prettier": "^3.4.2",
"prettier-plugin-svelte": "^3.3.3",
"prettier-plugin-tailwindcss": "^0.6.10",
"svelte": "^5.19.0",
"svelte-check": "^4.1.4",
"svelte": "^5.0.0",
"svelte-check": "^4.0.0",
"svelte-sonner": "^0.3.28",
"tailwind-merge": "^2.6.0",
"tailwind-variants": "^0.3.1",
"tailwindcss": "^3.4.17",
"tailwindcss-animate": "^1.0.7",
"typescript": "~5.6.3",
"vite": "^6.0.7"
"typescript": "~5.6.2",
"vite": "^6.0.3"
},
"packageManager": "pnpm@10.0.0+sha512.b8fef5494bd3fe4cbd4edabd0745df2ee5be3e4b0b8b08fa643aa3e4c6702ccc0f00d68fa8a8c9858a735a0032485a44990ed2810526c875e416f001b17df12b"
}

View File

@@ -12,29 +12,29 @@ importers:
specifier: ^8.0.7
version: 8.0.7
'@tauri-apps/api':
specifier: ^2.2.0
specifier: ^2
version: 2.2.0
'@tauri-apps/plugin-dialog':
specifier: ~2.2.0
specifier: ~2
version: 2.2.0
'@tauri-apps/plugin-opener':
specifier: ^2.2.5
specifier: ^2
version: 2.2.5
devDependencies:
'@sveltejs/adapter-static':
specifier: ^3.0.8
specifier: ^3.0.6
version: 3.0.8(@sveltejs/kit@2.16.0(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.19.0)(vite@6.0.7(jiti@1.21.7)(yaml@2.7.0)))(svelte@5.19.0)(vite@6.0.7(jiti@1.21.7)(yaml@2.7.0)))
'@sveltejs/kit':
specifier: ^2.16.0
specifier: ^2.9.0
version: 2.16.0(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.19.0)(vite@6.0.7(jiti@1.21.7)(yaml@2.7.0)))(svelte@5.19.0)(vite@6.0.7(jiti@1.21.7)(yaml@2.7.0))
'@sveltejs/vite-plugin-svelte':
specifier: ^5.0.3
specifier: ^5.0.0
version: 5.0.3(svelte@5.19.0)(vite@6.0.7(jiti@1.21.7)(yaml@2.7.0))
'@tailwindcss/typography':
specifier: ^0.5.16
version: 0.5.16(tailwindcss@3.4.17)
'@tauri-apps/cli':
specifier: ^2.2.5
specifier: ^2
version: 2.2.5
autoprefixer:
specifier: ^10.4.20
@@ -61,10 +61,10 @@ importers:
specifier: ^0.6.10
version: 0.6.10(prettier-plugin-svelte@3.3.3(prettier@3.4.2)(svelte@5.19.0))(prettier@3.4.2)
svelte:
specifier: ^5.19.0
specifier: ^5.0.0
version: 5.19.0
svelte-check:
specifier: ^4.1.4
specifier: ^4.0.0
version: 4.1.4(svelte@5.19.0)(typescript@5.6.3)
svelte-sonner:
specifier: ^0.3.28
@@ -82,10 +82,10 @@ importers:
specifier: ^1.0.7
version: 1.0.7(tailwindcss@3.4.17)
typescript:
specifier: ~5.6.3
specifier: ~5.6.2
version: 5.6.3
vite:
specifier: ^6.0.7
specifier: ^6.0.3
version: 6.0.7(jiti@1.21.7)(yaml@2.7.0)
packages:
@@ -600,8 +600,8 @@ packages:
resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==}
engines: {node: '>= 6'}
caniuse-lite@1.0.30001737:
resolution: {integrity: sha512-BiloLiXtQNrY5UyF0+1nSJLXUENuhka2pzy2Fx5pGxqavdrxSCW4U6Pn/PoG3Efspi2frRbHpBV2XsrPE6EDlw==}
caniuse-lite@1.0.30001695:
resolution: {integrity: sha512-vHyLade6wTgI2u1ec3WQBxv+2BrTERV28UXQu9LO6lZ9pYeMk34vjXFLOxo1A4UBA8XTL4njRQZdno/yYaSmWw==}
chokidar@3.6.0:
resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==}
@@ -1681,7 +1681,7 @@ snapshots:
autoprefixer@10.4.20(postcss@8.5.1):
dependencies:
browserslist: 4.24.4
caniuse-lite: 1.0.30001737
caniuse-lite: 1.0.30001695
fraction.js: 4.3.7
normalize-range: 0.1.2
picocolors: 1.1.1
@@ -1714,14 +1714,14 @@ snapshots:
browserslist@4.24.4:
dependencies:
caniuse-lite: 1.0.30001737
caniuse-lite: 1.0.30001695
electron-to-chromium: 1.5.83
node-releases: 2.0.19
update-browserslist-db: 1.1.2(browserslist@4.24.4)
camelcase-css@2.0.1: {}
caniuse-lite@1.0.30001737: {}
caniuse-lite@1.0.30001695: {}
chokidar@3.6.0:
dependencies:

View File

@@ -13,7 +13,6 @@
<!-- todo: this needs to be adjusted for multiplatform support -->
<Target Name="BuildTauriFrontend" BeforeTargets="BeforeBuild" Condition="'$(Configuration)' == 'Release'">
<Exec Command="pnpm install" WorkingDirectory="..\Il2CppInspector.Redux.GUI.UI" />
<Exec Command="pnpm tauri build --no-bundle" WorkingDirectory="..\Il2CppInspector.Redux.GUI.UI" />
<ItemGroup>
<EmbeddedResource Include="..\Il2CppInspector.Redux.GUI.UI\src-tauri\target\release\il2cppinspectorredux.exe" />

View File

@@ -8,7 +8,7 @@ This is a continuation of [Il2CppInspector, by djkaty](https://github.com/djkaty
### Redux only features
* Support for metadata version 29/29.1/31/35/38, with full reconstruction of custom attributes
* Support for metadata version 29 and 29.1, with full reconstruction of custom attributes
* Proper extraction of static array initializer contents with their correct length
* Proper support for v27.2+ Il2CppType
* Fixed support for v24.5
@@ -28,17 +28,6 @@ This is a continuation of [Il2CppInspector, by djkaty](https://github.com/djkaty
- Addition of custom fake string segment to show string literal contents in decompiler
- A fake xref between MethodInfo instances and their corresponding method to quickly get the correct function
* Binary Ninja script output, with all of the IDA-exclusive features
* New cross-platform capable CLI and GUIs with dark mode support, providing the same output formats.
> [!NOTE]
> As not all of the old UI features are implemented in the new UIs yet,
> the old ones are still built by GitHub Actions and available in the releases with the `Old` suffix.
> [!IMPORTANT]
> The below README is still largely based on the original Il2CppInspector documentation,
> and may not reflect all of the changes/differences in Il2CppInspectorRedux.
> Notably, it still features the old UIs and not the new Redux ones,
> among others that have been removed in Redux.
### Main features
@@ -332,9 +321,9 @@ The `--seperate-attributes` switch directs Il2CppInspector to put assembly-level
### Adding metadata to your IDA workflow
**NOTE:** IDA 7.6+ is required, but 7.7 is recommended. You also need to use Python 3.8+ to be able to run the script.
**NOTE:** IDA 7.6+ is required, but 7.7 is recommended.
**NOTE:** Run script as-soon-as-possible after IDA loads binary into database!
**NOTE:** Run script as-soon-as-possible after IDA loads binary into database
Simply run Il2CppInspector with the `-p` switch to choose the IDA script output file. Load your binary file into IDA, press Alt+F7 and select the generated script. Observe the Output Window while IDA analyzes the file - this may take a long time.
@@ -767,8 +756,7 @@ Unity version | IL2CPP version | Support
2021.2.0-2021.2.x | 29 | Working
2021.3.0-??? | 29.1 | Working
2022.3.33-6000.2.x | 31(.1) | Working
6000.3.0a2 | 35 | Working
6000.3.0a5 | 38 | Working
6000.3.0a2+ | 35 | Working
Please refer to the companion repository https://github.com/nneonneo/Il2CppVersions if you would like to track the changes between each IL2CPP release version.