The last time we analyzed Cydia substrate so hook Framework implementation, in practice, it is found that such a framework does not meet my needs, such as I want to know a function inside a code of the runtime register value, with the original framework can not be done.
the function you want to implement is to print the register environment at the time of the code execution, as long as you specify an address . The address of the HOOK and the TID of the thread , while supporting the addition of multiple addresses.
a generic message printing function is implemented first
void printallreg (INT REG_R0,INT REG_R1,INT REG_R2,INT REG_R3,INT STACK_SP, INT STACK_SP2) { int *psp2 = &stack_sp2; int reg_r12 = * (psp2+1); int reg_r11 = * (pSP2+2); int reg_r10 = * (psp2+3); int reg_r9 = * (psp2+4); int reg_r8 = * (psp2+5); int reg_r7 = * (psp2+13); int reg_r6 = * (psp2+12); int reg_r5 = * (psp2+11); int reg_r4 = * (PSP2+10); char *pformat= "hookaddr:0x%08x tid=%x r0:0x%08x r1:0x%08x r2:0x%08x r3:0x%08x \nr4:0x%08xr5:0x%08x r6:0x%08x r7:0x%08x r8:0x%08x r9 : 0x%08x r10:0x%08x R11:0x%08xR12:0x%08x "; logd (Pformat, (stack_sp2-1-(int) psselibbase), Gettid (), Reg_r0,reg_r1,reg _R2,REG_R3,REG_R4,REG_R5,REG_R6,REG_R7,REG_R8,REG_R9,REG_R10,REG_R11,REG_R12);}
Inside the specific parameter meaning is later said.
Printallreg to be called by a transit function, this function must meet the following requirements:
1. the value of the R0-r12,LR Register cannot be changed before and after the call
2. after calling the print function, skip to the old function
3. put the monitoring address into the stack, this requirement is more critical, otherwise printed out do not know where the code is printed, there is no point.
meet these three-point requirements at all, C language function is certainly not possible, only with arm assembly to achieve the
Void hookaddr () {__asm__ ( "push {r0-r7} \t\n"//save registers that may change "mov r4,r8 \t\n" "push {r4} \t\n" "Mov r4 , r9 \t\n " " push {r4} \t\n " "mov r4,r10 \t\n" "push {r4} \t\n" "Mov r4 , r11 \t\n " " push {r4} \t\n " "mov r4,r12 \t\n" "Push &nbSp {r4} \t\n "//R8-r12 into the stack, direct push {r8} Such instructions are not supported " LDR r7,=0x1a2b3001\t\n "//0x1a2b3001" What does that mean? "push {r7} \t\n" "push {lr} \t\n"//will return the address into the stack, printallreg after execution, the LR register will be changed "ldr r7, =printallreg \t\n"//After two addresses are in the stack, call the print function "blx r7 \t\n" " pop {r7} \t\n " " mov lr,r7 \t\n "//Recovery lr " pop {r7} \ t\n " " pop {r4} \t\n " "mov r12,r4 \t\n"//r12 after RLX, will be changed, here specifically to restore the "pop {r0-r3} \t\n" // Balance stacks "pop {r0-r7} \t\n" Restore r0-r7 "mov r0,r0 \t\n" //let the following BX  PC instruction 4 byte alignment "bx pc \t\n"//go to arm mode for jump "mov r0,r0 \t\n"//Placeholder "mov r0,r0 \t\n"//placeholder, where the back will be patch-off "MOV r0,r0 \t\n "//placeholder, there will be patches off the back " mov r0,r0 \t \//placeholder, the back will be patch off "bx lr \t\n");}
after compiling this function, the the results of IDA disassembly are as follows:
650) this.width=650; "src=" Http://s3.51cto.com/wyfs02/M01/57/31/wKioL1SUC5yQO82gAAU0E6OUgcE201.jpg "title=" Image001.png "alt=" Wkiol1suc5yqo82gaau0e6ougce201.jpg "/>
the instructions in the red box are the instructions we need patches .
0x1a2b3001 takes four bytes for this value, which is to be put into the stack for Printallreg , where we write the address of the HOOK and can be used by the Printallreg function.
then look back at the printallreg int Reg_r12 =* (psp2+1); The function of this instruction, from which we know that when calling Printallreg , the stack values are arranged in such a way that Lr,hook ADDR,R12,R11,R10,R9,R8,R7,R6,R5,R4,
STACK_SP2 Point is hookaddr, backward recursion, you can put r12-r4 address read out, of course, can also change the Printallreg call interface, Pass all these values in the parameters.
The first red box , Patch into a jump instruction , 0x16e0 put the next four bytes of content loaded into the PC's instructions,0x16e4 put a jump address
use the following function for patch
Void setaddrhook (Void* rawfunc) { int memsize = 0x60; char *membase = Mmap (0,memsize,prot_read| prot_write | prot_exec,map_anonymous | map_private,0,0); if (membase) { void*pHookFunc; pHookFunc= (char*) hookaddr; if (((int.) phookfunc)%4) { pHookFunc = (char*) hookaddr -1; } memcpy (membase,phookfunc,memsize); Mshookfunction (rawfunc, (void*) (membase+1), (void**) (membase+0x38)); * (int*) (membase+0x40) = (int) rawfunc; * (int*) (memBase+0x34) =0xe51ff004 ; int* pFunc = (int*) ((char*) rawfunc -1); }}
After this function patch , as shown in the relay function
650) this.width=650; "src=" Http://s3.51cto.com/wyfs02/M01/57/34/wKiom1SUCw3hUeCRAAVYvyw5eZM888.jpg "title=" Image003.png "alt=" Wkiom1sucw3huecraavyvyw5ezm888.jpg "/>
each hook will be allocated a piece of code memory to hold such a transfer function, in the future need to monitor a specified function, only need to call Setaddrhook, enter the address. Limited to the limitations of the Cydia substrate framework, the input hook address points to the front of the first byte preferably not to be split by the jump.
This article is from "Yan 12" blog, please be sure to keep this source http://chenjava.blog.51cto.com/374566/1591851
Retrofit Cydia substrate framework for hooks in function code