とBinary Hacks#29を見ながら、高林さんをdisって見るテスト :-)

とゆーわけでテスト

以下のファイルを準備

foo.c
extern void bar(void);

void foo(void){
printf("foo\n");
bar();
}


bar.c
void bar(void){
printf("bar\n");
}


libfoo.map
{
global: foo;
local: *;
};


あ、このバージョンスクリプトはfoo関数以外はライブラリ外から
呼べなくするよん。って意味ね > Binary Hack読んでない人へ


んで以下のようにコンパイル

gcc -shared foo.c bar.c -o libfoo.so -Wl,--version-script,libfoo.map


んで objdump -d して、foo関数を見ると以下

0000000000000900 :
900: 00 08 15 08 80 05 [MII] alloc r33=ar.pfs,5,4,0
906: 20 02 30 00 42 60 mov r34=r12
90c: 04 08 00 84 mov r35=r1
910: 01 00 00 00 01 00 [MII] nop.m 0x0
916: 00 02 00 62 00 80 mov r32=b0
91c: 84 ca df 9f addl r36=-66648,r1;;
920: 1c 00 00 00 01 00 [MFB] nop.m 0x0
926: 00 00 00 02 00 00 nop.f 0x0
92c: e8 fd ff 58 br.call.sptk.many b0=700 <_init+0xa0>
930: 0a 08 00 46 00 21 [MMI] mov r1=r35;;
936: 00 00 00 02 00 00 nop.m 0x0
93c: 00 00 04 00 nop.i 0x0
940: 1c 00 00 00 01 00 [MFB] nop.m 0x0
946: 00 00 00 02 00 00 nop.f 0x0
94c: 48 00 00 50 br.call.sptk.many b0=980


1つ目のcall(printfの呼び出し)は.pltへのポインタをつっこんでいるが、
2つ目のcall(barの呼び出し)はlibfooのbar関数のポインタを直接つっこんでいる

ためしに、ここでbar関数を別のライブラリでフックしようとしてみる

hook.c
extern void bar(void);

void bar(void){
printf("hook bar\n");
}


main.c
extern void foo(void);

main(){
foo();
}


$ gcc -shared foo.c bar.c -o libfoo.so -Wl,--version-script,libfoo.map
$ gcc -shared hook.c -o libhook.so
$ gcc main.c -L. -lfoo
$ LD_PRELOAD=./libhook.so ./a.out
foo
bar


見事フックに失敗した。

IA64で確認しているので他のアーキでは違うかもしれないけど、まあ、ハマった記録ということで。


実は、とある事情でbrkをフックしたかったのだが、なぜか失敗したので、objdump -d libc.so したら、.plt経由せずにbrk呼び出してたので、
ぐわー、なんじゃこりゃーーーー
とアホアホモード全開で深追いしてしまったよ。

しかし、libcの動作のフックが簡単に出来ないのはすごく不便だ。
なんとかしてくれ・・・


追記 なんかさっそくBinary Hacksの正誤表ページが更新されてる。高林さんの仕事は早過ぎる!!



あちゃー
あちゃー! ランキング