From 06e9f4d7c8505a1e8c8ec4d65e21e93161eae6f7 Mon Sep 17 00:00:00 2001 From: TheBrokenRail Date: Sat, 8 Jun 2024 04:23:03 -0400 Subject: [PATCH] WIP Forever --- include/trampoline/types.h | 11 ++++++--- native/src/main.cpp | 3 --- native/src/memory.cpp | 50 +++++++++++--------------------------- native/src/memory.h | 12 +++------ native/src/pipe/pipe.cpp | 18 +++++++++----- native/src/ptrace/loop.cpp | 6 ++--- 6 files changed, 39 insertions(+), 61 deletions(-) diff --git a/include/trampoline/types.h b/include/trampoline/types.h index c00bbcb..978d5ee 100644 --- a/include/trampoline/types.h +++ b/include/trampoline/types.h @@ -2,9 +2,6 @@ #include -// Shared Memory -#define TRAMPOLINE_SHARED_MEMORY_ENV "_MCPI_TRAMPOLINE_SHARED_MEMORY" - // Switch Between Pipe/PTrace Mode #define TRAMPOLINE_USE_PIPES_ENV "_MCPI_TRAMPOLINE_USE_PIPES" @@ -15,7 +12,13 @@ // Pipe Constants #define TRAMPOLINE_ARGUMENTS_PIPE_ENV "_MCPI_TRAMPOLINE_ARGUMENTS" #define TRAMPOLINE_RETURN_VALUE_PIPE_ENV "_MCPI_TRAMPOLINE_RETURN_VALUE" +struct trampoline_pipe_arguments { + uint32_t id; + uint32_t allow_early_return; + uint32_t length; + uint32_t args_addr; +}; // Function Types -typedef void (*trampoline_writer_t)(uint32_t guest_addr, void *data, uint32_t size); +typedef void (*trampoline_writer_t)(uint32_t guest_addr, const void *data, uint32_t size); typedef uint32_t (*trampoline_t)(trampoline_writer_t writer, uint32_t id, const unsigned char *args); \ No newline at end of file diff --git a/native/src/main.cpp b/native/src/main.cpp index a5d6793..61d42b6 100644 --- a/native/src/main.cpp +++ b/native/src/main.cpp @@ -18,7 +18,6 @@ int main(__attribute__((unused)) int argc, char *argv[]) { } bool use_ptrace = getenv(TRAMPOLINE_USE_PIPES_ENV) == nullptr; // Setup - init_shared_memory_common(); if (!use_ptrace) { init_pipe_common(); } @@ -29,7 +28,6 @@ int main(__attribute__((unused)) int argc, char *argv[]) { } else if (pid == 0) { // Setup setpgid(0, 0); - init_shared_memory_guest(); if (use_ptrace) { init_ptrace_guest(); } else { @@ -42,7 +40,6 @@ int main(__attribute__((unused)) int argc, char *argv[]) { // Parent // Setup Trampoline - init_shared_memory_host(); init_signals(pid); init_memory(pid); init_trampoline(); diff --git a/native/src/memory.cpp b/native/src/memory.cpp index da506c5..2de0e24 100644 --- a/native/src/memory.cpp +++ b/native/src/memory.cpp @@ -1,22 +1,16 @@ #include #include #include -#include -#include -#include -#include - -#include #include "memory.h" #include "log.h" -// Read Memory +// Read/Write Memory static pid_t guest_pid; void init_memory(pid_t pid) { guest_pid = pid; } -void memory_writer(uint32_t guest_addr, void *data, uint32_t size) { +void memory_reader(uint32_t guest_addr, void *data, uint32_t size) { if (size == 0) { return; } @@ -26,36 +20,20 @@ void memory_writer(uint32_t guest_addr, void *data, uint32_t size) { iovec remote[1]; remote[0].iov_base = (void *) (uint64_t) guest_addr; remote[0].iov_len = size; + const ssize_t ret = process_vm_readv(guest_pid, local, 1, remote, 1, 0); + if (ret != size) { + ERR("Unable To Read Data: %s", strerror(errno)); + } +} +void memory_writer(uint32_t guest_addr, const void *data, uint32_t size) { + iovec local[1]; + local[0].iov_base = (void *) data; + local[0].iov_len = size; + iovec remote[1]; + remote[0].iov_base = (void *) (uint64_t) guest_addr; + remote[0].iov_len = size; const ssize_t ret = process_vm_writev(guest_pid, local, 1, remote, 1, 0); if (ret != size) { ERR("Unable To Write Data: %s", strerror(errno)); } -} - -// Shared Memory -static std::string shared_memory_name; -static int shared_memory_fd; -void init_shared_memory_common() { - shared_memory_name = std::string("/mcpi-trampoline-") + std::to_string(getpid()); - shared_memory_fd = shm_open(shared_memory_name.c_str(), O_CREAT | O_EXCL | O_RDWR, 0600); - if (shared_memory_fd == -1) { - ERR("Unable To Create Shared Memory: %s", strerror(errno)); - } - if (ftruncate(shared_memory_fd, MAX_TRAMPOLINE_ARGS_SIZE) == -1) { - ERR("Unable To Set Shared Memory Size: %s", strerror(errno)); - } -} -void init_shared_memory_guest() { - setenv(TRAMPOLINE_SHARED_MEMORY_ENV, shared_memory_name.c_str(), true); -} -unsigned char *shared_memory_host_only; -void init_shared_memory_host() { - shared_memory_host_only = (unsigned char *) mmap(nullptr, MAX_TRAMPOLINE_ARGS_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, shared_memory_fd, 0); - if (shared_memory_host_only == MAP_FAILED) { - ERR("Unable To Map Shared Memory: %s", strerror(errno)); - } -} -void free_shared_memory() { - munmap(shared_memory_host_only, MAX_TRAMPOLINE_ARGS_SIZE); - shm_unlink(shared_memory_name.c_str()); } \ No newline at end of file diff --git a/native/src/memory.h b/native/src/memory.h index 54c5bb4..2a6a9a2 100644 --- a/native/src/memory.h +++ b/native/src/memory.h @@ -4,12 +4,6 @@ #include // Read External Memory -void memory_writer(uint32_t guest_addr, void *data, uint32_t size); -void init_memory(pid_t guest_pid); - -// Shared Memory -void init_shared_memory_common(); -void init_shared_memory_guest(); -void init_shared_memory_host(); -extern unsigned char *shared_memory_host_only; -void free_shared_memory(); \ No newline at end of file +void memory_reader(uint32_t guest_addr, void *data, uint32_t size); +void memory_writer(uint32_t guest_addr, const void *data, uint32_t size); +void init_memory(pid_t guest_pid); \ No newline at end of file diff --git a/native/src/pipe/pipe.cpp b/native/src/pipe/pipe.cpp index d78c24c..199f68b 100644 --- a/native/src/pipe/pipe.cpp +++ b/native/src/pipe/pipe.cpp @@ -44,18 +44,24 @@ void init_pipe_host(pid_t guest_pid) { close(arguments_pipe[PIPE_WRITE]); close(return_value_pipe[PIPE_READ]); // Wait For Commands - uint32_t cmd; - while (read(arguments_pipe[PIPE_READ], &cmd, sizeof(uint32_t)) > 0) { - uint32_t ret = trampoline(cmd, shared_memory_host_only); - write(return_value_pipe[PIPE_WRITE], &ret, sizeof(uint32_t)); + trampoline_pipe_arguments cmd = {}; + while (read(arguments_pipe[PIPE_READ], &cmd, sizeof(trampoline_pipe_arguments)) > 0) { + static unsigned char args[MAX_TRAMPOLINE_ARGS_SIZE]; + memory_reader(cmd.args_addr, args, cmd.length); + uint32_t ret = 0; + if (cmd.allow_early_return && cmd.length > 0) { + write(return_value_pipe[PIPE_WRITE], &ret, sizeof(uint32_t)); + } + ret = trampoline(cmd.id, args); + if (!cmd.allow_early_return) { + write(return_value_pipe[PIPE_WRITE], &ret, sizeof(uint32_t)); + } } // Reap Child int status; if (waitpid(guest_pid, &status, 0) == -1) { ERR("Unable To Reap Child: %s", strerror(errno)); } - // Close Shared Memory - free_shared_memory(); // Exit if (WIFEXITED(status)) { exit(WEXITSTATUS(status)); diff --git a/native/src/ptrace/loop.cpp b/native/src/ptrace/loop.cpp index 963fdb3..5c7baf6 100644 --- a/native/src/ptrace/loop.cpp +++ b/native/src/ptrace/loop.cpp @@ -26,7 +26,6 @@ void safe_wait(pid_t guest_pid, int *status) { } if (WIFEXITED(real_status)) { // Process Exited - free_shared_memory(); exit(WEXITSTATUS(real_status)); } if (status != nullptr) { @@ -92,7 +91,6 @@ static void set_syscall_return(pid_t guest_pid, arm32_pt_regs *regs) { // Main Loop void loop_ptrace(pid_t guest_pid) { - unsigned char *args = shared_memory_host_only; while (true) { // Wait For Syscall ptrace_wait_syscall(guest_pid); @@ -106,9 +104,11 @@ void loop_ptrace(pid_t guest_pid) { uint32_t length; uint32_t args_addr; get_arguments(®s, &id, &length, &args_addr); + unsigned char args[MAX_TRAMPOLINE_ARGS_SIZE]; + memory_reader(args_addr, args, length); // Run Trampoline const uint32_t ret = trampoline(id, args); - *(uint32_t *) args = ret; + memory_writer(args_addr, &ret, sizeof(uint32_t)); // Set Syscall Return set_syscall_return(guest_pid, ®s); }