Пример #1
0
int inject_code(const struct process_hook *ph)
{
	char sbuf1[1024], sbuf2[1024];
	struct my_user_regs regs, saved_regs, aregs;
	int status;
	size_t v = 0;

	assert(ph);

	printf("[+] 64bit mode\n");

	if (ptrace(PTRACE_ATTACH, ph->pid, NULL, NULL) < 0)
		die("[-] ptrace");
	waitpid(ph->pid, &status, 0);
	if (ptrace(PTRACE_GETREGS, ph->pid, NULL, &regs) < 0)
		die("[-] ptrace");

	peek_text(ph->pid, regs.rsp + 1024, sbuf1, sizeof(sbuf1));
	peek_text(ph->pid, regs.rsp, sbuf2, sizeof(sbuf2));

	/* fake saved return address, triggering a SIGSEGV to catch */
	v = 0;
	poke_text(ph->pid, regs.rsp, (char *)&v, sizeof(v));
	poke_text(ph->pid, regs.rsp + 1024, ph->dso, strlen(ph->dso) + 1);

	memcpy(&saved_regs, &regs, sizeof(regs));
	printf("[+] rdi=0x%zx rsp=0x%zx rip=0x%zx\n", regs.rdi, regs.rsp, regs.rip);

	/* arguments to function we call */
	regs.rdi = regs.rsp + 1024;
	regs.rsi = RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE;
	regs.rip = (size_t)ph->dlopen_address;

	if (ptrace(PTRACE_SETREGS, ph->pid, NULL, &regs) < 0)
		die("[-] ptrace");
	if (ptrace(PTRACE_CONT, ph->pid, NULL, NULL) < 0)
		die("[-] ptrace");
	/* Should receive a SIGSEGV for return to 0 */
	waitpid(ph->pid, &status, 0);

	if (ptrace(PTRACE_GETREGS, ph->pid, NULL, &aregs) < 0)
		die("[-] ptrace");

	printf("[+] rdi=0x%zx rsp=0x%zx rip=0x%zx\n", aregs.rdi, aregs.rsp, aregs.rip);
	if (ptrace(PTRACE_SETREGS, ph->pid, 0, &saved_regs) < 0)
		die("[-] ptrace");

	poke_text(ph->pid, saved_regs.rsp + 1024, sbuf1, sizeof(sbuf1));
	poke_text(ph->pid, saved_regs.rsp, sbuf2, sizeof(sbuf2));

	if (ptrace(PTRACE_DETACH, ph->pid, NULL, NULL) < 0)
		die("[-] ptrace");
	if (aregs.rip != 0)
		printf("[-] dlopen in target may have failed (no clean NULL fault)\n");

	return 0;
}
Пример #2
0
int inject_code(pid_t pid, size_t libc_addr, size_t dlopen_addr, char *dso)
{
	char sbuf1[1024], sbuf2[1024];
	struct user_regs_struct regs, saved_regs;
	int status;

	if (ptrace(PTRACE_ATTACH, pid, NULL, NULL) < 0)
		die("ptrace 1");
	waitpid(pid, &status, 0);
	if (ptrace(PTRACE_GETREGS, pid, NULL, &regs) < 0)
		die("ptrace 2");

	peek_text(pid, regs.rsp + 1024, sbuf1, sizeof(sbuf1));
	peek_text(pid, regs.rsp, sbuf2, sizeof(sbuf2));

	/* fake saved return address */
	libc_addr = 0x0;
	poke_text(pid, regs.rsp, (char *)&libc_addr, sizeof(libc_addr));
	poke_text(pid, regs.rsp + 1024, dso, strlen(dso) + 1); 

	memcpy(&saved_regs, &regs, sizeof(regs));

	/* pointer to &args */
	printf("rdi=%zx rsp=%zx rip=%zx\n", regs.rdi, regs.rsp, regs.rip);

	regs.rdi = regs.rsp + 1024;
	regs.rsi = RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE;
	regs.rip = dlopen_addr + 2;// kernel bug?! always need to add 2!

	if (ptrace(PTRACE_SETREGS, pid, NULL, &regs) < 0)
		die("ptrace 3");
	if (ptrace(PTRACE_CONT, pid, NULL, NULL) < 0)
		die("ptrace 4");

	/* Should receive a SIGSEGV */
	waitpid(pid, &status, 0);

	if (ptrace(PTRACE_SETREGS, pid, 0, &saved_regs) < 0)
		die("ptrace 5");

	poke_text(pid, saved_regs.rsp + 1024, sbuf1, sizeof(sbuf1));
	poke_text(pid, saved_regs.rsp, sbuf2, sizeof(sbuf2));

	if (ptrace(PTRACE_DETACH, pid, NULL, NULL) < 0)
		die("ptrace 6");

	return 0;
}
Пример #3
0
int inject_code(pid_t pid, size_t libc_addr, size_t dlopen_addr, char *dso_file)
{
	char sbuf1[1024], sbuf2[1024];
	struct my_user_regs regs, saved_regs, aregs;
	int status;
	char *dso = NULL;
	size_t v = 0;

	printf("32bit mode\n");
	dso = realpath(dso_file, NULL);
	if (!dso || access(dso, X_OK) < 0)
		die(dso ? dso : dso_file);
	printf("Using normalized path '%s' for injection.\n", dso);

	if (ptrace(PTRACE_ATTACH, pid, NULL, NULL) < 0)
		die("ptrace 1");
	waitpid(pid, &status, 0);
	if (ptrace(PTRACE_GETREGS, pid, NULL, &regs) < 0)
		die("ptrace 2");

	peek_text(pid, regs.esp + 1024, sbuf1, sizeof(sbuf1));
	peek_text(pid, regs.esp, sbuf2, sizeof(sbuf2));

	/* fake saved return address, triggering a SIGSEGV to catch */
	libc_addr = 0x0;
	poke_text(pid, regs.esp, (char *)&libc_addr, sizeof(libc_addr));
	poke_text(pid, regs.esp + 1024, dso, strlen(dso) + 1); 
	free(dso);

	memcpy(&saved_regs, &regs, sizeof(regs));

	printf("esp=0x%zx eip=0x%zx\n", regs.esp, regs.eip);

	/* arguments passed on stack this time (x86) */
	v = regs.esp + 1024;
	poke_text(pid, regs.esp + sizeof(size_t), &v, sizeof(v));
	v = RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE;
	poke_text(pid, regs.esp + 2*sizeof(size_t), &v, sizeof(v));

	/* kernel bug. always add 2; in -m32 mode on 64bit systems its
	 * not needed!!!
	 */
	regs.eip = dlopen_addr + 2;

	if (ptrace(PTRACE_SETREGS, pid, NULL, &regs) < 0)
		die("ptrace 3");
	if (ptrace(PTRACE_CONT, pid, NULL, NULL) < 0)
		die("ptrace 4");

	/* Should receive a SIGSEGV for return to 0 */
	waitpid(pid, &status, 0);

	if (ptrace(PTRACE_GETREGS, pid, NULL, &aregs) < 0)
		die("ptrace 5");

	printf("esp=0x%zx eip=0x%zx\n", aregs.esp, aregs.eip);

	if (ptrace(PTRACE_SETREGS, pid, 0, &saved_regs) < 0)
		die("ptrace 6");

	poke_text(pid, saved_regs.esp + 1024, sbuf1, sizeof(sbuf1));
	poke_text(pid, saved_regs.esp, sbuf2, sizeof(sbuf2));

	if (ptrace(PTRACE_DETACH, pid, NULL, NULL) < 0)
		die("ptrace 7");
	if (aregs.eip != 0)
		printf("dlopen in target may failed (no clean NULL fault)!\n");

	return 0;
}
Пример #4
0
int inject_code(pid_t pid, size_t libc_addr, size_t dlopen_addr, char *dso_file)
{
	char sbuf1[1024], sbuf2[1024];
	struct my_user_regs regs, saved_regs, aregs;
	int status;
	char *dso = NULL;

	printf("64bit mode\n");
	dso = realpath(dso_file, NULL);
	if (!dso || access(dso, X_OK) < 0)
		die(dso ? dso : dso_file);
	printf("Using normalized path '%s' for injection.\n", dso);

	if (ptrace(PTRACE_ATTACH, pid, NULL, NULL) < 0)
		die("ptrace 1");
	waitpid(pid, &status, 0);
	if (ptrace(PTRACE_GETREGS, pid, NULL, &regs) < 0)
		die("ptrace 2");

	peek_text(pid, regs.rsp + 1024, sbuf1, sizeof(sbuf1));
	peek_text(pid, regs.rsp, sbuf2, sizeof(sbuf2));

	/* fake saved return address, triggering a SIGSEGV to catch */
	libc_addr = 0x0;
	poke_text(pid, regs.rsp, (char *)&libc_addr, sizeof(libc_addr));
	poke_text(pid, regs.rsp + 1024, dso, strlen(dso) + 1); 
	free(dso);

	memcpy(&saved_regs, &regs, sizeof(regs));

	printf("rdi=0x%zx rsp=0x%zx rip=0x%zx\n", regs.rdi, regs.rsp, regs.rip);

	/* arguments to function we call */
	regs.rdi = regs.rsp + 1024;
	regs.rsi = RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE;
	regs.rip = dlopen_addr + 2;// kernel bug?! always need to add 2!

	if (ptrace(PTRACE_SETREGS, pid, NULL, &regs) < 0)
		die("ptrace 3");
	if (ptrace(PTRACE_CONT, pid, NULL, NULL) < 0)
		die("ptrace 4");

	/* Should receive a SIGSEGV for return to 0 */
	waitpid(pid, &status, 0);

	if (ptrace(PTRACE_GETREGS, pid, NULL, &aregs) < 0)
		die("ptrace 5");

	printf("rdi=0x%zx rsp=0x%zx rip=0x%zx\n", aregs.rdi, aregs.rsp, aregs.rip);

	if (ptrace(PTRACE_SETREGS, pid, 0, &saved_regs) < 0)
		die("ptrace 6");

	poke_text(pid, saved_regs.rsp + 1024, sbuf1, sizeof(sbuf1));
	poke_text(pid, saved_regs.rsp, sbuf2, sizeof(sbuf2));

	if (ptrace(PTRACE_DETACH, pid, NULL, NULL) < 0)
		die("ptrace 7");
	if (aregs.rip != 0)
		printf("dlopen in target may failed (no clean NULL fault)!\n");

	return 0;
}