Пример #1
0
int ptrace_call_wrapper(pid_t target_pid, const char * func_name, void * func_addr, long * parameters, int param_num, struct pt_regs * regs)     
{    
	DEBUG_PRINT("[+] Calling %s in target process.\n", func_name);    
	if (ptrace_call(target_pid, (uint32_t)func_addr, parameters, param_num, regs) == -1)    
		return -1;    

	if (ptrace_getregs(target_pid, regs) == -1)    
		return -1;    
	DEBUG_PRINT("[+] Target process returned from %s, return value=%x, pc=%x \n",     
		func_name, ptrace_retval(regs), ptrace_ip(regs));    
	return 0;    
}    
Пример #2
0
int inject_remote_process_new(pid_t target_pid, const char *library_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("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)    
		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;    
}    
Пример #3
0
/* 实现核心功能--注入 */
int inject_remote_process(pid_t target_pid, const char *library_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; // 存放目标进程mmap获取的内存块地址,mmap将一个文件或者其它对象映射进内存
    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);

    // step 1. attach到目标进程
    if (ptrace_attach(target_pid) == -1)
        goto exit;

    // step 2. save context, 保存目标进程被注入前的寄存器内容
    // 方便注入完成后恢复
    if (ptrace_getregs(target_pid, &regs) == -1)
        goto exit;

    /* save original registers */
    memcpy(&original_regs, &regs, sizeof(regs));

    /* step 3. 获取目标进程存放mmap()代码的地址,执行mmap调用,
     * 在目标进程分配一块地址,用于存放后面要注入的库路径和相关函数地址等
     * mmap()会开辟一块内存,用于将一个文件或者其它对象映射进内存
     */
    // 寻找目标进程mmap的地址
    // libc为c语音标准库,一般进程都会加载;libc.so包含mmap函数
    mmap_addr = get_remote_addr(target_pid, libc_path, (void *)mmap);
    DEBUG_PRINT("[+] Remote mmap address: %x\n", mmap_addr);

    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

    // 目标进程执行mmap
    if (ptrace_call_wrapper(target_pid, "mmap", mmap_addr, parameters, 6, &regs) == -1)
        goto exit;

    map_base = ptrace_retval(&regs);// mmap调用后返回值存入regs内的ax寄存器,syscall之前ax存调用号,调用后存返回值

    // step 4. 获取目标进程动态库的几个函数,并将要注入的so的路径写入刚刚申请的内存初始地址
    // dlopen()函数以指定模式打开指定的动态链接库文件,并返回一个句柄给dlsym()的调用进程。使用dlclose()来卸载打开的库。
    dlopen_addr = get_remote_addr(target_pid, linker_path, (void *)dlopen); // 找到dlopen()的地址
    dlsym_addr = get_remote_addr(target_pid, linker_path, (void *)dlsym); // 找到dlsys()地址
    dlclose_addr = get_remote_addr(target_pid, linker_path, (void *)dlclose); // 找到dlclose()地址
    dlerror_addr = get_remote_addr(target_pid, linker_path, (void *)dlerror); // 找到dlerror()地址

    DEBUG_PRINT("[+] Get imports: dlopen: %x, dlsym: %x, dlclose: %x, dlerror: %x\n",
            dlopen_addr, dlsym_addr, dlclose_addr, dlerror_addr);

    printf("library path = %s\n", library_path);
    // 将要注入的so的路径写入刚刚申请的内存初始地址,作为即将要调用的dlopen函数的参数parameters[0]
    ptrace_writedata(target_pid, map_base, library_path, strlen(library_path) + 1);

    // step 5. 在目标进程内调用dlopen函数加载要注入的so
    // 完成后so已经被注入目标进程的地址空间内了
    // 当库被装入后,可以把 dlopen() 返回的句柄作为给 dlsym() 的第一个参数,以获得符号在库中的地址。
    // 使用这个地址,就可以获得库中特定函数的指针,并且调用装载库中的相应函数。
    parameters[0] = map_base;
    parameters[1] = RTLD_NOW| RTLD_GLOBAL;

    if (ptrace_call_wrapper(target_pid, "dlopen", dlopen_addr, parameters, 2, &regs) == -1)
        goto exit;

    // step 6. 在目标进程内调用dlsym函数获取刚刚注入的so里的hook函数
    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;

    // step 7. 在目标进程内调用hook函数
    void * hook_entry_addr = ptrace_retval(&regs); // dlsys()返回hook函数地址
    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;
    function_name
    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 */
    // step 8. 恢复目标进程的寄存器,detach ptrace
    ptrace_setregs(target_pid, &original_regs);
    ptrace_detach(target_pid);
    ret = 0;

exit:
    return ret;
}