/* * interpose_profile.c — Profiling interposer for heap layout analysis * * Logs all malloc/free calls from AppleJPEGXL with sizes and caller info. * Output: one line per operation, parseable by the mutation test harness. * * Build: * clang -shared -o interpose_profile.dylib interpose_profile.c * * Use: * DYLD_INSERT_LIBRARIES=./interpose_profile.dylib ./wkwebview_poc poc.jxl 2>/tmp/profile.log */ #include #include #include #include #include #include #include typedef struct { const void *replacement; const void *replacee; } interpose_t; static int initialized = 0; static int in_hook = 0; static int op_count = 0; static inline void real_free(void *ptr) { malloc_zone_t *zone = malloc_default_zone(); if (zone && ptr) zone->free(zone, ptr); } __attribute__((constructor)) static void init(void) { initialized = 1; } static void hooked_free(void *ptr) { if (!ptr) { return; } if (in_hook || !initialized) { real_free(ptr); return; } in_hook = 1; Dl_info info; void *ra = __builtin_return_address(0); if (dladdr(ra, &info) && info.dli_fname && strstr(info.dli_fname, "AppleJPEGXL")) { op_count++; size_t sz = malloc_size(ptr); const char *sym = info.dli_sname ? info.dli_sname : "?"; unsigned long off = (unsigned long)((char *)ra - (char *)info.dli_saddr); char buf[256]; int n = snprintf(buf, sizeof(buf), "FREE %d %p %zu %s+0x%lx\n", op_count, ptr, sz, sym, off); write(STDERR_FILENO, buf, n); } in_hook = 0; real_free(ptr); } static void *hooked_malloc(size_t size) { void *ptr = malloc_zone_malloc(malloc_default_zone(), size); if (!ptr || in_hook || !initialized) return ptr; in_hook = 1; Dl_info info; void *ra = __builtin_return_address(0); if (dladdr(ra, &info) && info.dli_fname && strstr(info.dli_fname, "AppleJPEGXL")) { op_count++; char buf[256]; const char *sym = info.dli_sname ? info.dli_sname : "?"; unsigned long off = (unsigned long)((char *)ra - (char *)info.dli_saddr); int n = snprintf(buf, sizeof(buf), "MALLOC %d %p %zu %s+0x%lx\n", op_count, ptr, size, sym, off); write(STDERR_FILENO, buf, n); } in_hook = 0; return ptr; } __attribute__((used)) static const interpose_t interposers[] __attribute__((section("__DATA,__interpose"))) = { { (const void *)hooked_free, (const void *)free }, { (const void *)hooked_malloc, (const void *)malloc }, };