From 027e58ee9bdcfef285c16e731c8db218082b9639 Mon Sep 17 00:00:00 2001 From: TheBrokenRail Date: Sat, 8 Jun 2024 03:09:44 -0400 Subject: [PATCH] WIP --- include/trampoline/types.h | 16 ++++------- native/CMakeLists.txt | 2 +- native/src/main.cpp | 5 +++- native/src/memory.cpp | 56 +++++++++++++++++++++++++------------- native/src/memory.h | 11 ++++++-- native/src/pipe/pipe.cpp | 11 ++++---- native/src/ptrace/loop.cpp | 9 +++--- 7 files changed, 66 insertions(+), 44 deletions(-) diff --git a/include/trampoline/types.h b/include/trampoline/types.h index 15b141f..c00bbcb 100644 --- a/include/trampoline/types.h +++ b/include/trampoline/types.h @@ -2,25 +2,19 @@ #include -// Switch Between Pipe?PTrace Mode -#ifdef MCPI_USE_NATIVE_TRAMPOLINE -#define TRAMPOLINE_USE_PTRACE_ENV "_MCPI_TRAMPOLINE_USE_PTRACE" -#endif +// 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" // System Call Constants #define MAX_TRAMPOLINE_ARGS_SIZE 2097152 // 2 MiB #define TRAMPOLINE_SYSCALL 0x1337 // Pipe Constants -#ifdef MCPI_USE_NATIVE_TRAMPOLINE #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 length; - uint32_t args_addr; -}; -#endif // Function Types typedef void (*trampoline_writer_t)(uint32_t guest_addr, void *data, uint32_t size); diff --git a/native/CMakeLists.txt b/native/CMakeLists.txt index 1b42d25..9d1a994 100644 --- a/native/CMakeLists.txt +++ b/native/CMakeLists.txt @@ -15,7 +15,7 @@ add_executable(trampoline target_compile_options(trampoline PRIVATE -Wall -Wextra -Werror -Wpointer-arith -Wshadow -Wnull-dereference) # Link -target_link_libraries(trampoline dl trampoline-headers) +target_link_libraries(trampoline dl rt trampoline-headers) # RPath set_target_properties(trampoline PROPERTIES INSTALL_RPATH "$ORIGIN/../lib/native") diff --git a/native/src/main.cpp b/native/src/main.cpp index b3b35c8..a5d6793 100644 --- a/native/src/main.cpp +++ b/native/src/main.cpp @@ -16,8 +16,9 @@ int main(__attribute__((unused)) int argc, char *argv[]) { if (argc < 2) { ERR("Invalid Arguments"); } - bool use_ptrace = getenv(TRAMPOLINE_USE_PTRACE_ENV) != nullptr; + bool use_ptrace = getenv(TRAMPOLINE_USE_PIPES_ENV) == nullptr; // Setup + init_shared_memory_common(); if (!use_ptrace) { init_pipe_common(); } @@ -28,6 +29,7 @@ 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 { @@ -40,6 +42,7 @@ 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 f3be9ad..da506c5 100644 --- a/native/src/memory.cpp +++ b/native/src/memory.cpp @@ -1,18 +1,22 @@ #include #include #include +#include +#include +#include +#include + +#include #include "memory.h" #include "log.h" -// Store PID +// Read Memory static pid_t guest_pid; void init_memory(pid_t pid) { guest_pid = pid; } - -// Read Memory -void memory_reader(uint32_t guest_addr, void *data, uint32_t size) { +void memory_writer(uint32_t guest_addr, void *data, uint32_t size) { if (size == 0) { return; } @@ -22,22 +26,36 @@ void memory_reader(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; - ssize_t ret = process_vm_readv(guest_pid, local, 1, remote, 1, 0); - if (ret != size) { - ERR("Unable To Read Data: %s", strerror(errno)); - } -} - -// Write Memory -void memory_writer(uint32_t guest_addr, void *data, uint32_t size) { - iovec local[1]; - local[0].iov_base = data; - local[0].iov_len = size; - iovec remote[1]; - remote[0].iov_base = (void *) (uint64_t) guest_addr; - remote[0].iov_len = size; - ssize_t ret = process_vm_writev(guest_pid, local, 1, remote, 1, 0); + 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 06aa54b..54c5bb4 100644 --- a/native/src/memory.h +++ b/native/src/memory.h @@ -3,6 +3,13 @@ #include #include -void memory_reader(uint32_t guest_addr, void *data, uint32_t size); +// Read External Memory void memory_writer(uint32_t guest_addr, void *data, uint32_t size); -void init_memory(pid_t guest_pid); \ No newline at end of file +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 diff --git a/native/src/pipe/pipe.cpp b/native/src/pipe/pipe.cpp index c4d9d6b..d78c24c 100644 --- a/native/src/pipe/pipe.cpp +++ b/native/src/pipe/pipe.cpp @@ -44,11 +44,9 @@ void init_pipe_host(pid_t guest_pid) { close(arguments_pipe[PIPE_WRITE]); close(return_value_pipe[PIPE_READ]); // Wait For Commands - 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 = trampoline(cmd.id, args); + 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)); } // Reap Child @@ -56,6 +54,9 @@ void init_pipe_host(pid_t guest_pid) { 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)); } else { diff --git a/native/src/ptrace/loop.cpp b/native/src/ptrace/loop.cpp index 9d51e9b..963fdb3 100644 --- a/native/src/ptrace/loop.cpp +++ b/native/src/ptrace/loop.cpp @@ -7,7 +7,6 @@ #ifndef __aarch64__ #error "Unsupported Host Architecture" #endif -#include #include "ptrace.h" #include "../log.h" @@ -27,6 +26,7 @@ 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,6 +92,7 @@ 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); @@ -105,11 +106,9 @@ void loop_ptrace(pid_t guest_pid) { uint32_t length; uint32_t args_addr; get_arguments(®s, &id, &length, &args_addr); - static unsigned char args[MAX_TRAMPOLINE_ARGS_SIZE]; - memory_reader(args_addr, args, length); // Run Trampoline - uint32_t ret = trampoline(id, args); - memory_writer(args_addr, &ret, sizeof(uint32_t)); + const uint32_t ret = trampoline(id, args); + *(uint32_t *) args = ret; // Set Syscall Return set_syscall_return(guest_pid, ®s); }