I tried checking all memory writes (well, ok. for now I only check aligned 32bit stores) to the heap, of IOS and matching them to buffers that had been previously allocated with malloc(). During malloc() and free() I allow memory writes to occur anywhere. This is similar to the basic operation of Valgrind (ignoring the stack checks, and uninitialized variable usage checks).
10,007 reports of memory writes not associated with an allocated buffer, once booted 😦
It appears that lots of changes to heap structures are made outside of malloc and free. I can think of at least one function that does this, IncRefCnt(). CheckHeaps in IOS does memory reads, does it also do writes? What other things can be done.. Perhaps there is a wrapper layer about malloc and free. Infact, there is a layer about the malloc I have, but I have disassembled all of that and while I have no idea about what some of the arguments are, it’s pretty safe to say they dont write to the heap.
The approach I took to finding these functions which modify the heap, was to take a call trace everytime an out of bounds memory write occured. Given enough samples, I tried to find common functions in each call trace. I assume that there is a small set of functions where 1 must be seen everytime an out of bounds memory write occurs.
I wrote the code for that, and although I can’t quite say the algorithm I used is sound, it provided me with a list of functions. Trouble is, it hasn’t seemed to work too well.. My call tracer doesn’t seem to work too well either as it occurs more often than I’d like, that the call trace increases without ever decreasing again. Not a good sign. Also, one common function identified was at 0xbfxxxxxx, which is used by mips cpu. Oh, just had a thought as I write this, maybe I’m getting TLB miss exceptions and page lookup code. I hope not.. probably a crazy thought. Another problem is if you analyse a call trace with too large a depth. In that situation you can end up finding main() as a common function.
This is something that i’ll have to work on.. I dont think it’ll be too pretty. All of this in any case seems like a major distraction from my original goal of symbolic execution. But I figured it was important that I be able to check for out of bounds reads/writes in that environment, so a memcheck/valgrind implementation seemed like a good side project to get me what i wanted.