-
-
Save hshrzd/ec399a98ddc5f4daba6fe6d58735de02 to your computer and use it in GitHub Desktop.
FlareOn 7 - Task 10: a lib for hooking ptrace
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
compile: | |
gcc -fPIC -c -m32 hook.c -o hook.o | |
gcc -shared -m32 -o hook.so.6 hook.o | |
use: | |
LD_PRELOAD=./hook.so.6 ./break_hooked | |
*/ | |
#include <stdlib.h> | |
#include <stdio.h> | |
#include <dlfcn.h> | |
#include <string.h> | |
#include <sys/user.h> | |
#define PTRACE_PEEKDATA 2 | |
#define PTRACE_POKEDATA 5 | |
#define PTRACE_GETREGS 12 | |
#define PTRACE_SETREGS 13 | |
#define printreg(REGNAME) printf("%3s: 0x%08x\n", #REGNAME, regs->REGNAME) | |
void struct_dump(char *data, size_t size) | |
{ | |
u_int32_t *ptr = (u_int32_t*) data; | |
size_t dw_size = size / sizeof(u_int32_t); | |
printf("{ \n"); | |
for (size_t i = 0; i < dw_size; i++) { | |
printf("[%02d] = %08x\n", i, ptr[i]); | |
} | |
printf("} "); | |
printf("\n"); | |
} | |
void dump_regs(void *data) | |
{ | |
if (data == NULL) return; | |
struct user_regs_struct *regs = (struct user_regs_struct *)data; | |
//struct_dump(data, sizeof(struct user_regs_struct)); | |
printreg(eip); | |
printreg(eax); | |
printreg(ecx); | |
printreg(edx); | |
printreg(ebx); | |
printreg(esp); | |
printreg(ebp); | |
printreg(esi); | |
printreg(edi); | |
printreg(eflags); | |
} | |
void log_before(int request, pid_t pid, void *addr, void *data) | |
{ | |
printf("> Before, PID=[%d] req=%d\n", pid, request); | |
if (request == PTRACE_PEEKDATA) { | |
printf("\tPEEKDATA: addr=%p data=%p\n", addr, data); | |
} | |
if (request == PTRACE_POKEDATA) { | |
printf("\tPOKEDATA: addr=%p data=%p\n\n", addr, data); | |
char buf[5] = { 0 }; | |
memcpy(buf, &data, 4); | |
printf("\tbuf=%4s\n\n", buf); | |
} | |
if (request == PTRACE_GETREGS) { | |
printf("\tGETREGS: addr=%p data=%p\n", addr, data); | |
} | |
if (request == PTRACE_SETREGS) { | |
printf("\tSETREGS: addr=%p data=%p\n", addr, data); | |
dump_regs(data); | |
printf("\n"); | |
} | |
} | |
void log_after(int request, long int result, void *data) | |
{ | |
printf("< After\n"); | |
if (request == PTRACE_PEEKDATA) { | |
char buf[5] = { 0 }; | |
memcpy(buf, &result, 4); | |
printf("\tPEEKDATA: res=%p %4s\n\n", result, buf); | |
} | |
if (request == PTRACE_GETREGS) { | |
dump_regs(data); | |
printf("\tGETREGS: res=%p\n\n", result); | |
} | |
printf("\n"); | |
} | |
long int ptrace(int request, pid_t pid, void *addr, void *data) | |
{ | |
log_before(request, pid, addr, data); | |
int (*o_ptrace)(int request, pid_t pid, void *addr, void *data); | |
void *handle = dlopen("libc.so.6", 1); | |
o_ptrace = dlsym(handle, "ptrace"); | |
long int result = o_ptrace(request, pid, addr, data); | |
log_after(request, result, data); | |
return result; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment