2015-12-06 12 views
5

を働いていない:DYLD_LIBRARY_PATH&DYLD_INSERT_LIBRARIESは、私はは.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

それはそれをロードしますが、それは全く機能をフックしません。..任意のアイデア:

次は、私は次のように走りましたか?私はエル・キャピタンのアップグレードの前にこのコードを試していましたが、以前はそれを使用していました。また、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 

答えて

11

ヨセミテ上で動作するために使用私のオリジナルのポスト内のコード。エルキャピタンでは、それは動作しません。 dyldドキュメントから

#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); 
+2

お返事ありがとうございます。 –

+1

この回答はhttp://stackoverflow.com/a/20717262/1027966から来たようです。 –

+3

閉じるが、そこから来ていない。私は「OSX上の関数をフックする」方法を探していて、LD_PRELOADとDYLD_INSERT_LIBRARIESに出くわしました。どちらもうまくいきませんでしたので、OSXでコードインジェクションを行う方法を調べ、DYLD_INTERPOSEのGoogleフォーラムに投稿しました。面白いことに、両方のアイデアを組み合わせるまではうまくいかなかった。 – Brandon

1

:私は、次のようなアプローチを(DYLD_INTERPOSE + DYLD_INSERT_LIBRARIES)やってしまった

DYLD_INSERT_LIBRARIESこれは、プログラムで指定されたものの前にロードする動的ライブラリのコロン区切りのリストです。これにより、新しいモジュールだけで一時的な動的共有ライブラリをロードすることで、フラットな名前空間イメージで使用される既存の 動的共有ライブラリの新しいモジュールをテストできます。 これは、DYLD_FORCE_FLAT_NAMESPACEも使用されていない限り、動的共有ライブラリを使用して2レベルの名前空間イメージを構築したイメージには何の影響も与えないことに注意してください。

DYLD_FORCE_FLAT_NAMESPACE プログラム内のすべてのイメージをフラットな名前空間イメージとしてリンクし、2レベルの名前空間バインディングを無視します。これにより、2レベルの名前空間イメージを使用してイメージに複数のシンボルが定義されている場合、複数のシンボルが定義されたエラーでプログラムが失敗して が実行されることがあります。

コードにDYLD_FORCE_FLAT_NAMESPACE = 1が必要です。とにかく、/usr/local/bin/gitの場合はmy implementationが有効です。このオプションが有効な場合のみです。

+0

あなた自身のプログラムでテストすることを除いて。Safariや、/ System/Libraryの関数を使用し、関数のいずれかを置き換えるプログラムでこれを試してください。保証されても動作しません。 http://apple.stackexchange.com/questions/193368/what-is-the-rootless-feature-in-el-capitan-really – Brandon

+0

これを試みるとき、私はバットからセグメンテーションを得る。 –

1

あなたが夢中にされている実行可能ファイルを再コンパイルすることができるなら、私は簡単な解決策は-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 

More info。これはOSX 10.12.2 MacOS Sierraにあります。

関連する問題