Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix OOB read crash in Pass16ScanMethodRefs #83

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

khang06
Copy link

@khang06 khang06 commented Mar 20, 2023

I was running into a crash where Iced tried to disassemble past the end of the file, so here's a pretty straightforward fix for it.

@Kasuromi
Copy link
Member

Kasuromi commented Apr 1, 2023

What is the game you got the out of bounds exception on? I've been unable to reproduce this on several games.

@khang06
Copy link
Author

khang06 commented Apr 1, 2023

I ran into this on Rec Room. IIRC it also required modifying Cpp2IL to make it find CodeRegistration properly, which I did by porting this.

internal ulong FindCodeRegistrationKhangSearch(ulong expectedMetadataRegistration)
{
    // custom search
    // searching .text for the following pattern:
    // lea r8,  [rip+0x????????]
    // lea rdx, [rip+0x????????]
    // lea rcx, [rip+0x????????]
    // jmp [rip+0x????????]
    // or...
    // 4c 8d 05 ?? ?? ?? ??
    // 48 8d 15 ?? ?? ?? ??
    // 48 8d 0d ?? ?? ?? ??
    // e9
    // 22 bytes long

    // functions are always aligned to 16 bytes
    const int patternLength = 22;
    byte[] d = new byte[patternLength];
    ulong address = 0;
    for (int ptr = 0; ptr < _binaryBytes.Length - patternLength; ptr += 0x10)
    {
        Buffer.BlockCopy(_binaryBytes, ptr, d, 0, patternLength);
        if (
            d[0] == 0x4C && d[1] == 0x8D && d[2] == 0x05 &&
            d[7] == 0x48 && d[8] == 0x8D && d[9] == 0x15 &&
            d[14] == 0x48 && d[15] == 0x8D && d[16] == 0x0D &&
            d[21] == 0xE9
        )
        {
            var virtualPtr = _binary.MapRawAddressToVirtual((uint)ptr);
            address = virtualPtr + 21 + BitConverter.ToUInt32(d, 14 + 3);
            var metadataRegistration = virtualPtr + 14 + BitConverter.ToUInt32(d, 7 + 3);
            if (metadataRegistration == expectedMetadataRegistration)
            {
                LibLogger.VerboseNewline($"Found the offsets at 0x{virtualPtr.ToString("X2")}! codeRegistration: 0x{address.ToString("X2")}, metadataRegistration: 0x{metadataRegistration.ToString("X2")}");
                break;
            }
            break;
        }
    }

    var codeReg = LibCpp2IlMain.Binary!.ReadReadableAtVirtualAddress<Il2CppCodeRegistration>(address);

    var fields = typeof(Il2CppCodeRegistration).GetFields();
    var fieldsByName = fields.ToDictionary(f => f.Name);
    var success = ValidateCodeRegistration(codeReg, fieldsByName);

    if (success)
    {
        LibLogger.VerboseNewline("Looks good!");
        return address;
    }

    return 0;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants