Created
January 24, 2023 03:03
-
-
Save mvanotti/3c9fd20a2520a65af2c1050e283aa48f to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <assert.h> | |
#include <limits.h> | |
#include <signal.h> | |
#include <stdint.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <unistd.h> | |
uint64_t g_addr; | |
int g_last_code = INT_MIN; | |
uint64_t g_last_err = UINT64_MAX; | |
const char *si_code2str(int si_code) { | |
switch (si_code) { | |
case SEGV_MAPERR: | |
return "SEGV_MAPERR"; | |
case SEGV_ACCERR: | |
return "SEGV_ACCERR"; | |
case SEGV_BNDERR: | |
return "SEGV_BNDERR"; | |
case SEGV_PKUERR: | |
return "SEGV_PKUERR"; | |
default: | |
__builtin_trap(); | |
} | |
} | |
void handler(int sig, siginfo_t *info, void *ucontext) { | |
ucontext_t *uc = (ucontext_t *)ucontext; | |
g_addr += 0x1000; | |
uc->uc_mcontext.gregs[REG_RAX] = g_addr; | |
uint64_t reg_err = uc->uc_mcontext.gregs[REG_ERR]; | |
int code = info->si_code; | |
if (reg_err != g_last_err || code != g_last_code) { | |
g_last_code = code; | |
g_last_err = reg_err; | |
/* Do something useful with siginfo_t */ | |
fprintf(stderr, | |
"[!] signal %d, fault @ %p, " | |
"errno: 0x%x, code: %s, reg_err: 0x%016lx\n", | |
sig, info->si_addr, info->si_errno, si_code2str(code), reg_err); | |
} | |
} | |
void read_access(uint64_t addr) { | |
g_addr = addr; | |
__asm__ volatile("movq %0, %%rax\n" | |
"movq (%%rax), %%rdi\n" ::"r"(addr) | |
: "rax", "rdi"); | |
} | |
void write_access(uint64_t addr) { | |
g_addr = addr; | |
__asm__ volatile("movq %0, %%rax\n" | |
"movq %%rdi, (%%rax)\n" ::"r"(addr) | |
: "rax", "rdi"); | |
} | |
int main(int argc, char **argv) { | |
struct sigaction sa; | |
if (argc != 2) { | |
fprintf(stderr, "usage: %s addr-in-hex\n", argv[0]); | |
exit(EXIT_FAILURE); | |
} | |
uint64_t addr = (uint64_t)strtoull(argv[1], NULL, 16); | |
sa.sa_sigaction = handler; | |
sigemptyset(&sa.sa_mask); | |
sa.sa_flags = SA_RESTART | SA_SIGINFO; | |
sigaction(SIGSEGV, &sa, NULL); | |
write_access(addr); | |
fprintf(stderr, "[#] done, found addr: 0x%016lx\n", g_addr); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment