1. 概要

ダイナミックリンクライブラリまたはDLLファイルは、Windowsで使用される共有ライブラリであり、関数とデータが含まれています。 Windowsの他の実行可能ファイルと同様に、DLLファイルは Portable Executable (PE)ファイル形式です。 PEファイルのファイルヘッダーには、インポートテーブルやエクスポートテーブルなどのさまざまなデータがあります。

インポートテーブルは、PEファイルに他の共有ライブラリから含まれる関数とデータの配列です。 エクスポートテーブルは、PEファイル内に含まれる関数とデータの配列であり、外部に提供したいと考えています。 これらは、PEファイルが内部で使用する内部関数とは異なります。

DLLファイルのエクスポートデータが必要な理由はたくさんあります。 その1つは、DLLプログラムの関数を利用したプログラムを作成できるようにするためです。 Linuxでは、いくつかの異なるツールを使用して、DLLファイルのエクスポートテーブルを抽出できます。

このチュートリアルでは、これらのツールを使用してエクスポートされたシンボルを抽出する方法について説明します。これらのツールは、いくつかの異なるコマンドラインツールとPythonモジュールで構成されています。

2. ワイン

Wine は、LinuxなどのPOSIX準拠のシステムでWindowsプログラムを実行することを目的とした互換性ツールです。 また、PEファイルを操作するための一連のサポートツールも付属しています。

DLLPEファイルと対話するためのwinedumpツール。 winedump コマンドを使用して、PEファイルに関する情報を表示できます。

PEファイルは、エクスポートされたシンボルをエクスポートアドレステーブルに格納します。 次に、PEファイルはそのエクスポートアドレステーブルをPEファイルの「エクスポート」セクションに保存します。

winedumpをインストールしましょう:

sudo apt-get install wine64-tools

-j オプションを使用して、エクスポートされたシンボルをエクスポートセクションに表示します。

$ winedump -j export kernel32.dll
Contents of kernel32.dll: 725696 bytes

Exports table:

  Name:            KERNEL32.dll
  [...]
  Entry Pt  Ordn  Name
  0009417F     1 AcquireSRWLockExclusive (-> NTDLL.RtlAcquireSRWLockExclusive)
  000941B5     2 AcquireSRWLockShared (-> NTDLL.RtlAcquireSRWLockShared)
  0001E860     3 ActivateActCtx
  0001A570     4 ActivateActCtxWorker
  00021A70     5 AddAtomA
  0000FE30     6 AddAtomW
  00022DE0     7 AddConsoleAliasA
  00022DF0     8 AddConsoleAliasW
  0009423B     9 AddDllDirectory (-> api-ms-win-core-libraryloader-l1-1-0.AddDllDirectory)
  000375A0    10 AddIntegrityLabelToBoundaryDescriptor
  00053150    11 AddLocalAlternateComputerNameA
  000531B0    12 AddLocalAlternateComputerNameW
  00020570    13 AddRefActCtx
  0001E3C0    14 AddRefActCtxWorker
  00035FB0    15 AddResourceAttributeAce
  0001F3C0    16 AddSIDToBoundaryDescriptor
  00035FC0    17 AddScopedPolicyIDAce
  00034600    18 AddSecureMemoryCacheCallback
  00094374    19 AddVectoredContinueHandler (-> NTDLL.RtlAddVectoredContinueHandler)
  000943B4    20 AddVectoredExceptionHandler (-> NTDLL.RtlAddVectoredExceptionHandler)
  0001A6B0    21 AdjustCalendarDate
  00022A30    22 AllocConsole
  [...]
  00019E40  1614 lstrlen
  00019E40  1615 lstrlenA
  00017930  1616 lstrlenW
  0001D240  1617 timeBeginPeriod
  0001C2F0  1618 timeEndPeriod
  00020470  1619 timeGetDevCaps
  00061590  1620 timeGetSystemTime
  0001CFE0  1621 timeGetTime
  0001A510  1622 uaw_lstrcmpW
  00017950  1623 uaw_lstrcmpiW
  00033380  1624 uaw_lstrlenW
  000333D0  1625 uaw_wcschr
  000333F0  1626 uaw_wcscpy
  00033420  1627 uaw_wcsicmp
  00033430  1628 uaw_wcslen
  00033450  1629 uaw_wcsrchr

Done dumping kernel32.dll

3. Radare2

Radare2 は、UNIXライクなリバースエンジニアリングフレームワークです。 Radare2フレームワークには、バイナリを操作するための一連のコマンドラインツールも付属しています。 LinuxとWindowsの両方でRadare2を使用でき、PEファイル形式をサポートしています。

したがって、 rabin2 ツールを使用して、選択したバイナリからプログラム情報を抽出できます。

最初にradare2とrabin2をインストールしましょう。

$ sudo apt-get install radare2

-s オプションを使用して、コマンドラインにPEファイルのエクスポートされたシンボルを表示します。

$ rabin2 -s kernel32.dll
[Symbols]
000 0x0009277f 0x18009417f GLOBAL   FUNC    0 KERNEL32.dll_AcquireSRWLockExclusive
001 0x000927b5 0x1800941b5 GLOBAL   FUNC    0 KERNEL32.dll_AcquireSRWLockShared
002 0x0001dc60 0x18001e860 GLOBAL   FUNC    0 KERNEL32.dll_ActivateActCtx
003 0x00019970 0x18001a570 GLOBAL   FUNC    0 KERNEL32.dll_ActivateActCtxWorker
004 0x00020e70 0x180021a70 GLOBAL   FUNC    0 KERNEL32.dll_AddAtomA
005 0x0000f230 0x18000fe30 GLOBAL   FUNC    0 KERNEL32.dll_AddAtomW
[...]

また、 rabin2 からエクスポートされたシンボルは、winedumpの出力とは少し異なって表示されることに注意する必要があります。

4. objdump

objdump は、バイナリファイルに関する情報をダンプするために使用できるツールです。 PEファイル形式は、objdumpツールでサポートされている形式の1つです。

最初にobjdumpをインストールしましょう。

$ sudo apt-get install binutils

これで、 objdump を使用して、PEファイルのエクスポートアドレステーブルをダンプできます。

$ objdump -p kernel32.dll

kernel32.dll:     file format pei-x86-64
[...]
The Data Directory
Entry 0 0000000000090190 0000dd40 Export Directory [.edata (or where ever we found it)]

[Ordinal/Name Pointer] Table
        [   0] AcquireSRWLockExclusive
        [   1] AcquireSRWLockShared
        [   2] ActivateActCtx
        [   3] ActivateActCtxWorker
        [   4] AddAtomA
        [   5] AddAtomW
[...]

これにobjdumpを使用することの欠点は、エクスポートテーブルがPEに関する他の情報と一緒に表示されることです。 したがって、さらに処理したい場合は、エクスポートされたシンボルに関連する行を解析する必要があります。

また、出力として数千行のデータがある可能性があることにも注意する必要があります。そのため、 grep を実行し、それに応じて解析する必要があります。

5. pefile

最後に、 pefile は、PEファイルの操作に使用できるPythonモジュールです。

pip:を使用してpefileモジュールをインストールしましょう

$ pip3 install pefile

「exports」フラグを使用して、DLLファイルのエクスポートをダンプできます。

$ python3 -m pefile exports kernel32.dll
0x18009417f b'AcquireSRWLockExclusive' 1
0x1800941b5 b'AcquireSRWLockShared' 2
0x18001e860 b'ActivateActCtx' 3
0x18001a570 b'ActivateActCtxWorker' 4
0x180021a70 b'AddAtomA' 5
[...]

さらに、1つのPythonライナーを使用して、シンボル名の先頭から「b」を削除できます。

$ python3 -c 'import sys;import pefile;pe = pefile.PE(sys.argv[1]);wr = sys.stdout.write; [wr("%s %s %i\n"%(hex(pe.OPTIONAL_HEADER.ImageBase + exp.address), exp.name.decode("utf-8"), exp.ordinal)) for exp in pe.DIRECTORY_ENTRY_EXPORT.symbols]' kernel32.dll
0x18009417f AcquireSRWLockExclusive 1
0x1800941b5 AcquireSRWLockShared 2
0x18001e860 ActivateActCtx 3
0x18001a570 ActivateActCtxWorker 4
0x180021a70 AddAtomA 5
[...]

最後に、 pefile モジュールを使用するには、LinuxシステムにPythonが必要であることに注意する必要があります。

6. 結論

この記事では、wineツールの一部である winedump コマンドラインツールを使用して、DLLのエクスポートされたシンボルを表示する方法について説明しました。

次に、Radare2リバースエンジニアリングツールセットのrabin2ツールの使用を検討しました。 この後、objdumpツールを使用してPEファイルに関する情報を表示する方法について説明しました。

最後に、 pefilePythonモジュールを使用してDLLから情報を抽出する方法について説明しました。 これらのオプションのいずれかを使用して、DLLファイルがLinuxでエクスポートするシンボルを見つけることができます。