EAGLE 雑記 このページをアンテナに追加 RSSフィード

Sat July 26, 2008

[][] LD_PRELOAD を Mac

昨日、大学の図書館で偶然 BINARY HACKS という以前から読んでみたかった本を見つけた。

Binary Hacks ―ハッカー秘伝のテクニック100選

Binary Hacks ―ハッカー秘伝のテクニック100選

ただ、残念なことに GNU/Linux での話が前提になってしまっていて、Mac OS X などの他のプラットホームでの話がほとんどなかった。

Valgrind とか strace, ltrace とかも Mac OS X で使いたいなー。


で、HACK #60 に「LD_PRELOAD で共有ライブラリを差し換える」というのがあったんだけど、これと同様なことを Mac OS X でやる方法がわかったから、ここに書いておく。

gethostname(3) を差し換えて、hostname(1) の挙動を変えようというストーリー。

差し換える gethostname のコードは原本のまんまで。

/* gethostname.c */
#include <stdlib.h>
#include <string.h>

int gethostname(char *name, size_t len)
{
  char *p = getenv("FAKE_HOSTNAME");
  if (p == NULL)
    p = "localhost";
  strncpy(name, p, len-1);
  name[len-1] = '\0';
  return 0;
}

何はともあれ、共有ライブラリとしてコンパイル

$ gcc -shared -fPIC -o gethostname.dylib gethostname.c

GNU/Linux の場合、

$ LD_PRELOAD=./gethostname.dylib FAKE_HOSTNAME=foo hostname
foo

となるらしいのだけど、Mac の場合は

$ DYLD_INSERT_LIBRARIES=gethostname.dylib DYLD_FORCE_FLAT_NAMESPACE=YES FAKE_HOSTNAME=bar hostname
bar

とする。

DYLD_INSERT_LIBRARIES が LD_PRELOAD にあたると考えていいと思う。

その次の DYLD_FORCE_FLAT_NAMESPACE ってのは、どうやら Mac ではデフォルトで two-level namespace という環境でビルドされているがために必要な環境変数らしい。

Page Not Found - Apple Developer を読んでみたけど、一体 two-level namespace がどういうものかは分からなかった。

とにかく、two-level namespace だと DYLD_INSERT_LIBRARIES で指定したにもかかわらず、オリジナルの gethostname を呼んでしまうらしい。

そこで、シンボルの解決方法を強制的に flat namespace にするのが DYLD_FORCE_FLAT_NAMESPACE=YES というわけだ。

うぅむ、GNU/Linux の場合と違ってなかなかめんどくさいな。タイプ数的に。

もう一つの差し換える方法

あまり実践的な方法じゃないけど。

それは、プログラムコンパイルするときに、リンカに -flat_namespace という引数を与えてやるという方法。

/* myhostname.c */
#include <stdio.h>
#include <unistd.h>

int main(int argc, char *argv[])
{
  char name[128];
  gethostname(name, sizeof(name));
  puts(name);
  return 0;
}

こんな、hostname(1) もどきのプログラムを書いてみる。

そして、

$ cc -Wl,-flat_namespace -o myhostname myhostname.c
$ DYLD_INSERT_LIBRARIES=gethostname.dylib FAKE_HOSTNAME=baz ./myhostname
baz

こうやってコンパイル&リンクすることで、DYLD_FORCE_FLAT_NAMESPACE=YES といちいち指定する必要がなくなる。

そのバイナリが flat_namespace かどうか判定する方法はあるのかなぁ?otool で見れたりするんだろうか。


参考:

dyld(1) Mac OS X Manual Page

ld(1) Mac OS X Developer Tools Manual Page

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

トラックバック - http://d.hatena.ne.jp/eagletmt/20080726/1217085814
リンク元