2012-01-11 8 views
7

私はMach-oファイルの仕組みを理解しようとしており、利用可能なオンラインリソース(特にAppleページはhttp://developer.apple.com/library/mac/#documentation/developertools/conceptual/MachORuntime/Reference/reference.html)でかなり進歩しましたが、シンボルスタブがどのように機能するかを理解する上での障害となっています。Mach-Oシンボルスタブ(IOS)

を:私はバイナリエディタでバイナリファイルからのデータを見るとしかし、私は、次の4つのバイトは、何度も何度も繰り返し見

Section 
    sectname __symbolstub1 
    segname __TEXT 
     addr 0x00005fc0 
     size 0x00000040 
    offset 20416 
    align 2^2 (4) 
    reloff 0 
    nreloc 0 
    flags 0x80000408 

:私は次のセクションを参照してください「-lコマンドotool」使用

00005FC0 38 F0 9F E5 38 F0 9F E5 38 F0 9F E5 38 F0 9F E5 88 
00005FD0 38 F0 9F E5 38 F0 9F E5 38 F0 9F E5 38 F0 9F E5 88 
00005FE0 38 F0 9F E5 38 F0 9F E5 38 F0 9F E5 38 F0 9F E5 88 
00005FF0 38 F0 9F E5 38 F0 9F E5 38 F0 9F E5 38 F0 9F E5 88 

これは一定量のPCを増加させるLDRのように見えますが、シンボルテーブル内の各エントリの量が同じ理由はわかりません。

誰かがこれがなぜそうであるかを明らかにしたり、この低レベルを取得するリソースを提供してもらえる場合は、私に知らせてください。

ありがとうございます!

+0

私は、テーブルの4バイトのエントリのそれぞれが、関数呼び出しの場所を格納するDCD命令を持つデータ領域を指していることを理解したと思います。しかし、私はまだこの余分なレベルのインダイレクションが必要な理由を少し混乱させています。だから誰でもフォローインフォメーションを提供できれば分かります。 – Locksleyu

答えて

12

現在のiOSの状況を説明しますが、古いバージョンでは多少異なります。

シンボルスタブは実際にPCに関数ポインタをロードします。標準(オンデマンド)「怠惰」の輸入については、ポインタが__lazy_symbolセクションに置かれ、初期__stub_helperセクションのヘルパールーチンを指し、例えば:

__symbolstub1 _AudioServicesAddSystemSoundCompletion 
__symbolstub1 LDR PC, _AudioServicesAddSystemSoundCompletion$lazy_ptr 
__symbolstub1 ; End of function _AudioServicesAddSystemSoundCompletion 

__lazy_symbol _AudioServicesAddSystemSoundCompletion$lazy_ptr DCD _AudioServicesAddSystemSoundCompletion$stubHelper 

__stub_helper _AudioServicesAddSystemSoundCompletion$stubHelper 
__stub_helper LDR R12, =nnn ; symbol info offset in the lazy bind table 
__stub_helper B dyld_stub_binding_helper 

機能dyld_stub_binding_helperがで拳一つであり__stub_helperセクションであり、本質的にdyldのdyld_stub_binder関数のトランポリンに過ぎず、 "symbol info offset"という値を渡します。その値は、lyyバインディング情報ストリーム内のオフセット(LC_DYLD_INFOまたはLC_DYLD_INFO_ONLYロードコマンドによって指される)であり、これはdyldのコマンドを含む一種のバイトコードストリームです。

72: BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB(M, 0xYYYYY) 
19: BIND_OPCODE_SET_DYLIB_ORDINAL_IMM(NNNN) 
40: BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM(0x00, '_AudioServicesAddSystemSoundCompletion') 
90: BIND_OPCODE_DO_BIND() 

ここdyldのは、次の操作を行います:怠惰な輸入のための典型的なシーケンスは次のようになります

  1. は、に記載されているdylibsのリストでdylib番号NNNN から「_AudioServicesAddSystemSoundCompletion」という名前の関数を調べますロード コマンド。
  2. 実行可能ファイルのセグメント番号M(おそらく__DATA)を調べます。
  3. オフセットYYYYYに関数ポインタを書き込みます。ように見上げたアドレスへ
  4. ジャンプは実際の関数は、その仕事_AudioServicesAddSystemSoundCompletion$lazy_ptrスロットであることを起こるに書かれ

アドレスを行います。したがって、次に_AudioServicesAddSystemSoundCompletionが呼び出されると、dyldを経由することなく、インポートされた関数に直接ジャンプします。

N.B.:すぐにファイルのオフセット05fc0を見るべきではありません。 addrフィールドが仮想アドレスであるため、含まれているセグメントコマンドをルックアップし、VAの開始位置とファイルオフセットを確認してから計算します。通常、__TEXTセグメントは1000から始まります。

しかし、実際のシンボルスタブは貼り付けられたように見えますが、ファットマッハのfatヘッダが最初の1000バイトを取っているので、オフセットが並んでいます。

+0

+1。ゆっくりと拍手を立て、立位を立てる。素晴らしい答え。私はそれから多くを学んだ! – mattjgalloway

+0

すごい、驚くべき答え!私は完全に理解する前にそれを数回読む必要がありますが、イゴールは私に1つ教えてください。あなたはどこでこの知識を得ましたか?関連するすべてのASMを読むか、これはどこにでも完全に文書化されていますか?ありがとう! – Locksleyu

+0

バイナリからのものです。しかし理論的には、ソースコードからも分かります.dyld、ld64、およびCsuについては[Appleのソース](http://opensource.apple.com/source/)を参照してください。 –

関連する問題