Add ARMv8 (A64 ISA) support

This commit is contained in:
Katy Coe
2019-10-24 00:59:07 +02:00
parent 65982c6dec
commit 729a4cc6a6
2 changed files with 73 additions and 9 deletions

View File

@@ -1,6 +1,8 @@
using System;
using System.Collections.Generic;
using System.Text;
/*
Copyright 2019 Katy Coe - http://www.hearthcode.org - http://www.djkaty.com
All rights reserved.
*/
namespace Il2CppInspector
{
@@ -10,14 +12,75 @@ namespace Il2CppInspector
public Il2CppBinaryARM64(IFileFormatReader stream, uint codeRegistration, uint metadataRegistration) : base(stream, codeRegistration, metadataRegistration) { }
private (uint reg, ulong page) getAdrp(uint inst, ulong pc) {
if ((inst.Bits(24, 8) & 0b_1000_1111) != 1 << 7)
return (0, 0);
var addendLo = inst.Bits(29, 2);
var addendHi = inst.Bits(5, 19);
var addend = (addendHi << 14) + (addendLo << 12);
var page = pc & ~((1Lu << 12) - 1);
var reg = inst.Bits(0, 5);
return (reg, page + addend);
}
private (uint reg_n, uint reg_d, uint imm) getAdd64(uint inst) {
if (inst.Bits(22, 10) != 0b_1001_0001_00)
return (0, 0, 0);
var imm = inst.Bits(10, 12);
var reg_n = inst.Bits(5, 5);
var reg_d = inst.Bits(0, 5);
return (reg_n, reg_d, imm);
}
private ulong getAddressLoad(IFileFormatReader image, uint loc) {
// Get candidate ADRP Xa, #PAGE instruction
var inst = image.ReadUInt32(loc);
var adrp = getAdrp(inst, loc);
if (adrp.page == 0)
return 0;
// Get candidate ADD Xb, Xc, #OFFSET instruction
inst = image.ReadUInt32();
var add64 = getAdd64(inst);
if (add64.imm == 0)
return 0;
// Confirm a == b == c
if (adrp.reg != add64.reg_d || add64.reg_d != add64.reg_n)
return 0;
return adrp.page + add64.imm;
}
protected override (ulong, ulong) ConsiderCode(IFileFormatReader image, uint loc) {
// Assembly bytes to search for at start of each function
ulong metadataRegistration, codeRegistration;
byte[] buff;
var codeRegistration = getAddressLoad(image, loc);
if (codeRegistration == 0)
return (0, 0);
var metadataRegistration = getAddressLoad(image, loc + 8);
if (metadataRegistration == 0)
return (0, 0);
return (0, 0);
// There should be an Il2CppCodeGenOptions address load after the above two
if (getAddressLoad(image, loc + 16) == 0)
return (0, 0);
// TODO: Verify loc + 24 is a hard branch (B)
return (image.GlobalOffset + codeRegistration, image.GlobalOffset + metadataRegistration);
}
}
internal static class UIntExtensions
{
// Return count bits starting at bit low of integer x
public static uint Bits(this uint x, int low, int count) => (x >> low) & (uint) ((1 << count) - 1);
}
}

View File

@@ -3,11 +3,12 @@ Extract types, methods, properties and fields from Unity IL2CPP binaries.
* Supports ELF (Android .so), PE (Windows .exe), Mach-O (Apple iOS/Mac) and Universal Binary (Fat Mach-O) file formats
* 64-bit support for Mach-O files
* Supports ARMv7, ARMv7 Thumb T1 and x86 architectures regardless of file format
* Supports ARMv7, ARMv7 Thumb T1, ARMv8 (A64) and x86 architectures regardless of file format
* Supports metadata versions 21, 22, 23, 24, 24.1 (Unity 2018.3+) and 24.2 (Unity 2019+)
* No manual reverse-engineering required; all data is calculated automatically
* Support for classes, methods, fields, properties, enumerations, events, delegates, interfaces, structs and default field values
* Static and dynamic symbol table scanning for ELF binaries if present
* Static symbol table scanning for ELF and Mach-O binaries if present
* Dynamic symbol table scanning for ELF binaries if present
* Symbol relocation handling for ELF binaries
* **Il2CppInspector** re-usable class library for low-level access to IL2CPP binaries and metadata
* **Il2CppReflector** re-usable class library for high-level .NET Reflection-style access to IL2CPP types and data as a tree model