php 解析pe版本号,PE 文件解析2-获取PE头、区段、数据目录

本帖最后由 appsion 于 2020-10-31 12:33 编辑

PE 文件解析2 -获取PE头、区段、数据目录新手学习PE文件解析记录,  持续更新. 部分参考来源于网络, 无法逐一标注, 如果侵权,请及时联系. 如有错误请指正,误喷.

上文链接:https://www.52pojie.cn/thread-1294150-1-1.html

55fd2b2273b5a8b4531f72773c469d6e.gif

2.png (61.5 KB, 下载次数: 0)

2020-10-31 10:32 上传

概念:

TLS:

Thread Local Storage,   线程本地存储,用来保存变量或回调函数.

IAT:

Import Address Table, 导入地址表, 由于导入函数就是被程序调用但其执行代码又不在程序中的函数,这些函数的代码位于一个或者多个DLL 中.当PE 文件被装入内存的时候,Windows 装载器才将DLL 装入,并将调用导入函数的指令和函数实际所处的地址联系起来(动态连接),这操作就需要导入表完成.其中导入地址表就指示函数实际地址.

结构体: IMAGE_DATA_DIRECTORY

说明: 数据目录

头文件: winnt.h

参考文档: https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-image_data_directory

[Asm] 纯文本查看 复制代码typedef struct _IMAGE_DATA_DIRECTORY

{

DWORD VirtualAddress;

DWORD Size;

} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;

参数说明: 仅供参考, 详细说明请参考原文.

VirtualAddress:

数据目录相对虚拟地址(RVA)

Size:

表的大小

VirtualAddress成员如下:

Offset (PE/PE32+)Description

96/112Export table address and size

104/120Import table address and size

112/128Resource table address and size

120/136Exception table address and size

128/144Certificate table address and size

136/152Base relocation table address and size

144/160Debugging information starting address and size

152/168Architecture-specific data address and size

160/176Global pointer register relative virtual address

168/184Thread local storage (TLS) table address and size

176/192Load configuration table address and size

184/200Bound import table address and size

192/208Import address table address and size

200/216Delay import descriptor address and size

208/224The CLR header address and size

216/232Reserved

2.1 获取PE头信息

IMAGE_FILE_HEADER.Machine                                                                 // 处理器类型

IMAGE_OPTIONAL_HEADER.MajorLinkerVersion                                     // 链接器版本号

IMAGE_OPTIONAL_HEADER.MinorLinkerVersion

IMAGE_OPTIONAL_HEADER.MajorOperatingSystemVersion                  // 系统版本号

IMAGE_OPTIONAL_HEADER.MinorOperatingSystemVersion

IMAGE_OPTIONAL_HEADER.Subsystem                                                 // 子系统名称

IMAGE_OPTIONAL_HEADER.MajorSubsystemVersion                           // 子系统版本号

IMAGE_OPTIONAL_HEADER.MinorSubsystemVersion

IMAGE_FILE_HEADER.TimeDateStamp                                                  // 映像时间

IMAGE_FILE_HEADER.Characteristics                                                    // 映像特征

IMAGE_OPTIONAL_HEADER.Magic                                                      // 映像类型

IMAGE_OPTIONAL_HEADER.MajorImageVersion                                // 映像版本号

IMAGE_OPTIONAL_HEADERMinorImageVersion

IMAGE_OPTIONAL_HEADER.ImageBase                                              // 映像基址

IMAGE_OPTIONAL_HEADER.BaseOfCode                                           // 代码基址

IMAGE_OPTIONAL_HEADER.BaseOfData                                            // 数据基址

IMAGE_OPTIONAL_HEADER.AddressOfEntryPoint                             // 入口点相对地址

ImageBase + AddressOfEntryPoint                                                    // 入口点实际地址

IMAGE_OPTIONAL_HEADER.SizeOfImage                                         // 映像内存大小

IMAGE_OPTIONAL_HEADER.CheckSum                                            // 映像校验合

IMAGE_OPTIONAL_HEADER.DllCharacteristics                                 // 映像的DLL特性

IMAGE_OPTIONAL_HEADER.SizeOfHeaders                                    // 文件头大小

IMAGE_FILE_HEADER.NumberOfSections                                       // 节表数量

IMAGE_OPTIONAL_HEADER.SectionAlignment                              // 节表内存对齐

IMAGE_OPTIONAL_HEADER.FileAlignment                                    // 文件对齐

IMAGE_FILE_HEADER.PointerToSymbolTable                                // 符号表偏移地址

IMAGE_FILE_HEADER.NumberOfSymbols                                     // 符号表数量

IMAGE_OPTIONAL_HEADER.SectionAlignment                            // 节表(区段)对齐

IMAGE_OPTIONAL_HEADER.FileAlignment                                  // 文件对齐

IMAGE_OPTIONAL_HEADER.DataDirectory                                 // 数据目录

