根据PE文件格式获取LoadLibraryA()/GetProcAddress()地址

本文详细介绍了如何分析PE(Portable Executable)文件格式,以定位并获取LoadLibraryA和GetProcAddress这两个重要API函数的地址。通过理解PE文件结构,包括节区、导出表和导入表等,读者将能够实现从二进制文件中提取这些关键函数的指针,从而在没有源代码的情况下进行动态链接库的加载和函数调用。
摘要由CSDN通过智能技术生成

本节与PE文件格式相关的术语以<<微软PE/COFF规范>>为准([13]),不再强调该点。
winnt.h中定义了部分相关数据结构,后面如未单独注明来自哪个头文件,均隐指来
自winnt.h。执行vulnerable_0.exe,进入windbg调试状态。

> !list -t _LIST_ENTRY.Flink -x "dd" -a "+18 L1" 241ec0
00241ed8  00400000
00241f30  77f50000
00241fd8  77e60000
... ...

从上节可知,ntdll.dll基址是0x77f50000,kernel32.dll基址是0x77e60000。最开
始的64字节按如下数据结构解析:

--------------------------------------------------------------------------
#define IMAGE_DOS_SIGNATURE 0x5A4D      // MZ

typedef struct _IMAGE_DOS_HEADER        // DOS .EXE header
{
    WORD   e_magic;                     // +0x00 Magic number
    WORD   e_cblp;                      // +0x02 Bytes on last page of file
    WORD   e_cp;                        // +0x04 Pages in file
    WORD   e_crlc;                      // +0x06 Relocations
    WORD   e_cparhdr;                   // +0x08 Size of header in paragraphs
    WORD   e_minalloc;                  // +0x0a Minimum extra paragraphs needed
    WORD   e_maxalloc;                  // +0x0c Maximum extra paragraphs needed
    WORD   e_ss;                        // +0x0e Initial (relative) SS value
    WORD   e_sp;                        // +0x10 Initial SP value
    WORD   e_csum;                      // +0x12 Checksum
    WORD   e_ip;                        // +0x14 Initial IP value
    WORD   e_cs;                        // +0x16 Initial (relative) CS value
    WORD   e_lfarlc;                    // +0x18 File address of relocation table
    WORD   e_ovno;                      // +0x1a Overlay number
    WORD   e_res[4];                    // +0x1c Reserved words
    WORD   e_oemid;                     // +0x24 OEM identifier (for e_oeminfo)
    WORD   e_oeminfo;                   // +0x26 OEM information; e_oemid specific
    WORD   e_res2[10];                  // +0x28 Reserved words
    LONG   e_lfanew;                    // +0x3c File address of new exe header
                                        // +0x40
} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
--------------------------------------------------------------------------

> db 77e60000 L0n64
77e60000  4d 5a 90 00 03 00 00 00-04 00 00 00 ff ff 00 00  MZ..............
77e60010  b8 00 00 00 00 00 00 00-40 00 00 00 00 00 00 00  ........@.......
77e60020  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
77e60030  00 00 00 00 00 00 00 00-00 00 00 00 f8 00 00 00  ................
> dd 77e60000+3c L1 (显示e_lfanew成员)
77e6003c  000000f8

其中e_lfanew成员用于定位PE头。从注释中理解,e_lfanew是File pointer,非RVA,
不过在这里当成RVA处理也没关系。e_lfanew值为0x000000f8,PE头在基址加0xf8的
位置。PE头最开始是标识"PE\0\0",占4字节,然后是20字节固定头。

--------------------------------------------------------------------------
#define IMAGE_NT_SIGNATURE       0x00004550  // PE00
#define IMAGE_SIZEOF_FILE_HEADER 20

typedef struct _IMAGE_FILE_HEADER
{
    WORD    Machine;               // +0x00
    WORD    NumberOfSections;      // +0x02
    DWORD   TimeDateStamp;         // +0x04
    DWORD   PointerToSymbolTable;  // +0x08
    DWORD   NumberOfSymbols;       // +0x0c
    WORD    SizeOfOptionalHeader;  // +0x10
    WORD    Characteristics;       // +0x12
                                   // +0x14
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
--------------------------------------------------------------------------

> db 77e60000+f8 L0n24
77e600f8  50 45 00 00 4c 01 04 00-28 fa 6d 3d 00 00 00 00  PE..L...(.m=....
77e60108  00 00 00 00 e0 00 0e 21
                      ^^^^^
接下来是可选头,SizeOfOptionalHeader成员表明可选头占用了224字节(0x00e0)。

--------------------------------------------------------------------------
typedef struct _IMAGE_OPTIONAL_HEADER
{
    WORD    Magic;                        // +0x00
    BYTE    MajorLinkerVersion;           // +0x02
    BYTE    MinorLinkerVersion;           // +0x03
    DWORD   SizeOfCode;                   // +0x04
    DWORD   SizeOfInitializedData;        // +0x08
    DWORD   SizeOfUninitializedData;      // +0x0c
    DWORD   AddressOfEntryPoint;          // +0x10
    DWORD   BaseOfCode;                   // +0x14
    DWORD   BaseOfData;                   // +0x18
    DWORD   ImageBase;                    // +0x1c
    DWORD   SectionAlignment;             // +0x20
    DWORD   FileAlignment;                // +0x24
    WORD    MajorOperatingSystemVersion;  // +0x28
    WORD    MinorOperatingSystemVersion;  // +0x2a
    WORD    MajorImageVersion;            // +0x2c
    WORD    MinorImageVersion;            // +0x2e
    WORD    MajorSubsystemVersion;        // +0x30
    WORD    MinorSubsystemVersion;        // +0x32
    DWORD   Win32VersionValue;            // +0x34
    DWORD   SizeOfImage;                  // +0x38
    DWORD   SizeOfHeaders;                // +0x3c
    DWORD   CheckSum;                     // +0x40
    WORD    Subsystem;                    // +0x44
    WORD    DllCharacteristics;           // +0x46
    DWORD   SizeOfStackReserve;           // +0x48
    DWORD   SizeOfStackCommit;            // +0x4c
    DWORD   SizeOfHeapReserve;            // +0x50
    DWORD   SizeOfHeapCommit;             // +0x54
    DWORD   LoaderFlags;                  // +0x58
    DWORD   NumberOfRvaAndSizes;          // +0x5c Number of data-dictionary entries in the remainder of the Optional Header
                                          // +0x60
    IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
                                          // +0xe0
} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;

typedef struct _IMAGE_DATA_DIRECTORY
{
    DWORD   VirtualAddress;  // +0x00 RVA
    DWORD   Size;            // +0x04 The size in bytes
                             // +0x08
} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIREC

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值