Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- reference https://pastebin.com/yezsesij (enstone hooking. scroll to the bottom)
- reference https://pastebin.com/RBYPZEb5 (original)
- GOAL:
- - make a hooking method without the need of a stub. that way we can use it on HEN and hopefully in Kernel LV2
- - have the ability to hook functions with less than 4 instructions
- TODO
- - change executable detour location from 0xA104E8 to 0x10000 (ELF segment) so it works on any game
- - get rid of empty memory addresses (0x10065600) and use the stack
- - get rid of redundant parameters
- - fix warnings
- - make into a class?
- - find a better way to using get "original"
- - use __builtin_return_address() to get LR
- - use __builtin_get_toc() to get r2
- - use __reg(3) __reg(4) ect.. to get registers
- ------------------------------------------------------------------------------------------------------------------------------------
- Revision #2 by TheRouLetteBoi
- - addded 2 examples
- - auto increment and find hooks using STL
- - clean up code so it is easier to understand
- - changed detour location to 0x10080 to support all games
- - renamed one_hook to HookHandler
- - remove PatchInJump
- - removed "some" not all redundant parameters
- - fixed warnings
- #undef vector
- #include <vector>
- #include <algorithm>
- #define MAKE_JUMP(addr, to) *(uint32_t *)(addr) = (0x12 << 26) | ((((to-(addr))>>2)&0xFFFFFF) << 2)
- #define __NAKED __attribute__((naked))
- using original_t = void(*)();
- using hooked_t =
- uint64_t(*)(original_t,
- uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t,
- uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t);
- struct hookCache
- {
- uint32_t hookAddress;
- uint32_t originalInstruction;
- uint64_t functionCallback;
- };
- std::vector<hookCache> hookList;
- // three free memory locations (24 bytes)
- #define ONE_HOOK_LR *(uint32_t*)0x10065600
- #define ONE_HOOK_R2 *(uint32_t*)0x10065610
- #define ONE_HOOK_BRANCHDATA *(uint32_t*)0x10065608
- // need to add another one of these functions if the function you are hooking does not start with one of these two instructions
- __NAKED void Stub_mflr_r0()
- {
- __asm("mflr %r0");
- // can't put comments on the code below but it's grabbing the address to branch to and r2 and loading them up
- __asm("lis %r11, 0x1006");
- __asm("addi %r11, %r11, 0x5610");
- __asm("lwz %r2, 0x0(%r11)"); // r2 = *(uint32_t*)(0x10065610)
- __asm("lis %r11, 0x1006");
- __asm("addi %r11, %r11, 0x5608");
- __asm("lwz %r11, 0x0(%r11)"); // r11 = *(uint32_t*)(0x10065608)
- __asm("mtctr %r11");
- __asm("bctr"); // jump_to r11
- }
- __NAKED void Stub_r1_0x70()
- {
- __asm("stdu %r1, -0x70(%r1)");
- // can't put comments on the code below but it's grabbing the address to branch to and r2 and loading them up
- __asm("lis %r11, 0x1006");
- __asm("addi %r11, %r11, 0x5610");
- __asm("lwz %r2, 0x0(%r11)"); // r2 = *(uint32_t*)(0x10065610)
- __asm("lis %r11, 0x1006");
- __asm("addi %r11, %r11, 0x5608");
- __asm("lwz %r11, 0x0(%r11)"); // r11 = *(uint32_t*)(0x10065608)
- __asm("mtctr %r11");
- __asm("bctr"); // jump_to r11
- }
- uint32_t ResolveBranch(uint32_t branchAddress)
- {
- uint32_t instruction = *(uint32_t*)(branchAddress);
- int32_t offset = instruction & 0x3FFFFFC;
- if (offset & (1 << 25))
- offset |= ~0x03FFFFFF;
- return branchAddress + offset;
- }
- uint64_t HookHandler(uint64_t r3, uint64_t r4, uint64_t r5, uint64_t r6, uint64_t r7, uint64_t r8, uint64_t r9,
- uint64_t r10, uint64_t r11, uint64_t r12, uint64_t r13, uint64_t r14, uint64_t r15, uint64_t r16, uint64_t r17,
- uint64_t r18, uint64_t r19, uint64_t r20, uint64_t r21)
- {
- uint32_t lr_val = ONE_HOOK_LR;
- printf("LR found: 0x%X\n", lr_val);
- uint32_t branched_from = lr_val - 0x4; // link register -0x4 is the branch command
- uint32_t hookedAddress = ResolveBranch(branched_from);
- printf("hooked address discovered: 0x%X\n", hookedAddress);
- auto currentHook = std::find_if(hookList.begin(), hookList.end(), [&hookedAddress](const hookCache& cache)
- {
- return cache.hookAddress == hookedAddress;
- });
- ONE_HOOK_BRANCHDATA = hookedAddress + 4; // go to the next instruction after it
- original_t original = nullptr;
- uint64_t ret = 0;
- if (hookList.end() != currentHook)
- {
- // find the original instruction depending on our hook
- if ((*currentHook).originalInstruction == 0x7C0802A6) // mflr %r0
- original = &Stub_mflr_r0;
- else if ((*currentHook).originalInstruction == 0xF821FF91) // stdu %r1, -0x70(%r1)
- original = &Stub_r1_0x70;
- if (original != nullptr)
- {
- hooked_t func = (hooked_t)&(*currentHook).functionCallback;
- ret = func(original, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21);
- }
- }
- return ret;
- }
- __NAKED void HookHandlerAsm()
- {
- __asm("mflr %r0");//this will link back to the previous func
- __asm("stdu %r1, -0x70(%r1)");
- __asm("std %r0, 0x60(%r1)");
- //now locate the link register from the previous function
- //branched to - branched from = dif (lower 26 bits of instruction)
- //branched to = dif + branched from
- __asm("lis %r11, 0x1006");//assume r11 is never used
- __asm("addi %r11, %r11, 0x5600");//ONE_HOOK_LR
- __asm("stw %r0, 0x0(%r11)");//stores the lr to get back to the original call point into the spot we like
- __asm("lis %r11, 0x1006");//assume r11 is never used
- __asm("addi %r11, %r11, 0x5610");//ONE_HOOK_R2
- __asm("stw %r2, 0x0(%r11)");//stores the r2 for us to reload later because it is used in many functions
- __asm("bl ._Z11HookHandleryyyyyyyyyyyyyyyyyyy");//if you get a linker error then it is probably because of this
- __asm("ld %r0, 0x60(%r1)");
- __asm("mtlr %r0");//this will be the link register to the
- __asm("addi %r1, %r1, 0x70");
- __asm("blr");//goes all the way back to the function that called our hooked function
- }
- void SetupHook(uint32_t fnAddress, uintptr_t fnCallback)
- {
- uint32_t instructions[4]{};
- instructions[0] = 0x3D600000 + ((fnCallback >> 16) & 0xFFFF); // lis %r11, fnCallback@h
- instructions[1] = 0x616B0000 + (fnCallback & 0xFFFF); // ori %r11, %r11, fnCallback@l
- instructions[2] = 0x7D6903A6; // mtctr %r11
- instructions[3] = 0x4E800420; // bctr
- WriteProcessMemory(sys_process_getpid(), (void*)fnAddress, instructions, sizeof(instructions));
- }
- void InstallHook()
- {
- SetupHook(0x10080, *(uintptr_t*)HookHandlerAsm);
- }
- void AddToHandler(uint32_t fnAddress, uintptr_t fnCallback)
- {
- hookList.push_back({
- fnAddress,
- *reinterpret_cast<uint32_t*>(fnAddress),
- *reinterpret_cast<uint64_t*>(fnCallback)
- });
- MAKE_JUMP(fnAddress, 0x10080);
- }
- EXAMPLES
- using GetLabelTextByHash_t = const char*(*)(uintptr_t labelHashMap, uint32_t labelHash, uintptr_t nameHash);
- const char* GetLabelTextByHashHook(GetLabelTextByHash_t original, uintptr_t labelHashMap, uint32_t labelHash, uintptr_t nameHash)
- {
- if (labelHash == 0x478FDC87)
- return "EPIC GAMER STYLE";
- return original(labelHashMap, labelHash, nameHash);
- }
- using AssignPhysicalIndex_t = uintptr_t(*)(uintptr_t networkPlayerMgr, uintptr_t netGamePlayer, uint8_t index);
- uintptr_t AssignPhysicalIndexHook(AssignPhysicalIndex_t original, uintptr_t networkPlayerMgr, uintptr_t netGamePlayer, uint8_t index)
- {
- printf("AssignPhysicalIndexHook\n");
- printf("netGamePlayer 0x%X\n", netGamePlayer);
- return original(networkPlayerMgr, netGamePlayer, index);
- }
- int main()
- {
- InstallHook();
- // https://imgur.com/usuPNXK
- AddToHandler(0xD91468, (uintptr_t)GetLabelTextByHashHook);
- // https://imgur.com/yMbnnDC
- AddToHandler(0xA15618, (uintptr_t)AssignPhysicalIndexHook);
- }
- ------------------------------------------------------------------------------------------------------------------------------------
- Revision #1 by gopro2027
- - add "original" into function hook
- - fix branch instruction
- #define __NAKED __attribute__ ((naked)) __attribute__((noinline))
- #define NUM_HOOKS 1
- //three free memory locations (24 bytes)
- #define ONE_HOOK_LR *(unsigned int*)0x10065600
- #define ONE_HOOK_BRANCHDATA *(unsigned int*)0x10065608
- #define ONE_HOOK_R2 *(unsigned int*)0x10065610
- typedef uint64_t(*one_hook_function_call)(uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t);
- uint64_t one_hook_dummy_func(uint64_t r3, uint64_t r4, uint64_t r5, uint64_t r6, uint64_t r7, uint64_t r8, uint64_t r9, uint64_t r10, uint64_t r11, uint64_t r12, uint64_t r13, uint64_t r14, uint64_t r15, uint64_t r16, uint64_t r17, uint64_t r18, uint64_t r19, uint64_t r20, uint64_t r21) {
- return 0;
- }
- struct hook_pairs {
- unsigned int hookaddress;
- unsigned int firstinstruction;
- unsigned int functionToCallInSprxOPD;
- };
- hook_pairs one_hooks[NUM_HOOKS];
- //can't put comments on the code below but it's grabbing the address to branch to and r2 and loading them up
- #define one_hook_stub \
- __asm("lis %r11, 0x1006");\
- __asm("addi %r11, %r11, 0x5610");\
- __asm("lwz %r2, 0x0(%r11)");\
- __asm("lis %r11, 0x1006");\
- __asm("addi %r11, %r11, 0x5608");\
- __asm("lwz %r11, 0x0(%r11)");\
- __asm("mtctr %r11");\
- __asm("bctr");//braches to hooked function
- //need to add another one of these functions if the function you are hooking does not start with one of these two instructions
- __NAKED uint64_t one_hook_stub_mflrr0(uint64_t r3, uint64_t r4, uint64_t r5, uint64_t r6, uint64_t r7, uint64_t r8, uint64_t r9, uint64_t r10, uint64_t r11, uint64_t r12, uint64_t r13, uint64_t r14, uint64_t r15, uint64_t r16, uint64_t r17, uint64_t r18, uint64_t r19, uint64_t r20, uint64_t r21) {
- __asm("mflr %r0");
- one_hook_stub;
- }
- __NAKED uint64_t one_hook_stub_r170(uint64_t r3, uint64_t r4, uint64_t r5, uint64_t r6, uint64_t r7, uint64_t r8, uint64_t r9, uint64_t r10, uint64_t r11, uint64_t r12, uint64_t r13, uint64_t r14, uint64_t r15, uint64_t r16, uint64_t r17, uint64_t r18, uint64_t r19, uint64_t r20, uint64_t r21) {
- __asm("stdu %r1, -0x70(%r1)");
- one_hook_stub;
- }
- int one_hook(uint64_t r3, uint64_t r4, uint64_t r5, uint64_t r6, uint64_t r7, uint64_t r8, uint64_t r9, uint64_t r10, uint64_t r11, uint64_t r12, uint64_t r13, uint64_t r14, uint64_t r15, uint64_t r16, uint64_t r17, uint64_t r18, uint64_t r19, uint64_t r20, uint64_t r21) {
- unsigned int lr_val = ONE_HOOK_LR;
- printf("LR found: 0x%X\n",lr_val);
- unsigned int branched_from = ONE_HOOK_LR - 0x4; //link register -0x4 is the branch command
- unsigned int dif = *(unsigned int*)(branched_from) & 0x3FFFFFF; //getting the lower 26 bits of the branch command which is the offset
- unsigned int extra = dif % 4;//should return 0, 1, 2, or 3 //extra will be 1 if bl command (should be)
- dif = dif - extra;//now dif should be the proper dif //subtract the link value (1) from the offset
- int check = dif >> 25;//check the very highest bit of the difference. If it is 1 then it is a negative value, so we extend it to 32 bits
- if (check == 1) {
- dif = dif | 0xFC000000;//extend the negative from 26 bits to 32 bits if it is negative
- }
- unsigned int branched_to = dif + branched_from;
- unsigned int hooked_address = branched_to;
- printf("hooked address discovered: 0x%X\n",hooked_address);
- int hookIndex = -1;
- for (int i = 0; i < NUM_HOOKS; i++) {
- if (one_hooks[i].hookaddress == hooked_address) {
- hookIndex = i;
- }
- }
- ONE_HOOK_BRANCHDATA = hooked_address + 4;//go to the next instruction after it
- one_hook_function_call callFunc = one_hook_dummy_func;
- int ret = 0;
- if (hookIndex != -1) {
- if (one_hooks[hookIndex].firstinstruction == 0x7C0802A6)//mflr %r0
- callFunc = &one_hook_stub_mflrr0;
- else if (one_hooks[hookIndex].firstinstruction == 0xF821FF91)//stdu %r1, -0x70(%r1)
- callFunc = &one_hook_stub_r170;
- else {
- printf("Hook at 0x%X does not have a registered stub for instruction 0x%X !!\n", hooked_address, one_hooks[hookIndex].firstinstruction);
- }
- }
- else {
- printf("Hook at 0x%X does not exist at all (invalid index) !!\n", hooked_address);
- }
- if (hookIndex != -1) {
- opd_s func_ = { *(int*)one_hooks[hookIndex].functionToCallInSprxOPD , *(int*)(one_hooks[hookIndex].functionToCallInSprxOPD + 0x4) };
- uint64_t(*func)(one_hook_function_call hooked_func,uint64_t r3, uint64_t r4, uint64_t r5, uint64_t r6, uint64_t r7, uint64_t r8, uint64_t r9, uint64_t r10, uint64_t r11, uint64_t r12, uint64_t r13, uint64_t r14, uint64_t r15, uint64_t r16, uint64_t r17, uint64_t r18, uint64_t r19, uint64_t r20, uint64_t r21) = (uint64_t(*)(one_hook_function_call,uint64_t r3, uint64_t r4, uint64_t r5, uint64_t r6, uint64_t r7, uint64_t r8, uint64_t r9, uint64_t r10, uint64_t r11, uint64_t r12, uint64_t r13, uint64_t r14, uint64_t r15, uint64_t r16, uint64_t r17, uint64_t r18, uint64_t r19, uint64_t r20, uint64_t r21)) & func_;
- ret = func(callFunc,r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21);
- }
- return ret;
- }
- __NAKED int one_hook_intermediate() {
- __asm("mflr %r0");//this will link back to the previous func
- __asm("stdu %r1, -0x70(%r1)");
- __asm("std %r0, 0x60(%r1)");
- //now locate the link register from the previous function
- //branched to - branched from = dif (lower 26 bits of instruction)
- //branched to = dif + branched from
- __asm("lis %r11, 0x1006");//assume r11 is never used
- __asm("addi %r11, %r11, 0x5600");//ONE_HOOK_LR
- __asm("stw %r0, 0x0(%r11)");//stores the lr to get back to the original call point into the spot we like
- __asm("lis %r11, 0x1006");//assume r11 is never used
- __asm("addi %r11, %r11, 0x5610");//ONE_HOOK_R2
- __asm("stw %r2, 0x0(%r11)");//stores the r2 for us to reload later because it is used in many functions
- __asm("bl ._Z8one_hookyyyyyyyyyyyyyyyyyyy");//if you get a linker error then it is probably because of this
- __asm("ld %r0, 0x60(%r1)");
- __asm("mtlr %r0");//this will be the link register to the
- __asm("addi %r1, %r1, 0x70");
- __asm("blr");//goes all the way back to the function that called our hooked function
- }
- bool onehookhasbeensetup = false;
- void setup_one_hook() {
- //address we are putting it at is X
- //anything between X and X+Y is guarenteed to hit a trap, so it's probably never executed. We assume that and also add a small check just in case it is if necessary
- //Any unused part of the code segment with 4 instructions would technically work. Originally i needed 13 instructions for my code which is why I did the modification and got 13 total, but now only 4 is required because it only uses patchinjump
- //0x38A048 has 10 instructions to work with
- //0xA104F0 has 11 instructions to work with
- //with a slgiht modification (below), 0xA104E8 can be used with 13 instructions and never be ran under normal circumstances
- *(int*)0xA104E4 = 0x48000038;//change this to always branch and squeeze out 2 more instructions
- PatchInJump2(0xA104E8/* + 4*3*/, (int)one_hook_intermediate, false);//4 instructions, false to make it unlinked
- }
- void create_hook_one(unsigned int address, unsigned int hookinsprx) {
- static int hook_counter = 0;
- one_hooks[hook_counter].hookaddress = address;
- one_hooks[hook_counter].firstinstruction = *(unsigned int*)address;
- one_hooks[hook_counter].functionToCallInSprxOPD = hookinsprx;
- hook_counter++;
- //initialize the setup if not done yet
- if (onehookhasbeensetup == false) {
- onehookhasbeensetup = true;
- setup_one_hook();
- }
- //this cannot cannot be a bl, or else the link register for the previous function will be lost
- //must be unlinked
- unsigned int branch_to = 0xA104E8;//address we did patchinjump to.
- unsigned int branch_from = address;
- unsigned int instruction = 0;
- int dif = branch_to - branch_from;
- instruction = 0x48000000 + ((dif) & 0x3FFFFFF);//b instruction forwards and backwards. Last 26 bits are the value :)
- *(int*)address = instruction;
- printf("[Hook] set address 0x%X to instruction 0x%X\n",address,instruction);
- }
- uint64_t EXPLOSION_EVENT_local_hook(one_hook_function_call hooked_func, uint64_t r3, uint64_t r4, uint64_t r5, uint64_t r6, uint64_t r7, uint64_t r8, uint64_t r9, uint64_t r10, uint64_t r11, uint64_t r12, uint64_t r13, uint64_t r14, uint64_t r15, uint64_t r16, uint64_t r17, uint64_t r18, uint64_t r19, uint64_t r20, uint64_t r21) {
- printf("You created an explosion!\n");
- return hooked_func(r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,r13,r14,r15,r16,r17,r18,r19,r20,r21);
- }
- void setup_hooks() {
- create_hook_one(0x12C5728, (int)EXPLOSION_EVENT_local_hook);
- }
- -------------------------------------------------------------------------------------------------------------------------------
- Initial Commit by gopro2027
- #define NUM_HOOKS 1
- //two free memory locations (16 bytes)
- #define ONE_HOOK_LR *(unsigned int*)0x10065600
- #define ONE_HOOK_BRANCHDATA *(unsigned int*)0x10065608
- struct hook_pairs {
- unsigned int hookaddress;
- unsigned int firstinstruction;
- unsigned int functionToCallInSprxOPD;
- };
- hook_pairs one_hooks[NUM_HOOKS];
- #define one_hook_stub \
- __asm("lis %r11, 0x1006");\
- __asm("addi %r11, %r11, 0x5608");\
- __asm("lwz %r11, 0x0(%r11)");\
- __asm("mtctr %r11");\
- __asm("bctr");//branches to hooked function
- //need to add another one of these functions if the function you are hooking does not start with one of these two instructions
- __attribute__((naked)) int one_hook_stub_mflrr0(uint64_t r3, uint64_t r4, uint64_t r5, uint64_t r6, uint64_t r7, uint64_t r8, uint64_t r9, uint64_t r10, uint64_t r11, uint64_t r12, uint64_t r13, uint64_t r14, uint64_t r15, uint64_t r16, uint64_t r17, uint64_t r18, uint64_t r19, uint64_t r20, uint64_t r21) {
- __asm("mflr %r0");
- one_hook_stub;
- }
- __attribute__((naked)) int one_hook_stub_r170(uint64_t r3, uint64_t r4, uint64_t r5, uint64_t r6, uint64_t r7, uint64_t r8, uint64_t r9, uint64_t r10, uint64_t r11, uint64_t r12, uint64_t r13, uint64_t r14, uint64_t r15, uint64_t r16, uint64_t r17, uint64_t r18, uint64_t r19, uint64_t r20, uint64_t r21) {
- __asm("stdu %r1, -0x70(%r1)");
- one_hook_stub;
- }
- int one_hook(uint64_t r3, uint64_t r4, uint64_t r5, uint64_t r6, uint64_t r7, uint64_t r8, uint64_t r9, uint64_t r10, uint64_t r11, uint64_t r12, uint64_t r13, uint64_t r14, uint64_t r15, uint64_t r16, uint64_t r17, uint64_t r18, uint64_t r19, uint64_t r20, uint64_t r21) {
- unsigned int lr_val = ONE_HOOK_LR;
- printf("LR found: 0x%X\n", lr_val);//lr val was the original bytes for some reason 0x636C6544.....
- unsigned int branched_from = ONE_HOOK_LR - 0x4;
- unsigned int dif = *(unsigned int*)(branched_from) & 0xFFFFFF;
- unsigned int extra = dif % 4;//should return 0, 1, 2, or 3
- dif = dif - extra;//now dif should be the proper dif
- unsigned int branched_to = dif + branched_from;//should be correct!
- unsigned int hooked_address = branched_to;
- printf("hooked address discovered: 0x%X\n", hooked_address);
- unsigned int instruction = 0;
- unsigned int functionToCallInSprxOPD = 0;
- for (int i = 0; i < NUM_HOOKS; i++) {
- if (one_hooks[i].hookaddress == hooked_address) {
- instruction = one_hooks[i].firstinstruction;
- functionToCallInSprxOPD = one_hooks[i].functionToCallInSprxOPD;
- }
- }
- bool shouldCallOrig = true;
- if (functionToCallInSprxOPD != 0) {
- //need to fix the function first before we call it
- opd_s func_ = { *(int*)functionToCallInSprxOPD , *(int*)(functionToCallInSprxOPD + 0x4) };
- uint64_t(*func)(uint64_t r3, uint64_t r4, uint64_t r5, uint64_t r6, uint64_t r7, uint64_t r8, uint64_t r9, uint64_t r10, uint64_t r11, uint64_t r12, uint64_t r13, uint64_t r14, uint64_t r15, uint64_t r16, uint64_t r17, uint64_t r18, uint64_t r19, uint64_t r20, uint64_t r21) = (uint64_t(*)(uint64_t r3, uint64_t r4, uint64_t r5, uint64_t r6, uint64_t r7, uint64_t r8, uint64_t r9, uint64_t r10, uint64_t r11, uint64_t r12, uint64_t r13, uint64_t r14, uint64_t r15, uint64_t r16, uint64_t r17, uint64_t r18, uint64_t r19, uint64_t r20, uint64_t r21)) & func_;
- shouldCallOrig = func(r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21);
- }
- ONE_HOOK_BRANCHDATA = hooked_address;
- int ret = 0;
- if (shouldCallOrig) {
- //printf("About to call on instruction: 0x%X\n", instruction);
- if (instruction == 0x7C0802A6)//mflr %r0
- ret = one_hook_stub_mflrr0(r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21);
- else if (instruction == 0xF821FF91)//stdu %r1, -0x70(%r1)
- ret = one_hook_stub_r170(r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21);
- else
- printf("Hook at 0x%X does not have a registered stub for instruction 0x%X !!\n", hooked_address, instruction);
- }
- return ret;
- }
- __attribute__((naked)) int one_hook_intermediate()
- {
- __asm("mflr %r0");//this will link back to the previous func
- __asm("stdu %r1, -0x70(%r1)");
- __asm("std %r0, 0x60(%r1)");
- //now locate the link register from the previous function
- //branched to - branched from = dif (lower 3 bytes of instruction)
- //branched to = dif + branched from
- __asm("lis %r11, 0x1006");//assume r11 is never used
- __asm("addi %r11, %r11, 0x5600");
- __asm("stw %r0, 0x0(%r11)");//stores the lr value into the spot we like
- __asm("bl ._Z8one_hookyyyyyyyyyyyyyyyyyyy");
- __asm("ld %r0, 0x60(%r1)");
- __asm("mtlr %r0");//this will be the link register to the
- __asm("addi %r1, %r1, 0x70");
- __asm("blr");//goes all the way back to the function that called our hooked function
- }
- bool onehookhasbeensetup = false;
- void setup_one_hook() {
- //address we are putting it at is X
- //anything between X and X+Y is guaranteed to hit a trap, so it's probably never executed. We assume that and also add a small check just in case it is if necessary
- //0x38A048 has 10 instructions to work with
- //0xA104F0 has 11 instructions to work with
- //with a signed int modification (below), 0xA104E8 can be used with 13 instructions and never be ran under normal circumstances
- *(int*)0xA104E4 = 0x48000038;//change this to always branch and squeeze out 2 more instructions
- //bytes based off this function: 0x474054 entityToIndex
- unsigned char bytes_storelr[] = { 0xF8, 0x21, 0xFF, 0x91, 0x7C, 0x08, 0x02, 0xA6, 0xF8, 0x01, 0x00, 0x80 };//3 instructions
- unsigned char bytes_retreivelrandbranch[] = { 0xE8, 0x01, 0x00, 0x80, 0x7C, 0x08, 0x03, 0xA6, 0x38, 0x21, 0x00, 0x70, 0x4E, 0x80, 0x00, 0x20 };//4 instructions
- //memcpy(0xA104E8 + 4*0, bytes_storelr, 4*3);//3 instructions
- PatchInJump((uint32_t*)0xA104E8/* + 4*3*/, (uint32_t)one_hook_intermediate, false);//4 instructions
- //memcpy(0xA104E8 + 4*7, bytes_retreivelrandbranch, 4 * 4);//4 instructions
- //this code will
- }
- void create_hook_one(unsigned int address, unsigned int hookinsprx)
- {
- static int hook_counter = 0;
- one_hooks[hook_counter].hookaddress = address;
- one_hooks[hook_counter].firstinstruction = *(unsigned int*)address;
- one_hooks[hook_counter].functionToCallInSprxOPD = hookinsprx;
- hook_counter++;
- //initialize the setup if not done yet
- if (onehookhasbeensetup == false)
- {
- onehookhasbeensetup = true;
- setup_one_hook();
- }
- //this cannot cannot be a bl, or else the link register for the previous function will be lost
- //must be unlinked
- unsigned int branch_to = 0xA104E8;//address we did patchinjump to
- unsigned int branch_from = address;
- unsigned int instruction = 0;
- int dif = branch_to - branch_from;
- if (dif < 0)
- {
- instruction = 0x4b000000 + ((dif) & 0xFFFFFF);//b but backwards direction
- }
- else
- {
- instruction = 0x48000000 + ((dif) & 0xFFFFFF);//b instruction
- }
- *(int*)address = instruction;
- printf("[Hook] set address 0x%X to instruction 0x%X\n", address, instruction);
- }
- bool GetLabelTextByHashHook(int32_t unk_20668B0, int32_t label_hash, int32_t unk_1809560)
- {
- printf("GetLabelTextByHashHook\n");
- printf("label_hash: 0x%X\n", label_hash);
- if (label_hash == 0x478FDC87)
- printf("????\n");
- return true; // return true to get original
- }
- void setup_hooks()
- {
- printf("Creating hooks...");
- create_hook_one(0xD91468, (int)GetLabelTextByHashHook);
- printf("Done creating hooks.");
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement