CEO of Backflip180, LLC.
Mac OSを触るようになって初めて知ったのですが、Mac OSのバイナリ形式は他のUnixと異なり、ELFではなく、Mach-Oと呼ばれるファイル形式です。 そのため、LD_PRELOADは使えず、代わりにDYLD_INSERT_LIBRARIESを使う必要があります。
まずは以下のように今回使用するサンプルコードを書きます。
#include <stdio.h>
int main()
{
char * s = "aaa\n";
printf(s);
return 0;
}
コンパイル、実行して動作することを確認します。
$ gcc main.c
$ ./a.out
aaa
"aaa"が表示されていることが確認されます。
ここでは先程のコードのprintf関数をフックし、"aaa"を"bbb"に置き換えるコードを作成します。
#include <dlfcn.h>
#include <stdio.h>
int printf(const char * _restrict, ...)
{
typedef int (*ftype)(const char *, ...);
return ((ftype)dlsym(RTLD_NEXT, "printf"))("bbb\n");
}
コンパイルし、dylibファイルを作成します。
$ gcc -ldl -dynamiclib printf.c -o printf.dylib
先程作成したdylibファイルを読み込ませて関数をフックしたいのですが、上述のとおりLD_PRELOADは使えません。 代わりにDYLD_INSERT_LIBRARIESが使えます。 しかし、ここで注意が必要なのが、同時にDYLD_FORCE_FLAT_NAMESPACE=YESを設定する必要がある、ということです。
$ DYLD_INSERT_LIBRARIES=printf.dylib DYLD_FORCE_FLAT_NAMESPACE=YES ./a.out
bbb
"bbb"と表示されることが確認されました。 この手法を応用すればMac OSでHappy Hackingライフを送れるでしょう。