Inject Zygote and Hook Native Method(过反调试,过防dump)

    xiaoxiao2024-12-28  15

       0x00 进程注入

        通过ptrace机制,调用目标进程的dlopen来加载我们的so,实现进程注入。

        这部分知识在Android中的so注入(inject)和挂钩(hook) - For both x86 and arm,有详细的解释,请读者先阅读这篇文章。

        那么被注入的进程是如何返回到我们的进程中呢?答案在regs->ARM_lr = 0。具体的分析请参考Android注入完全剖析。

       0x01 要被注入的so

        这个so主要的任务是hook住Zygote的Native Method。基于HOOK的Anti-debug调用点trace和Anti-anti这篇文章讲解了原理和对应的工程。为了方便起见,我上传了源码工程,这个被注入的so的工程可以在http://download.csdn.net/detail/jltxgcy/9602656下载。

        下面是工程目录:

        

        由于我们要注入的so是两个,一是libTKHooklib.so,一个是libtrace_anti.so,而入口函数hook_entry在libtrace_anti.so中,由于Android中的so注入(inject)和挂钩(hook) - For both x86 and arm这篇文章只介绍了注入一个so的源码,所以我们要修改源码,注入两个so。

        那么怎么样才能注入两个so呢?很简单,libTKHooklib.so是libtrace_anti.so所依赖的,所以先注入libTKHooklib.so,然后再注入libtrace_anti.so,并调用hook_entry,即可。

        我们也可以先在java层用System.load来先后加载这两个so,看看会不会报错。如果不报错,就放心的加载吧。注入这两个so,修改Android中的so注入(inject)和挂钩(hook) - For both x86 and arm后的代码如下:

    int inject_remote_process(pid_t target_pid, const char *library_path, const char *depend_path ,const char *function_name, const char *param, size_t param_size) { int ret = -1; void *mmap_addr, *dlopen_addr, *dlsym_addr, *dlclose_addr, *dlerror_addr; void *local_handle, *remote_handle, *dlhandle; uint8_t *map_base = 0; uint8_t *dlopen_param1_ptr, *dlsym_param2_ptr, *saved_r0_pc_ptr, *inject_param_ptr, *remote_code_ptr, *local_code_ptr; struct pt_regs regs, original_regs; extern uint32_t _dlopen_addr_s, _dlopen_param1_s, _dlopen_param2_s, _dlsym_addr_s, \ _dlsym_param2_s, _dlclose_addr_s, _inject_start_s, _inject_end_s, _inject_function_param_s, \ _saved_cpsr_s, _saved_r0_pc_s; uint32_t code_length; long parameters[10]; DEBUG_PRINT("[+] Injecting process: %d\n", target_pid); if (ptrace_attach(target_pid) == -1) goto exit; if (ptrace_getregs(target_pid, &regs) == -1) goto exit; /* save original registers */ memcpy(&original_regs, &regs, sizeof(regs)); mmap_addr = get_remote_addr(target_pid, libc_path, (void *)mmap); DEBUG_PRINT("[+] Remote mmap address: %x\n", mmap_addr); /* call mmap */ parameters[0] = 0; // addr parameters[1] = 0x4000; // size parameters[2] = PROT_READ | PROT_WRITE | PROT_EXEC; // prot parameters[3] = MAP_ANONYMOUS | MAP_PRIVATE; // flags parameters[4] = 0; //fd parameters[5] = 0; //offset if (ptrace_call_wrapper(target_pid, "mmap", mmap_addr, parameters, 6, &regs) == -1) goto exit; map_base = ptrace_retval(&regs); dlopen_addr = get_remote_addr( target_pid, linker_path, (void *)dlopen ); dlsym_addr = get_remote_addr( target_pid, linker_path, (void *)dlsym ); dlclose_addr = get_remote_addr( target_pid, linker_path, (void *)dlclose ); dlerror_addr = get_remote_addr( target_pid, linker_path, (void *)dlerror ); DEBUG_PRINT("[+] Get imports: dlopen: %x, dlsym: %x, dlclose: %x, dlerror: %x\n", dlopen_addr, dlsym_addr, dlclose_addr, dlerror_addr); printf("depend path = %s\n", depend_path); ptrace_writedata(target_pid, map_base, depend_path, strlen(depend_path) + 1); parameters[0] = map_base; parameters[1] = RTLD_NOW| RTLD_GLOBAL; if (ptrace_call_wrapper(target_pid, "dlopen", dlopen_addr, parameters, 2, &regs) == -1) //先注入libTKHooklib.so goto exit; mmap_addr = get_remote_addr(target_pid, libc_path, (void *)mmap); DEBUG_PRINT("[+] Remote mmap address: %x\n", mmap_addr); /* call mmap */ parameters[0] = 0; // addr parameters[1] = 0x4000; // size parameters[2] = PROT_READ | PROT_WRITE | PROT_EXEC; // prot parameters[3] = MAP_ANONYMOUS | MAP_PRIVATE; // flags parameters[4] = 0; //fd parameters[5] = 0; //offset if (ptrace_call_wrapper(target_pid, "mmap", mmap_addr, parameters, 6, &regs) == -1) goto exit; map_base = ptrace_retval(&regs); printf("library path = %s\n", library_path); ptrace_writedata(target_pid, map_base, library_path, strlen(library_path) + 1); parameters[0] = map_base; parameters[1] = RTLD_NOW| RTLD_GLOBAL; if (ptrace_call_wrapper(target_pid, "dlopen", dlopen_addr, parameters, 2, &regs) == -1) //然后再注入libtrace_anti.so goto exit; void * sohandle = ptrace_retval(&regs); #define FUNCTION_NAME_ADDR_OFFSET 0x100 ptrace_writedata(target_pid, map_base + FUNCTION_NAME_ADDR_OFFSET, function_name, strlen(function_name) + 1); parameters[0] = sohandle; parameters[1] = map_base + FUNCTION_NAME_ADDR_OFFSET; if (ptrace_call_wrapper(target_pid, "dlsym", dlsym_addr, parameters, 2, &regs) == -1) goto exit; void * hook_entry_addr = ptrace_retval(&regs); DEBUG_PRINT("hook_entry_addr = %p\n", hook_entry_addr); #define FUNCTION_PARAM_ADDR_OFFSET 0x200 ptrace_writedata(target_pid, map_base + FUNCTION_PARAM_ADDR_OFFSET, param, strlen(param) + 1); parameters[0] = map_base + FUNCTION_PARAM_ADDR_OFFSET; if (ptrace_call_wrapper(target_pid, "hook_entry", hook_entry_addr, parameters, 1, &regs) == -1) goto exit; printf("Press enter to dlclose and detach\n"); getchar(); parameters[0] = sohandle; if (ptrace_call_wrapper(target_pid, "dlclose", dlclose, parameters, 1, &regs) == -1) goto exit; /* restore */ ptrace_setregs(target_pid, &original_regs); ptrace_detach(target_pid); ret = 0; exit: return ret; } int main(int argc, char** argv) { pid_t target_pid; target_pid = find_pid_of("zygote"); if (-1 == target_pid) { printf("Can't find the process\n"); return -1; } //target_pid = find_pid_of("/data/test"); inject_remote_process(target_pid, argv[1], argv[2], "hook_entry", "I'm parameter!", strlen("I'm parameter!")); return 0; }

        在代码中,先注入libTKHooklib.so,然后再注入libtrace_anti.so。    

       0x02 过反调试和过防dump

        在基于HOOK的Anti-debug调用点trace和Anti-anti已经讲过了如何过防dump,代码如下:

    static int new_inotify_add_watch(int fd, const char *pathname, uint32_t mask){ unsigned lr; GETLR(lr); LOGD("[*] Traced-inotify_add_watch Call function: 0x%x\n", lr); LOGD("[*] Traced-inotify_add_watch --> %s, 0x%x", pathname, mask); return old_inotify_add_watch(fd, pathname, 0x00000200); }    过反调试,只给出了部分代码,没有给出完整代码,这里给出完整的代码:

    bool HasGenFile(const char *re_path) { FILE *fpr; char buffer[BUFFERSIZE]; fpr = old_fopen(re_path, "r"); if (fpr == NULL) { return false; } while (fgets(buffer, BUFFERSIZE, fpr) != NULL) { if (strstr(buffer, "State") != NULL) { return true; } if (strstr(buffer, "TracerPid") != NULL) { return true; } } LOGD("[*] HasGenFile return false"); return false; } FILE* hookToNewFile(const char *path, const char * mode) { char re_path[256]; sprintf(re_path, "/data/local/tmp/status"); if (!HasGenFile(re_path)) { char buffer[BUFFERSIZE]; FILE *fpr, *fpw; fpr = old_fopen(path, "r"); fpw = old_fopen(re_path, "w"); if (fpr == NULL || fpw == NULL) { LOGD("[E] re-path [%s]failed", path); return old_fopen(path, mode); } while (fgets(buffer, BUFFERSIZE, fpr) != NULL) { if (strstr(buffer, "State") != NULL) { fputs("State:\tS (sleeping)\n", fpw); } if (strstr(buffer, "TracerPid") != NULL) { fputs("TracerPid:\t0\n", fpw); } else { fputs(buffer, fpw); } } fclose(fpr); fclose(fpw); } LOGD("[*] hookToNewFile Success"); return old_fopen(re_path, mode); } FILE* new_fopen(const char *path,const char * mode){ unsigned lr; GETLR(lr); if(strstr(path, "status") != NULL){ LOGD("[*] Traced-fopen Call function: 0x%x\n", lr); if(strstr(path, "task") != NULL){ LOGD("[*] Traced-anti-task/status"); }else { LOGD("[*] Traced-anti-status"); return hookToNewFile(path, mode); } }else if(strstr(path, "wchan") != NULL){ LOGD("[*] Traced-fopen Call function: 0x%x\n", lr); LOGD("[*] Traced-anti-wchan"); } return old_fopen(path, mode); }    使读取的文件实现重定向到/data/local/tmp/status。

    转载请注明原文地址: https://ju.6miu.com/read-1295068.html
    最新回复(0)