本サイトでは、アフィリエイト広告およびGoogleアドセンスを利用しています。

Mach-O編 Import関数の列挙

前回の最後で dysymの undef extsymbolのほうがImport関数の情報として正しそうと感じていましたが、どうやらそれは間違っていたようです。正しくはIndirectテーブルから求めていくのが正解のようです。

このIndirectテーブルは struct dysymtab_command の indirectsymoff で示される場所に配置されています。
そしてこのテーブルのエントリ数は nindirectsyms となっています。

ではこのエントリ数分のnindirectsymsがインポート関数かと言われるとそうでもないようで、この中の一部分となっているようです。
セクション __la_symbol_ptr で示される reserved1メンバがこのIndirectテーブルでの開始点を示すことになっているようです。
そこで、エントリのreserved1から nindirectsymsまでの中身を確認してみます。

このエントリは uint32_t の配列となっているので取り出すと単なる整数です。
これはシンボルテーブルのエントリのインデックスとなっています。情報表示をするにはシンボルテーブルの情報にアクセスする必要があります。

これらの処理を以下のようにコードにしてみました。割と自明なところのコードは省きます。

void listupImportFunc() {
    mach_header_64* mh;
    symtab_command* symtab = (symtab_command*)getLoadCommand( mh, LC_SYMTAB );
    dysymtab_command* dysymtab = (dysymtab_command*)getLoadCommand(mh, LC_DYSYMTAB );
    nlist_64* nlist = (nlist_64*)( (uint8_t*)mh + symtab->symoff );
    uint32_t* indtab = (uint32_t*) ((uint8_t*)mh + dysymtab->indirectsymoff);
    uint32_t indoff = getIndirectTableOffset( mh );
    char* strtab = (char*)mh + symtab->stroff;
    
    printf( "Indirect Syms = %u\n", dysymtab->nindirectsyms );
    for( int i = indoff; i < dysymtab->nindirectsyms; ++i ) {
        uint32_t index = indtab[ i ];
        nlist_64* nl = &nlist[index];
        const char* name = strtab + nl->n_un.n_strx;
        printf( "  %u : %s\n", index, name );
    }
}

この実行結果の一部を公開するとこんな感じになります。

  256 : __ZNSt3__113basic_ostreamIcNS_11char_traitsIcEEE6sentryD1Ev
  257 : __ZNSt3__113basic_ostreamIcNS_11char_traitsIcEEElsEi
  258 : __ZNSt3__113basic_ostreamIcNS_11char_traitsIcEEElsEm
  261 : __ZNSt3__16localeD1Ev
  262 : __ZNSt3__18ios_base33__set_badbit_and_consider_rethrowEv
  263 : __ZNSt3__18ios_base5clearEj
  264 : __ZSt9terminatev
  265 : __ZdlPv
  266 : __Znwm
  268 : ___cxa_begin_catch
  269 : ___cxa_end_catch
  245 : __Unwind_Resume
  267 : ___cxa_atexit
  271 : ___stack_chk_fail
  273 : __dyld_get_image_header
  274 : __dyld_get_image_name
  275 : __dyld_get_image_vmaddr_slide
  276 : __dyld_image_count
  277 : _getpid
  278 : _mach_port_deallocate
  280 : _mach_vm_region
  281 : _printf
  282 : _strcmp
  283 : _strlen
  284 : _sysctl

それっぽいものが出力されるようになりました!

データ解析プログラミング
すらりんをフォローする
すらりん日記
タイトルとURLをコピーしました