-
Notifications
You must be signed in to change notification settings - Fork 177
Closed
Description
I've come across multiple issues with hooking imported functions on MacOS, resulting hook either not working at all or hooking wrong function (after "fixing" issue with hook not working at all).
So here is what I found out after many many hours of debugging:
- in read_chained_fixups function value of
const uint8_t *ptr
is calculated incorrectly, making that pointer off by
linkedit->vmaddr - linkedit->fileoff
bytes, which results in rest of the things to be read incorrectly and ends up with "unknown imports format 0" error message in my case. I've changed code a bit and it fixed that error for me:
//const uint8_t *ptr = (const uint8_t *)mh + d->chained_fixups->dataoff;
struct segment_command_64* linkedit = d->segments[d->linkedit_segment_idx];
const uint8_t* ptr = (uint8_t*)(linkedit->vmaddr - linkedit->fileoff + d->slide + d->chained_fixups->dataoff);
- after "fixing" above error another one surfaced which results in plthook hooking incorrect functions, which results in app crashing when that hooked function is called, more specifically it is hooking functions that are located at address that is 0x30 bytes lower than intended (in my case), for example if target function's __got entry is located at 0x4BF2C8, plthook hooks function with __got entry at 0x4BF298 instead... At this point calculated addr already has incorrect value:
void **addr = (void**)(d->got_addr + i * sizeof(void*));
DEBUG_FIXUPS(" lib_ordinal %u, weak_import %u, name_offset %u (%s), addr %p, addend %llu\n",
imp.lib_ordinal, imp.weak_import, imp.name_offset, name, addr, imp.addend);
d->plthook->entries[i].name = name;
d->plthook->entries[i].addr = addr;
lib_base 0x10d9a7000
lib_ordinal 1, weak_import 0, name_offset 1387 (_dlopen), addr 0x10de66298, addend 0
dlopen=0x10de66298-0x10d9a7000=0x4BF298 while real dlopen is at 0x4BF2C8 if you look at IDA
Rough code I'm using:
void* dlopen_hook(const char* filename, int flags)
{
// stuff
}
void* dlsym_hook(void* handle, const char* symbol)
{
// stuff
}
bool hook_stuff()
{
plthook_t* plthook;
if (plthook_open(&plthook, "libname.dylib") != 0) {
return false;
}
if (plthook_replace(plthook, "dlopen", (void*)dlopen_hook, nullptr) != 0) {
plthook_close(plthook);
return false;
}
if (plthook_replace(plthook, "dlsym", (void*)dlsym_hook, nullptr) != 0) {
plthook_close(plthook);
return false;
}
}
Metadata
Metadata
Assignees
Labels
No labels