PE勉強会#3参加メモ その3

このエントリの和訳です。http://d.hatena.ne.jp/takahirox/20110522/1306052298

はじめに

このエントリは前回からの続きです。 http://d.hatena.ne.jp/takahirox/20110503/1304412918

参考リンク

今回やったこと

勉強会で学んだthunkに関する知識を基にPE解析ツールを作りました。DLLの関数を表示します。

% ./analysis.exe ./hoge.exe
*IMAGE_DOS_HEADER
 e_magic    : 5A4D [MZ] <000000>
 e_cblp     : 0090      <000002>
 e_cp       : 0003      <000004>
 e_crlc     : 0000      <000006>

... snip ...

*IMAGE_IMPORT_DESCRIPTOR[0] <KERNEL32.dll>
 Characteristics    : 703C [283C] <002800>
 OriginalFirstThunk : 703C [283C] <002800>
 TimeDateStamp      : 0000        <002804>
 ForwarderChain     : 0000        <002808>
 Name               : 73DC [2BDC] <00280C>
 FirstThunk         : 70E0 [28E0] <002810>
   <functions>
    DeleteCriticalSection <002986>
    EnterCriticalSection <00299E>
    ExitProcess     <0029B6>
    FreeLibrary     <0029C4>
    GetLastError    <0029D2>
    GetModuleHandleA <0029E2>
    GetProcAddress  <0029F6>
    InitializeCriticalSection <002A08>
    LeaveCriticalSection <002A24>
    LoadLibraryA    <002A3C>
    SetUnhandledExceptionFilter <002A4C>
    TlsGetValue     <002A6A>
    VirtualProtect  <002A78>
    VirtualQuery    <002A8A>
*IMAGE_IMPORT_DESCRIPTOR[1] <msvcrt.dll>
 Characteristics    : 7078 [2878] <002814>
 OriginalFirstThunk : 7078 [2878] <002814>
 TimeDateStamp      : 0000        <002818>
 ForwarderChain     : 0000        <00281C>
 Name               : 7450 [2C50] <002820>
 FirstThunk         : 711C [291C] <002824>
   <functions>
    __getmainargs   <002A9A>
    __p__environ    <002AAA>
    __p__fmode      <002ABA>
    __set_app_type  <002AC8>
    _cexit          <002ADA>
    _iob            <002AE4>
    _onexit         <002AEC>
    _setmode        <002AF6>
    _winmajor       <002B02>
    abort           <002B0E>
    atexit          <002B16>
    calloc          <002B20>
    fclose          <002B2A>
    fopen           <002B34>
    fprintf         <002B3C>
    free            <002B46>
    fwrite          <002B4E>
    getc            <002B58>
    getenv          <002B60>
    memcpy          <002B6A>
    printf          <002B74>
    putchar         <002B7E>
    puts            <002B88>
    signal          <002B90>
    vfprintf        <002B9A>

thunk

thunkとはダイナミックリンクライブラリ(DLL)を扱うためのメカニズムです。勉強会では理解ができなかったので絵で描いてみました。

thunkが使われているのはDLLのファイル名や関数名、関数の数に制限をつけないためだと思います。

IMAGE_IMPORT_DESCRIPTOR.Nameはこんな感じです。PEファイルを16進数ダンプしたイメージだと思ってください。

IMAGE_IMPORT_DESCRIPTOR.OriginalFirstThunkとIMAGE_IMPORT_DESCRIPTOR.FirstThunkはこんな感じです. IMAGE_IMPORT_DESCRIPTOR.FirstThunkは実行時に上書きされます。動的にロードされたDLLのアドレスを指します。

識者によるとIMAGE_IMPORT_DESCRIPTOR.OriginalFirstThunkはDLLの読み込みに失敗したときに使われるとかなんとか……?

thunkについての詳しい情報は勉強会の配布資料を参考にしてください。

終わりに

どうにかこうにかthunkが理解できた気がします。難しかったのですが、ツールを作ったことが理解の助けになりました。