IMAGE_NT_HEADERS.OptionalHeader.NumberOfRvaAndSizes             // 数据目录数量

IMAGE_OPTIONAL_HEADER.DataDirectory                                // 数据目录表

2.2 获取区段信息

[Asm] 纯文本查看 复制代码// 节表数量

IMAGE_FILE_HEADER.NumberOfSections

// 节表头

IMAGE_SECTION_HEADER *SectionHead = (IMAGE_SECTION_HEADER *)(DataBuff + DosHead->e_lfanew + sizeof(IMAGE_NT_HEADERS));

for (size_t i = 0; i < IMAGE_FILE_HEADER.NumberOfSections; i++)

{

IMAGE_SECTION_HEADER Section = SectionHead[i];

// 节表名称

// Section.Name

// 节表的RVA

// Section.VirtualAddress

// 节表的虚拟大小

// Section.Misc.VirtualSize

// 节表的Raw

// Section.PointerToRawData

// 节表的Raw的数据大小

// Section.SizeOfRawData

// 特征

// Section.Characteristics

}

2.3 获取数据目录

// NT头

IMAGE_NT_HEADERS * NTHead = GetNTHead(DataBuff);

// 数据目录数量

DataDirectoryCount = NTHead->OptionalHeader.NumberOfRvaAndSizes;

// 数据目录头

IMAGE_DATA_DIRECTORY *DirectoryHead = NTHead->OptionalHeader.DataDirectory;

// 数据目录说明

IMAGE_DIRECTORY_ENTRY_EXPORT0导出表

IMAGE_DIRECTORY_ENTRY_IMPORT1导入表

IMAGE_DIRECTORY_ENTRY_RESOURCE2资源表

IMAGE_DIRECTORY_ENTRY_EXCEPTION3异常表

IMAGE_DIRECTORY_ENTRY_SECURITY4安全证书表

IMAGE_DIRECTORY_ENTRY_BASERELOC5基址重定位表

IMAGE_DIRECTORY_ENTRY_DEBUG6调试表

IMAGE_DIRECTORY_ENTRY_ARCHITECTURE7版权信息

IMAGE_DIRECTORY_ENTRY_GLOBALPTR8全局指针

IMAGE_DIRECTORY_ENTRY_TLS9TLS表

IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG10加载配置表

IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT11绑定导入表

IMAGE_DIRECTORY_ENTRY_IAT12IAT表

IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT13延迟导入表

IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR14COM描述符表

15保留

获取数据目录

[Asm] 纯文本查看 复制代码for (size_t i = 0; i < DataDirectoryCount; i++)

{

// 获取数据目录标题

switch (i)

{

case 0: Caption = "导出表"; break;

case 1: Caption = "导入表"; break;

case 2: Caption = "资源表"; break;

case 3: Caption = "异常表"; break;

case 4: Caption = "安全证书表"; break;

case 5: Caption = "基址重定位表"; break;

case 6: Caption = "调试表"; break;

case 7: Caption = "版权信息"; break;

case 8: Caption = "全局指针"; break;

case 9: Caption = "TLS表"; break;

case 10: Caption = "加载配置表"; break;

case 11: Caption = "绑定导入表"; break;

case 12: Caption = "IAT表"; break;

case 13: Caption = "延迟导入表"; break;

case 14: Caption = "COM描述符表"; break;

case 15: Caption = "保留"; break;

default: break;

}

// 表的RVA

// DataDirectoryHead[i].VirtualAddress

// 表的大小

// DataDirectoryHead[i].Size

// 节表数量

int SECTIONCount = IMAGE_FILE_HEADER.NumberOfSections;

// 节表头

IMAGE_SECTION_HEADER *SectionHead = (IMAGE_SECTION_HEADER *)(DataBuff + DosHead->e_lfanew + sizeof(IMAGE_NT_HEADERS));

// 表的FOA

// 注: 获取表的FOA需要以下几步

//1. 判断表的RVA所在节表中的哪一个.

//2. 表的FOA = 表的RVA - 节表的RVA + 节表FOA

DWORD DataDirectoryFOA = RVAToRaw(SectionHead, SectionCount, DataDirectoryHead[i].VirtualAddress);

}

RVA 转 FOA

[Asm] 纯文本查看 复制代码DWORD RVAToRaw(IMAGE_SECTION_HEADER *SectionHead, int SECTIONCount, DWORD m_RVA)

{

// 遍历节表

for (size_t i = 0; i < SECTIONCount; i++)

{

IMAGE_SECTION_HEADER section = ((IMAGE_SECTION_HEADER*)SectionHead)[i];

// 判断 RVA 所在的节表

if (m_RVA >= section.VirtualAddress && m_RVA <= (section.VirtualAddress + section.SizeOfRawData))

{

// 获取偏移差

m_RVA = m_RVA - section.VirtualAddress;

m_RVA = m_RVA + section.PointerToRawData;

return m_RVA;

}

}

return 0;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值