This is a continuation of the post https://silviocesare.wordpress.com/2008/07/27/finding-malloc-in-ios/.
Now that I have the address of malloc, I can go about finding free(). The logic behind determining free, is by looking for mallocs that return the same address. This must surely indicate a free() has occured, and memory is being recycled. Next, we track all calls, that use as an argument (register $a0-$a3) the address of the malloced buffer. One of these functions must be free.
Using the logic described over a number of test cases, we look at the common functions before the following malloc. This gives us an address which we think is free.
To test that we have the right address, I track all mallocs and suspected frees, making sure that no mallocs return the same buffer without a free in between, and that there are no double frees. That is, make sure all our mallocs and frees match up.
So did it work?
I spent several hours last night testing without success, and was truely becoming frustrated. A few minutes this morning with fresh eyes identified the problem. I was hooking free() by breaking on jalr/jar (MIPS call instructions), instead of hooking directly at the head of the real function. Hooking at the first instruction resolved the issues I was having. This must mean that there are jumps being made directly to free instead of using the call subroutine approach.
Anyway, a happy ending to several hours of frustration.. I have the addresses of malloc and free, in a fairly portable way across IOS versions.