Я пытаюсь перехватить функцию, но у меня возникают проблемы, когда я пытаюсь перехватить sh. Что происходит, я подключаю функцию, когда функция вызывается, я cra sh по адресу 0x00000000 с исключением 0xC0000005 (нарушение доступа к памяти чтения по адресу 0x00000000.)
Функция, которую я пытаюсь перехватить, вызывает системный вызов и находится ниже.
void __declspec(naked) HvxGetVersions(DWORD dwMagic, DWORD dwMode, unsigned addr, QWORD outBuff, DWORD dwLength) {
__asm {
li r0, 0
sc
blr
}
}
Вот как я бы попытался подключить функцию
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);
Функции, которые я использую выше, опубликованы ниже.
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;
}