rgb565和rgb555的文件头区别_Windows可执行文件格式
前言
下文提及的相关数据结构,代码片段均为64位环境,32位环境会加以标注.
PE文件
PE(即Portable Executable)表示可移植的可执行文件,是Windows平台原生的可执行代码载体(此处要区别于NET的IL, JAVA的字节码等),Windows平台所有可以被加载执行的文件都遵从PE文件格式。
注:在linux平台下的可执行文件都遵从ELF文件格式,PE与ELF文件格式都继承于Unix的COFF文件格式,由此可见,虽然不同平台上的可执行文件不能兼容,但是从设计思想上有很多共通之处。
PE文件格式详解
文件数据结构布局
(网上有很多查看PE文件格式的工具,我常用010editor配合其EXE模版)
注:010editor模版所显示的在Section Data后还有其他内容,这只是模版的显示,相关内容其实还是在某个Section Data内部,但是由于其有特殊用途,故被模版单独展示。
由上图所示,一个PE文件有定长部分和不定长部分,这也体现了PE文件格式良好的可扩展性和兼容性。
定长部分:
DOS header + DOS Stub + NT header
不定长部分:
Section header[n] + Section data[n]
磁盘布局与内存布局
一个PE文件,在加载运行前后的布局这里我叫做磁盘布局和内存布局,这两种布局由于不同时期的对齐粒度不同导致有所差异:磁盘布局的对齐粒度是0x200,内存布局的对齐粒度是0x1000。
所以这里就有一个偏移地址转换的问题,PE文件中大体上有四类地址:
虚拟内存地址(VA):RVA + 加载基地址
相对虚拟地址(RVA):内存偏移
文件偏移地址(FOA):文件偏移
特殊地址:这中地址很少见,在资源节中有使用,其计算方式类似于汇编相对跳转的计算
相关数据结构(依次说明)
//DOS Header结构typedef struct _IMAGE_DOS_HEADER{ WORD e_magic; //DOS文件签名 0x4d5a WORD e_cblp; WORD e_cp; WORD e_crlc; WORD e_cparhdr; WORD e_minalloc; WORD e_maxalloc; WORD e_ss; WORD e_sp; WORD e_csum; WORD e_ip; WORD e_cs; WORD e_lfarlc; WORD e_ovno; WORD e_res[4]; WORD e_oemid; WORD e_oeminfo; WORD e_res2[10]; LONG e_lfanew; //NT头偏移} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
其中最重要的是e_magic和e_lfanew字段,e_magic字段是文件头,固定值0x4D5A,e_lfanew:NT头的文件偏移,通常是0xE8
//DOS Stub这是一小段Dos程序,当在Dos系统下运行时,会打印出"This program cannot be run in DOS mode",现在基本不会用到。
//NT header结构typedef struct _IMAGE_NT_HEADERS64 { DWORD Signature; //PE签名,0x4550 IMAGE_FILE_HEADER FileHeader; //文件头 IMAGE_OPTIONAL_HEADER64 OptionalHeader; //可选头} IMAGE_NT_HEADERS64, *PIMAGE_NT_HEADERS64;
//File Header结构typedef struct _IMAGE_FILE_HEADER { WORD Machine; //运行平台 WORD NumberOfSections; //Section Header的数目 DWORD TimeDateStamp; //编译时间戳 DWORD PointerToSymbolTable; //COFF符号表指针 DWORD NumberOfSymbols; //符号数目 WORD SizeOfOptionalHeader; //可选头大小,32位与64位大小不同 WORD Characteristics; //属性,实际上是一个bitmap} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
运行平台:
value | 平台 |
---|---|
IMAGE_FILE_MACHINE_I386(0x014c) | x86 |
IMAGE_FILE_MACHINE_IA64(0x0200) | Intel Itanium |
IMAGE_FILE_MACHINE_AMD64(0x8664) | x64 |
//IMAGE_FILE_HEADER.Characteristics字段struct FILE_CHARACTERISTICS Characteristics { WORD IMAGE_FILE_RELOCS_STRIPPED : 1 //在可执行文件中没有使用。 WORD IMAGE_FILE_EXECUTABLE_IMAGE : 1 //置1表示该文件为exe文件。 WORD IMAGE_FILE_LINE_NUMS_STRIPPED : 1 //在可执行文件中没有使用。 WORD IMAGE_FILE_LOCAL_SYMS_STRIPPED : 1 //在可执行文件中没有使用。 WORD IMAGE_FILE_AGGRESIVE_WS_TRIM : 1 //在可执行文件中没有使用。 WORD IMAGE_FILE_LARGE_ADDRESS_AWARE : 1 //该应用程序可以处理大于2G的地址。 WORD IMAGE_FILE_BYTES_REVERSED_LO : 1 //在可执行文件中没有使用。 WORD IMAGE_FILE_32BIT_MACHINE : 1 //置1表示希望是32位平台 WORD IMAGE_FILE_DEBUG_STRIPPED : 1 //在可执行文件中没有使用。 WORD IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP : 1 //置1表示该程序不能在可移动介质中运行。 WORD IMAGE_FILE_NET_RUN_FROM_SWAP : 1 //置1表示该程序不能在网络中运行。 WORD IMAGE_FILE_SYSTEM : 1 //在可执行文件中没有使用。 WORD IMAGE_FILE_DLL : 1 //置1表示文件是一个动态链接库。 WORD IMAGE_FILE_UP_SYSTEM_ONLY : 1 //置1该文件应仅在单处理器计算机上运行。 WORD IMAGE_FILE_BYTES_REVERSED_HI : 1 //在可执行文件中没有使用。}
//IMAGE_OPTIONAL_HEADER64结构typedef struct _IMAGE_OPTIONAL_HEADER64 { WORD Magic; //判断是32还是64位可执行映像 BYTE MajorLinkerVersion; //链接器主版本号 BYTE MinorLinkerVersion; //链接器此版本号 DWORD SizeOfCode; //多个代码段大小 DWORD SizeOfInitializedData; //多个初始化数据段大小 DWORD SizeOfUninitializedData; //多个为初始化数据段大小 DWORD AddressOfEntryPoint; //代码入口点的RVA DWORD BaseOfCode; //代码段基址 ULONGLONG ImageBase; //加载基址 DWORD SectionAlignment; //内存对齐粒度,默认为页面大小4k DWORD FileAlignment; //文件对齐粒度 WORD MajorOperatingSystemVersion; //操作系统主版本号 WORD MinorOperatingSystemVersion; //操作系统此次版本号 WORD MajorImageVersion; //可执行文件主版本号 WORD MinorImageVersion; //可执行文件次版本号 WORD MajorSubsystemVersion; //子系统主版本号 WORD MinorSubsystemVersion; //子系统此次版本号 DWORD Win32VersionValue; //保留,必须为0 DWORD SizeOfImage; //占用内存的大小,需对齐 DWORD SizeOfHeaders; //定长部分+SectionHeader数组的大小,需对齐 DWORD CheckSum; //校验和 WORD Subsystem; //所需子系统环境 WORD DllCharacteristics; //映像属性 ULONGLONG SizeOfStackReserve; //栈保留大小 ULONGLONG SizeOfStackCommit; //栈提交大小 ULONGLONG SizeOfHeapReserve; //堆保留大小 ULONGLONG SizeOfHeapCommit; //堆提交大小 DWORD LoaderFlags; //在可执行文件中没有使用。 DWORD NumberOfRvaAndSizes; //DataDirectory表表项的数目 IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; //DataDirectory表} IMAGE_OPTIONAL_HEADER64, *PIMAGE_OPTIONAL_HEADER64;
可选头虽说名字叫可选头,但是确是PE⽂件中最不可缺少的部分,其中 DataDirectory 数组尤为重要,⾥⾯是系统加映像时,初始化资源的重要数据的索引,数组⼀共有16项,⼀项保留,其余15项分别对应15种资源索引,由于篇幅原因, DataDirectory 会在后⾯的⽂章中单独详细解读。
以上就是PE⽂件中的定⻓结构部分,下⾯是不定⻓的Section Header数组和各个Section Data。
//Section Header数组就是由一项一项的IMAGE_SECTION_HEADER结构构成//IMAGE_SECTION_HEADER结构typedef struct _IMAGE_SECTION_HEADER { BYTE Name[IMAGE_SIZEOF_SHORT_NAME]; //char类型的八字节数组,保存section的名称 union { DWORD PhysicalAddress; DWORD VirtualSize; } Misc; //section加载到内存的大小 DWORD VirtualAddress; //section起始地址的RVA DWORD SizeOfRawData; //Misc.VirtualSize内存对齐后的大小 DWORD PointerToRawData; //section起始地址的文件偏移 DWORD PointerToRelocations; //指向该部分的重定位条目的文件偏移。为0则没有重定位。 DWORD PointerToLinenumbers; //未使用 WORD NumberOfRelocations; //未使用 WORD NumberOfLinenumbers; //未使用 DWORD Characteristics; //section属性} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
section常⽤属性:
flag | 属性 |
---|---|
IMAGE_SCN_CNT_CODE(0x00000020) | 本节包含可执行代码。 |
IMAGE_SCN_CNT_INITIALIZED_DATA(0x00000040) | Section 含初始化数据。 |
IMAGE_SCN_CNT_UNINITIALIZED_DATA(0x00000080) | Section 含未初始化的数据。 |
IMAGE_SCN_GPREL(0x00008000) | 本节包含通过全局指针引用的数据。 |
IMAGE_SCN_LNK_NRELOC_OVFL(0x01000000) | 本节包含扩展的重定位。 |
IMAGE_SCN_MEM_SHARED(0x10000000) | 该部分可以在内存中共享。 |
IMAGE_SCN_MEM_EXECUTE(0x20000000) | 该部分可以作为代码执行。 |
IMAGE_SCN_MEM_READ(0x40000000) | 可读 |
IMAGE_SCN_MEM_WRITE0x80000000 | 可写 |
其他不常用标志见后面 MSDN 链接。
最后说明一下文件偏移和内存相对偏移的计算:FOA = RVA - VirtualAddress + PointerToRawData首先要判断的的RVA地址所落在的section,条件是VirtualAddress <= RVA < VirtualAddress + SizeOfRawData
附上我写的转换代码,⼀个壳的代码⽚段:
/*参数:RVA:内存相对偏移,pNT:指向NT头的指针返回:转换后的文件偏移*/
UINT32 RvaToOffset(UINT32 RVA, PIMAGE_NT_HEADERS pNT){ UINT32 NumberOfSections = pNT->FileHeader.NumberOfSections; //获取Section数量 UINT32 offset = 0; PIMAGE_SECTION_HEADER pSH = (PIMAGE_SECTION_HEADER)((UINT64)pNT + sizeof(IMAGE_NT_HEADERS)); //获取Section header数组
for (UINT32 i = 0; i { pSH->Characteristics |= IMAGE_SCN_MEM_WRITE; //为每个section添加写属性 if (RVA >= pSH->VirtualAddress&& RVA VirtualAddress + pSH->SizeOfRawData) { offset = RVA - pSH->VirtualAddress + pSH->PointerToRawData; } } return offset;}
常⻅section
这些都是VS编译器⽣成的,⾥⾯的数据带有特定作⽤.
.bss:存放未初始化数据
.data:存放初始化数据
.edata:存放导出表
.idata:存放导⼊表
.pdata:存放异常信息
.rdata:存放初始化的只读数据
.reloc:存放重定位信息
.rsrc:存放资源数据
.text:存放可执⾏代码
.xdata:存放异常信息
⾃定义section
//在vs中可以通过以下方式自定一个section,命名为syclover#pragma data_seg("syclover") char WhoAmI[] = "syclover!"; #pragma data_seg()
注:SectionHeadr和SectionData并不是一一对应的关系,例如.bss段,占内存但是并不占文件空间,在文件中可以找到.bss段对应的SectionHeadr条目,但是并没有对应的SectionData存在,
参考
https://blog.csdn.net/liuyez123/article/details/51281905
https://docs.microsoft.com/zh-cn/windows/win32/api/winnt/ns-winnt-image_nt_headers64
https://docs.microsoft.com/zh-cn/windows/win32/api/winnt/ns-winnt-image_section_header
长
按
关
注
三叶草小组公众号
微信号 : 三叶草小组Syclover
新浪微博:@三叶草小组Syclover
在与你相遇的路上马不停蹄~
rgb565和rgb555的文件头区别_Windows可执行文件格式相关推荐
- 通过文件头标识判断图片格式
通过文件头标识判断图片格式 用Delphi从内存流中通过文件头标识判断图片格式 文件头标识大全: http://www.garykessler.net/library/file_sigs.html h ...
- 文件头标识判断图片格式
同图片的文件头标志: 图片的格式很多,一个图片文件的后缀名并不能说明这个图片的真正格式什么,那么如何获取图片的格式呢?我想到了几个简单但有效的方法,那就是读取图片文件的文件头标识.我们知道各种格式的图 ...
- wav文件头修复_windows文件夹分析(xp版,网络整理)
├-WINDOWS │ ├-system32(存放Windows的系统文件和硬件驱动程序) │ │ ├-config(用户配置信息和密码信息) │ │ │ └-systemprofile(系统配置信息 ...
- 2014 ecb,_it’s_easy_as_123(修改bmp文件头) 攻防世界;
这道题有两种方法,主要就是把bmp文件头,修改成正确格式,图片就可以查看了 拿到文件放入winhex里面分析 发现是个压缩包,修改文件后缀为zip打开, Somebody leaked a still ...
- web.xml文件头出错
原先将web.xml文件头设置为如下格式 <?xml version="1.0" encoding="UTF-8"?> <web-app ve ...
- CTFHub笔记之WEB文件上传:无验证、前端验证、文件头检查
小白一个,如有错误请指正! 一.无验证 我们这次来到了文件上传模块了,这是一个无验证的文件上传,那我们直接上传一个一句话木马即可. 代码: <?php@eval($_REQUEST[" ...
- 程序的本质之二ELF文件的文件头、section header和program header
操作系统:CentOS Linux release 7.7.1908 内核版本:3.10.0-1062.1.1.el7.x86_64 运行平台:x86_64 参考文献:http://refspecs. ...
- java 判断文件类型(根据文件头)
后缀判断的隐患: 对于判断前端(或网络)发送过来文件的类型,有些同学第一个想到的可能就是:根据其后缀名进行格式的判断... 正常情况下,是可以这样做.但实际上,任何文件的后缀都可以随意命名,因此仅通过 ...
- 视频文件头解析之---avi
AVI格式是音频视频交错(Audio VideoInterleaved)的英文缩写,它是Microsoft公司开发的一种符合RIFF文件规范的数字音频与视频文件格式,原先用于Microsoft Vid ...
最新文章
- 4蓝图遍历actor_【虚幻4笔记15】浮动平台
- R语言临床预测模型的评价指标与验证指标实战:综合判别改善指数IDI(Integrated Discrimination Improvement, IDI)
- linux date
- 马斯克公布火星太空船最新照片:施工已达最后一步,10月有望正式推出
- 树莓派的linux系统安装,树莓派安装Linux操作系统
- 整数和小数的移码计算方法
- docker ps 和docker ps -a
- 福布斯中国2018年30位30岁以下精英榜单发布,为什么是他们?
- TensorFlow Seq2Seq
- 一次选中多个物体_经验之谈|Anchor Boxes:物体检测的关键
- 项目后台运行关闭_iOS到底有没有必要上滑强制关闭APP?
- java heapdump 分析工具_heapdump分析工具
- python写斗地主游戏_python编程斗地主 python编程入门
- php中的图片变名为8位用什么,CSS_详解PNG图片,1、PNG图片类型
PNG格式有8位、 - phpStudy...
- 中国行政区域经纬度(免费下载)
- No base URI; hope URI is absolute: http://
- Stata | 时间序列操作
- 洛谷 P1489 猫狗大战
- 服务器运维KPI指标,IT运维包括哪些内容,考核标准是什么
- html拖拽模态框,bootstrap模态框实现拖拽效果