2

I want to find all accesses to heap memory in an application. I need to store each allocation and, consequently, can not only check for addresses in the [heap] range (which also does not include heap memory areas allocated by mmap()). Therefore, I wrote a pintool and captured all calls to malloc(), calloc(), realloc() and free(). Because of optimizations such as tail-call elimiation Pin can not detect the last instruction of these calls. Therefore, I manually added callbacks after (precisely, I used IPOINT_TAKEN_BRANCH) the ret... instructions in each of the probable direct/indirect jump targets out of these functions (e.g., malloc(), indirectly, jumps to malloc_hook_ini(). So I added instrumentation code after all ret... instructions in malloc_hook_ini()). These targets, themselves, may have outgoing direct/indirect jumps and, again, I tried to capture them.

But, there are still some accesses in the [heap] range (and also in mmap() ranges) which do not pertain to any of the previously captured allocations. To clear up any doubts, I used Pwngdb to display all currently allocated heap chunks, right before the access point. The access address was clearly in an allocated heap chunk. Of course, knowing the allocation IP for these heap chunks will be a great help. But this is not supported in Pwngdb or any other similar tools.

In many cases analyzed by Pin, the access address does not belong to any address range allocated (even those removed in the meantime) during the whole program execution. How can I determine which allocation function was missed during Pin analysis?

It seems that there are two possible situations:

1) There exists some omitted function other than malloc(), calloc(), realloc() and free().

2) There are some missed return points for malloc(), calloc(), realloc() and free().

The second candidate is not possible. Because I put a counter before and after each of these allocation functions and at the end, they had equal values.


UPDATE:

Here is the backtrace for one such access point and also the value for the RSI register: enter image description here

TheAhmad
  • 810
  • 1
  • 9
  • 21
  • 1
    Perhaps you would be better of doing this at the syscall level, aka intercepting all calls to the os for ram? – PiRocks May 03 '20 at 17:34
  • 1
    In general languages other than c may not use malloc to allocate their memory, and even c may use alternatives depending on the context. – PiRocks May 03 '20 at 17:35
  • Thanks. Interception at the system call level does not seem to help. Because (in `ptmalloc`) memory is **aggressively** obtained from the OS and stored in variable-sized chunks for **future** allocation. I need *actual* allocations. Could you mention a dynamic allocation mechanism in `C` that does not use `malloc()/calloc()/realloc()` or `mmap()`? – TheAhmad May 03 '20 at 18:42
  • So someone could always `sbrk()` more memory, and use that? That seems like a plausible explanation. So you have further details on the heap accesses in question? Like a stacktrace or similar? – PiRocks May 03 '20 at 19:54
  • But memory allocation without using/updating `ptmalloc` metadata about the list of free chunks will put the allocator in an inconsistent state. I have added a dynamic memory access backtrace. – TheAhmad May 04 '20 at 01:22
  • 1
    It's a long shot but are you correctly handling stuff like shared memory e.g. shmat? http://man7.org/linux/man-pages/man2/shmat.2.html – PiRocks May 04 '20 at 15:39
  • Additionally are you sure you have no race conditions etc. with memory allocated on a different thread? – PiRocks May 04 '20 at 15:43
  • 1
    Thanks for your time. The program is single process. I found the bug. The reason was a silly mishandling of `calloc()` arguments. I thought that its input arguments are the same as that of `malloc()`. – TheAhmad May 04 '20 at 17:04

0 Answers0