rodionovd / rd_route

Function hooking for macOS
MIT License
184 stars 26 forks source link

Crash when calling reentry/original function (latest Yosemite GM, 10.9.5) #6

Closed nfgrilo closed 9 years ago

nfgrilo commented 9 years ago

Hi!

Thank you so much for this project! I was previously using mach_override, but since I found rd_route, I have switched!

I noticed that at some point (OS X 10.10 DP5 or DP6), calling the reentry function crashes the application. One quick and dirty workaround I found, was to change the _remap_image() function, changing the existing x86_64 hack: err = mach_vm_allocate(mach_task_self(), new_location, image_size*3, VM_FLAGS_ANYWHERE); mach_vm_size_t lefover = image_size * 2; to: err = mach_vm_allocate(mach_task_self(), new_location, image_size*4, VM_FLAGS_ANYWHERE); mach_vm_size_t lefover = image_size * 3;

That (apparently) fixed, but it looks like apps still crash after some time. One thing that may or not be related, if I injected myself on Quicktime Player (OSX 10.10 too), app crashes immediately when calling rd_route() (at _patch_memory + 178 (rd_route.c:306)).

Hope this helps!

Thank you, Nuno

rodionovd commented 9 years ago

Hi Nuno,

I've just came across the same issue (I'm on 10.9.5). I guess Apple may have changed something in their latest releases for both 10.9 and 10.10.

This x86_64 hack is very old and I really should have fixed it months ago…

Anyway, the reason of this hack is that __DATA segment is allocated quite far from other segments and, most importantly, before the image header itself. Due to this fact, current _remap_image() implementation will remap __DATA segment to an invalid location before our pre-allocated zone:

mach_vm_address_t seg_target = *new_location + (seg_source - header);
                                                ^^^^^^^^^^^^^^^^^^^
                                                  negative value

That's what I've added a „leftover hack“ for: to allocate a safety zone before the actual target address. In this case __DATA segment would be mapped into a valid (owned by user) memory region and everything would be OK.

For some reasons __DATA segment was shifted even further in modern versions of OS X, and now we have to pre-allocate up to 3*image_size bytes of safety zone before the actual remapped image.

One possible solution for the problem is to allocate a separate memory zone for each segment, and use an address of __TEXT segment as pointer to a new location of the image.


I'm quite sure that your patch is enough to solve the problem with a reentry function you have. But I'm not sure about these unpredictable crashes… It would be great if you could reproduce them.

rodionovd commented 9 years ago

@nfgrilo please check if this solution works for you: fix-DATA-segment-remapping-issue branch

nfgrilo commented 9 years ago

@rodionovd, thank you so much for looking into this so quickly, and for your detailed explanation! Also, I have been playing with your fix from the branch, and so far so good! Applications doesn't crash when calling the reentry function, Quicktime Player doesn't crash when calling rd_route(), and so far I have not been able to experience those unpredictable crashes (not easy to reproduce)!

Thank you sooooo much! Since I'm relying and playing a lot with your rd_route(), I will keep you updated in case anything unusual is detected.

Loving your _rdroute project :yum:

rodionovd commented 9 years ago

Thank you very much, @nfgrilo! I really appreciate you effort to help the project :v:

Looking forward for your further feedback.