Advertisement
gopro2027

PS3 GTA V HookFunctionStart Alternative/1 instruction hooks

Apr 17th, 2021 (edited)
500
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.63 KB | None | 0 0
  1. #define __NAKED __attribute__ ((naked)) __attribute__((noinline))
  2.  
  3. #define NUM_HOOKS 1
  4.  
  5. //three free memory locations (24 bytes)
  6. #define ONE_HOOK_LR *(unsigned int*)0x10065600
  7. #define ONE_HOOK_BRANCHDATA *(unsigned int*)0x10065608
  8. #define ONE_HOOK_R2 *(unsigned int*)0x10065610
  9.  
  10. 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);
  11.  
  12.  
  13. 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) {
  14.     return 0;
  15. }
  16.  
  17. struct hook_pairs {
  18.     unsigned int hookaddress;
  19.     unsigned int firstinstruction;
  20.     unsigned int functionToCallInSprxOPD;
  21. };
  22.  
  23. hook_pairs one_hooks[NUM_HOOKS];
  24.  
  25. //can't put comments on the code below but it's grabbing the address to branch to and r2 and loading them up
  26. #define one_hook_stub \
  27.     __asm("lis %r11, 0x1006");\
  28.     __asm("addi %r11, %r11, 0x5610");\
  29.     __asm("lwz %r2, 0x0(%r11)");\
  30.     __asm("lis %r11, 0x1006");\
  31.     __asm("addi %r11, %r11, 0x5608");\
  32.     __asm("lwz %r11, 0x0(%r11)");\
  33.     __asm("mtctr %r11");\
  34.     __asm("bctr");//braches to hooked function
  35.  
  36.  
  37.  
  38. //need to add another one of these functions if the function you are hooking does not start with one of these two instructions
  39. __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) {
  40.     __asm("mflr %r0");
  41.  
  42.     one_hook_stub;
  43. }
  44.  
  45. __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) {
  46.     __asm("stdu %r1, -0x70(%r1)");
  47.  
  48.     one_hook_stub;
  49. }
  50.  
  51.  
  52. 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) {
  53.     unsigned int lr_val = ONE_HOOK_LR;
  54.  
  55.     printf("LR found: 0x%X\n",lr_val);
  56.  
  57.     unsigned int branched_from = ONE_HOOK_LR - 0x4;                     //link register -0x4 is the branch command
  58.     unsigned int dif = *(unsigned int*)(branched_from) & 0x3FFFFFF;     //getting the lower 26 bits of the branch command which is the offset
  59.     unsigned int extra = dif % 4;//should return 0, 1, 2, or 3          //extra will be 1 if bl command (should be)
  60.     dif = dif - extra;//now dif should be the proper dif                //subtract the link value (1) from the offset
  61.  
  62.     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
  63.     if (check == 1) {
  64.         dif = dif | 0xFC000000;//extend the negative from 26 bits to 32 bits if it is negative
  65.     }
  66.  
  67.     unsigned int branched_to = dif + branched_from;
  68.    
  69.     unsigned int hooked_address = branched_to;
  70.     printf("hooked address discovered: 0x%X\n",hooked_address);
  71.    
  72.     int hookIndex = -1;
  73.     for (int i = 0; i < NUM_HOOKS; i++) {
  74.         if (one_hooks[i].hookaddress == hooked_address) {
  75.             hookIndex = i;
  76.         }
  77.     }
  78.  
  79.      
  80.     ONE_HOOK_BRANCHDATA = hooked_address + 4;//go to the next instruction after it
  81.  
  82.     one_hook_function_call callFunc = one_hook_dummy_func;
  83.  
  84.     int ret = 0;
  85.     if (hookIndex != -1) {
  86.         if (one_hooks[hookIndex].firstinstruction == 0x7C0802A6)//mflr %r0
  87.             callFunc = &one_hook_stub_mflrr0;
  88.         else if (one_hooks[hookIndex].firstinstruction == 0xF821FF91)//stdu %r1, -0x70(%r1)
  89.             callFunc = &one_hook_stub_r170;
  90.         else {
  91.             printf("Hook at 0x%X does not have a registered stub for instruction 0x%X !!\n", hooked_address, one_hooks[hookIndex].firstinstruction);
  92.         }
  93.     }
  94.     else {
  95.         printf("Hook at 0x%X does not exist at all (invalid index) !!\n", hooked_address);
  96.     }
  97.    
  98.  
  99.     if (hookIndex != -1) {
  100.        
  101.  
  102.         opd_s func_ = { *(int*)one_hooks[hookIndex].functionToCallInSprxOPD , *(int*)(one_hooks[hookIndex].functionToCallInSprxOPD + 0x4) };
  103.         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_;
  104.  
  105.         ret = func(callFunc,r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21);
  106.     }
  107.    
  108.    
  109.    
  110.  
  111.     return ret;
  112. }
  113.  
  114. __NAKED int one_hook_intermediate() {
  115.     __asm("mflr %r0");//this will link back to the previous func
  116.     __asm("stdu %r1, -0x70(%r1)");
  117.     __asm("std %r0, 0x60(%r1)");
  118.  
  119.     //now locate the link register from the previous function
  120.     //branched to - branched from = dif (lower 26 bits of instruction)
  121.     //branched to = dif + branched from
  122.     __asm("lis %r11, 0x1006");//assume r11 is never used
  123.     __asm("addi %r11, %r11, 0x5600");//ONE_HOOK_LR
  124.     __asm("stw %r0, 0x0(%r11)");//stores the lr to get back to the original call point into the spot we like
  125.  
  126.     __asm("lis %r11, 0x1006");//assume r11 is never used
  127.     __asm("addi %r11, %r11, 0x5610");//ONE_HOOK_R2
  128.     __asm("stw %r2, 0x0(%r11)");//stores the r2 for us to reload later because it is used in many functions
  129.  
  130.  
  131.     __asm("bl ._Z8one_hookyyyyyyyyyyyyyyyyyyy");//if you get a linker error then it is probably because of this
  132.  
  133.  
  134.  
  135.     __asm("ld %r0, 0x60(%r1)");
  136.     __asm("mtlr %r0");//this will be the link register to the
  137.     __asm("addi %r1, %r1, 0x70");
  138.     __asm("blr");//goes all the way back to the function that called our hooked function
  139. }
  140.  
  141.  
  142. bool onehookhasbeensetup = false;
  143. void setup_one_hook() {
  144.     //address we are putting it at is X
  145.     //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
  146.     //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
  147.    
  148.     //0x38A048 has 10 instructions to work with
  149.     //0xA104F0 has 11 instructions to work with
  150.     //with a slgiht modification (below), 0xA104E8 can be used with 13 instructions and never be ran under normal circumstances
  151.     *(int*)0xA104E4 = 0x48000038;//change this to always branch and squeeze out 2 more instructions
  152.  
  153.     PatchInJump2(0xA104E8/* + 4*3*/, (int)one_hook_intermediate, false);//4 instructions, false to make it unlinked
  154.  
  155. }
  156.  
  157. void create_hook_one(unsigned int address, unsigned int hookinsprx) {
  158.     static int hook_counter = 0;
  159.     one_hooks[hook_counter].hookaddress = address;
  160.     one_hooks[hook_counter].firstinstruction = *(unsigned int*)address;
  161.     one_hooks[hook_counter].functionToCallInSprxOPD = hookinsprx;
  162.     hook_counter++;
  163.  
  164.  
  165.     //initialize the setup if not done yet
  166.     if (onehookhasbeensetup == false) {
  167.         onehookhasbeensetup = true;
  168.         setup_one_hook();
  169.     }
  170.  
  171.     //this cannot cannot be a bl, or else the link register for the previous function will be lost
  172.     //must be unlinked
  173.     unsigned int branch_to = 0xA104E8;//address we did patchinjump to.
  174.     unsigned int branch_from = address;
  175.     unsigned int instruction = 0;
  176.     int dif = branch_to - branch_from;
  177.     instruction = 0x48000000 + ((dif) & 0x3FFFFFF);//b instruction forwards and backwards. Last 26 bits are the value :)
  178.     *(int*)address = instruction;
  179.     printf("[Hook] set address 0x%X to instruction 0x%X\n",address,instruction);
  180.  
  181. }
  182.  
  183. 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) {
  184.     printf("You created an explosion!\n");
  185.     return hooked_func(r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,r13,r14,r15,r16,r17,r18,r19,r20,r21);
  186. }
  187.  
  188. void setup_hooks() {
  189.     create_hook_one(0x12C5728, (int)EXPLOSION_EVENT_local_hook);
  190. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement