예제 #1
0
int ptrace_writestring(pid_t pid, unsigned char *dest, char *str){
	return ptrace_writedata(pid, dest, (unsigned char *)str, strlen(str)+ 1);
}
예제 #2
0
파일: ptrace_32.c 프로젝트: 03199618/linux
long arch_ptrace(struct task_struct *child, long request,
		 unsigned long addr, unsigned long data)
{
	unsigned long addr2 = current->thread.kregs->u_regs[UREG_I4];
	void __user *addr2p;
	const struct user_regset_view *view;
	struct pt_regs __user *pregs;
	struct fps __user *fps;
	int ret;

	view = task_user_regset_view(current);
	addr2p = (void __user *) addr2;
	pregs = (struct pt_regs __user *) addr;
	fps = (struct fps __user *) addr;

	switch(request) {
	case PTRACE_GETREGS: {
		ret = copy_regset_to_user(child, view, REGSET_GENERAL,
					  32 * sizeof(u32),
					  4 * sizeof(u32),
					  &pregs->psr);
		if (!ret)
			copy_regset_to_user(child, view, REGSET_GENERAL,
					    1 * sizeof(u32),
					    15 * sizeof(u32),
					    &pregs->u_regs[0]);
		break;
	}

	case PTRACE_SETREGS: {
		ret = copy_regset_from_user(child, view, REGSET_GENERAL,
					    32 * sizeof(u32),
					    4 * sizeof(u32),
					    &pregs->psr);
		if (!ret)
			copy_regset_from_user(child, view, REGSET_GENERAL,
					      1 * sizeof(u32),
					      15 * sizeof(u32),
					      &pregs->u_regs[0]);
		break;
	}

	case PTRACE_GETFPREGS: {
		ret = copy_regset_to_user(child, view, REGSET_FP,
					  0 * sizeof(u32),
					  32 * sizeof(u32),
					  &fps->regs[0]);
		if (!ret)
			ret = copy_regset_to_user(child, view, REGSET_FP,
						  33 * sizeof(u32),
						  1 * sizeof(u32),
						  &fps->fsr);

		if (!ret) {
			if (__put_user(0, &fps->fpqd) ||
			    __put_user(0, &fps->flags) ||
			    __put_user(0, &fps->extra) ||
			    clear_user(fps->fpq, sizeof(fps->fpq)))
				ret = -EFAULT;
		}
		break;
	}

	case PTRACE_SETFPREGS: {
		ret = copy_regset_from_user(child, view, REGSET_FP,
					    0 * sizeof(u32),
					    32 * sizeof(u32),
					    &fps->regs[0]);
		if (!ret)
			ret = copy_regset_from_user(child, view, REGSET_FP,
						    33 * sizeof(u32),
						    1 * sizeof(u32),
						    &fps->fsr);
		break;
	}

	case PTRACE_READTEXT:
	case PTRACE_READDATA:
		ret = ptrace_readdata(child, addr, addr2p, data);

		if (ret == data)
			ret = 0;
		else if (ret >= 0)
			ret = -EIO;
		break;

	case PTRACE_WRITETEXT:
	case PTRACE_WRITEDATA:
		ret = ptrace_writedata(child, addr2p, addr, data);

		if (ret == data)
			ret = 0;
		else if (ret >= 0)
			ret = -EIO;
		break;

	default:
		if (request == PTRACE_SPARC_DETACH)
			request = PTRACE_DETACH;
		ret = ptrace_request(child, request, addr, data);
		break;
	}

	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){

	/*
	[1]通过远程进程pid,ATTACH到远程进程。

	[2]获取远程进程寄存器值,并保存,以便注入完成后恢复进程原有状态。

	[3]获取远程进程系统调用mmap、dlopen、dlsym调用地址。

	[4]调用远程进程mmap分配一段存储空间,并在空间中写入so库路径以及函数调用参数。

	[5]执行远程进程dlopen,加载so库。

	[6]执行远程进程dlsym,获取so库中需要执行的函数地址。

	[7]执行远程进程中的函数。

	[7]恢复远程进程寄存器。

	[8]DETACH远程进程。
	 * */
	int ret = -1;
	void*mmap_addr, *dlopen_addr, *dlsym_addr, *dlclose_addr;
	void*local_handle, *remote_handle, *dlhandle;
	unsigned char* map_base;
	unsigned char* 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 unsigned int _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;

	unsigned int code_length;
	long parameters[10];

	printf("[+] Injecting process: %d\n", target_pid );
	if (ptrace_attach(target_pid)== -1)
		return EXIT_SUCCESS;

	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, "/system/lib/libc.so", (void*)mmap);
	printf("[+] 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
	printf("[+] Calling mmap in target process.\n" );
	if (ptrace_call(target_pid, (unsigned int)mmap_addr, parameters, 6, &regs)
			== -1)
		goto exit;

	if (ptrace_getregs(target_pid, &regs)== -1)
		goto exit;

	printf("[+] Target process returned from mmap, return value=%x, pc=%x \n", regs.ARM_r0, regs.ARM_pc );
	map_base = (unsigned char*)regs.ARM_r0;

	/*------------------------------------------------------------------------------------------------------*/

	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);

	printf("[+] Get imports: dlopen: %x, dlsym: %x, dlclose: %x\n", dlopen_addr, dlsym_addr, dlclose_addr );
	remote_code_ptr = map_base + 0x3C00;
	local_code_ptr = (unsigned char*)&_inject_start_s;

	_dlopen_addr_s = (unsigned int)dlopen_addr;
	_dlsym_addr_s = (unsigned int)dlsym_addr;
	_dlclose_addr_s = (unsigned int)dlclose_addr;
	printf("[+] Inject code start: %x, end: %x\n", local_code_ptr, &_inject_end_s );

	code_length = (unsigned int)&_inject_end_s - (unsigned int)&_inject_start_s;
	dlopen_param1_ptr = local_code_ptr + code_length + 0x20;
	dlsym_param2_ptr = dlopen_param1_ptr + MAX_PATH;	// 偏移
	saved_r0_pc_ptr = dlsym_param2_ptr + MAX_PATH; 		//偏移
	inject_param_ptr = saved_r0_pc_ptr + MAX_PATH;		//偏移

	/* dlopen parameter 1: library name */
	strcpy((char*)dlopen_param1_ptr, library_path);
	_dlopen_param1_s = REMOTE_ADDR(dlopen_param1_ptr, local_code_ptr, remote_code_ptr);
	printf("[+] _dlopen_param1_s: %x\n", _dlopen_param1_s );

	/* dlsym parameter 2: function name */
	strcpy((char*)dlsym_param2_ptr, function_name);
	_dlsym_param2_s = REMOTE_ADDR(dlsym_param2_ptr, local_code_ptr, remote_code_ptr);
	printf("[+] _dlsym_param2_s: %x\n", _dlsym_param2_s );

	/* saved cpsr */
	_saved_cpsr_s = original_regs.ARM_cpsr;

	/* saved r0-pc */
	memcpy(saved_r0_pc_ptr, &(original_regs.ARM_r0), 16 * 4); // r0 ~ r15
	_saved_r0_pc_s = REMOTE_ADDR(saved_r0_pc_ptr, local_code_ptr, remote_code_ptr);
	printf("[+] _saved_r0_pc_s: %x\n", _saved_r0_pc_s );

	/* Inject function parameter */
	memcpy(inject_param_ptr, param, param_size);
	_inject_function_param_s = REMOTE_ADDR(inject_param_ptr, local_code_ptr, remote_code_ptr);
	printf("[+] _inject_function_param_s: %x\n", _inject_function_param_s );

	printf("[+] Remote shellcode address: %x\n", remote_code_ptr );
	ptrace_writedata(target_pid, remote_code_ptr, local_code_ptr, 0x400);

	memcpy(&regs, &original_regs, sizeof(regs));
	regs.ARM_sp= (long)remote_code_ptr;
	regs.ARM_pc= (long)remote_code_ptr;

	printf("[+] recovery regs.\n");
	ptrace_setregs(target_pid, &regs);

	printf("[+] detach.\n");
	ptrace_detach(target_pid);

	// inject succeeded
	printf("[+] inject succeeded\n");
	ret = 0;

	exit: return ret;
}