我创建一个.dylib文件并编译它:
#define _GNU_SOURCE
#include <dlfcn.h>
#include <stdio.h>
static void* (*real_malloc)(size_t);
void *malloc(size_t size)
{
void *p = NULL;
fprintf(stderr, "malloc(%zd) = ", size);
p = real_malloc(size);
fprintf(stderr, "%p\n", p);
return p;
}
void __attribute((constructor))init()
{
real_malloc = (decltype(real_malloc))dlsym(RTLD_NEXT, "malloc");
if (NULL == real_malloc) {
fprintf(stderr, "Error in `dlsym`: %s\n", dlerror());
return;
}
}然后创建一个调用malloc的测试程序。我确保对malloc的调用没有优化。
接下来,我运行了以下命令:
DYLD_PRINT_LIBRARIES=1 X=1 DYLD_INSERT_LIBRARIES=./libTestHook.dylib ./malloctest
它加载它,但它根本不挂钩这个函数。有什么想法吗?我在El Capitan升级之前试过这段代码,它曾经有效..我还将malloc抛出一个异常,以查看是否正在调用它。事实并非如此。
我遗漏了什么?
研究结果如下:
sh-3.2# DYLD_PRINT_LIBRARIES=1 X=1 DYLD_INSERT_LIBRARIES=./libTestHook.dylib ./malloctest clear
dyld: loaded: /Users/Brandon/Desktop/./malloctest
dyld: loaded: ./libTestHook.dylib
dyld: loaded: /usr/lib/libc++.1.dylib
dyld: loaded: /usr/lib/libSystem.B.dylib
dyld: loaded: /usr/lib/libc++abi.dylib
dyld: loaded: /usr/lib/system/libcache.dylib
dyld: loaded: /usr/lib/system/libcommonCrypto.dylib
dyld: loaded: /usr/lib/system/libcompiler_rt.dylib
dyld: loaded: /usr/lib/system/libcopyfile.dylib
dyld: loaded: /usr/lib/system/libcorecrypto.dylib
dyld: loaded: /usr/lib/system/libdispatch.dylib
dyld: loaded: /usr/lib/system/libdyld.dylib
dyld: loaded: /usr/lib/system/libkeymgr.dylib
dyld: loaded: /usr/lib/system/liblaunch.dylib
dyld: loaded: /usr/lib/system/libmacho.dylib
dyld: loaded: /usr/lib/system/libquarantine.dylib
dyld: loaded: /usr/lib/system/libremovefile.dylib
dyld: loaded: /usr/lib/system/libsystem_asl.dylib
dyld: loaded: /usr/lib/system/libsystem_blocks.dylib
dyld: loaded: /usr/lib/system/libsystem_c.dylib
dyld: loaded: /usr/lib/system/libsystem_configuration.dylib
dyld: loaded: /usr/lib/system/libsystem_coreservices.dylib
dyld: loaded: /usr/lib/system/libsystem_coretls.dylib
dyld: loaded: /usr/lib/system/libsystem_dnssd.dylib
dyld: loaded: /usr/lib/system/libsystem_info.dylib
dyld: loaded: /usr/lib/system/libsystem_kernel.dylib
dyld: loaded: /usr/lib/system/libsystem_m.dylib
dyld: loaded: /usr/lib/system/libsystem_malloc.dylib
dyld: loaded: /usr/lib/system/libsystem_network.dylib
dyld: loaded: /usr/lib/system/libsystem_networkextension.dylib
dyld: loaded: /usr/lib/system/libsystem_notify.dylib
dyld: loaded: /usr/lib/system/libsystem_platform.dylib
dyld: loaded: /usr/lib/system/libsystem_pthread.dylib
dyld: loaded: /usr/lib/system/libsystem_sandbox.dylib
dyld: loaded: /usr/lib/system/libsystem_secinit.dylib
dyld: loaded: /usr/lib/system/libsystem_trace.dylib
dyld: loaded: /usr/lib/system/libunc.dylib
dyld: loaded: /usr/lib/system/libunwind.dylib
dyld: loaded: /usr/lib/system/libxpc.dylib
dyld: loaded: /usr/lib/libobjc.A.dylib
dyld: loaded: /usr/lib/libauto.dylib
dyld: loaded: /usr/lib/libDiagnosticMessagesClient.dylib
A
B
C
D发布于 2015-12-06 17:12:22
我最初的文章中的代码是用来处理约塞米蒂的。在埃尔卡皮坦,它不起作用。最后,我执行了以下方法(DYLD_INTERPOSE + DYLD_INSERT_LIBRARIES):
#define _GNU_SOURCE
#include <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
#define DYLD_INTERPOSE(_replacment,_replacee) \
__attribute__((used)) static struct{ const void* replacment; const void* replacee; } _interpose_##_replacee \
__attribute__ ((section ("__DATA,__interpose"))) = { (const void*)(unsigned long)&_replacment, (const void*)(unsigned long)&_replacee };
void* pMalloc(size_t size) //would be nice if I didn't have to rename my function..
{
printf("Allocated: %zu\n", size);
return malloc(size);
}
DYLD_INTERPOSE(pMalloc, malloc);发布于 2016-02-26 21:28:24
来自dyld文档:
DYLD_INSERT_LIBRARIES --这是一个用冒号分隔的动态库列表,在程序中指定的库之前加载。这允许您测试现有动态共享库的新模块,这些模块用于平面命名空间映像中,只需加载一个临时动态共享库即可。请注意,这对使用动态共享库构建的两级命名空间映像没有任何影响,除非还使用DYLD_FORCE_FLAT_NAMESPACE。 DYLD_FORCE_FLAT_NAMESPACE强制程序中的所有图像以平面命名空间映像的形式链接,而忽略任何两级命名空间绑定。如果使用两级命名空间映像来允许图像具有多定义符号,则这可能导致程序无法执行带有多个定义符号错误的程序。
因此,您的代码需要DYLD_FORCE_FLAT_NAMESPACE=1。无论如何,我的实施只在启用此选项的情况下才适用于/usr/local/bin/git。
发布于 2016-12-30 19:35:40
如果您可以重新编译挂起的可执行文件,那么我认为更简单的解决方案是使用-force_flat_namespace重新编译可执行文件。
➜ clang slow_leak.c -force_flat_namespace -o slow_leak
➜ DYLD_INSERT_LIBRARIES=malloc_hook.dylib ./slow_leak
leaking
in hooked malloc更多信息。这是在OSX 10.12.2 MacOS塞拉利昂。
对HN的评论 (2年后)提到,在不可能重新编译的情况下,DYLD_FORCE_FLAT_NAMESPACE=1可以提供帮助。我还没试过所以YMMV。
https://stackoverflow.com/questions/34114587
复制相似问题