note : PE file format study
IMAGE_OPTIONAL_HEADER64 没有 BaseOfData 成员
发布日期:2021-06-30 22:01:46
浏览次数:2
分类:技术文章
本文共 8971 字,大约阅读时间需要 29 分钟。
参考资料
http://msdn.microsoft.com/en-us/library/ms680195(v=vs.85).aspx
http://msdn.microsoft.com/en-us/magazine/cc301805.aspx
<<Inside Windows An In-Depth Look into the Win32 Portable Executable File Format>>http://msdn.microsoft.com/en-us/library/ms809762.aspx
<<Peering Inside the PE: A Tour of the Win32 Portable Executable File Format>>备注
PE文件结构中分x86和X64两种版本, 记录笔记的时候以 _X 代替
_X means 32 or 64
e.g. IMAGE_NT_HEADERS32, IMAGE_NT_HEADERS64 以 IMAGE_NT_HEADERS_X代替
PE文件被加载后,在内存中的实体叫映像 (Image)
PE文件从前到后的结构顺序
Dos头
NT头 = 文件头 + 可选头
节区头
PE结构定义
Dos头
typedef struct _IMAGE_DOS_HEADER { WORD e_magic; ///< 有效性标记 ... LONG e_lfanew; ///< offset NtHeaders } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
IMAGE_DOS_HEADER 不分x86/x64
PE文件有效性 = (IMAGE_DOS_SIGNATURE == e_magic);
Nt头
typedef struct _IMAGE_NT_HEADERS { ULONG Signature; ///< 有效性标记 IMAGE_FILE_HEADER FileHeader; ///< 文件头 IMAGE_OPTIONAL_HEADER_X OptionalHeader; ///< 可选头 } IMAGE_NT_HEADERS_X, *PIMAGE_NT_HEADERS_X;
PE文件有效性 = (IMAGE_NT_SIGNATURE == IMAGE_NT_HEADERS->Signature)
IMAGE_FILE_HEADER 不分x86/x64
IMAGE_OPTIONAL_HEADER 有x86/x64 区别.
文件头
文件头属于Nt头, 内容全在Nt头结构中
typedef struct _IMAGE_FILE_HEADER { WORD Machine; ///< Windows平台类型, x86, x64, etc WORD NumberOfSections; ///< 扇区数量 ... WORD SizeOfOptionalHeader; ///< 可选头size ... } IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;Windows平台类型为 IMAGE_FILE_HEADER.Machine, 值为 IMAGE_FILE_MACHINE_X e.g. IMAGE_FILE_MACHINE_I386
可选头
可选头属于Nt头, 内容全在Nt头结构中
typedef struct _IMAGE_OPTIONAL_HEADER { // // Standard fields. // WORD Magic; ///< IMAGE_ROM_OPTIONAL_HDR_X BYTE MajorLinkerVersion; BYTE MinorLinkerVersion; DWORD SizeOfCode; ///< 所有代码节的size之和 DWORD SizeOfInitializedData; ///< 所有被初始化的数据节size之和 DWORD SizeOfUninitializedData; ///< 所有未被初始化数据size之和 DWORD AddressOfEntryPoint; ///< 入口地址, OEP ? DWORD BaseOfCode; ///< 代码节开始地址 DWORD BaseOfData; ///< 数据节开始地址, X64版本没有这个成员! // // NT additional fields. // DWORD ImageBase; ///< PE映像在内存的开始地址 DWORD SectionAlignment; DWORD FileAlignment; WORD MajorOperatingSystemVersion; WORD MinorOperatingSystemVersion; WORD MajorImageVersion; WORD MinorImageVersion; WORD MajorSubsystemVersion; WORD MinorSubsystemVersion; DWORD Win32VersionValue; DWORD SizeOfImage; ///< PE映像的size DWORD SizeOfHeaders; DWORD CheckSum; WORD Subsystem; ///< 是Dos程序, 还是Window程序. IMAGE_SUBSYSTEM_X WORD DllCharacteristics; ///< Dll被装入的方式 DWORD SizeOfStackReserve; ///< 进程栈保留size DWORD SizeOfStackCommit; DWORD SizeOfHeapReserve; ///< 进程堆保留size DWORD SizeOfHeapCommit; DWORD LoaderFlags; DWORD NumberOfRvaAndSizes; IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; ///< 数据目录数组, 没有x86/x64区别} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;
typedef struct _IMAGE_OPTIONAL_HEADER64 { WORD Magic; BYTE MajorLinkerVersion; BYTE MinorLinkerVersion; DWORD SizeOfCode; DWORD SizeOfInitializedData; DWORD SizeOfUninitializedData; DWORD AddressOfEntryPoint; DWORD BaseOfCode; ULONGLONG ImageBase; ///< size变大 DWORD SectionAlignment; DWORD FileAlignment; WORD MajorOperatingSystemVersion; WORD MinorOperatingSystemVersion; WORD MajorImageVersion; WORD MinorImageVersion; WORD MajorSubsystemVersion; WORD MinorSubsystemVersion; DWORD Win32VersionValue; DWORD SizeOfImage; DWORD SizeOfHeaders; DWORD CheckSum; WORD Subsystem; WORD DllCharacteristics; ULONGLONG SizeOfStackReserve; ///< size变大 ULONGLONG SizeOfStackCommit; ///< size变大 ULONGLONG SizeOfHeapReserve; ///< size变大 ULONGLONG SizeOfHeapCommit; ///< size变大 DWORD LoaderFlags; DWORD NumberOfRvaAndSizes; IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];} IMAGE_OPTIONAL_HEADER64, *PIMAGE_OPTIONAL_HEADER64;
其余成员有些变成了ULONGLONG
可选头.Magic 直接能看出可选头是哪种了 #define IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x10b #define IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b #define IMAGE_ROM_OPTIONAL_HDR_MAGIC 0x107
DataDirectory数组索引宏
#define IMAGE_DIRECTORY_ENTRY_EXPORT 0 // Export Directory#define IMAGE_DIRECTORY_ENTRY_IMPORT 1 // Import Directory#define IMAGE_DIRECTORY_ENTRY_RESOURCE 2 // Resource Directory#define IMAGE_DIRECTORY_ENTRY_EXCEPTION 3 // Exception Directory#define IMAGE_DIRECTORY_ENTRY_SECURITY 4 // Security Directory#define IMAGE_DIRECTORY_ENTRY_BASERELOC 5 // Base Relocation Table#define IMAGE_DIRECTORY_ENTRY_DEBUG 6 // Debug Directory// IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7 // (X86 usage)#define IMAGE_DIRECTORY_ENTRY_ARCHITECTURE 7 // Architecture Specific Data#define IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8 // RVA of GP#define IMAGE_DIRECTORY_ENTRY_TLS 9 // TLS Directory#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10 // Load Configuration Directory#define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT 11 // Bound Import Directory in headers#define IMAGE_DIRECTORY_ENTRY_IAT 12 // Import Address Table#define IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT 13 // Delay Load Import Descriptors#define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR 14 // COM Runtime descriptor#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16
数据目录最后一个是保留的, 所以只有15个数据目录可以使用.
保留一份自己定义的数据目录索引, 含义看得清楚些
#ifndef IMAGE_DIRECTORY_ENTRIES_EXPORT_TABLE#define IMAGE_DIRECTORY_ENTRY_EXPORT_TABLE 0#define IMAGE_DIRECTORY_ENTRY_IMPORT_TABLE 1#define IMAGE_DIRECTORY_ENTRY_RESOURCE_TABLE 2#define IMAGE_DIRECTORY_ENTRY_EXCEPTION_TABLE 3#define IMAGE_DIRECTORY_ENTRY_CERTIFICATE_TABLE 4#define IMAGE_DIRECTORY_ENTRY_BASE_RELOCATION_TABLE 5#define IMAGE_DIRECTORY_ENTRY_DBGINFO 6#define IMAGE_DIRECTORY_ENTRY_ARCHITECTURE_SPECIFIC_DATA 7#define IMAGE_DIRECTORY_ENTRY_GLOBAL_POINTER_REGISTER 8#define IMAGE_DIRECTORY_ENTRY_TLS_TABLE 9#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG_TABLE 10#define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT_TABLE 11#define IMAGE_DIRECTORY_ENTRY_IMPORT_ADDRESS_TABLE 12#define IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT_DESCRIPTOR 13#define IMAGE_DIRECTORY_ENTRY_CLR_HEADER 14#define IMAGE_DIRECTORY_ENTRY_RESERVED 15#endif // #ifndef IMAGE_DIRECTORY_ENTRIES_EXPORT_TABLE
节区头
#define IMAGE_FIRST_SECTION( ntheader ) ((PIMAGE_SECTION_HEADER) \ ((ULONG_PTR)(ntheader) + \ FIELD_OFFSET( IMAGE_NT_HEADERS, OptionalHeader ) + \ ((ntheader))->FileHeader.SizeOfOptionalHeader \ ))由 IMAGE_FIRST_SECTION 看出, Nt头后跟的是一组节区头
typedef struct _IMAGE_SECTION_HEADER { ... ULONG VirtualAddress; ///< 本扇区头开始地址 ULONG SizeOfRawData; ///< 本扇区长度 ... } IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;节区头数量: PIMAGE_NT_HEADERS->FileHeader->NumberOfSections 本节区开始地址 : PIMAGE_SECTION_HEADER->VirtualAddress 本节区长度 : PIMAGE_SECTION_HEADER->SizeOfRawData
PE读取类的定义
PE分析程序编译结果为 X86/x64, 被分析的文件 x86/x64 都有.
需要根据PE映像内的x86/x64标记, 分别分析
/// @file PeImage.h/// @brief PE映像基类#ifndef __PE_IMAGE_H__#define __PE_IMAGE_H__class CPeImage{public: CPeImage(); virtual ~CPeImage(); virtual BOOL Load(BYTE * pcImgMemory, LONGLONG llSize) = 0;private: void DataInit(); void DataUnInit();protected: IMAGE_DOS_HEADER m_DosHeader;};#endif // #ifndef __PE_IMAGE_H__
/// @file PeImageX86.h/// @brief PE X86映像类#ifndef __PE_IMAGE_X86_H__#define __PE_IMAGE_X86_H__#include "PeImage.h"class CX86PeImage : public CPeImage{public: CX86PeImage(); virtual ~CX86PeImage(); virtual BOOL Load(BYTE * pcImgMemory, LONGLONG llSize);private: void DataInit(); void DataUnInit();private: IMAGE_NT_HEADERS32 m_NtHeader;};#endif // #ifndef __PE_IMAGE_X86_H__
/// @file PeImageX64.h/// @brief PE X64映像类#ifndef __PE_IMAGE_X64_H__#define __PE_IMAGE_X64_H__#include "PeImage.h"class CX64PeImage : public CPeImage{public: CX64PeImage(); virtual ~CX64PeImage(); virtual BOOL Load(BYTE * pcImgMemory, LONGLONG llSize);private: void DataInit(); void DataUnInit();private: IMAGE_NT_HEADERS64 m_NtHeader;};#endif // #ifndef __PE_IMAGE_X64_H__
根据PE平台不同,进行不同的读取
BOOL CpeParse::parseImage(BYTE * pcImgMemory, LONGLONG llSize){ BOOL bRc = FALSE; DWORD dwOsType = 0; if (NULL == pcImgMemory) return bRc; /// 确定 PE Os版本, x86/x64 ? bRc = fnGetPeOsTypeFromMemory((ULONG_PTR)pcImgMemory, llSize, dwOsType); if (!bRc) return bRc; m_bPeX86 = IsPeOsType(dwOsType, TRUE); m_bPeX64 = IsPeOsType(dwOsType, FALSE); /// 按照x86/x64分别进行分析 if (m_bPeX86) bRc = m_PeImgX86.Load(pcImgMemory, llSize); else if (m_bPeX64) bRc = m_PeImgX64.Load(pcImgMemory, llSize); return bRc;}
转载地址:https://lostspeed.blog.csdn.net/article/details/10299891 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
不错!
[***.144.177.141]2024年04月07日 01时48分42秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
OpenCV杂记 - Mat in C++
2019-04-30
location区段
2019-04-30
nginx访问控制、基于用户认证、https配置
2019-04-30
SaltStack
2019-04-30
linux内存的寻址方式
2019-04-30
how2heap-double free
2019-04-30
how2heap-fastbin_dup_consolidate
2019-04-30
orw_shellcode_模板
2019-04-30
fmt在bss段(neepusec_easy_format)
2019-04-30
python 函数式编程
2019-04-30
tensorflow 数据格式
2019-04-30
tf keras SimpleRNN源码解析
2019-04-30
tf keras Dense源码解析
2019-04-30
keras、tf、numpy实现logloss对比
2019-04-30
MyBatisPlus简单入门(SpringBoot)
2019-04-30
攻防世界web进阶PHP2详解
2019-04-30
攻防世界web进阶区web2详解
2019-04-30
xss-labs详解(上)1-10
2019-04-30
xss-labs详解(下)11-20
2019-04-30
攻防世界web进阶区ics-05详解
2019-04-30