README.md
Rendering markdown...
/*
* 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 <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
#include <string.h>
#include <stdint.h>
#include <unistd.h>
#include <malloc/malloc.h>
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 },
};