依旧温故一下之前学的内容,即几个重要结构体的之间的关系。因为听说它们很重要
IMAGE_DOS_HEADER
Dos stub
PE signature
IMAGE_FILE_HEADER
IMAGE_OPTIONAL_HEADER32
......IMAGE_NT_HEADERS
IMAGE_DATA_DIRECTORY
IMAGE_SECTION_HEADER
//.........................................................................................................................................................................................................................................................
typedef struct _IMAGE_FILE_HEADER {
WORD Machine; //运行平台
WORD NumberOfSections; //节数
DWORD TimeDateStamp; //创建时间距离1970.1.1.00:00:00总共的秒数
DWORD PointerToSymbolTable; //指向符号表
DWORD NumberOfSymbols; //符号表中元素的个数
WORD SizeOfOptionalHeader; //IMAGE_OPTIONAL_HEADER32结构体的大小
WORD Characteristics; //文件标志符
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
运行平台对应的宏及十六进制数:
#define IMAGE_FILE_MACHINE_UNKNOWN 0 适用于任何处理器
#define IMAGE_FILE_MACHINE_I386 0x014c // Intel 386. 或后续兼容处理器
#define IMAGE_FILE_MACHINE_R3000 0x0162 // MIPS little-endian, 0x160 big-endian
#define IMAGE_FILE_MACHINE_R4000 0x0166 // MIPS little-endian
#define IMAGE_FILE_MACHINE_R10000 0x0168 // MIPS little-endian
#define IMAGE_FILE_MACHINE_WCEMIPSV2 0x0169 // MIPS little-endian WCE v2
#define IMAGE_FILE_MACHINE_ALPHA 0x0184 // Alpha_AXP
#define IMAGE_FILE_MACHINE_POWERPC 0x01F0 // IBM PowerPC Little-Endian
#define IMAGE_FILE_MACHINE_SH3 0x01a2 // SH3 little-endian
#define IMAGE_FILE_MACHINE_SH3E 0x01a4 // SH3E little-endian
#define IMAGE_FILE_MACHINE_SH4 0x01a6 // SH4 little-endian
#define IMAGE_FILE_MACHINE_ARM 0x01c0 // ARM Little-Endian
#define IMAGE_FILE_MACHINE_THUMB 0x01c2
#define IMAGE_FILE_MACHINE_IA64 0x0200 // Intel 64
#define IMAGE_FILE_MACHINE_MIPS16 0x0266 // MIPS
#define IMAGE_FILE_MACHINE_MIPSFPU 0x0366 // MIPS
#define IMAGE_FILE_MACHINE_MIPSFPU16 0x0466 // MIPS
#define IMAGE_FILE_MACHINE_ALPHA64 0x0284 // ALPHA64
#define IMAGE_FILE_MACHINE_AXP64 IMAGE_FILE_MACHINE_ALPHA64
IMAGE_FILE_HEADER.Characteristics属性位的含义:
#define IMAGE_FILE_RELOCS_STRIPPED 0x0001 // 文件中不存在重定位信息.
#define IMAGE_FILE_EXECUTABLE_IMAGE 0x0002 // 文件是可执行的
#define IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004 // 不存在行信息
#define IMAGE_FILE_LOCAL_SYMS_STRIPPED 0x0008 // 不存在符号信息
#define IMAGE_FILE_AGGRESIVE_WS_TRIM 0x0010 // 调整工作集
#define IMAGE_FILE_LARGE_ADDRESS_AWARE 0x0020 // 应用程序可处理大于2GB的地址
#define IMAGE_FILE_BYTES_REVERSED_LO 0x0080 // 小尾方式.
#define IMAGE_FILE_32BIT_MACHINE 0x0100 // 只在32位平台上运行.
#define IMAGE_FILE_DEBUG_STRIPPED 0x0200 // 不包含调试信息
#define IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP 0x0400 // 不能从可移动盘运行
#define IMAGE_FILE_NET_RUN_FROM_SWAP 0x0800 // 不能从网络运行
#define IMAGE_FILE_SYSTEM 0x1000 // 系统文件(如驱动程序),不能直接运行.
#define IMAGE_FILE_DLL 0x2000 // 这是一个DLL文件.
#define IMAGE_FILE_UP_SYSTEM_ONLY 0x4000 // 文件不能在多处理器计算机上运行
#define IMAGE_FILE_BYTES_REVERSED_HI 0x8000 // 大尾方式
//...................................................................................................................................................................................................................................
typedef struct _IMAGE_OPTIONAL_HEADER {
//
// Standard fields.
//
WORD Magic; //文件类型,如果为010BH,表示该文件为PE32,如果为0107H,ROM 映像,如果为020BH,PE32+
BYTE MajorLinkerVersion; //链接器版本号
BYTE MinorLinkerVersion;
DWORD SizeOfCode; //所有字节码的总和,该大小是基于文件对齐后的大小,而非内存对齐后的大小
DWORD SizeOfInitializedData; //所有包含已经初始化的数据的节的总大小
DWORD SizeOfUninitializedData; //所有包含未初始化的数据的节的总大小
DWORD AddressOfEntryPoint; //RVA,记录了启动代码距离该PE加载后的起始位置有多少个字节
DWORD BaseOfCode; //加载进内存时代码节的开头相对于映像基址的偏移地址
DWORD BaseOfData; //加载进内存时数据节的开头相对于映像基址的偏移地址 (这个地方有问题,基地址为 0x00400000,这里的偏移为0x1000,内存中数据节的开头地址并不是0x00401000)
//
// NT additional fields.
//
DWORD ImageBase; //PE映像的优先装入地址,可以自已指定,如果不指定,那么链接器默认装入EXE的地址是 0x00400000,相对于DLL文件它的值不是这个
DWORD SectionAlignment; //内存中节的对齐粒数
DWORD FileAlignment; //文件中节的对齐粒数
WORD MajorOperatingSystemVersion; //操作系统的版本号
WORD MinorOperatingSystemVersion;
WORD MajorImageVersion; //PE文件映像的版本号
WORD MinorImageVersion;
WORD MajorSubsystemVersion; //运行所需要的子系统的版本号
WORD MinorSubsystemVersion;
DWORD Win32VersionValue; //子系统版本的值,暂时保留未用,必须设置为0
DWORD SizeOfImage; //内存中整个PE文件的映射尺寸
DWORD SizeOfHeaders; //所有头加节表按照文件对齐粒数对齐后的大小
DWORD CheckSum; //校验和。在大多数PE文件中,该值为0.但在一些内核模式的驱动程序和系统的DLL中,该 值必须正确。
WORD Subsystem; //指定使用界面的子系统
WORD DllCharacteristics; //Dll文件属性
DWORD SizeOfStackReserve; //初始化时保留栈的大小
DWORD SizeOfStackCommit; //初始化时实际提交的栈的大小
DWORD SizeOfHeapReserve; //初始化时保留堆的大小
DWORD SizeOfHeapCommit; //初始化时实际提交的堆的大小
DWORD LoaderFlags; //加载标志
DWORD NumberOfRvaAndSizes; //定义数据目录结构的数量,一般为16个,该值由SizeOfOptionalHeaders决定,实际 应用中可以取2~16的值。
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; //由16个数据目录项线性排列而成
} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;
//...................................................................................................................................................................................................................................
typedef struct _IMAGE_DATA_DIRECTORY {
DWORD VirtualAddress; //特定类型数据的起始RVA,针对不同的数据结构它的含义不一样
DWORD Size; //特定类型的数据块的长度
} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;
//...................................................................................................................................................................................................................................
typedef struct _IMAGE_SECTION_HEADER {
BYTE Name[IMAGE_SIZEOF_SHORT_NAME]; //节名称
union {
DWORD PhysicalAddress;
DWORD VirtualSize;
} Misc;
DWORD VirtualAddress; //节区的RVA
DWORD SizeOfRawData; //节在文件中对齐后的尺寸
DWORD PointerToRawData; //节区起始数据在文件中的偏移
DWORD PointerToRelocations; //在.obj文件中使用,指向重定位表的指针
DWORD PointerToLinenumbers; //行号表的位置
WORD NumberOfRelocations; //重定位表的个数
WORD NumberOfLinenumbers; //行号表中行号的数量
DWORD Characteristics; //节的属性
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
节的数据位的含义:
#define IMAGE_SCN_CNT_CODE 0x00000020 // Section contains code. 节中包代码
#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 // Section contains initialized data. 节中包含已初始化的数据
#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080 // Section contains uninitialized data. 节中包含未初始化的数据
#define IMAGE_SCN_LNK_OTHER 0x00000100 // Reserved.
#define IMAGE_SCN_LNK_NRELOC_OVFL 0x01000000 // Section contains extended relocations.
#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000 // Section can be discarded.
#define IMAGE_SCN_MEM_NOT_CACHED 0x04000000 // Section is not cachable.
#define IMAGE_SCN_MEM_NOT_PAGED 0x08000000 // Section is not pageable.
#define IMAGE_SCN_MEM_SHARED 0x10000000 // Section is shareable.
#define IMAGE_SCN_MEM_EXECUTE 0x20000000 // Section is executable.
#define IMAGE_SCN_MEM_READ 0x40000000 // Section is readable.
#define IMAGE_SCN_MEM_WRITE 0x80000000 // Section is writeable.
下面还有一些比如找到某一节点,映射等的问题明天再来解决。
其中想说明一点就是:我这里总结的任何东西不涉及侵权什么的,只是对我每天学习及思考的一个总结,学习的过程当中我当然会去查找很多的资料及看很多人的博客,目的仅仅是知道自已每天做了什么及哪些还需要改进,还有就是分享。有好的建议及想法的网友欢迎你们的评论及留言。