@@ -67,63 +67,56 @@ static int calc_jump(uint8_t *output, void *src, void *dst, bool link) {
6767 return calc_near_jump (output , src , dst , link );
6868}
6969
70- static void save_head (void * * src , void * * dst , int min_len ) {
71- // return header len (rewritten insns len to dst)
72- // int skip_len = 0; // insns(to be overwritten) len from src
73- // int head_len = 0; // rewritten insns len to dst
70+ static void * trampo ;
71+ static mach_vm_address_t vmbase ;
72+
73+ static inline void save_header (void * * src , void * * dst , int min_len ) {
74+ mach_vm_protect (mach_task_self (), vmbase , PAGE_SIZE , FALSE, VM_PROT_DEFAULT );
7475#ifdef __aarch64__
75- // skip_len = min_len;
76- // head_len = min_len;
77- // uint8_t bytes_out[MAX_JUMP_SIZE];
78- // read_mem(bytes_out, src, MAX_JUMP_SIZE);
76+ uint32_t insn ;
7977 for (int i = 0 ; i < min_len ; i += 4 ) {
80- uint32_t cur = * (uint32_t * )* src ;
81- if (((cur ^ 0x90000000 ) & 0x9f000000 ) == 0 ) {
78+ insn = * (uint32_t * )* src ;
79+ if (((insn ^ 0x90000000 ) & 0x9f000000 ) == 0 ) {
8280 // adrp
8381 // modify the immediate
8482 // TODO: improve this
85- int32_t len = (cur >> 29 & 0x3 ) | ((cur >> 3 ) & 0x1ffffc );
83+ int32_t len = (insn >> 29 & 0x3 ) | ((insn >> 3 ) & 0x1ffffc );
8684 len += ((int64_t )* src >> 12 ) - ((int64_t )* dst >> 12 );
87- cur &= 0x9f00001f ; // clean the immediate
88- cur = ((len & 0x3 ) << 29 ) | (len >> 2 << 5 ) | cur ;
85+ insn &= 0x9f00001f ; // clean the immediate
86+ insn = ((len & 0x3 ) << 29 ) | (len >> 2 << 5 ) | insn ;
8987 }
90- * (uint32_t * )* dst = cur ;
88+ * (uint32_t * )* dst = insn ;
9189 * dst += 4 ;
9290 * src += 4 ;
9391 }
9492#elif __x86_64__
9593 struct fde64s insn ;
96- uint8_t bytes_in [MAX_JUMP_SIZE * 2 ], bytes_out [MAX_JUMP_SIZE * 4 ];
97- read_mem (bytes_in , src , MAX_JUMP_SIZE * 2 );
98- for (; skip_len < min_len ; skip_len += insn .len ) {
99- uint64_t cur_addr = (uint64_t )src + skip_len ;
100- decode (bytes_in + skip_len , & insn );
94+ for (int i = 0 ; i < min_len ; i += insn .len ) {
95+ decode (* src , & insn );
10196 if (insn .opcode == 0x8b && insn .modrm_rm == RM_DISP32 ) {
10297 // mov r64, [rip+]
10398 // split it into 2 instructions
10499 // mov r64 $rip+(immediate)
100+ * (uint16_t * )* dst = X86_64_MOV_RI64 ;
101+ * dst += sizeof (uint16_t );
102+ * (uint8_t * )* dst = insn .modrm_reg ;
103+ * dst += sizeof (uint8_t );
104+ * (uint64_t * )* dst = insn .disp32 + (uint64_t )* src + insn .len ;
105+ * dst += sizeof (uint64_t );
105106 // mov r64 [r64]
106- * (uint16_t * )(bytes_out + head_len ++ ) = X86_64_MOV_RI64 ;
107- bytes_out [head_len ++ ] += insn .modrm_reg ;
108- * (uint64_t * )(bytes_out + head_len ) = insn .disp32 + cur_addr + insn .len ;
109- head_len += 8 ;
110- * (uint16_t * )(bytes_out + head_len ) = X86_64_MOV_RM64 ;
111- bytes_out [head_len + 2 ] = insn .modrm_reg << 3 | insn .modrm_reg ;
112- head_len += 3 ;
107+ * (uint16_t * )* dst = X86_64_MOV_RM64 ;
108+ * dst += sizeof (uint16_t );
109+ * (uint8_t * )* dst = insn .modrm_reg << 3 | insn .modrm_reg ;
110+ * dst += sizeof (uint8_t );
113111 }
114112 else {
115- memcpy (bytes_out + head_len , bytes_in + skip_len , insn .len );
116- head_len += insn .len ;
113+ memcpy (* dst , * src , insn .len );
114+ * dst += insn .len ;
117115 }
116+ * src += insn .len ;
118117 }
119118#endif
120- // *skip_lenp = skip_len;
121- // *head_lenp = head_len;
122- // int kr = write_mem(dst, bytes_out, head_len);
123- // if (kr != 0) {
124- // LOG_ERROR("save_head: write_mem failed");
125- // }
126- // return kr;
119+ mach_vm_protect (mach_task_self (), vmbase , PAGE_SIZE , FALSE, VM_PROT_READ | VM_PROT_EXECUTE );
127120 return ;
128121}
129122
@@ -136,29 +129,23 @@ int tiny_hook(void *src, void *dst, void **orig) {
136129 kr = write_mem (src , jump_insns , jump_size );
137130 }
138131 else {
139- // static int position = 0;
140- static mach_vm_address_t vmbase ;
141- static void * trampoline ;
142- if (!trampoline ) {
132+ if (!trampo ) {
143133 // alloc a vm to store headers and jumps
144134 kr = mach_vm_allocate (mach_task_self (), & vmbase , PAGE_SIZE , VM_FLAGS_ANYWHERE );
145135 if (kr != 0 ) {
146136 LOG_ERROR ("mach_vm_allocate: %s" , mach_error_string (kr ));
147137 return kr ;
148138 }
149- trampoline = (void * )vmbase ;
139+ trampo = (void * )vmbase ;
150140 }
151- // int skip_len, head_len;
152141 void * bak = src ;
153- * orig = trampoline ;
142+ * orig = trampo ;
154143 jump_size = calc_jump (jump_insns , src , dst , false);
155- mach_vm_protect (mach_task_self (), vmbase , PAGE_SIZE , FALSE, VM_PROT_DEFAULT );
156- save_head (& bak , & trampoline , jump_size );
157- mach_vm_protect (mach_task_self (), vmbase , PAGE_SIZE , FALSE, VM_PROT_READ | VM_PROT_EXECUTE );
144+ save_header (& bak , & trampo , jump_size );
158145 kr |= write_mem (src , jump_insns , jump_size );
159- jump_size += calc_jump (jump_insns , trampoline , bak , false);
160- kr |= write_mem (trampoline , jump_insns , jump_size );
161- trampoline += jump_size ;
146+ jump_size += calc_jump (jump_insns , trampo , bak , false);
147+ kr |= write_mem (trampo , jump_insns , jump_size );
148+ trampo += jump_size ;
162149 }
163150 return kr ;
164151}
0 commit comments