WIP Forever

This commit is contained in:
TheBrokenRail 2024-06-08 04:23:03 -04:00
parent 027e58ee9b
commit 06e9f4d7c8
6 changed files with 39 additions and 61 deletions

View File

@ -2,9 +2,6 @@
#include <stdint.h> #include <stdint.h>
// Shared Memory
#define TRAMPOLINE_SHARED_MEMORY_ENV "_MCPI_TRAMPOLINE_SHARED_MEMORY"
// Switch Between Pipe/PTrace Mode // Switch Between Pipe/PTrace Mode
#define TRAMPOLINE_USE_PIPES_ENV "_MCPI_TRAMPOLINE_USE_PIPES" #define TRAMPOLINE_USE_PIPES_ENV "_MCPI_TRAMPOLINE_USE_PIPES"
@ -15,7 +12,13 @@
// Pipe Constants // Pipe Constants
#define TRAMPOLINE_ARGUMENTS_PIPE_ENV "_MCPI_TRAMPOLINE_ARGUMENTS" #define TRAMPOLINE_ARGUMENTS_PIPE_ENV "_MCPI_TRAMPOLINE_ARGUMENTS"
#define TRAMPOLINE_RETURN_VALUE_PIPE_ENV "_MCPI_TRAMPOLINE_RETURN_VALUE" #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 // 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); typedef uint32_t (*trampoline_t)(trampoline_writer_t writer, uint32_t id, const unsigned char *args);

View File

@ -18,7 +18,6 @@ int main(__attribute__((unused)) int argc, char *argv[]) {
} }
bool use_ptrace = getenv(TRAMPOLINE_USE_PIPES_ENV) == nullptr; bool use_ptrace = getenv(TRAMPOLINE_USE_PIPES_ENV) == nullptr;
// Setup // Setup
init_shared_memory_common();
if (!use_ptrace) { if (!use_ptrace) {
init_pipe_common(); init_pipe_common();
} }
@ -29,7 +28,6 @@ int main(__attribute__((unused)) int argc, char *argv[]) {
} else if (pid == 0) { } else if (pid == 0) {
// Setup // Setup
setpgid(0, 0); setpgid(0, 0);
init_shared_memory_guest();
if (use_ptrace) { if (use_ptrace) {
init_ptrace_guest(); init_ptrace_guest();
} else { } else {
@ -42,7 +40,6 @@ int main(__attribute__((unused)) int argc, char *argv[]) {
// Parent // Parent
// Setup Trampoline // Setup Trampoline
init_shared_memory_host();
init_signals(pid); init_signals(pid);
init_memory(pid); init_memory(pid);
init_trampoline(); init_trampoline();

View File

@ -1,22 +1,16 @@
#include <sys/uio.h> #include <sys/uio.h>
#include <cstring> #include <cstring>
#include <cerrno> #include <cerrno>
#include <sys/mman.h>
#include <fcntl.h>
#include <string>
#include <unistd.h>
#include <trampoline/types.h>
#include "memory.h" #include "memory.h"
#include "log.h" #include "log.h"
// Read Memory // Read/Write Memory
static pid_t guest_pid; static pid_t guest_pid;
void init_memory(pid_t pid) { void init_memory(pid_t pid) {
guest_pid = 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) { if (size == 0) {
return; return;
} }
@ -26,36 +20,20 @@ void memory_writer(uint32_t guest_addr, void *data, uint32_t size) {
iovec remote[1]; iovec remote[1];
remote[0].iov_base = (void *) (uint64_t) guest_addr; remote[0].iov_base = (void *) (uint64_t) guest_addr;
remote[0].iov_len = size; 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); const ssize_t ret = process_vm_writev(guest_pid, local, 1, remote, 1, 0);
if (ret != size) { if (ret != size) {
ERR("Unable To Write Data: %s", strerror(errno)); 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());
} }

View File

@ -4,12 +4,6 @@
#include <sys/types.h> #include <sys/types.h>
// Read External Memory // Read External Memory
void memory_writer(uint32_t guest_addr, void *data, uint32_t size); void memory_reader(uint32_t guest_addr, void *data, uint32_t size);
void init_memory(pid_t guest_pid); void memory_writer(uint32_t guest_addr, const 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();

View File

@ -44,18 +44,24 @@ void init_pipe_host(pid_t guest_pid) {
close(arguments_pipe[PIPE_WRITE]); close(arguments_pipe[PIPE_WRITE]);
close(return_value_pipe[PIPE_READ]); close(return_value_pipe[PIPE_READ]);
// Wait For Commands // Wait For Commands
uint32_t cmd; trampoline_pipe_arguments cmd = {};
while (read(arguments_pipe[PIPE_READ], &cmd, sizeof(uint32_t)) > 0) { while (read(arguments_pipe[PIPE_READ], &cmd, sizeof(trampoline_pipe_arguments)) > 0) {
uint32_t ret = trampoline(cmd, shared_memory_host_only); static unsigned char args[MAX_TRAMPOLINE_ARGS_SIZE];
write(return_value_pipe[PIPE_WRITE], &ret, sizeof(uint32_t)); 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 // Reap Child
int status; int status;
if (waitpid(guest_pid, &status, 0) == -1) { if (waitpid(guest_pid, &status, 0) == -1) {
ERR("Unable To Reap Child: %s", strerror(errno)); ERR("Unable To Reap Child: %s", strerror(errno));
} }
// Close Shared Memory
free_shared_memory();
// Exit // Exit
if (WIFEXITED(status)) { if (WIFEXITED(status)) {
exit(WEXITSTATUS(status)); exit(WEXITSTATUS(status));

View File

@ -26,7 +26,6 @@ void safe_wait(pid_t guest_pid, int *status) {
} }
if (WIFEXITED(real_status)) { if (WIFEXITED(real_status)) {
// Process Exited // Process Exited
free_shared_memory();
exit(WEXITSTATUS(real_status)); exit(WEXITSTATUS(real_status));
} }
if (status != nullptr) { if (status != nullptr) {
@ -92,7 +91,6 @@ static void set_syscall_return(pid_t guest_pid, arm32_pt_regs *regs) {
// Main Loop // Main Loop
void loop_ptrace(pid_t guest_pid) { void loop_ptrace(pid_t guest_pid) {
unsigned char *args = shared_memory_host_only;
while (true) { while (true) {
// Wait For Syscall // Wait For Syscall
ptrace_wait_syscall(guest_pid); ptrace_wait_syscall(guest_pid);
@ -106,9 +104,11 @@ void loop_ptrace(pid_t guest_pid) {
uint32_t length; uint32_t length;
uint32_t args_addr; uint32_t args_addr;
get_arguments(&regs, &id, &length, &args_addr); get_arguments(&regs, &id, &length, &args_addr);
unsigned char args[MAX_TRAMPOLINE_ARGS_SIZE];
memory_reader(args_addr, args, length);
// Run Trampoline // Run Trampoline
const uint32_t ret = trampoline(id, args); 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
set_syscall_return(guest_pid, &regs); set_syscall_return(guest_pid, &regs);
} }