├── README.md ├── example ├── Android.mk ├── Application.mk └── example.c └── inject └── Arm64-v8a ├── Android.mk ├── Application.mk ├── ReadMe.txt ├── elf_utils.c ├── elf_utils.h ├── inject.c ├── logger.h ├── ptrace_utils.c ├── ptrace_utils.h ├── tools.c └── tools.h /README.md: -------------------------------------------------------------------------------- 1 | # LKHook 2 | 3 | Support android Hook 4 | 5 | for armeabi-v7a 6 | for arm64-v8a -------------------------------------------------------------------------------- /example/Android.mk: -------------------------------------------------------------------------------- 1 | LOCAL_PATH := $(call my-dir) 2 | 3 | include $(CLEAR_VARS) 4 | 5 | # 编译生成的模块的名称 6 | LOCAL_MODULE := example 7 | 8 | # 需要被编译的源码文件 9 | LOCAL_SRC_FILES := example.c 10 | 11 | # 支持log日志打印android/log.h里函数调用的需要 12 | LOCAL_LDLIBS += -L$(SYSROOT)/usr/lib -llog 13 | 14 | # 编译模块生成可执行文件 15 | include $(BUILD_SHARED_LIBRARY) -------------------------------------------------------------------------------- /example/Application.mk: -------------------------------------------------------------------------------- 1 | # 编译生成的模块运行支持的平台 2 | APP_ABI := arm64-v8a 3 | # 设置编译连接的工具的版本 4 | #NDK_TOOLCHAIN_VERSION = 4.9 5 | APP_PLATFORM = android-23 -------------------------------------------------------------------------------- /example/example.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define LOG_TAG "example" 5 | #define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__) 6 | 7 | 8 | int entry() 9 | { 10 | LOGI("Just a entry!\n"); 11 | 12 | return 0; 13 | } 14 | 15 | void __attribute__ ((constructor)) load() 16 | { 17 | entry(); 18 | } 19 | 20 | -------------------------------------------------------------------------------- /inject/Arm64-v8a/Android.mk: -------------------------------------------------------------------------------- 1 | LOCAL_PATH := $(call my-dir) 2 | 3 | include $(CLEAR_VARS) 4 | 5 | # 编译生成的模块的名称 6 | LOCAL_MODULE := inject 7 | 8 | # 需要被编译的源码文件 9 | LOCAL_SRC_FILES := inject.c\ 10 | ptrace_utils.c\ 11 | tools.c\ 12 | elf_utils.c 13 | 14 | # 编译模块生成可执行文件 15 | include $(BUILD_EXECUTABLE) -------------------------------------------------------------------------------- /inject/Arm64-v8a/Application.mk: -------------------------------------------------------------------------------- 1 | # 编译生成的模块运行支持的平台 2 | APP_ABI := arm64-v8a 3 | # 设置编译连接的工具的版本 4 | #NDK_TOOLCHAIN_VERSION = 4.9 5 | APP_PLATFORM = android-23 -------------------------------------------------------------------------------- /inject/Arm64-v8a/ReadMe.txt: -------------------------------------------------------------------------------- 1 | 1:How to Build 2 | 3 | ndk-build NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=./Android.mk NDK_APPLICATION_MK=./Application.mk 4 | 5 | 2:arch 6 | This is only for arch64-v8a -------------------------------------------------------------------------------- /inject/Arm64-v8a/elf_utils.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #define DEBUG 11 | 12 | #include "tools.h" 13 | #include "elf_utils.h" 14 | #include "ptrace_utils.h" 15 | #include "logger.h" 16 | 17 | void* get_module_base(pid_t pid, const char* module_name) { 18 | FILE *fp; 19 | long addr = 0; 20 | char *pch; 21 | char filename[32]; 22 | char line[1024]; 23 | 24 | if (pid < 0) { 25 | /* self process */ 26 | snprintf(filename, sizeof(filename), "/proc/self/maps"); 27 | } else { 28 | snprintf(filename, sizeof(filename), "/proc/%d/maps", pid); 29 | } 30 | 31 | fp = fopen(filename, "r"); 32 | 33 | if (fp != NULL) { 34 | while (fgets(line, sizeof(line), fp)) { 35 | 36 | if (strstr(line, module_name)) { 37 | pch = strtok(line, "-"); 38 | addr = strtoul(pch, NULL, 16); 39 | 40 | if (addr == 0x8000) 41 | addr = 0; 42 | 43 | break; 44 | } 45 | } 46 | 47 | fclose(fp); 48 | } 49 | 50 | return (void *) addr; 51 | } 52 | 53 | void* find_space_by_mmap(pid_t target_pid, int size) { 54 | struct user_pt_regs regs; 55 | if (ptrace_getregs(target_pid, ®s) == -1) 56 | return 0; 57 | 58 | long parameters[10]; 59 | 60 | /* call mmap */ 61 | parameters[0] = 0; // addr 62 | parameters[1] = size; // size 63 | parameters[2] = PROT_READ | PROT_WRITE | PROT_EXEC; // prot 64 | parameters[3] = MAP_ANONYMOUS | MAP_PRIVATE; // flags 65 | parameters[4] = 0; //fd 66 | parameters[5] = 0; //offset 67 | 68 | void *remote_mmap_addr = get_remote_address(target_pid, get_method_address("/system/lib64/libc.so", "mmap")); 69 | LOGI("[+] Calling mmap in target process. mmap addr %p.\n", remote_mmap_addr); 70 | 71 | if (remote_mmap_addr == NULL) { 72 | LOGE("[-] Get Remote mmap address fails.\n"); 73 | return 0; 74 | } 75 | 76 | if (ptrace_call(target_pid, (uint64_t) remote_mmap_addr, parameters, 6, ®s) == -1) 77 | return 0; 78 | 79 | if (ptrace_getregs(target_pid, ®s) == -1) 80 | return 0; 81 | 82 | LOGI("[+] Target process returned from mmap, return r0=%llx, r7=%llx, pc=%llx, \n", regs.regs[0], regs.regs[7], regs.pc); 83 | 84 | return regs.pc == 0 ? (void *) regs.regs[0] : 0; 85 | } 86 | 87 | static char* nexttok(char **strp) { 88 | char *p = strsep(strp, " "); 89 | return p == NULL ? "" : p; 90 | } 91 | 92 | void* find_space_in_maps(pid_t pid, int size) { 93 | char statline[1024]; 94 | FILE * fp; 95 | uint64_t* addr = (uint64_t*) 0x40008000; 96 | char *address, *proms, *ptr; 97 | const char* tname = "/system/lib64/libc.so"; 98 | const char* tproms = "r-xp"; 99 | int tnaem_size = strlen(tname); 100 | int tproms_size = strlen(tproms); 101 | 102 | size = ((size / 8) + 1) * 8; 103 | 104 | sprintf(statline, "/proc/%d/maps", pid); 105 | 106 | fp = fopen(statline, "r"); 107 | if (fp == 0) 108 | return 0; 109 | 110 | while (fgets(statline, sizeof(statline), fp)) { 111 | ptr = statline; 112 | address = nexttok(&ptr); // skip address 113 | proms = nexttok(&ptr); // skip proms 114 | nexttok(&ptr); // skip offset 115 | nexttok(&ptr); // skip dev 116 | nexttok(&ptr); // skip inode 117 | 118 | while (*ptr != '\0') { 119 | if (*ptr == ' ') 120 | ptr++; 121 | else 122 | break; 123 | } 124 | 125 | if (ptr && proms && address) { 126 | if (strncmp(tproms, proms, tproms_size) == 0) { 127 | if (strncmp(tname, ptr, tnaem_size) == 0) { 128 | // address like 7f8e29b000-7f8e2a0000 129 | if (strlen(address) == 21) { 130 | addr = (uint64_t*) strtoul(address + 11, NULL, 16); 131 | addr -= size; 132 | printf("proms=%s address=%s name=%s", proms, address, 133 | ptr); 134 | break; 135 | } 136 | } 137 | } 138 | } 139 | } 140 | 141 | fclose(fp); 142 | return (void*) addr; 143 | } 144 | 145 | int find_module_info_by_address(pid_t pid, void* addr, char *module, void** start, void** end) { 146 | char statline[1024]; 147 | FILE *fp; 148 | char *address, *proms, *ptr, *p; 149 | 150 | if ( pid < 0 ) { 151 | /* self process */ 152 | snprintf( statline, sizeof(statline), "/proc/self/maps"); 153 | } else { 154 | snprintf( statline, sizeof(statline), "/proc/%d/maps", pid ); 155 | } 156 | 157 | fp = fopen( statline, "r" ); 158 | 159 | if ( fp != NULL ) { 160 | while ( fgets( statline, sizeof(statline), fp ) ) { 161 | ptr = statline; 162 | address = nexttok(&ptr); // skip address 163 | proms = nexttok(&ptr); // skip proms 164 | nexttok(&ptr); // skip offset 165 | nexttok(&ptr); // skip dev 166 | nexttok(&ptr); // skip inode 167 | 168 | while(*ptr != '\0') { 169 | if(*ptr == ' ') 170 | ptr++; 171 | else 172 | break; 173 | } 174 | 175 | p = ptr; 176 | while(*p != '\0') { 177 | if(*p == '\n') 178 | *p = '\0'; 179 | p++; 180 | } 181 | 182 | //7f8e5bf000-7f8e5c0000 183 | if(strlen(address) == 21) { 184 | address[10] = '\0'; 185 | 186 | *start = (void*)strtoul(address, NULL, 16); 187 | *end = (void*)strtoul(address+11, NULL, 16); 188 | 189 | // LOGI("[%p-%p] %s | %p\n", *start, *end, ptr, addr); 190 | 191 | if(addr > *start && addr < *end) { 192 | strcpy(module, ptr); 193 | 194 | fclose( fp ) ; 195 | return 0; 196 | } 197 | } 198 | } 199 | 200 | fclose( fp ) ; 201 | } 202 | 203 | return -1; 204 | } 205 | 206 | int find_module_info_by_name(pid_t pid, const char *module, void** start, void** end) { 207 | char statline[1024]; 208 | FILE *fp; 209 | char *address, *proms, *ptr, *p; 210 | 211 | if ( pid < 0 ) { 212 | /* self process */ 213 | snprintf( statline, sizeof(statline), "/proc/self/maps"); 214 | } else { 215 | snprintf( statline, sizeof(statline), "/proc/%d/maps", pid ); 216 | } 217 | 218 | fp = fopen( statline, "r" ); 219 | 220 | if ( fp != NULL ) { 221 | while ( fgets( statline, sizeof(statline), fp ) ) { 222 | ptr = statline; 223 | address = nexttok(&ptr); // skip address 224 | proms = nexttok(&ptr); // skip proms 225 | nexttok(&ptr); // skip offset 226 | nexttok(&ptr); // skip dev 227 | nexttok(&ptr); // skip inode 228 | 229 | while(*ptr != '\0') { 230 | if(*ptr == ' ') 231 | ptr++; 232 | else 233 | break; 234 | } 235 | 236 | p = ptr; 237 | while(*p != '\0') { 238 | if(*p == '\n') 239 | *p = '\0'; 240 | p++; 241 | } 242 | 243 | //7f8e5bf000-7f8e5c0000 244 | if(strlen(address) == 21) { 245 | address[10] = '\0'; 246 | 247 | *start = (void*)strtoul(address, NULL, 16); 248 | *end = (void*)strtoul(address+11, NULL, 16); 249 | 250 | // LOGI("[%p-%p] %s \n", *start, *end, ptr); 251 | 252 | if(strncmp(module, ptr, strlen(module)) == 0) { 253 | fclose( fp ) ; 254 | return 0; 255 | } 256 | } 257 | } 258 | 259 | fclose( fp ) ; 260 | } 261 | 262 | return -1; 263 | } 264 | 265 | void* get_remote_address(pid_t pid, void *local_addr) { 266 | char buf[256]; 267 | void* local_start = 0; 268 | void* local_end = 0; 269 | void* remote_start = 0; 270 | void* remote_end = 0; 271 | 272 | if(find_module_info_by_address(-1, local_addr, buf, &local_start, &local_end) < 0) { 273 | LOGI("[-] find_module_info_by_address FAIL"); 274 | return NULL; 275 | } 276 | 277 | LOGI("[+] the local module is %s\n", buf); 278 | 279 | if(find_module_info_by_name(pid, buf, &remote_start, &remote_end) < 0) { 280 | LOGI("[-] find_module_info_by_name FAIL"); 281 | return NULL; 282 | } 283 | 284 | LOGI("[+] the remote module is %s\n", buf); 285 | 286 | // LOGI("local_addr:%lx,local_start:%lx,remote_start:%lx \n",local_addr,local_start,remote_start); 287 | 288 | uint64_t remote = (uint64_t)local_addr - (uint64_t)local_start + (uint64_t)remote_start; 289 | 290 | // LOGI("remote:%lx\n",remote); 291 | 292 | return (void*)remote ; 293 | } 294 | 295 | 296 | -------------------------------------------------------------------------------- /inject/Arm64-v8a/elf_utils.h: -------------------------------------------------------------------------------- 1 | #ifndef ELF_UTILS_H_ 2 | #define ELF_UTILS_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | void* get_module_base(pid_t pid, const char* module_name); 11 | 12 | void* find_space_by_mmap(pid_t target_pid, int size); 13 | 14 | void* find_space_in_maps(pid_t pid, int size); 15 | 16 | int find_module_info_by_address(pid_t pid, void* addr, char *module, void** start, void** end); 17 | 18 | int find_module_info_by_name(pid_t pid, const char *module, void** start, void** end); 19 | 20 | void* get_remote_address(pid_t pid, void *local_addr); 21 | 22 | #endif /* ELF_UTILS_H_ */ 23 | -------------------------------------------------------------------------------- /inject/Arm64-v8a/inject.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | //debug is on 10 | #define DEBUG 11 | //debug is android log 12 | //#define _ANDROID_ 13 | 14 | #include "logger.h" 15 | #include "ptrace_utils.h" 16 | #include "tools.h" 17 | 18 | 19 | #define USAGE "usage:\n inject pid /absolutepath/xxx.so \n" 20 | 21 | struct process_inject { 22 | pid_t pid; 23 | char *dso; 24 | // void *dlopen_addr; 25 | // void *dlsym_addr; 26 | // void *mmap_addr; 27 | } process_inject = {0, "" /*NULL, NULL, NULL*/}; 28 | 29 | 30 | int main(int argc,char *argv[]) 31 | { 32 | if (argc < 2){ 33 | LOGI(USAGE); 34 | exit(0); 35 | } 36 | 37 | process_inject.pid = atoi(argv[1]); 38 | process_inject.dso = strdup(argv[2]); 39 | 40 | LOGI("Try to inject to %d with %s\n",process_inject.pid,process_inject.dso); 41 | 42 | if (access(process_inject.dso, R_OK|X_OK) < 0) { 43 | LOGE("[-] so file must chmod rx\n"); 44 | exit(1); 45 | } 46 | 47 | const char* process_name = get_process_name(process_inject.pid); 48 | int zygote = (int)strstr(process_name,"zygote"); 49 | 50 | LOGI("[+] Try Attach %s ,%d ,zygote:%d\n",process_name,process_inject.pid,zygote); 51 | ptrace_attach(process_inject.pid,zygote); 52 | LOGI("[+] Attach Success!\n"); 53 | 54 | struct user_pt_regs upr={0}; 55 | if (ptrace_getregs(process_inject.pid,&upr) < 0) 56 | { 57 | LOGE("[-] Can't get reg values !\n"); 58 | goto DETACH; 59 | } 60 | LOGI("[+] pc: %llx, LR: %lx\n", upr.pc, upr.regs[30]); 61 | 62 | /*some test*/ 63 | /* 64 | struct user_pt_regs upr={0}; 65 | ptrace_getregs(process_inject.pid,&upr); 66 | show_regs(&upr); 67 | ptrace_setregs(process_inject.pid,&upr); 68 | 69 | uint8_t buffer[32]={0}; 70 | ptrace_read(process_inject.pid,upr.pc,buffer,32); 71 | show_mem(buffer,32); 72 | ptrace_write(process_inject.pid,upr.pc,buffer,32); 73 | */ 74 | // &0x7fffffffff maybe a bug 75 | // void* remote_dlsym_addr = get_remote_address(process_inject.pid, (void *)dlsym) & 0x7fffffffff; 76 | void* remote_dlopen_addr = get_remote_address(process_inject.pid, (void *)dlopen) & 0x7fffffffff; 77 | 78 | // LOGI("[+] remote_dlsym_addr:%lx,remote_dlopen_addr:%lx \n",remote_dlsym_addr,remote_dlopen_addr); 79 | 80 | if(ptrace_dlopen(process_inject.pid, remote_dlopen_addr, process_inject.dso) == NULL){ 81 | LOGE("[-] Ptrace dlopen fail. %s\n", dlerror()); 82 | } 83 | 84 | if (ptrace_setregs(process_inject.pid, &upr) == -1) { 85 | LOGE("[-] Set regs fail. %s\n", strerror(errno)); 86 | goto DETACH; 87 | } 88 | 89 | LOGI("[+] Inject success!\n"); 90 | 91 | 92 | DETACH: 93 | ptrace_detach(process_inject.pid); 94 | LOGI("[+] Inject done!\n"); 95 | 96 | return 0; 97 | } -------------------------------------------------------------------------------- /inject/Arm64-v8a/logger.h: -------------------------------------------------------------------------------- 1 | #ifndef _LOGGER_H_ 2 | #define _LOGGER_H_ 3 | 4 | #ifdef _ANDROID_ 5 | #include 6 | #define LOG_TAG "TTT" 7 | #endif 8 | 9 | #ifdef DEBUG 10 | 11 | #ifdef _ANDROID_ 12 | #define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__) 13 | #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__) 14 | #else 15 | #define LOGI printf 16 | #define LOGE printf 17 | #endif 18 | 19 | #else 20 | #define LOGI(...) while(0) 21 | #define LOGE(...) while(0) 22 | #endif 23 | 24 | #endif /* LOG_H_ */ -------------------------------------------------------------------------------- /inject/Arm64-v8a/ptrace_utils.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #define DEBUG 12 | 13 | #include "logger.h" 14 | #include "ptrace_utils.h" 15 | 16 | 17 | int show_regs(struct user_pt_regs* upr) 18 | { 19 | int i; 20 | for (i=0;i<32;i++){ 21 | if (i % 4 == 0)LOGI("\n"); 22 | LOGI("X%02d: %08llx ",i,upr->regs[i]); 23 | } 24 | 25 | LOGI("\nsp:%08llx pc:%08llx pstate:%08llx \n",upr->sp,upr->pc,upr->pstate); 26 | 27 | return 0; 28 | } 29 | 30 | int show_mem(uint8_t *src,size_t size) 31 | { 32 | int i; 33 | LOGI("Mem start:"); 34 | for (i=0; i 0) { 209 | d.val = ptrace(PTRACE_PEEKTEXT, pid, (void *)dest, NULL); 210 | for (i = 0; i < remain; i++) { 211 | d.chars[i] = *laddr++; 212 | } 213 | 214 | ptrace(PTRACE_POKETEXT, pid, (void *)dest, (void *)d.val); 215 | 216 | } 217 | 218 | return 0; 219 | } 220 | 221 | int ptrace_read( pid_t pid, uint8_t *src, uint8_t *buf, size_t size ) 222 | { 223 | long i, j, remain; 224 | uint8_t *laddr; 225 | 226 | union u { 227 | long val; 228 | char chars[BYTES_WIDTH]; 229 | } d; 230 | 231 | j = size / BYTES_WIDTH; 232 | remain = size % BYTES_WIDTH; 233 | 234 | laddr = buf; 235 | 236 | for ( i = 0; i < j; i ++ ) 237 | { 238 | d.val = ptrace( PTRACE_PEEKTEXT, pid, src, 0 ); 239 | memcpy( laddr, d.chars, BYTES_WIDTH); 240 | src += BYTES_WIDTH; 241 | laddr += BYTES_WIDTH; 242 | } 243 | 244 | if ( remain > 0 ) 245 | { 246 | d.val = ptrace( PTRACE_PEEKTEXT, pid, src, 0 ); 247 | memcpy( laddr, d.chars, remain ); 248 | } 249 | 250 | return 0; 251 | } 252 | 253 | #define NUM_PARAMS_REGISTERS 8 254 | int ptrace_call(pid_t pid, uintptr_t addr, long *params, int num_params, struct user_pt_regs* pupr) 255 | { 256 | int i; 257 | 258 | for (i=0; i < num_params && i < NUM_PARAMS_REGISTERS; i++) 259 | { 260 | pupr->regs[i] = params[i]; 261 | } 262 | 263 | //push remained params onto stack 264 | if (i < num_params) 265 | { 266 | pupr->sp -= (num_params - i) * BYTES_WIDTH; 267 | ptrace_write(pid,(void*)pupr->sp,(uint8_t*)params[i],(num_params -i) * BYTES_WIDTH); 268 | } 269 | 270 | pupr->pc = addr; 271 | if (pupr->pc & 1) 272 | { 273 | /*thumb*/ 274 | pupr->pc &= (~1u); 275 | pupr->pstate |= CPSR_T_MASK; 276 | }else{ 277 | /*arm*/ 278 | pupr->pstate &= ~CPSR_T_MASK; 279 | } 280 | 281 | pupr->regs[30] = 0; 282 | 283 | if (ptrace_setregs(pid,pupr) == -1 || ptrace_continue(pid) == -1) 284 | { 285 | LOGI("[-] call error\n"); 286 | return -1; 287 | } 288 | 289 | int stat = 0; 290 | pid_t wret = waitpid(pid,&stat,WUNTRACED); 291 | // LOGI("wait ret:%x,stat:%x\n",wret,stat); 292 | while(stat != 0xb7f){ 293 | if(ptrace_continue(pid) == -1){ 294 | LOGI("[-] call error \n"); 295 | return -1; 296 | } 297 | 298 | waitpid(pid,&stat,WUNTRACED); 299 | } 300 | 301 | return 0; 302 | } 303 | 304 | void* ptrace_dlopen(pid_t target_pid, void* remote_dlopen_addr, const char* filename){ 305 | struct user_pt_regs regs; 306 | if (ptrace_getregs(target_pid, ®s) == -1) 307 | return NULL ; 308 | 309 | 310 | long mmap_params[2]; 311 | size_t filename_len = strlen(filename) + 1; 312 | void* filename_addr = find_space_by_mmap(target_pid, 256) & 0x7fffffffff; 313 | 314 | if (filename_addr == NULL ) { 315 | LOGE("[-] Call Remote mmap fails.\n"); 316 | return NULL ; 317 | } 318 | 319 | LOGI("[+] mmap addr:%p \n",filename_addr); 320 | 321 | ptrace_write(target_pid, (uint8_t *)filename_addr, (uint8_t *)filename, filename_len); 322 | 323 | mmap_params[0] = (long)filename_addr; //filename pointer 324 | mmap_params[1] = RTLD_NOW | RTLD_GLOBAL; // flag 325 | 326 | // remote_dlopen_addr = (remote_dlopen_addr == NULL) ? get_remote_address(target_pid, (void *)dlopen) : remote_dlopen_addr; 327 | 328 | if (remote_dlopen_addr == NULL) { 329 | LOGE("[-] Get Remote dlopen address fails.\n"); 330 | return NULL; 331 | } 332 | 333 | LOGI("[+] remote dlopen addr:%lx \n",remote_dlopen_addr); 334 | 335 | if (ptrace_call(target_pid, (uint64_t) remote_dlopen_addr, mmap_params, 2, ®s) == -1) 336 | return NULL; 337 | 338 | if (ptrace_getregs(target_pid, ®s) == -1) 339 | return NULL; 340 | 341 | LOGI("[+] Target process returned from dlopen, return r0=%llx, r7=%llx, pc=%llx, \n", regs.regs[0] & 0x7fffffffff, regs.regs[7], regs.pc); 342 | 343 | return regs.pc == 0 ? (void *) regs.regs[0] : NULL; 344 | } 345 | -------------------------------------------------------------------------------- /inject/Arm64-v8a/ptrace_utils.h: -------------------------------------------------------------------------------- 1 | #ifndef _PTRACE_UTILS_H_ 2 | #define _PTRACE_UTILS_H_ 3 | 4 | #define CPSR_T_MASK ( 1u << 5 ) 5 | 6 | int ptrace_attach( pid_t pid , int zygote); 7 | int ptrace_detach( pid_t pid ); 8 | 9 | int ptrace_continue(pid_t pid); 10 | 11 | int ptrace_syscall(pid_t pid); 12 | 13 | int ptrace_getregs(pid_t pid, struct user_pt_regs* regs); 14 | int ptrace_setregs(pid_t pid, struct user_pt_regs* regs); 15 | 16 | int ptrace_write(pid_t pid, uint8_t *dest, uint8_t *data, size_t size); 17 | int ptrace_read( pid_t pid, uint8_t *src, uint8_t *buf, size_t size ); 18 | 19 | int show_regs(struct user_pt_regs* regs); 20 | int show_mem(uint8_t *src,size_t size); 21 | 22 | int ptrace_call(pid_t pid, uintptr_t addr, long *params, int num_params, struct user_pt_regs* regs); 23 | 24 | void* ptrace_dlopen(pid_t target_pid, void* remote_dlopen_addr, const char* filename); 25 | 26 | 27 | #endif -------------------------------------------------------------------------------- /inject/Arm64-v8a/tools.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "tools.h" 6 | 7 | void *get_method_address(const char *soname, const char *methodname) { 8 | void *handler = dlopen(soname, RTLD_NOW | RTLD_GLOBAL); 9 | return dlsym(handler, methodname); 10 | } 11 | 12 | const char* get_process_name(pid_t pid) { 13 | static char buffer[255]; 14 | FILE* f; 15 | char path[255]; 16 | 17 | snprintf(path, sizeof(path), "/proc/%d/cmdline", pid); 18 | if ((f = fopen(path, "r")) == NULL) { 19 | return NULL; 20 | } 21 | 22 | if (fgets(buffer, sizeof(buffer), f) == NULL) { 23 | return NULL; 24 | } 25 | 26 | fclose(f); 27 | return buffer; 28 | } 29 | -------------------------------------------------------------------------------- /inject/Arm64-v8a/tools.h: -------------------------------------------------------------------------------- 1 | #ifndef _TOOL_H_ 2 | #define _TOOL_H_ 3 | 4 | #include 5 | #include 6 | 7 | void *get_method_address(const char *soname, const char *methodname); 8 | 9 | const char* get_process_name(pid_t pid); 10 | 11 | #endif --------------------------------------------------------------------------------