diff --git a/Il2CppInspector/Il2CppBinaryARM64.cs b/Il2CppInspector/Il2CppBinaryARM64.cs index fa15814..8db2d5f 100644 --- a/Il2CppInspector/Il2CppBinaryARM64.cs +++ b/Il2CppInspector/Il2CppBinaryARM64.cs @@ -29,6 +29,22 @@ namespace Il2CppInspector return (reg, page + addend); } + // https://static.docs.arm.com/100878/0100/fundamentals_of_armv8_a_100878_0100_en.pdf states: + // Unlike ARMv7-A, there is no implied offset of 4 or 8 bytes + private (uint reg, ulong addr)? getAdr(uint inst, ulong pc) { + if (inst.Bits(24, 5) != 0b10000 || inst.Bits(31, 1) != 0) + return null; + + ulong imm = (inst.Bits(5, 19) << 2) + inst.Bits(29, 2); + + // Sign extend the 21-bit number to 64 bits + imm = (imm & (1 << 20)) == 0 ? imm : imm | unchecked((ulong) -(1 << 21)); + + var reg = inst.Bits(0, 5); + + return (reg, pc + imm); + } + private (uint reg_n, uint reg_d, uint imm)? getAdd64(uint inst) { if (inst.Bits(22, 10) != 0b_1001_0001_00) return null; @@ -70,6 +86,13 @@ namespace Il2CppInspector regs.Add(reg, page); } + if (getAdr(inst, pc) is (uint reg_adr, ulong addr)) { + if (regs.ContainsKey(reg_adr)) + regs[reg_adr] = addr; + else + regs.Add(reg_adr, addr); + } + // Is it an ADD Xm, Xn, #offset? if (getAdd64(inst) is (uint reg_n, uint reg_d, uint imm)) { // We are only interested in registers that have already had an ADRP, and the ADD must be to itself