Integrate with C++ scaffolding Add new tests Rename Il2CppModel to TypeModel Incomplete IDAPython integration CLI and GUI support Update README.md
120 lines
3.6 KiB
C#
120 lines
3.6 KiB
C#
/*
|
|
Copyright 2020 Katy Coe - http://www.hearthcode.org - http://www.djkaty.com
|
|
|
|
All rights reserved.
|
|
*/
|
|
|
|
using System;
|
|
using System.Diagnostics;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using Il2CppInspector.Cpp;
|
|
using Il2CppInspector.Cpp.UnityHeaders;
|
|
using Il2CppInspector.Reflection;
|
|
using NUnit.Framework;
|
|
|
|
namespace Il2CppInspector
|
|
{
|
|
[TestFixture]
|
|
public partial class FixedTests
|
|
{
|
|
[Test]
|
|
public void TestCppTypeDeclarations() {
|
|
// NOTE: This test doesn't check for correct results, only that parsing doesn't fail!
|
|
|
|
var unityAllHeaders = UnityHeader.GetAllHeaders();
|
|
|
|
// Ensure we have read the embedded assembly resources
|
|
Assert.IsTrue(unityAllHeaders.Any());
|
|
|
|
// Ensure we can interpret every header from every version of Unity without errors
|
|
// This will throw InvalidOperationException if there is a problem
|
|
foreach (var unityHeader in unityAllHeaders) {
|
|
var cppTypes = CppTypeCollection.FromUnityHeaders(unityHeader);
|
|
foreach (var cppType in cppTypes.Types)
|
|
Debug.WriteLine("// " + cppType.Key + "\n" + cppType.Value.ToString("o"));
|
|
}
|
|
|
|
// Do a few sanity checks taken from real applications
|
|
// NOTE: Does not provide full code coverage!
|
|
|
|
var cppTypes2 = CppTypeCollection.FromUnityVersion(new UnityVersion("2019.3.1f1"), 64);
|
|
|
|
CppComplexType ct;
|
|
CppField field;
|
|
|
|
// Un-nested class
|
|
ct = (CppComplexType) cppTypes2["Il2CppClass"];
|
|
|
|
field = ct[0xD8].First();
|
|
|
|
Assert.AreEqual(field.Name, "cctor_finished");
|
|
|
|
field = ct[0x128].First();
|
|
|
|
Assert.AreEqual(field.Name, "vtable");
|
|
|
|
field = ct["cctor_finished"];
|
|
|
|
Assert.AreEqual(field.OffsetBytes, 0xD8);
|
|
|
|
field = ct["vtable"];
|
|
|
|
Assert.AreEqual(field.OffsetBytes, 0x128);
|
|
|
|
// Nested class
|
|
ct = (CppComplexType) cppTypes2["Il2CppClass_Merged"];
|
|
var fields = ct.Flattened;
|
|
|
|
field = fields[0xD8].First();
|
|
|
|
Assert.AreEqual(field.Name, "cctor_finished");
|
|
|
|
field = fields[0x128].First();
|
|
|
|
Assert.AreEqual(field.Name, "vtable");
|
|
|
|
field = fields["cctor_finished"];
|
|
|
|
Assert.AreEqual(field.OffsetBytes, 0xD8);
|
|
|
|
field = fields["vtable"];
|
|
|
|
Assert.AreEqual(field.OffsetBytes, 0x128);
|
|
|
|
// Bitfield
|
|
ct = (CppComplexType) cppTypes2["Il2CppType"];
|
|
|
|
field = ct.Fields[0xB * 8 + 7].First();
|
|
|
|
Assert.AreEqual(field.Name, "pinned");
|
|
|
|
// Nested fields
|
|
ct = (CppComplexType) cppTypes2["Il2CppWin32Decimal"];
|
|
fields = ct.Flattened;
|
|
|
|
field = fields[0x08].First();
|
|
|
|
Assert.AreEqual(field.Name, "lo32");
|
|
|
|
field = fields[0x08].Last();
|
|
|
|
Assert.AreEqual(field.Name, "lo64");
|
|
|
|
field = fields[0x0C].First();
|
|
|
|
Assert.AreEqual(field.Name, "mid32");
|
|
|
|
// Pointer alias
|
|
var alias = (CppAlias) cppTypes2.GetType("Il2CppHString");
|
|
|
|
Assert.AreEqual(alias.ElementType.GetType(), typeof(CppPointerType));
|
|
Assert.AreEqual(alias.ElementType.Name, "Il2CppHString__ *");
|
|
|
|
// Typedef struct with no tag
|
|
Assert.True(cppTypes2.Types.ContainsKey("Il2CppGenericMethodIndices"));
|
|
Assert.True(((CppComplexType)cppTypes2["Il2CppGenericMethodIndices"]).ComplexValueType == ComplexValueType.Struct);
|
|
}
|
|
}
|
|
}
|