12月
13
2008
0

DarwinはデフォルトでPosition Independentらしい

まだまだMac初心者やなぁと思わされたコト

今までLeopardの共有ライブラリをビルドするには,

$ cc -c -fPIC -fno-common -Wall -o hoge.o hoge.c
$ cc -dynamiclib -o hoge.dylib hoge.o

とかやって,-fPICを指定してコンパイルしていたのですが,なんとDarwinは標準でPosition Independentでしたw

 

そもそも気づいたきっかけは,Libtool

そろそろ更新も安定してきたのでAutotools対応にしようとしたところ・・・Libtoolの吐くコードに-fPICがない・・・?

Libtoolを使うと,.loファイルにPICと非PICオブジェクトの場所が書いてあります
場所をチェックして,両方のMD5チェックサムを調べたところ・・・なんと同じ!?

不思議なので逆アセンブルしてみたところ,たしかにPICっポイ
でも,オプション指定してないのになんで???

っと思ってたらFinkのサイトにこんな記述が・・・

位置独立コード (PIC: Position Independent Code) の生成は Darwin ではデフォルトです.実際, PowerPC コードは設計上 position-independent となり,パフォーマンスや空間上の損失はありません.このため,共有ライブラリやモジュールへコードをコンパイルする際も,PIC を指定する必要はありません.

ABIによってPICと非PICの区別がないシステムもあるけど,Darwinもそうなのか?
それとも,デフォルトがPICなだけで区別はあるのか?
デフォルトでPICということは,実行可能コードはPIE?

ということで,おなじみHello, Worldで試したみた

使ったコードは以下の通り

#include <stdio.h>
int main(int argc, const char* argv[])
{
        printf("hoge\n");
        return 0;
}

いろいろビルドオプションを変えてみた

$ cc -Wall -o hoge hoge.c
$ md5 hoge
MD5 (hoge) = e440d2da97997f3d6242426c7af2697d

$ cc -Wall -fPIE -o hoge hoge.c
$ md5 hoge
MD5 (hoge) = e440d2da97997f3d6242426c7af2697d

$ cc -Wall -fno-pie -o hoge hoge.c
$ md5 hoge
MD5 (hoge) = e440d2da97997f3d6242426c7af2697d

$ cc -Wall -fno-pic -o hoge hoge.c
$ md5 hoge
MD5 (hoge) = 3a8543d19ef046c85ada6bc71c144ef2

どうやら非PICなコードも吐ける模様なので,両方とも逆アセンブルして比較してみる

まず,PICなコードのtextセクション後半
1fd91fde(=次の命令)にジャンプするcall命令は一見無意味そうだが,次の1fdeでスタックからeipの値を取得するためにある
1fdf1fe5スタックの先頭0x1a+ebx(=0x1fde) = 0x1ffd(=main関数の終端アドレス)が入る
その結果,次の1fe8call命令は,0x1ffdをリターンアドレスとしてスタックにプッシュしてprintfを呼び戻ってくるのでPIC

    ・・・
    1fd9:    e8 00 00 00 00     call  1fde <LC_SEGMENT.__TEXT+0xfde>
    1fde:    5b                 pop  %ebx
    1fdf:    8d 83 1a 00 00 00  lea  0x1a(%ebx),%eax
    1fe5:    89 04 24           mov  %eax,(%esp)
    1fe8:    e8 18 10 00 00     call  3005 <dyld__mach_header+0xff5>
    1fed:    b8 00 00 00 00     mov  $0x0,%eax
    1ff2:    83 c4 14           add  $0x14,%esp
    1ff5:    5b                 pop  %ebx
    1ff6:    c9                 leave
    1ff7:    c3                 ret
    1ff8:    68 6f 67 65 00     push  $0x65676f
    1ffd:    00 00              add  %al,(%eax)

次は,非PICなコードのtextセクション後半
こちらは,1fe8でスタックの先頭に,main関数の終端アドレスである1ffbを直接指定しているのでPICではない

    ・・・
    1fd4:    e8 00 00 00 00         call  1fd9 <LC_SEGMENT.__TEXT+0xfd9>
    1fd9:    58                     pop  %eax
    1fda:    8b 80 3f 00 00 00      mov  0x3f(%eax),%eax
    1fe0:    ff e0                  jmp  *%eax
    1fe2:    55                     push  %ebp
    1fe3:    89 e5                  mov  %esp,%ebp
    1fe5:    83 ec 18               sub  $0x18,%esp
    1fe8:    c7 04 24 fb 1f 00 00 	movl  $0x1ffb,(%esp)
    1fef:    e8 11 10 00 00         call 3005 <dyld__mach_header+0xff5>
    1ff4:    b8 00 00 00 00         mov  $0x0,%eax
    1ff9:    c9                     leave
    1ffa:    c3                     ret
    1ffb:    68 6f 67 65 00         push  $0x65676f

ということで,DarwinではやっぱりPICでないコードも吐けるが,標準はPICなコードを吐くようになっている

セキュリティ的にもPIEは大歓迎!!
Macやるなぁ・・・

Written by h2 in: PC | タグ: ,

TheBuckmaker WordPress Themes Webhosting, MP3, AAC & Co