Skip to content

Instantly share code, notes, and snippets.

@hasB4K
Created January 7, 2026 15:01
Show Gist options
  • Select an option

  • Save hasB4K/5211529e2a1741c478f253b82c110d69 to your computer and use it in GitHub Desktop.

Select an option

Save hasB4K/5211529e2a1741c478f253b82c110d69 to your computer and use it in GitHub Desktop.
#define _GNU_SOURCE
#include <execinfo.h>
#include <stdlib.h>
#include <stdio.h>
#include <dlfcn.h>
#include <unistd.h>
#include <stdbool.h>
#include <string.h>
#include <assert.h>
#include <stdarg.h>
#include <sys/syscall.h>
#include <sys/mman.h> // For mremap and munmap
// Define the function pointer types
typedef void* (*mmap_fn)(void*, size_t, int, int, int, off_t);
typedef void* (*mremap_fn)(void*, size_t, size_t, int, ...);
typedef int (*munmap_fn)(void*, size_t);
typedef long (*syscall_fn)(long, ...);
// Original function pointers
static mmap_fn orig_mmap = NULL;
static mremap_fn orig_mremap = NULL;
static munmap_fn orig_munmap = NULL;
static syscall_fn orig_syscall = NULL;
// Log file
static FILE *log_file = NULL;
static bool flush_after_each = true;
// Initialize hooks
__attribute__((constructor))
void init_hooks(void) {
char filename[256];
snprintf(filename, sizeof(filename), "mmap_dump_%d.txt", getpid());
log_file = fopen(filename, "a+");
if (!log_file) {
fprintf(stderr, "Failed to open log file\n");
exit(-1);
}
// Resolve original functions
orig_mmap = (mmap_fn)dlsym(RTLD_NEXT, "mmap");
if (!orig_mmap) {
fprintf(stderr, "Failed to resolve mmap\n");
exit(-1);
}
orig_mremap = (mremap_fn)dlsym(RTLD_NEXT, "mremap");
if (!orig_mremap) {
fprintf(stderr, "Failed to resolve mremap\n");
exit(-1);
}
orig_munmap = (munmap_fn)dlsym(RTLD_NEXT, "munmap");
if (!orig_munmap) {
fprintf(stderr, "Failed to resolve munmap\n");
exit(-1);
}
orig_syscall = (syscall_fn)dlsym(RTLD_NEXT, "syscall");
if (!orig_syscall) {
fprintf(stderr, "Failed to resolve syscall\n");
exit(-1);
}
}
// Helper function to log stack traces and details
void log_call(const char *func_name, const char *format, ...) {
va_list args;
va_start(args, format);
void *array[50];
size_t size = backtrace(array, 50);
char **strings = backtrace_symbols(array, size);
// Calculate the required buffer size
size_t total_size = 256; // Initial size for basic info
for (size_t i = 0; i < size; i++) {
total_size += strlen(strings[i]) + 1; // +1 for newline
}
// Allocate buffer
char *buffer = malloc(total_size);
if (!buffer) {
free(strings);
va_end(args);
return;
}
// Construct the full log message
char *ptr = buffer;
ptr += snprintf(ptr, total_size, "\n--- %s called ---\n", func_name);
// Append formatted arguments
ptr += vsnprintf(ptr, buffer + total_size - ptr, format, args);
ptr += snprintf(ptr, buffer + total_size - ptr, "\nStack trace:\n");
for (size_t i = 0; i < size; i++) {
ptr += snprintf(ptr, buffer + total_size - ptr, "%s\n", strings[i]);
}
// Write to log file
fprintf(log_file, "%s", buffer);
free(strings);
free(buffer);
va_end(args);
if (flush_after_each) {
fflush(log_file);
}
}
// Hook for mmap
void *mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t off) {
void *result = orig_mmap(addr, len, prot, flags, fildes, off);
log_call("mmap", "addr: %p, len: %zu, prot: %d, flags: %d, fildes: %d, off: %ld\nReturn value: %p",
addr, len, prot, flags, fildes, off, result);
return result;
}
// Hook for mremap
void *mremap(void *old_addr, size_t old_size, size_t new_size, int flags, ...) {
va_list args;
va_start(args, flags);
void *new_addr = va_arg(args, void*);
va_end(args);
void *result = orig_mremap(old_addr, old_size, new_size, flags, new_addr);
log_call("mremap", "old_addr: %p, old_size: %zu, new_size: %zu, flags: %d, new_addr: %p\nReturn value: %p",
old_addr, old_size, new_size, flags, new_addr, result);
return result;
}
// Hook for munmap
int munmap(void *addr, size_t len) {
int result = orig_munmap(addr, len);
log_call("munmap", "addr: %p, len: %zu\nReturn value: %d", addr, len, result);
return result;
}
// Hook for syscall
long syscall(long number, ...) {
va_list args;
va_start(args, number);
// Only log if the syscall is related to mmap (SYS_mmap)
if (number == SYS_mmap) {
void *addr = va_arg(args, void*);
size_t len = va_arg(args, size_t);
int prot = va_arg(args, int);
int flags = va_arg(args, int);
int fildes = va_arg(args, int);
off_t off = va_arg(args, off_t);
// Call the original syscall
long result = orig_syscall(number, addr, len, prot, flags, fildes, off);
// Log the syscall
log_call("syscall(SYS_mmap)", "addr: %p, len: %zu, prot: %d, flags: %d, fildes: %d, off: %ld\nReturn value: %p",
addr, len, prot, flags, fildes, off, (void*)result);
va_end(args);
return result;
}
// For other syscalls, pass through without logging
long result = orig_syscall(number,
va_arg(args, void*),
va_arg(args, size_t),
va_arg(args, int),
va_arg(args, int),
va_arg(args, int),
va_arg(args, off_t));
va_end(args);
return result;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment