How to set malloc hooks in OSX Lion / 10.7

Intercepting the malloc layer in OSX has been (mostly) straight forward. I need to be able to intercept any calls to free() so I can do some cleanup.

To my suprise, my custom free function stopped working in OSX Lion DP4 (the first 10.7 version I tried). A quick check and 5 minutes later, I discovered that the application was throwing an exception when trying to assign a new value for the zone->free pointer
malloc_zone_t *dz=malloc_default_zone();
original_free=dz->free;
dz->free=&my_free; //this line is throwing a bad ptr exception
A few Google searches (read 2 days) later and many pages read (lots of experts got me up to speed on the amazing amount of changes in Lion, like...err...Look! Preeetty!....new Photo Booth or something equally fluffy iCloudy) I still had no answer/solution so I ended up looking at a couple versions of the malloc.c code published by Apple. One line caught my attention:
vm_protect(mach_task_self(), (uintptr_t)malloc_zones, protect_size, 0, VM_PROT_READ | VM_PROT_WRITE);
and, a few lines down the road:
vm_protect(mach_task_self(), (uintptr_t)malloc_zones, protect_size, 0, VM_PROT_READ);

It looks like newer libc versions have the tendency to write protect the zones and all you get when you try to rewrite the zone's memory is a bad ptr exception.

The basic solution (will only work in 10.7 like this):

malloc_zone_t *dz=malloc_default_zone();
if(dz->version>=8)
{
vm_protect(mach_task_self(), (uintptr_t)malloc_zones, protect_size, 0, VM_PROT_READ | VM_PROT_WRITE);//remove the write protection
}
original_free=dz->free;
dz->free=&my_free; //this line is throwing a bad ptr exception
if(dz->version==8)
{
vm_protect(mach_task_self(), (uintptr_t)malloc_zones, protect_size, 0, VM_PROT_READ);//put the write protection back
}
Worth reading:



Comments

Popular Posts