-
-
Save hasB4K/5211529e2a1741c478f253b82c110d69 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
| #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