pe文件解析:读取pe信息获取文件资源
来源:互联网 发布:淘宝主营占比怎么提高 编辑:程序博客网 时间:2024/06/07 05:05
查看过关于pe文件分析的文章:
(1)http://www.vckbase.com/document/viewdoc/?id=1334
(2)http://www.vckbase.com/document/viewdoc/?id=1335
(3)http://www.cppblog.com/aurain/archive/2009/06/29/88771.html
(4)http://www.fishc.com/a/shipin/jiemixilie/_PExilie_/2011/0429/997.html
(5)http://hi.baidu.com/6121017/blog/item/07d4ebc29d938d31e4dd3b1e.html
还有罗云彬的win32汇编后面附带的pe文件分析。
PE文件被称为可移植的执行体是Portable Execute的全称,常见的EXE、DLL、OCX、SYS、COM都是PE文件,PE文件是微软Windows操作系统上的程序文件(可能是间接被执行,如DLL)。
本文实现一个读取自身自定义资源(TXT)并打印其中内容的小程序。
关于自定义资源可查看http://blog.csdn.net/qq752923276/article/details/6363810
首先看看pe文件的结构:
实际编码使用如下结构:
IMAGE_DOS_HEADER //DOS-MZ头部
IMAGE_NT_HEADERS
{ DWORD Signature;//对应上图PE文件标志 总是为PE00
IMAGE_FILE_HEADER FileHeader;//PE文件头
IMAGE_OPTIONAL_HEADER32 OptionalHeader;//PE文件可选头(实际非可选)
}
//后面是一系列段头(win32汇编上表述是节表)
IMAGE_SECTION_HEADER //对应.text头部等
最后是各个实际段
上述结构都在winnt.h中有定义,具体的说明可以查看msdn或者上面附带的链接(1),都有详细说明。
再说明下RVA,
RVA是相对虚拟地址(Relative Virtual Address)的缩写,顾名思义,它是一个“相对”地址,也可以说是“偏移量”,PE文件的各种数据结构中涉及到地址的字段大部分都是以RVA表示的,准确地说,RVA就是当PE文件被装载到内存中后,某个数据的位置相对于文件头的偏移量。。
由于pe的磁盘映像和内存映像不同(可查看上面附带链接(4)),而pe的地址信息大多是RVA,所以如果要读取文件中资源需要做RVA到文件实际偏移长度的转换。
关于RVA到FileAddr的转换详解:http://blog.csdn.net/jccz_zys/article/details/1526971
下面是代码:
exe附带自定义资源部分请查看上述内容说明。
// pe2.cpp : Defines the entry point for the console application.//#include "stdafx.h"#include <Windows.h>#include <stdio.h>#include <assert.h>#define TEST(n) (n>>31)&0x1int main(int argc, char* argv[]){char szFile[MAX_PATH]="";GetModuleFileName(NULL,szFile,MAX_PATH);//获取本身路径FILE *fp=fopen(szFile,"rb");assert(fp!=NULL);IMAGE_DOS_HEADER dosHeader;assert(fread(&dosHeader,sizeof dosHeader,1,fp)!=-1);fseek(fp,dosHeader.e_lfanew,SEEK_SET);IMAGE_NT_HEADERS ntHeaders;assert(fread(&ntHeaders,sizeof ntHeaders,1,fp)!=-1);DWORD RsAddr=ntHeaders.OptionalHeader.DataDirectory[2].VirtualAddress;DWORD RsRealAddr=0;//获取资源在文件中实际偏移量 IMAGE_SECTION_HEADER sectionHeader;DWORD RsPointToRawData=0;for (int i=0;i<ntHeaders.FileHeader.NumberOfSections;++i){assert(fread(§ionHeader,sizeof sectionHeader,1,fp)!=-1);char szName[9];memset(szName,0,9);memcpy(szName,sectionHeader.Name,8);puts(szName);if (RsAddr>=sectionHeader.VirtualAddress&&RsAddr<sectionHeader.VirtualAddress+sectionHeader.SizeOfRawData){RsRealAddr=RsAddr-sectionHeader.VirtualAddress+sectionHeader.PointerToRawData;//RVA到文件实际偏移的转换RsPointToRawData=sectionHeader.PointerToRawData;printf("res fileaddr:0x%x\n",RsRealAddr);}}//fseek(fp,RsRealAddr,SEEK_SET);loop:IMAGE_RESOURCE_DIRECTORY resDir;IMAGE_RESOURCE_DIRECTORY_ENTRY resDirEntry;assert(fread(&resDir,sizeof resDir,1,fp)!=-1);assert(fread(&resDirEntry,sizeof resDirEntry,1,fp)!=-1);if (TEST(resDirEntry.OffsetToData)){DWORD nextPoint=resDirEntry.OffsetToData&0x7fff;fseek(fp,RsRealAddr+nextPoint,SEEK_SET);goto loop; }else{fseek(fp,RsRealAddr+resDirEntry.OffsetToData,SEEK_SET);IMAGE_RESOURCE_DATA_ENTRY resDataEntry;assert(fread(&resDataEntry,sizeof resDataEntry,1,fp)!=-1);DWORD ResSize=resDataEntry.Size;DWORD ResOffset=resDataEntry.OffsetToData-RsAddr+RsPointToRawData;//RVA到文件实际偏移的转换printf("res size:%d\n",ResSize);printf("res offset:0x%x\n",ResOffset);puts("get res:");fseek(fp,ResOffset,SEEK_SET);char *pRes=new char[ResSize+1];assert(pRes!=NULL);memset(pRes,0,ResSize+1);assert(pRes!=NULL);assert(fread(pRes,ResSize,1,fp)!=-1);puts(pRes);delete [] pRes;}fclose(fp);getchar();return 0;}完整代码:http://download.csdn.net/detail/qq752923276/4103847
- pe文件解析:读取pe信息获取文件资源
- 读取PE文件的资源表
- PE总结13 --PE文件结构之 解析资源表
- PE总结15--PE文件结构之 解析资源表
- 获取PE文件信息的封装
- 获取PE文件信息的封装
- PE文件信息浏览
- Python解析PE文件
- PE文件解析
- PE文件结构解析
- PE文件结构解析
- PE文件解析代码
- PE文件-PE文件格式
- PE 文件格之资源
- 分析pe文件资源(学习)
- 自己写的一个PE文件FileVersionInfo类,可以轻松获取PE文件版本信息
- PE文件解析(C#)
- Ruby解析Windows PE文件
- Varbinary转换成等长的varchar
- C语言深度解剖笔记
- 当TextView或者EditView的内容发生变化时,其他组件及时给予响应时,我们可以使用TextWatcher来实现。
- 为什么要做软件过程改进工程师
- 骑自行车游北京
- pe文件解析:读取pe信息获取文件资源
- Flex反射得到属性和属性的值
- sql查出数据是long类型
- 线程池
- ecc错误的处理方式-ECC_CorrectData问题
- suse linux oracle自动启动
- Eclipse 配置tomcat访问http://localhost:8080出现404
- c++ string与字符串之间的转换
- 使用中科院ICTCLAS构建自己分词器中用到的public String readerToString(Reader reader)