From 1b7e227ca5a48bd9b451a76cff55d735d38f0fee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20H=C3=BCttel?= Date: Mon, 17 Dec 2018 21:42:31 +0100 Subject: [PATCH] Init --- main.c | 121 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 main.c diff --git a/main.c b/main.c new file mode 100644 index 0000000..1522577 --- /dev/null +++ b/main.c @@ -0,0 +1,121 @@ +#undef _GNU_SOURCE +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include +#include +#include + + +volatile uint32_t *page = NULL; +static int write_flag = 0; +static void *address_buffer; + +static uint32_t read_memory(uint32_t *addr) +{ + static uint32_t foo = 0; + /* Always return incremented number */ + foo++; + return foo; +} + +static uint32_t write_memory(uint32_t* addr, uint32_t val) +{ + printf("Write @ %p: %u\n", (void *)addr, val); +} + + +static void segfault_handler(int signal, siginfo_t* sig_info, void *uap) +{ + ucontext_t *context; + int err; + uint32_t read_val; + + /* Unhandled error */ + if (sig_info->si_code != SEGV_ACCERR) + exit(-2); + + context = (ucontext_t *)uap; + + /* Allow access */ + mprotect(page, getpagesize(), PROT_READ | PROT_WRITE); + + /* Read or Write instruction? */ + err = context->uc_mcontext.gregs[REG_ERR]; + write_flag = ((err & 2) ? 1 : 0); + + address_buffer = (void *)sig_info->si_addr; + + /* Handle read */ + if (!write_flag) { + read_val = read_memory((uint32_t *)address_buffer); + /* Fill value to memory */ + *((uint32_t *)address_buffer) = read_val; + } + + /* Set Trap flag. Leads to single step */ + context->uc_mcontext.gregs[REG_EFL] |= 0x100; + +} + +static void trap_handler(int signal, siginfo_t* sig_info, void *uap) +{ + /* Disable trap */ + ((ucontext_t *)uap)->uc_mcontext.gregs[REG_EFL] &= ~(0x100U); + + /* Read written value and call callback */ + if (write_flag) + write_memory((uint32_t *)address_buffer, *((uint32_t *)address_buffer)); + + /* Lock memory */ + mprotect(page, getpagesize(), PROT_NONE); +} + +static void register_handler() +{ + struct sigaction action; + struct sigaction trap; + + memset(&action, 0, sizeof(struct sigaction)); + sigemptyset(&action.sa_mask); + action.sa_flags = SA_SIGINFO; + action.sa_sigaction = segfault_handler; + + sigaction(SIGSEGV, &action, NULL); + + memset(&trap, 0, sizeof(struct sigaction)); + sigemptyset(&trap.sa_mask); + trap.sa_flags = SA_SIGINFO; + trap.sa_sigaction = trap_handler; + + sigaction(SIGTRAP, &trap, NULL); +} + +int main() +{ + + /* Allocate memory */ + page = (uint32_t *)mmap(NULL, getpagesize(), PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED, -1, 0); + if (!page) + return -1; + printf("VMA: %p\n", page); + *page=12; + /* Register SIGSEGV handler */ + register_handler(); + + /* Protect memory */ + mprotect(page, getpagesize(), PROT_NONE); + + + printf("RD1: %d\n", *page); + printf("RD2: %d\n", *page); + printf("RD3: %d\n", *page); + + *page = 100; + + return 0; +}