Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- static uint32_t GetFunctionBranch(uint32_t address)
- {
- uint32_t dest, temp;
- dest = *(uint32_t*)address;
- temp = dest;
- dest = temp & 0x03FFFFFC;
- if (temp & 0x02000000) dest |= 0xFC000000;
- dest = address + dest;
- return dest;
- }
- bool bCheckIfCMP(int ptr)
- {
- unsigned char b = *(unsigned char *)ptr;
- unsigned char b2 = *(unsigned char *)(ptr + 1);
- if (b == 0x40 || b == 0x41)
- {
- if (b2 == 0x9A || b2 == 0x82 || b2 == 0x99
- || b2 == 0x81 || b2 == 0x98 || b2 == 0x80)
- return true;
- }
- return false;
- }
- bool IsValidPtr(void *value)
- {
- if (value == 0)
- {
- return false;
- }
- /*if ((uint32_t)(value) > 0x10000)
- {
- if (*(uint32_t *)(value) == 0)
- {
- return false;
- }
- }*/
- return true;
- }
- struct importStub_s
- {
- int16_t ssize;
- int16_t header1;
- int16_t header2;
- int16_t imports;
- int32_t zero1;
- int32_t zero2;
- const char* name;
- uint32_t* fnid;
- opd_s** stub;
- int32_t zero3;
- int32_t zero4;
- int32_t zero5;
- int32_t zero6;
- } *g_imports;
- struct exportStub_s
- {
- int16_t ssize;
- int16_t header1;
- int16_t header2;
- int16_t exports;
- int32_t zero1;
- int32_t zero2;
- const char* name;
- uint32_t* fnid;
- opd_s** stub;
- } *g_exports;
- /*
- skate 3
- + 0x30 export_adress_table
- + 0x38 import_adress_table
- gta v
- + 0x38 export_adress_table // gta v doesn't have any exports
- + 0x40 import_adress_table
- minecraft
- + 0x38 export_adress_table // minecraft doesn't have any exports
- + 0x40 import_adress_table
- */
- opd_s * find_export(const char* module, uint32_t fnid)
- {
- uint32_t temp_prt = *(uint32_t *)(0x10000 + 0x1AC);
- printf("temp_prt: 0x%X\n", temp_prt);
- uint32_t export_adress_table = *(uint32_t *)(temp_prt + 0x38);
- printf("export_adress_table: 0x%X\n", export_adress_table);
- uint16_t *temp_exp = (uint16_t*)export_adress_table;
- printf("temp_exp: 0x%X\n", temp_exp);
- // while ((--temp_exp)->ssize == 0x1C00);
- g_exports = (exportStub_s*)(temp_exp + 1);
- printf("g_exports: 0x%X\n", g_exports);
- exportStub_s* temp = g_exports;
- printf("find_export temp: 0x%X\n", temp);
- while (temp->ssize == 0x1C00)
- {
- printf("temp->name: %s\n", temp->name);
- if (!strcmp(module, temp->name))
- {
- printf("temp->exports: 0x%X\n", temp->exports);
- for (int16_t i = 0; i < temp->exports; i++)
- {
- if (temp->fnid[i] == fnid)
- {
- printf("temp->fnid[%i]: 0x%X\n", i, temp->fnid[i]);
- return temp->stub[i];
- }
- }
- }
- temp++;
- }
- return NULL;
- }
- opd_s * find_import(const char* module, uint32_t fnid)
- {
- uint32_t temp_prt = *(uint32_t *)(0x10000 + 0x1AC);
- printf("temp_prt: 0x%X\n", temp_prt);
- uint32_t import_adress_table = *(uint32_t *)(temp_prt + 0x40);
- printf("import_adress_table: 0x%X\n", import_adress_table);
- uint16_t *temp_imp = (uint16_t*)import_adress_table;
- printf("temp_imp: 0x%X\n", temp_imp);
- while (*temp_imp++ != 0x2C00);
- g_imports = (importStub_s*)(temp_imp - 1);
- printf("g_imports: 0x%X\n", g_imports);
- importStub_s* temp = g_imports;
- printf("find_import temp: 0x%X\n", temp);
- while (temp->ssize == 0x2C00)
- {
- printf("temp->name: %s\n", temp->name);
- if (!strcmp(module, temp->name))
- {
- printf("temp->imports: 0x%X\n", temp->imports);
- for (int16_t i = 0; i < temp->imports; i++)
- {
- printf("temp->fnid[%i]: 0x%X\n", i, temp->fnid[i]);
- if (temp->fnid[i] == fnid)
- {
- return temp->stub[i];
- }
- }
- }
- temp++;
- }
- return NULL;
- }
- __attribute__((section(".text"))) uint8_t DetourAsm[500] = { 0 }; // was 0x3000, changed it to a smaller size because when I use 0x3000 it crashes my thread. I believe the reason it does that is because of the PS3 memory limit. use __attribute__((section(".text"))) to make the buffer executable
- uint32_t DetourAsmIndex;
- /*
- TODO:
- - make a stub for branchHook if possible???
- - clean up FindExportByName FindImportByName
- - make derived classes for different types of hooks
- */
- template <class R>
- class DetourHook
- {
- public:
- // Made by Xx jAmes t xX ported and adapted to PS3 by TheRouLetteBoi
- // This .h is used to edit functions to detour to your own custom one
- //
- // you may want to change the size of uint8_t DetourAsm[500] = { 0 }; depending on how many hooks you have but 500 should be enough for about 10 hooks
- explicit DetourHook() : m_saveStub(0), m_moduleTOC(GAME_TOC) { } // __builtin_get_toc()
- virtual ~DetourHook() { }
- DetourHook(DetourHook const&) = delete;
- DetourHook(DetourHook&&) = delete;
- DetourHook& operator=(DetourHook const&) = delete;
- DetourHook& operator=(DetourHook&&) = delete;
- public:
- enum class BranchhookType
- {
- BRANCH_HOOK,
- BRANKLINK_HOOK,
- };
- public:
- /***
- * e.g
- * detour_vmHook->Hook(0x9B4D00, (uint32_t)VM_HOOK);
- * In the hook
- * return detour_vmHook->GetOriginal(r3, globals, scrProgram, scrThread);
- */
- virtual bool Hook(uint32_t address, uint32_t destination)
- {
- // prevent buffer overflow
- if (g_DetourAsmCount > (MAX_DETOUR_ASM_SIZE - 2)) // if (g_DetourAsmCount > (sizeof(g_DetourAsm) - 2))
- return false;
- if (m_cache.address != address || m_saveStub == 0)
- {
- m_saveStub = (uint32_t)&g_DetourAsm[g_DetourAsmCount];
- // save the address in case we take-down the detour
- m_cache.address = address;
- // Copy the asm bytes before we replace it with the hook
- WriteProcessMemory(sys_process_getpid(), m_cache.originalAsm, (void*)address, 0x10);
- // increment the index for the space we are using for the stub
- g_DetourAsmCount += DetourFunctionStart(address, m_saveStub, destination);
- return true;
- }
- return false;
- }
- /***
- * e.g
- * detour_cloneCreateHook->HookVMT(0x1C707E0, (uint32_t)CLONE_CREATE_HOOK);
- * In the hook
- * return detour_cloneCreateHook->GetOriginalVMT(netObjectMgr, netGamePlayerClient, netGamePlayerSelf, netObjType, objectId, sequenceId, syncData, timestamp);
- */
- virtual bool HookVMT(uint32_t address, uint32_t destination)
- {
- if (m_cache.address != address)
- {
- // save the address in case we take-down the detour
- m_cache.address = address;
- // Copy the opd_s before we replace it with the hook
- WriteProcessMemory(sys_process_getpid(), (void*)&m_cache.originalAsm, (void*)address, m_cache.originalSize = 0x8);
- return VMTSwapHook(address, destination);
- }
- return false;
- }
- /***
- * e.g
- * detour_sysPpuThreadCreate = new DetourHook<int>;
- * detour_sysPpuThreadCreate->HookIAT("sysPrxForUser", 0x24A1EA07, (uint32_t)SYS_PPU_THREAD_CREATE_HOOK);
- * In the hook
- * return detour_sysPpuThreadCreate->GetOriginalImportExport(thread_id, entry, arg, prio, stacksize, flags, threadname);
- *
- * e.g
- * detour_cellFsOpen = new DetourHook<CellFsErrno>;
- * detour_cellFsOpen->HookIAT("sys_fs", 0x718BF5F8, (uint32_t)CELL_FS_OPEN_HOOK);
- * In the hook
- * return detour_cellFsOpen->GetOriginalImportExport(path, flags, fd, arg, size);
- */
- virtual bool HookIAT(const char* libaryName, uint32_t fnid, uint32_t destination) // IAT Hooking - "Import Address Table"
- {
- m_importExportCache.m_ImportExportOriginal = FindImportByName(libaryName, fnid);
- if (m_importExportCache.m_ImportExportOriginal->sub == 0)
- return false;
- return Hook(m_importExportCache.m_ImportExportOriginal->sub, destination);
- }
- virtual bool HookEAT(const char* libaryName, uint32_t fnid, uint32_t destination) // EAT Hooking - "Export Address Table"
- {
- m_importExportCache.m_ImportExportOriginal = FindExportByName(libaryName, fnid);
- if (m_importExportCache.m_ImportExportOriginal->sub == 0)
- return false;
- return Hook(m_importExportCache.m_ImportExportOriginal->sub, destination);
- }
- /***
- * e.g
- * detour_networkObjectMgr = new DetourHook<uint32_t>;
- * detour_networkObjectMgr->HookClass(0x192F490, 18, (uint32_t)CLONE_CREATE_HOOK);
- * detour_networkObjectMgr->HookClass(0x192F490, 20, (uint32_t)CLONE_SYNC_HOOK);
- * detour_networkObjectMgr->HookClass(0x192F490, 22, (uint32_t)CLONE_REMOVE_HOOK);
- * Since you have 3 hooks
- * return detour_networkObjectMgr->GetOriginalClass(18, netObjectMgr, netGamePlayerClient, netGamePlayerSelf, netObjType, objectId, sequenceId, syncData, timestamp);
- * return detour_networkObjectMgr->GetOriginalClass(20, networkObjectMgr, netGamePlayerClient, netGamePlayerSelf, netObjType, objectId, syncData, sequenceId, timestamp);
- * return detour_networkObjectMgr->GetOriginalClass(22, networkObjectMgr, netGamePlayerClient, netGamePlayerSelf, objectId, r7);
- */
- virtual bool HookClass(uint32_t classAddr, uint16_t vmtFunctionIndex, uint32_t destination)
- {
- if (ScanClassForFunctions(classAddr))
- {
- return VMTSwapHookAtIndex(vmtFunctionIndex, destination);
- }
- return false;
- }
- /***
- * e.g
- * detour_networkObjectMgr->HookClass("17CNetworkObjectMgr", 18, (uint32_t)CLONE_CREATE_HOOK);
- * detour_networkObjectMgr->HookClass("17CNetworkObjectMgr", 20, (uint32_t)CLONE_SYNC_HOOK);
- * detour_networkObjectMgr->HookClass("17CNetworkObjectMgr", 22, (uint32_t)CLONE_REMOVE_HOOK);
- * Since you have 3 hooks
- * return detour_networkObjectMgr->GetOriginalClass(18, netObjectMgr, netGamePlayerClient, netGamePlayerSelf, netObjType, objectId, sequenceId, syncData, timestamp);
- * return detour_networkObjectMgr->GetOriginalClass(20, networkObjectMgr, netGamePlayerClient, netGamePlayerSelf, netObjType, objectId, syncData, sequenceId, timestamp);
- * return detour_networkObjectMgr->GetOriginalClass(22, networkObjectMgr, netGamePlayerClient, netGamePlayerSelf, objectId, r7);
- */
- virtual bool HookClass(const char* className, uint16_t vmtFunctionIndex, uint32_t destination)
- {
- uint32_t addr = FindClassByName(className);
- if (addr == 0)
- return false;
- return HookClass(addr, vmtFunctionIndex, destination);
- }
- /***
- * e.g
- * detour_vmHook->HookInstruction(0x9B770C, (uint32_t)VM_HOOK, DetourHook<uint32_t>::BranchhookType::BRANKLINK_HOOK);
- * In the hook
- * return detour_vmHook->GetOriginalBranchLink(r3, globals, scrProgram, scrThread);
- */
- virtual bool HookInstruction(uint32_t address, uint32_t destination, BranchhookType type = BranchhookType::BRANKLINK_HOOK) // HookSingleInstruction
- {
- if (m_cache.address != address)
- {
- m_cache.address = address;
- WriteProcessMemory(sys_process_getpid(), (void*)&m_cache.originalAsm, (void*)address, m_cache.originalSize = 0x4);
- // this should be a new variable instead of using the cache, but doing it for memory's sake
- m_cache.originalAsm[1] = GetFunctionBranch(m_cache.address);
- return BranchHook(address, destination, type);
- }
- return false;
- }
- // TODO: this is untested so test it soon
- virtual void UnHook()
- {
- if (m_cache.address)
- {
- WriteProcessMemory(sys_process_getpid(), (void*)m_cache.address, (const void*)m_cache.originalAsm, 0x10);
- }
- }
- // TODO: this is untested so test it soon
- virtual void UnHookVMT()
- {
- if (m_cache.address)
- {
- WriteProcessMemory(sys_process_getpid(), (void*)m_cache.address, (const void*)m_cache.originalAsm, 0x8);
- }
- }
- // TODO: this is untested so test it soon
- virtual void UnHookClass()
- {
- if (m_classCache.m_hasBeenScanned)
- {
- for (int i = 0; i < m_classCache.m_vmtFunctionCount; i++)
- {
- WriteProcessMemory(sys_process_getpid(), (void*)m_classCache.m_vmt[i], (const void*)&m_classCache.m_redirectMap[i], 0x8);
- }
- if (m_classCache.m_redirectMap)
- {
- delete[] m_classCache.m_redirectMap;
- }
- m_classCache.m_hasBeenScanned = false;
- }
- }
- // TODO: this is untested so test it soon
- virtual void UnHookInstruction()
- {
- if (m_cache.address)
- {
- WriteProcessMemory(sys_process_getpid(), (void*)m_cache.address, (const void*)m_cache.originalAsm, 0x4);
- }
- }
- // No more virtual :(
- template <typename... TArgs>
- R GetOriginal(TArgs... args)
- {
- volatile opd_s opd = { m_saveStub, m_moduleTOC };
- return ((R(*)(...)) & opd)(args...);
- }
- template <typename... TArgs>
- R GetOriginalVMT(TArgs... args)
- {
- volatile opd_s opd = { m_cache.originalAsm[0], m_cache.originalAsm[1] };
- return ((R(*)(...)) & opd)(args...);
- }
- template <typename... TArgs>
- R GetOriginalClass(uint32_t vmtFunctionIndex, TArgs... args)
- {
- volatile opd_s opd = { m_classCache.m_redirectMap[vmtFunctionIndex].sub, m_classCache.m_redirectMap[vmtFunctionIndex].toc };
- return ((R(*)(...)) & opd)(args...);
- }
- template <typename... TArgs>
- R GetOriginalImportExport(TArgs... args)
- {
- volatile opd_s opd = { m_saveStub, m_importExportCache.m_ImportExportOriginal->toc };
- return ((R(*)(...)) & opd)(args...);
- }
- // this will only work if you hook a function that starts with a "bl sub_123456"
- template <typename... TArgs>
- R GetOriginalBranchLink(TArgs... args)
- {
- volatile opd_s opd = { m_cache.originalAsm[1], GAME_TOC };
- return ((R(*)(...)) & opd)(args...);
- }
- private:
- /***
- * This function will get any 'b' or 'bl' and any 'cmp' function added to the stub that it replaces
- * @return the size of the stub in byte lengths
- */
- virtual uint32_t DetourFunctionStart(uint32_t functionAddress, uint32_t stubAddress, uint32_t destination)
- {
- destination = GetRawDestination(uint32_t, destination);
- uint32_t writeLength = 0;
- uint32_t branchBytes;
- uint32_t tempFuncAddr;
- bool bTemp;
- for (int i = 0; i < 4; i++)
- {
- tempFuncAddr = functionAddress + (i * 4);
- uint8_t b = *reinterpret_cast<uint8_t*>(tempFuncAddr);
- // b or bl
- if (b == 0x48 || b == 0x49 || b == 0x4B)
- {
- branchBytes = GetFunctionBranch(tempFuncAddr);
- bTemp = (*reinterpret_cast<uint32_t*>(tempFuncAddr) & 1) != 0;
- PatchInJump(reinterpret_cast<uint32_t*>(stubAddress + writeLength), branchBytes, bTemp, false);
- writeLength += 0x10;
- // if it was a 'b loc_' call, we won't need to anything else to the stub
- if (!bTemp)
- {
- goto DoHook;
- }
- }
- // beq or bne, ble or bgt, bge or blt
- else if (CheckIfCMP(tempFuncAddr))
- {
- branchBytes = *reinterpret_cast<uint32_t*>(tempFuncAddr & 0xFFFF);
- // if bTemp is true the op code is 'beq'
- bTemp = b == 0x41;
- // check if the branch location is within the stub
- if (branchBytes <= 0x10 && branchBytes > 0)
- {
- if (branchBytes <= (0x10 - (i * 4)))
- {
- write_mem<uint32_t>((stubAddress + writeLength), *reinterpret_cast<uint32_t*>(tempFuncAddr));
- writeLength += 4;
- }
- else
- {
- goto branch_else;
- }
- }
- else
- {
- branch_else:
- // make a jump past the call if the cmp != what it is checking
- write_mem<uint32_t>(stubAddress + writeLength, (((0x40000000 + ((*reinterpret_cast<uint32_t*>(tempFuncAddr) & 0x00FF0000)) + 0x14)) + (bTemp ? 0x00000000 : 0x01000000)));
- writeLength += 4;
- PatchInJump(reinterpret_cast<uint32_t*>(stubAddress + writeLength), (tempFuncAddr + branchBytes), false, false);
- writeLength += 0x10;
- }
- }
- // if the function op code is null it is invalid
- else if (*reinterpret_cast<uint32_t*>(tempFuncAddr) == 0)
- {
- break;
- }
- else
- {
- write_mem<uint32_t>((stubAddress + writeLength), *reinterpret_cast<uint32_t*>(tempFuncAddr));
- writeLength += 4;
- }
- }
- // make the stub call the orig function
- PatchInJump(reinterpret_cast<uint32_t*>(stubAddress + writeLength), (functionAddress + 0x10), false, false);
- writeLength += 0x10;
- DoHook:
- // apply the hook
- PatchInJump(reinterpret_cast<uint32_t*>(functionAddress), destination, false, false);
- return writeLength;
- }
- virtual bool VMTSwapHook(uint32_t address, uint32_t destination) // VMT Hooking / Pointer redirections
- {
- // replace the virtual table function with ours to intercept
- if (write_mem<uint64_t>(address, *reinterpret_cast<uint64_t*>(destination)))
- return true;
- return false;
- }
- virtual bool VMTSwapHookAtIndex(int16_t vmtFunctionIndex, uint32_t destination)
- {
- return VMTSwapHook(m_classCache.m_vmt[vmtFunctionIndex], destination);
- }
- // makes a b or bl at the giving address
- virtual bool BranchHook(uint32_t address, uint32_t destination, BranchhookType type)
- {
- destination = GetRawDestination(uint32_t, destination);
- uint32_t branch;
- if (type == BranchhookType::BRANCH_HOOK)
- {
- branch = (0x48000000 + ((destination - address) & 0x3FFFFFF));
- }
- else // type == BranchhookType::BRANKLINK_HOOK // branch link
- {
- branch = (0x48000000 + ((destination - address) & 0x3FFFFFF));
- branch = branch += 1;
- }
- return write_mem<uint32_t>(address, branch);
- }
- uint16_t GetClassFunctionsCount()
- {
- uint16_t count = 0;
- for (;; count++)
- {
- // if you have more than 500 virtual table functions you have a problem and i don't support you :)
- if (m_classCache.m_vmt[count] == 0 || count > 500)
- break;
- }
- return count;
- }
- bool ScanClassForFunctions(uint32_t& classAddr)
- {
- if (!m_classCache.m_hasBeenScanned)
- {
- // save the address in case we take-down the detour
- m_cache.address = classAddr;
- m_classCache.m_vmt = (uint32_t*)classAddr;
- m_classCache.m_vmtFunctionCount = GetClassFunctionsCount();
- // make sure this class thats virtual functions
- if (m_classCache.m_vmtFunctionCount == 0)
- return false;
- // allocate an array to store our virtual table functions
- m_classCache.m_redirectMap = new opd_s[m_classCache.m_vmtFunctionCount];
- if (m_classCache.m_redirectMap == nullptr)
- return false;
- // clear the heap memory
- memset(m_classCache.m_redirectMap, 0, sizeof(opd_s) * m_classCache.m_vmtFunctionCount);
- // save a copy of the virtual table function addresses in case we need to restore them
- for (int i = 0; i < m_classCache.m_vmtFunctionCount; i++)
- write_mem<uint64_t>((uint32_t)&m_classCache.m_redirectMap[i], *reinterpret_cast<uint64_t*>(m_classCache.m_vmt[i]));
- m_classCache.m_hasBeenScanned = true;
- }
- return true;
- }
- private:
- struct HookCache
- {
- uint32_t address;
- uint32_t originalAsm[4]; // 4 instructions
- uint32_t originalSize;
- HookCache() : address(0), originalSize(sizeof(uint32_t) * 4) { memset(originalAsm, 0, sizeof(originalAsm)); }
- };
- struct ClassHookCache
- {
- opd_s* m_redirectMap;
- uint32_t* m_vmt;
- uint16_t m_vmtFunctionCount;
- bool m_hasBeenScanned;
- ClassHookCache() : m_vmtFunctionCount(0), m_hasBeenScanned(false) { }
- };
- struct ImportExportHookCache
- {
- opd_s* m_ImportExportOriginal; // import export opd_s(sub, toc)
- };
- HookCache m_cache;
- ClassHookCache m_classCache;
- ImportExportHookCache m_importExportCache;
- uint32_t m_saveStub;
- uint32_t m_moduleTOC; // get the TOC of our sprx so we can use it to call our function later
- };
- -----------------------------------------------------------------------------------------------------------------------------
- // this was me trying to get enstones hooking method working
- uint64_t HookHandler(uint64_t a1, uint64_t a2)
- {
- printf("HookHandler\n");
- printf("a1: 0x%X\n", a1);
- printf("a2: 0x%X\n", a2);
- /*
- bool bVar1;
- uint uVar2;
- ulonglong uVar3;
- ulonglong uVar4;
- uint* puVar5;
- undefined8 uVar6;
- int iVar7;
- uint uVar8;
- uVar6 = *(undefined8*)(param_2 + 0x100);
- while (*(char*)(param_1 + 0x18) == '\0')
- {
- sleep(100);
- }
- iVar7 = 0;
- uVar8 = 0;
- uVar2 = *(uint*)(param_1 + 0x14);
- while (true)
- {
- bVar1 = uVar8 == uVar2;
- uVar3 = (ulonglong)uVar8;
- uVar4 = param_1 + 4U & 0xffffffff;
- uVar8 = uVar8 + 1;
- if (bVar1)
- break;
- puVar5 = (uint*)FUN_d00ff7ec(uVar4, uVar3);
- if ((int)uVar6 - 4U == puVar5[1])
- {
- iVar7 = iVar7 + 1;
- if (*(char*)(puVar5 + 2) == '\0')
- {
- ccapi_syscall(0x241); // enable syscall
- *(undefined*)(puVar5 + 2) = 1;
- }
- (*(code*)(ulonglong) * (uint*)(ulonglong)*puVar5)(param_2 & 0xffffffff);
- }
- }
- if (iVar7 == 0)
- {
- trapWord(0x1f, &stack0xffffffffffffff50, &stack0xffffffffffffff50);
- }
- return uVar4;
- */
- return 1;
- }
- __attribute__((naked)) uint64_t HookHandlerAsm2(uint32_t a1)
- {
- __asm__(
- "mr %r4, %r3;"
- "addis %r3, %r2, -1;"
- "addic %r3, %r3, 0x6CFC;"
- "b ._Z11HookHandleryy;"
- );
- }
- __attribute__((naked)) uint64_t HookHandlerAsm1() // uint32_t r3, uint32_t r4, uint32_t r5, uint32_t r6, uint32_t r7, uint32_t r8, uint32_t r9, uint32_t r10, uint32_t r11, uint32_t r12, uint32_t r13, uint32_t r14, uint32_t r15, uint32_t r16, uint32_t r17, uint32_t r18, uint32_t r19, uint32_t r20, uint32_t r21
- {
- __asm__(
- "std %r0, 0x70(%r1);"
- "addi %r0, %r1, 0x300;"
- "std %r0, 0x78(%r1);"
- "std %r4, 0x90(%r1);"
- "std %r5, 0x98(%r1);"
- "std %r6, 0xA0(%r1);"
- "std %r7, 0xA8(%r1);"
- "std %r8, 0xB0(%r1);"
- "std %r9, 0xB8(%r1);"
- "std %r10, 0xC0(%r1);"
- "std %r11, 0xC8(%r1);"
- "std %r12, 0xD0(%r1);"
- "std %r13, 0xD8(%r1);"
- "std %r14, 0xE0(%r1);"
- "std %r15, 0xE8(%r1);"
- "std %r16, 0xF0(%r1);"
- "std %r17, 0xF8(%r1);"
- "std %r18, 0x100(%r1);"
- "std %r19, 0x108(%r1);"
- "std %r20, 0x110(%r1);"
- "std %r21, 0x118(%r1);"
- "std %r22, 0x120(%r1);"
- "std %r23, 0x128(%r1);"
- "std %r24, 0x130(%r1);"
- "std %r25, 0x138(%r1);"
- "std %r26, 0x140(%r1);"
- "std %r27, 0x148(%r1);"
- "std %r28, 0x150(%r1);"
- "std %r29, 0x158(%r1);"
- "std %r30, 0x160(%r1);"
- "std %r31, 0x168(%r1);"
- "mfctr %r0;"
- "std %r0, 0x178(%r1);"
- "mfcr %r0;"
- "std %r0, 0x180(%r1);"
- "mfxer %r0;"
- "std %r0, 0x188(%r1);"
- "stfd %f0, 0x190(%r1);"
- "stfd %f1, 0x198(%r1);"
- "stfd %f2, 0x1A0(%r1);"
- "stfd %f3, 0x1A8(%r1);"
- "stfd %f4, 0x1B0(%r1);"
- "stfd %f5, 0x1B8(%r1);"
- "stfd %f6, 0x1C0(%r1);"
- "stfd %f7, 0x1C8(%r1);"
- "stfd %f8, 0x1D0(%r1);"
- "stfd %f9, 0x1D8(%r1);"
- "stfd %f10, 0x1E0(%r1);"
- "stfd %f11, 0x1E8(%r1);"
- "stfd %f12, 0x1F0(%r1);"
- "stfd %f13, 0x1F8(%r1);"
- "stfd %f14, 0x200(%r1);"
- "stfd %f15, 0x208(%r1);"
- "stfd %f16, 0x210(%r1);"
- "stfd %f17, 0x218(%r1);"
- "stfd %f18, 0x220(%r1);"
- "stfd %f19, 0x228(%r1);"
- "stfd %f20, 0x230(%r1);"
- "stfd %f21, 0x238(%r1);"
- "stfd %f22, 0x240(%r1);"
- "stfd %f23, 0x248(%r1);"
- "stfd %f24, 0x250(%r1);"
- "stfd %f25, 0x258(%r1);"
- "stfd %f26, 0x260(%r1);"
- "stfd %f27, 0x268(%r1);"
- "stfd %f28, 0x270(%r1);"
- "stfd %f29, 0x278(%r1);"
- "stfd %f30, 0x280(%r1);"
- "stfd %f31, 0x288(%r1);"
- "addi %r3, %r1, 0x70;"
- "bl ._Z15HookHandlerAsm2j;"
- "nop;"
- "ld %r0, 0x170(%r1);"
- "mtlr %r0;"
- "ld %r0, 0x178(%r1);"
- "mtctr %r0;"
- "ld %r0, 0x180(%r1);"
- "mtcr %r0;"
- "ld %r0, 0x188(%r1);"
- "mtxer %r0;"
- "ld %r0, 0x70(%r1);"
- "nop;"
- "ld %r2, 0x80(%r1);"
- "ld %r3, 0x88(%r1);"
- "ld %r4, 0x90(%r1);"
- "ld %r5, 0x98(%r1);"
- "ld %r6, 0xA0(%r1);"
- "ld %r7, 0xA8(%r1);"
- "ld %r8, 0xB0(%r1);"
- "ld %r9, 0xB8(%r1);"
- "ld %r10, 0xC0(%r1);"
- "ld %r11, 0xC8(%r1);"
- "ld %r12, 0xD0(%r1);"
- "ld %r13, 0xD8(%r1);"
- "ld %r14, 0xE0(%r1);"
- "ld %r15, 0xE8(%r1);"
- "ld %r16, 0xF0(%r1);"
- "ld %r17, 0xF8(%r1);"
- "ld %r18, 0x100(%r1);"
- "ld %r19, 0x108(%r1);"
- "ld %r20, 0x110(%r1);"
- "ld %r21, 0x118(%r1);"
- "ld %r22, 0x120(%r1);"
- "ld %r23, 0x128(%r1);"
- "ld %r24, 0x130(%r1);"
- "ld %r25, 0x138(%r1);"
- "ld %r26, 0x140(%r1);"
- "ld %r27, 0x148(%r1);"
- "ld %r28, 0x150(%r1);"
- "ld %r29, 0x158(%r1);"
- "ld %r30, 0x160(%r1);"
- "ld %r31, 0x168(%r1);"
- "lfd %f0, 0x190(%r1);"
- "lfd %f1, 0x198(%r1);"
- "lfd %f2, 0x1A0(%r1);"
- "lfd %f3, 0x1A8(%r1);"
- "lfd %f4, 0x1B0(%r1);"
- "lfd %f5, 0x1B8(%r1);"
- "lfd %f6, 0x1C0(%r1);"
- "lfd %f7, 0x1C8(%r1);"
- "lfd %f8, 0x1D0(%r1);"
- "lfd %f9, 0x1D8(%r1);"
- "lfd %f10, 0x1E0(%r1);"
- "lfd %f11, 0x1E8(%r1);"
- "lfd %f12, 0x1F0(%r1);"
- "lfd %f13, 0x1F8(%r1);"
- "lfd %f14, 0x200(%r1);"
- "lfd %f15, 0x208(%r1);"
- "lfd %f16, 0x210(%r1);"
- "lfd %f17, 0x218(%r1);"
- "lfd %f18, 0x220(%r1);"
- "lfd %f19, 0x228(%r1);"
- "lfd %f20, 0x230(%r1);"
- "lfd %f21, 0x238(%r1);"
- "lfd %f22, 0x240(%r1);"
- "lfd %f23, 0x248(%r1);"
- "lfd %f24, 0x250(%r1);"
- "lfd %f25, 0x258(%r1);"
- "lfd %f26, 0x260(%r1);"
- "lfd %f27, 0x268(%r1);"
- "lfd %f28, 0x270(%r1);"
- "lfd %f29, 0x278(%r1);"
- "lfd %f30, 0x280(%r1);"
- "lfd %f31, 0x288(%r1);"
- "ld %r1, 0x78(%r1);"
- "blr;"
- );
- }
- // Destination = HookHandler
- bool SetupHookHandler(uint32_t hookHandlerInstallationAddress, void* hookHandler) // enstone hooking method
- {
- // todo: add check to see if it's been hooked already
- printf("SetupHookHandler\n");
- printf("hookHandler: 0x%X\n", hookHandler);
- uint32_t opcode[12];
- opcode[0] = 0xF821FD01; // stdu r1,-0x300(r1)
- opcode[1] = 0xF8410080; // std r2,0x80(r1)
- opcode[2] = 0xF8610088; // std r3,0x88(r1)
- opcode[3] = 0x7C4802A6; // mfspr r2,lr
- opcode[4] = 0xF8410170; // std r2,0x170(r1) 0xC699EC
- opcode[5] = 0x38600000; // li r3, 0x0
- opcode[6] = 0x64630000 + ((((uint32_t)hookHandler) >> 16) & 0xFFFF); // oris r3,r3,0x188 opd@hi
- opcode[7] = 0x60630000 + (((uint32_t)hookHandler) & 0xFFFF); // ori r3,r3,0x150 opd@low
- opcode[8] = 0x80430004; // lwz r2,0x4(r3)
- opcode[9] = 0x80630000; // lwz r3,0x0(r3) 0x18882B0 (sprx toc)
- opcode[10] = 0x7C6803A6; // mtspr lr,r3
- opcode[11] = 0x4E800020; // blr
- WriteProcessMemory((void*)hookHandlerInstallationAddress, opcode, sizeof(opcode));
- return true;
- }
- void HookAnyToHandler(uint32_t someTypeOfAllocator, uint32_t Destination, uint32_t Address)
- {
- printf("HookAnyToHandler\n");
- SetupHookHandler(0x10080, HookHandlerAsm1);
- //printf("Destination: 0x%X\n", Destination);
- //Destination = (void*)*(uint32_t*)Destination; // opd_s
- //printf("Destination: 0x%X\n", Destination);
- uint32_t branchTo = 0x10080;
- uint32_t branchFrom = Address;
- // branch link hook
- // 0x48000001
- // 0x4C000001
- // branch hook
- // 0x48000000
- // 0x4C000000
- uint32_t branchInstruction = (branchTo > branchFrom) ?
- 0x48000001 + (branchTo - branchFrom) :
- 0x4C000001 - (branchFrom - branchTo);
- printf("branchInstruction: 0x%X\n", branchInstruction);
- WriteProcessMemory((void*)branchFrom, (const void*)&branchInstruction, 4);
- // todo: it seems to have some type of std:: function. maybe std::bind or std::invoke or something else idk
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement