从 DLL 中提取信息
1. 概述
动态链接库 或 DLL 文件是 Windows 上使用的包含函数和数据的共享库。与 Windows 上的其他可执行文件一样,DLL 文件是可移植可执行文件 (PE) 文件格式。PE文件的文件头中有多种数据,包括导入表和导出表。
导入表是 PE 文件从其他共享库中包含的一组函数和数据。导出表是包含在 PE 文件中希望提供给外界的一组函数和数据。这些与 PE 文件在内部使用的内部函数不同。
需要 DLL 文件的导出数据的原因有很多。其中之一是我们可以编写一个利用 DLL 程序中的函数的程序。在 Linux 上,我们可以使用几种不同的工具来提取 DLL 文件的导出表。
在本教程中,我们将讨论如何使用这些工具提取导出的符号,这些工具包括几个不同的命令行工具和一个 Python 模块。
2. wine
Wine 是一种兼容性工具,旨在在符合 POSIX 的系统(如 Linux)上运行 Windows 程序。它还附带一组支持工具来处理 PE 文件。
用于与 DLL PE 文件交互的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工具支持的格式之一。
我们先安装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 *是一个 Python 模块,我们可以使用它来处理 PE 文件。
让我们使用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
[...]
此外,我们可以使用一个 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
[...]
最后,我们应该注意的一件事是,我们确实需要在 Linux 系统上使用 Python 才能使用pefile模块。