I need help detouring a function that makes a system call using inline asm

2

I'm attempting to hook a function, but I am having a bit of trouble when I attempt the hook I crash. What happens is I hook the function, when the function is called I crash at address 0x00000000 with an exception of 0xC0000005(Access violation reading memory at 0x00000000.)

The function I am trying to hook makes a system call and is below.

void __declspec(naked) HvxGetVersions(DWORD dwMagic, DWORD dwMode, unsigned addr, QWORD outBuff, DWORD dwLength) {
    __asm {
        li    r0, 0
        sc
        blr
    }
}

Here is how I would attempt to hook the function

typedef void(* tHvxGetVersions)(DWORD dwMagic, DWORD dwMode, unsigned addr, QWORD outBuff, DWORD dwLength);
tHvxGetVersions HvxGetVersionsOriginal;
void __declspec(naked) HvxGetVersionsHook(DWORD dwMagic, DWORD dwMode, unsigned addr, QWORD outBuff, DWORD dwLength) {
    printf("HvxGetVersions Called\n");

    //I've tried replicating what the function does like this below
    _asm {
        li    r0, 0
        sc
        blr
    }

    //I've also tried doing this(Note I would not do the asm and this just showing you what i've attempted)
    HvxGetVersionsOriginal(dwMagic, dwMode, addr, outBuff, dwLength);
}

//Note I obviously know that I wouldn't be using the address 0x00000000 it's just a placeholder.
HvxGetVersionsOriginal = (tHvxGetVersions)HookFunctionStub(0x00000000, &HvxGetVersionsHook);

The functions that I am using above are posted below.

void PatchInJump(DWORD* pAddress, DWORD dwDestination, bool bLinked) {
    pAddress[0] = 0x3D600000 + ((dwDestination >> 16) & 0xFFFF);
    if (dwDestination & 0x8000) 
        pAddress[0] += 1;
    pAddress[1] = 0x396B0000 + (dwDestination & 0xFFFF);
    pAddress[2] = 0x7D6903A6;
    pAddress[3] = bLinked ? 0x4E800421 : 0x4E800420;
}

void __declspec(naked) GLPR(void) {
    __asm {
        std     r14, -0x98(sp)
        std     r15, -0x90(sp)
        std     r16, -0x88(sp)
        std     r17, -0x80(sp)
        std     r18, -0x78(sp)
        std     r19, -0x70(sp)
        std     r20, -0x68(sp)
        std     r21, -0x60(sp)
        std     r22, -0x58(sp)
        std     r23, -0x50(sp)
        std     r24, -0x48(sp)
        std     r25, -0x40(sp)
        std     r26, -0x38(sp)
        std     r27, -0x30(sp)
        std     r28, -0x28(sp)
        std     r29, -0x20(sp)
        std     r30, -0x18(sp)
        std     r31, -0x10(sp)
        stw     r12, -0x8(sp)
        blr
    }
}

DWORD RelinkGPLR(DWORD SFSOffset, DWORD* SaveStubAddress, DWORD* OriginalAddress) {
    DWORD Instruction = NULL, Replacing;
    DWORD* Saver = (DWORD*)GLPR;

    if (SFSOffset & 0x2000000) 
        SFSOffset |= 0xFC000000;

    Replacing = OriginalAddress[SFSOffset / 0x04];
    for (DWORD i = NULL; i < 0x14; i++) {
        if (Replacing == Saver[i]) {
            DWORD NewAddress = (DWORD)&Saver[i] - (DWORD)SaveStubAddress;
            Instruction = (0x48000001 | (NewAddress & 0x03FFFFFC));
        }
    } 
    return Instruction;
}

void HookFunctionStart(DWORD* pAddress, DWORD* pSaveStub, DWORD dwDestination) {
    if ((pAddress!= NULL) && (pSaveStub!= NULL)) {
        DWORD dwRelocation = (DWORD)(&pAddress[0x04]);
        pSaveStub[0x00] = (0x3D600000 + ((dwRelocation >> 0x10) & 0xFFFF));
        pSaveStub[0x01] = (0x616B0000 + (dwRelocation & 0xFFFF));
        pSaveStub[0x02] = 0x7D6903A6;

        for (DWORD i = 0; i < 0x04; i++) {
            if ((pAddress[i] & 0x48000003) == 0x48000001) 
                pSaveStub[i + 0x03] = RelinkGPLR((pAddress[i] & ~0x48000003), &pSaveStub[i + 0x03], &pAddress[i]);
            else pSaveStub[i + 0x03] = pAddress[i];
        }

        pSaveStub[0x07] = 0x4E800420;
        __dcbst(NULL, pSaveStub);
        __sync();
        __isync();
        PatchInJump(pAddress, dwDestination, false);
    }
}

char m_hookSection[0x500];
int m_hookCount;
DWORD HookFunctionStub(DWORD dwAddress, void* pFunction) {
    DWORD* startStub = (DWORD*)&m_hookSection[m_hookCount * 32];
    m_hookCount++;

    for (auto i = 0; i < 7; i++)
        startStub[i] = 0x60000000;
    startStub[7] = 0x4E800020;

    HookFunctionStart((DWORD*)dwAddress, startStub, (DWORD)pFunction);
    return (DWORD)startStub;
}
c
assembly
powerpc
asked on Stack Overflow Aug 5, 2020 by Jack Leon • edited Aug 5, 2020 by JCWasmx86

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0