From ebbccfb7ae9eb01858c69b0f8691125ddf0a9313 Mon Sep 17 00:00:00 2001 From: Michael <20937441+KMikeeU@users.noreply.github.com> Date: Sun, 17 May 2026 19:58:50 +0200 Subject: [PATCH] Revert "fix: static build + new syscall spoofer" This reverts commit 197cc3098d9a97eb488f1e49e2fb71740dd64645. --- Makefile | 4 +- src/spoof/spoofer.c | 188 ++++++++------------------------------------ 2 files changed, 34 insertions(+), 158 deletions(-) diff --git a/Makefile b/Makefile index 3bf8ce0..eef5fc7 100644 --- a/Makefile +++ b/Makefile @@ -72,11 +72,11 @@ host: $(HOST_EXE) $(HOST_EXE_SPOOFER) # Build the main challenge executable $(HOST_EXE): $(HOST_SRC) | $(BUILD_DIR) - $(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -static $(HOST_INCLUDE) $(HOST_SRC) -o $@ + $(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) $(HOST_INCLUDE) $(HOST_SRC) -o $@ # Build the spoofer $(HOST_EXE_SPOOFER): $(HOST_SRC_SPOOFER) | $(BUILD_DIR) - $(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -static $^ -o $@ -ldl + $(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -shared -fPIC $^ -o $@ -ldl # Build the encryptor $(HOST_EXE_ENCRYPTOR): $(HOST_SRC_ENCRYPTOR) | $(BUILD_DIR) diff --git a/src/spoof/spoofer.c b/src/spoof/spoofer.c index bdfe917..6aebc63 100644 --- a/src/spoof/spoofer.c +++ b/src/spoof/spoofer.c @@ -1,164 +1,40 @@ -#define _GNU_SOURCE #include #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include -static void write_mem(pid_t pid, unsigned long addr, const char *buf, size_t len) -{ - struct iovec local = {(void *)buf, len}; - struct iovec remote = {(void *)addr, len}; - if (process_vm_writev(pid, &local, 1, &remote, 1, 0) < 0) - { - perror("spoofer: process_vm_writev"); - abort(); +static FILE *(*real_fopen)(const char *path, const char *mode) = NULL; + +static void init_real_fopen(void) { + if (!real_fopen) { + real_fopen = dlsym(RTLD_NEXT, "fopen"); + if (!real_fopen) { + fprintf(stderr, "proc_redirect: dlsym(fopen) failed: %s\n", dlerror()); + abort(); + } } } -static int read_string(pid_t pid, unsigned long addr, char *buf, size_t max) -{ - struct iovec local = {buf, max}; - struct iovec remote = {(void *)addr, max}; - ssize_t n = process_vm_readv(pid, &local, 1, &remote, 1, 0); - if (n < 0) - return -1; - buf[n < (ssize_t)max ? (size_t)n : max - 1] = '\0'; - buf[strnlen(buf, max - 1)] = '\0'; - return 0; -} - -static void handle_openat(pid_t pid, struct user_regs_struct *regs) -{ - unsigned long path_ptr = regs->rsi; - char orig[4096] = {0}; - if (read_string(pid, path_ptr, orig, sizeof(orig)) < 0) - return; - if (strncmp(orig, "/proc/", 6) != 0) - return; - - char newpath[4096]; - snprintf(newpath, sizeof(newpath), ".%s", orig + 1); - - /* Scratch space below the red zone, safe from any live stack frame */ - unsigned long scratch = regs->rsp - 256 - sizeof(newpath); - write_mem(pid, scratch, newpath, strlen(newpath) + 1); - - struct user_regs_struct r = *regs; - r.rsi = scratch; - if (ptrace(PTRACE_SETREGS, pid, NULL, &r) < 0) - perror("spoofer: PTRACE_SETREGS"); - else - fprintf(stderr, "spoofer: redirected '%s' -> '%s'\n", orig, newpath); -} - -int main(int argc, char **argv) -{ - if (argc < 2) - { - fprintf(stderr, "usage: %s [args...]\n", argv[0]); - return 1; - } - - pid_t pid = fork(); - if (pid < 0) - { - perror("fork"); - return 1; - } - - if (pid == 0) - { - if (ptrace(PTRACE_TRACEME, 0, NULL, NULL) < 0) - { - perror("spoofer: PTRACE_TRACEME"); - _exit(1); - } - execvp(argv[1], argv + 1); - perror("spoofer: execvp"); - _exit(1); - } - - int status; - if (waitpid(pid, &status, 0) < 0) - { - perror("waitpid"); - return 1; - } - if (!WIFSTOPPED(status)) - { - fprintf(stderr, "spoofer: unexpected initial status %d\n", status); - return 1; - } - - if (ptrace(PTRACE_SETOPTIONS, pid, NULL, - (void *)(long)(PTRACE_O_TRACESYSGOOD | PTRACE_O_EXITKILL)) < 0) - { - perror("spoofer: PTRACE_SETOPTIONS"); - return 1; - } - - int in_syscall = 0; - - while (1) - { - if (ptrace(PTRACE_SYSCALL, pid, NULL, NULL) < 0) - { - perror("spoofer: PTRACE_SYSCALL"); - break; - } - if (waitpid(pid, &status, 0) < 0) - { - perror("waitpid"); - break; - } - if (WIFEXITED(status) || WIFSIGNALED(status)) - break; - if (!WIFSTOPPED(status)) - continue; - - int sig = WSTOPSIG(status); - - if (sig == (SIGTRAP | 0x80)) - { - if (!in_syscall) - { - struct user_regs_struct regs; - if (ptrace(PTRACE_GETREGS, pid, NULL, ®s) == 0) - { - if (regs.orig_rax == SYS_openat) - { - handle_openat(pid, ®s); - } - else if (regs.orig_rax == SYS_open) - { - /* SYS_open: rdi=path — copy to rsi so handle_openat works */ - regs.rsi = regs.rdi; - handle_openat(pid, ®s); - } - } - } - in_syscall ^= 1; - } - else - { - /* Forward real signals to the tracee */ - ptrace(PTRACE_SYSCALL, pid, NULL, (void *)(long)sig); - in_syscall = 0; - continue; - } - } - - if (WIFEXITED(status)) - return WEXITSTATUS(status); - if (WIFSIGNALED(status)) - return 128 + WTERMSIG(status); - return 0; +FILE *fopen(const char *path, const char *mode) { + init_real_fopen(); + + if (path && strncmp(path, "/proc/", 6) == 0) { + const char *rel_suffix = path + 1; + size_t len = strlen(rel_suffix) + 4; + char *new_path = malloc(len); + if (!new_path) { + fprintf(stderr, "proc_redirect: malloc failed\n"); + abort(); + } + new_path[0] = '.'; + new_path[1] = '/'; + new_path[2] = '.'; + strcpy(new_path + 3, rel_suffix); + + FILE *f = real_fopen(new_path, mode); + free(new_path); + return f; + } + + return real_fopen(path, mode); }