Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #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);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement