首页 > 程序开发 > 软件开发 > Vc > 正文
图解VC++版PE文件解析器源码分析
2016-07-14       个评论    来源:bcbobo21cn的专栏  
收藏    我要投稿

1 Understand 分析的图表

\

 

\

 

\

 

\

 

\

 

\

 

\

 

\

 

\

 

\

 

\

 

\

 

\

 

\

 

\

 

\

 

2 PE结构解析的主要代码简要分析

首先看下PE结构体的定义;与PE文件结构一致;

 

/************************************************************************/
/* 定义PE文件的结构体
2011-08-30 Wizard~ZL*/
/************************************************************************/
#ifndef _PESTRUCT_H_
#define _PESTRUCT_H_

//PE文件最开始是一个 _IMAGE_DOS_HEADER   也就是MS_DOS
struct   stMS_DOS
{	
	WORD e_magic;//magic number DOS头标记              00h
	WORD e_cblp; // Bytes on last page of file		   02h
	WORD e_cp;	//pages in file						   04h
	WORD e_crlc;// Relocations						   06h
	WORD e_cparhdr;// Size of header in paragraphs	   08h
	WORD e_minalloc;// Minimum extra paragraphs needed 0ah
	WORD e_maxalloc;// Maximum extra paragraphs needed 0ch
	WORD e_ss;	//  Initial (relative) SS value        0eh
	WORD e_sp;	//  Initial SPvalue					   10h
	WORD e_csum;//check sum							   12h
	WORD e_ip; //Initial IP value					   14h
	WORD e_cs;// Initial (relative) CS value		   16h
	WORD e_lfarlc;// File address of relocation table  18h
	WORD e_ovno;  // Overlay number					   1ah
	WORD e_res[4];// Reserved words					   1ch
	WORD e_oemid;// OEM identifier (for e_oeminfo)	   24h
	WORD e_oeminfo;//OEM information; e_oemid specific 26h
	WORD e_res2[10];// Reserved words				   28h	
	long e_lfanew;	//File address of new exe header   3ch     **指向PE头部
};

//IMAGE_DOS_HEADER之后是一个 _IMAGE_NT_HEADERS 
 struct stPE_HEADER
{
	DWORD Signature;		//定义PE标志信息 		    00h         在有效的PE文件中值是 00 00 45 50	

	/*映像文件头 PE文件的基本信息
	IMAGE_FILE_HEADER 开始*/
	WORD  Machine;		//								04h	  		
	WORD  NumberOfSections;	//							06h		//pe文件中区块的数量
	DWORD TimeDateStamp;//								08h		//文件日期时间戳,指这个pe文件生成的时间,它的值是从1969年12月31日16:00:00以来的秒数.
	DWORD PointerToSymbolTable;//						0ch		//Coff调试符号表的偏移地址.
	DWORD NumberOfSymbols;//							10h		//Coff符号表中符号的个数. 这个域和前个域在release版本的程序里是0.
	WORD  SizeOfOptionalHeader;//IMAGE_OPTON_HEADER大小 14h		//IMAGE_OPTIONAL_HEADER32结构的大小(即多少字节).
	WORD  Characteristics;//							16h		//这个域描述pe文件的一些属性信息,比如是否可执行,是否是一个动态连接库等
	/*IMAGE_FILE_HEADER 结束*/

	//IMAGE_OPTIONAL_HEADER32 option_header;
	//这个IMAGE_OPTION_HEADER32结构放入PE_EXTHEADER中
};

 //映像可选头 
 struct stPE_ExtHeader
 {
	 /*_IMAGE_OPTIONAL_HEADER开始*/
	 // Standard fields
	 //Magic用来标记可执行文件是Rom镜像还是普通可执行程序 如果是一般的可执行程序则是010Bh 如果是PE32+ 即64位是 020Bh
	 WORD    Magic;//									18h		//幻数,32位pe文件总为010bh
	 BYTE    MajorLinkerVersion;//						1ah		//连接器主版本号
	 BYTE    MinorLinkerVersion;//						1bh		//连接器副版本号
	 DWORD   SizeOfCode;//								1ch		//代码段总大小
	 DWORD   SizeOfInitializedData;//					20h		//已初始化数据段总大小
	 DWORD   SizeOfUninitializedData;//					24h		//未初始化数据段总大小
	 DWORD   AddressOfEntryPoint;//						28h		//程序执行入口地址(RVA)
	 DWORD   BaseOfCode;//								2ch		//代码段起始地址(RVA)
	 DWORD   BaseOfData;//								30h		//数据段起始地址(RVA)
	
	 // NT additional fields.
	 DWORD   ImageBase;//								34h		//程序默认的装入起始地址
	 DWORD   SectionAlignment;//						38h		//内存中区块的对齐单位
	 DWORD   FileAlignment;//							3ch		//文件中区块的对齐单位
	 WORD    MajorOperatingSystemVersion;//				40h		//所需操作系统主版本号
	 WORD    MinorOperatingSystemVersion;//				42h		//所需操作系统副版本号
	 WORD    MajorImageVersion;//						44h		//自定义主版本号
	 WORD    MinorImageVersion;//						46h		//自定义副版本号
	 WORD    MajorSubsystemVersion;//					48h		//所需子系统主版本号
	 WORD    MinorSubsystemVersion;//					4ah		//所需子系统副版本号
	 DWORD   Win32VersionValue;//						4ch		//总是0
	 DWORD   SizeOfImage;//								50h		//pe文件在内存中的映像总大小
	 DWORD   SizeOfHeaders;//							54h		//从pe文件开始到节表(包含节表)的总大小
	 DWORD   CheckSum;//								58h		//pe文件CRC校验和
	 WORD    Subsystem;//								5ch		//用户界面使用的子系统类型
	 WORD    DllCharacteristics;//						5eh		//为0
	 DWORD   SizeOfStackReserve;//						60h		//为线程的栈初始保留的虚拟内存的默认值
	 DWORD   SizeOfStackCommit;//						64h		//为线程的栈初始提交的虚拟内存的大小
	 DWORD   SizeOfHeapReserve;//						68h		//为进程的堆保留的虚拟内存的大小
	 DWORD   SizeOfHeapCommit;//						6ch		//为进程的堆初始提交的虚拟内存的大小
	 DWORD   LoaderFlags;	//							70h		//为0	
	 DWORD   NumberOfRvaAndSizes;//						74h		//数据目录结构数组的项数,总为 00000010h
	 IMAGE_DATA_DIRECTORY DataDirectory[16];		//78h	
	 /*_IMAGE_OPTIONAL_HEADER结束*/
 };

 struct stSECTION_HEADER
 {
	  BYTE    Name[IMAGE_SIZEOF_SHORT_NAME]; //			00h			块名,8个字节长 
	  union {
		 DWORD   PhysicalAddress; //					08h			obj文件中,区段的实际地址
		 DWORD   VirtualSize;    //									exe和dll文件中区段在文件中对齐前的大小
	 } Misc;
	  DWORD   VirtualAddress;         //				0ch			块的RVA(相对虚拟地址)  
	  DWORD   SizeOfRawData;          //				10h			在文件中对齐后的大小 
	  DWORD   PointerToRawData;       //                14h			在文件中的偏移 
	  DWORD   PointerToRelocations;   //				18h			重定位的偏移(obj文件中使用)
	  DWORD   PointerToLinenumbers;   // 				1ch			行号表的偏移(调试用) 
	  WORD    NumberOfRelocations;    //				1eh			重定位项数目(obj文件中使用)
	  WORD    NumberOfLinenumbers;    //				20h			行号表中行号的数目
	  DWORD   Characteristics;        //				24h			块属性
 };

 struct stIMAGE_IMPORT_DESCRIPTOR 
 {
	 union {
		 DWORD   Characteristics;    // 0 for terminating null import descriptor
		 DWORD   OriginalFirstThunk; // RVA to original unbound IAT (PIMAGE_THUNK_DATA)
	 };
	 DWORD   TimeDateStamp;          // 0 if not bound,
	 // -1 if bound, and real date\time stamp
	 //     in IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT (new BIND)
	 // O.W. date/time stamp of DLL bound to (Old BIND)

	 DWORD   ForwarderChain;         // -1 if no forwarders
	 DWORD   Name;
	 DWORD   FirstThunk;             // RVA to IAT (if bound this IAT has actual addresses)
 } ; 

  struct stIMAGE_THUNK_DATA
 {
	 union {
		 PBYTE  ForwarderString;
		 PDWORD Function;
		 DWORD Ordinal;
		 PIMAGE_IMPORT_BY_NAME  AddressOfData;
	 } u1;
 } ;
 
  struct stIMAGE_IMPORT_BY_NAME 
  {
	  WORD    Hint;              //指出函数在所在的dll的输出表中的序号
	  BYTE    Name[1];           //指出要输入的函数的函数名
  };

#endif


 

看下PE解析的主要函数;

 

void CPEToolDlg::OnBnClickedBtnbrowse()
{	
	WCHAR szFilter[] =L"可执行文件|*.exe";
	CFileDialog fileDlg(TRUE,L"exe",NULL,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,szFilter);
	if (fileDlg.DoModal()==IDOK)
	{
		m_strfilePathNeme = fileDlg.GetPathName();
	}
	m_FilepathEdit.SetWindowText(m_strfilePathNeme);
	m_FilepathEdit.SetReadOnly(TRUE);
	
	if (m_strfilePathNeme == L"")
	{
		MessageBox(L"请选择可执行文件!");
		return;
	}
	((CButton*)GetDlgItem(IDC_BTNDOSHEAD))->EnableWindow(TRUE);
	((CButton*)GetDlgItem(IDC_BTNPEHEAD))->EnableWindow(TRUE);
	((CButton*)GetDlgItem(IDC_BTNDIC))->EnableWindow(TRUE);
	((CButton*)GetDlgItem(IDC_BTNSEC))->EnableWindow(TRUE);
	((CButton*)GetDlgItem(IDC_BTN_IMPORTTABLE))->EnableWindow(TRUE);
	
	//开始解析PE
	ParsePE();	
}

装载PE文件,开始解析;通常的VC++打开文件对话框,过滤器为*.exe;

 

 

 

void CPEToolDlg::ParsePE()
{	
	_wfopen_s(&pFile,m_strfilePathNeme.GetBuffer(0),L"r+");
	fread_s(&m_stMsDos.e_magic,sizeof(DWORD),sizeof(DWORD),1,pFile);
	if (m_stMsDos.e_magic != IMAGE_DOS_SIGNATURE)
	{
		MessageBox(L"不是有效的PE文件,因为emagic的值不为0x5A4D\n");
		return ;
	}

	
	//解析 IMAGE_NT_HEADERS
	ParseImageNTHeaders();
	
	//解析_IMAGE_OPTION_HEADERS32
	ParseImageOptionHeaders();	

	//解析节表
	ParseSectionHeder();
}

解析PE文件,首先判断是否是有效的PE文件,然后解析NT头,文件头,节表;

 

 

 

void CPEToolDlg::ParseImageNTHeaders()
{
	//文件偏移到3C处,获得e_lfanew的值 读取IMAGE_NT_HEADERS
	fseek(pFile,0x3c,SEEK_SET);
	fread_s(&m_stMsDos.e_lfanew,sizeof(DWORD),sizeof(DWORD),1,pFile);	
	if (m_stMsDos.e_lfanew == 0 )
	{
		MessageBox(L"获取IMAGE_NT_HEADERS的偏移位置失败!\n");
		return ;
	}
	fseek(pFile,m_stMsDos.e_lfanew,SEEK_SET);	
	fread(&m_stPeHeader,sizeof(stPE_HEADER),1,pFile);
	if (m_stPeHeader.Signature != IMAGE_NT_SIGNATURE)
	{
		MessageBox(L"不是有效的PE文件,因为Signature值不等于0x00004550(即是ASCII的'PE')");
		return;
	}

}

解析NT头;把对应内容读入m_stPeHeader;

 

 

 

void CPEToolDlg::ParseImageOptionHeaders()
{
	//读取IMAGE_OPTION_HEADER
	fread(&m_stExtPeHeader,sizeof(stPE_ExtHeader),1,pFile);
	//幻数(魔数)
	if (m_stExtPeHeader.Magic !=  IMAGE_NT_OPTIONAL_HDR32_MAGIC)
	{
		MessageBox(L"不是Win32PE文件,因为幻数不等于0x010b\n");
		return ;
	}

	//解析输入数据目录
	//输出表从PE头处偏移78h 输入表从PE头处偏移80h
	//偏移到输出表
	iLocation = m_stMsDos.e_lfanew;//PE头
	iLocation += 0x78;
	fseek(pFile,iLocation,SEEK_SET);
	//第一个IMAGE_DATA_DIRECTORY是输出表
	fread(&m_stExtPeHeader.DataDirectory[0].VirtualAddress,sizeof(DWORD),1,pFile); //输出表的RVA
	fread(&m_stExtPeHeader.DataDirectory[0].Size,sizeof(DWORD),1,pFile);//输出表大小

	//第二个IMAGE_DATA_DIRECTORY是输入表
	fread(&m_stExtPeHeader.DataDirectory[1].VirtualAddress,sizeof(DWORD),1,pFile); //输入表RVA
	fread(&m_stExtPeHeader.DataDirectory[1].Size,sizeof(DWORD),1,pFile);//输入表大小

	//第三个是ResourceDirectory
	fread(&m_stExtPeHeader.DataDirectory[2].VirtualAddress,sizeof(DWORD),1,pFile); 
	fread(&m_stExtPeHeader.DataDirectory[2].Size,sizeof(DWORD),1,pFile);

	//第四个是ExceptionDirectory
	fread(&m_stExtPeHeader.DataDirectory[3].VirtualAddress,sizeof(DWORD),1,pFile); 
	fread(&m_stExtPeHeader.DataDirectory[3].Size,sizeof(DWORD),1,pFile);

	//第五个是SecurityDirectory
	fread(&m_stExtPeHeader.DataDirectory[4].VirtualAddress,sizeof(DWORD),1,pFile); 
	fread(&m_stExtPeHeader.DataDirectory[4].Size,sizeof(DWORD),1,pFile);

	//第六个是Base Relocation table
	fread(&m_stExtPeHeader.DataDirectory[5].VirtualAddress,sizeof(DWORD),1,pFile); 
	fread(&m_stExtPeHeader.DataDirectory[5].Size,sizeof(DWORD),1,pFile);

	//第7个是DebugDirectory
	fread(&m_stExtPeHeader.DataDirectory[6].VirtualAddress,sizeof(DWORD),1,pFile); 
	fread(&m_stExtPeHeader.DataDirectory[6].Size,sizeof(DWORD),1,pFile);

	//第8个是ArchitetureSpecificData
	fread(&m_stExtPeHeader.DataDirectory[7].VirtualAddress,sizeof(DWORD),1,pFile); 
	fread(&m_stExtPeHeader.DataDirectory[7].Size,sizeof(DWORD),1,pFile);
	
	//第9个是GlobalPtr
	fread(&m_stExtPeHeader.DataDirectory[8].VirtualAddress,sizeof(DWORD),1,pFile); 
	fread(&m_stExtPeHeader.DataDirectory[8].Size,sizeof(DWORD),1,pFile);

	//第10个是TLSDirectory
	fread(&m_stExtPeHeader.DataDirectory[9].VirtualAddress,sizeof(DWORD),1,pFile); 
	fread(&m_stExtPeHeader.DataDirectory[9].Size,sizeof(DWORD),1,pFile);
	
	//第11个是LoadConfigationDirectory
	fread(&m_stExtPeHeader.DataDirectory[10].VirtualAddress,sizeof(DWORD),1,pFile); 
	fread(&m_stExtPeHeader.DataDirectory[10].Size,sizeof(DWORD),1,pFile);

	//第12个是BoundImport
	fread(&m_stExtPeHeader.DataDirectory[11].VirtualAddress,sizeof(DWORD),1,pFile); 
	fread(&m_stExtPeHeader.DataDirectory[11].Size,sizeof(DWORD),1,pFile);

	//第13个是ImportAddressTable
	fread(&m_stExtPeHeader.DataDirectory[12].VirtualAddress,sizeof(DWORD),1,pFile); 
	fread(&m_stExtPeHeader.DataDirectory[12].Size,sizeof(DWORD),1,pFile);

	//第14个是DelayImportDescriptor
	fread(&m_stExtPeHeader.DataDirectory[13].VirtualAddress,sizeof(DWORD),1,pFile); 
	fread(&m_stExtPeHeader.DataDirectory[13].Size,sizeof(DWORD),1,pFile);

	//第15个是CLIHeader
	fread(&m_stExtPeHeader.DataDirectory[14].VirtualAddress,sizeof(DWORD),1,pFile); 
	fread(&m_stExtPeHeader.DataDirectory[14].Size,sizeof(DWORD),1,pFile);

	//第16个是Reserved
	fread(&m_stExtPeHeader.DataDirectory[15].VirtualAddress,sizeof(DWORD),1,pFile); 
	fread(&m_stExtPeHeader.DataDirectory[15].Size,sizeof(DWORD),1,pFile);

}

解析可选头;逐个读入数据目录;

 

 

 

void CPEToolDlg::ParseSectionHeder()
{
	//偏移到节表位置
	iLocation = m_stMsDos.e_lfanew + sizeof(stPE_HEADER) + m_stPeHeader.SizeOfOptionalHeader;//PE头+PE头的大小(IMAGE_FILE_HEADER)_+PE可选头的大小(IMAGE_OPTION_HEADER)
	fseek(pFile,iLocation,SEEK_SET);
	for (WORD i=0;i

解析节头;读入对应内容到m_stSectionHeader;

 

 

 

DWORD CPEToolDlg :: RVAtoFileOffset(int iThe_Section,const DWORD& RVAOffset)
{
	DWORD dwFileOffset = 0;
	//传入的RavOffset先要转换成相对于节(比如.idata 或.text)的偏移RVA
	//第iThe_Section个节中
	DWORD dwVrk_TheSection = vct_SectionHeader.at(iThe_Section).VirtualAddress - vct_SectionHeader.at(iThe_Section).PointerToRawData;//虚拟地址和物理地址之间的差值
	dwFileOffset = RVAOffset - dwVrk_TheSection;
	return dwFileOffset;
}

RVA转换;

 

 

 

void CPEToolDlg::OnBnClickedBTN_DATADIC()
{
	//数据目录
	dlgDirectoryDate = new Cdialog1;
	dlgDirectoryDate->Create(IDD_DIALOG1,this);	
	dlgDirectoryDate->OnInitCtrlList();
	dlgDirectoryDate->ShowWindow(SW_SHOW);	
	//输出可选头里的数据目录IMAGE_DATA_DIRECTORY
	//1导出表
	CString strExportSymbol,strExportSymbolSize;
	strExportSymbol.Format(L"0x%08x/%d(十进制)",m_stExtPeHeader.DataDirectory[0].VirtualAddress,m_stExtPeHeader.DataDirectory[0].VirtualAddress);
	strExportSymbolSize.Format(L"0x%08x/%d(十进制)",m_stExtPeHeader.DataDirectory[0].Size,m_stExtPeHeader.DataDirectory[0].Size);
	dlgDirectoryDate->AddToCtrlList(L"01 .edata 导出表",L"偏移"+strExportSymbol,L"IMAGE_OPTION_HEADER--IMAGE_DATA_DIRECTORY",L"偏移大小为:"+strExportSymbolSize);

	//2导入表
	CString strImportSymbol,strImportSymbolSize;
	strExportSymbol.Format(L"0x%08x/%d(十进制)",m_stExtPeHeader.DataDirectory[1].VirtualAddress,m_stExtPeHeader.DataDirectory[1].VirtualAddress);
	strImportSymbolSize.Format(L"0x%08x/%d(十进制)",m_stExtPeHeader.DataDirectory[1].Size,m_stExtPeHeader.DataDirectory[1].Size);
	dlgDirectoryDate->AddToCtrlList(L"02 .idata 导入表",L"偏移"+strExportSymbol,L"IMAGE_OPTION_HEADER--IMAGE_DATA_DIRECTORY",L"偏移大小为:"+strImportSymbolSize);

	//3资源表
	CString strResource,strResourceSize;
	strResource.Format(L"0x%08x/%d(十进制)",m_stExtPeHeader.DataDirectory[2].VirtualAddress,m_stExtPeHeader.DataDirectory[2].VirtualAddress);
	strResourceSize.Format(L"0x%08x/%d(十进制)",m_stExtPeHeader.DataDirectory[2].Size,m_stExtPeHeader.DataDirectory[2].Size);
	dlgDirectoryDate->AddToCtrlList(L"03 .rsrc 资源表",L"偏移"+strResource,L"IMAGE_OPTION_HEADER--IMAGE_DATA_DIRECTORY",L"偏移大小为:"+strResourceSize);

	//4异常表
	CString strException,strExceptionSize;
	strException.Format(L"0x%08x/%d(十进制)",m_stExtPeHeader.DataDirectory[3].VirtualAddress,m_stExtPeHeader.DataDirectory[3].VirtualAddress);
	strExceptionSize.Format(L"0x%08x/%d(十进制)",m_stExtPeHeader.DataDirectory[3].Size,m_stExtPeHeader.DataDirectory[3].Size);
	dlgDirectoryDate->AddToCtrlList(L"04 .pdata 异常表",L"偏移"+strException,L"IMAGE_OPTION_HEADER--IMAGE_DATA_DIRECTORY",L"偏移大小为:"+strExceptionSize);

	//5属性证书表
	CString strSecurity,strSecuritySize;
	strSecurity.Format(L"0x%08x/%d(十进制)",m_stExtPeHeader.DataDirectory[4].VirtualAddress,m_stExtPeHeader.DataDirectory[4].VirtualAddress);
	strSecuritySize.Format(L"0x%08x/%d(十进制)",m_stExtPeHeader.DataDirectory[4].Size,m_stExtPeHeader.DataDirectory[4].Size);
	dlgDirectoryDate->AddToCtrlList(L"05 .属性证书表",L"偏移"+strSecurity,L"IMAGE_OPTION_HEADER--IMAGE_DATA_DIRECTORY",L"偏移大小为:"+strSecuritySize);

	//6	基址重定位表
	CString strBaseReloation,strBaseReloationSize;
	strBaseReloation.Format(L"0x%08x/%d(十进制)",m_stExtPeHeader.DataDirectory[5].VirtualAddress,m_stExtPeHeader.DataDirectory[5].VirtualAddress);
	strBaseReloationSize.Format(L"0x%08x/%d(十进制)",m_stExtPeHeader.DataDirectory[5].Size,m_stExtPeHeader.DataDirectory[5].Size);
	dlgDirectoryDate->AddToCtrlList(L"06 .reloc 基址重定位表",L"偏移"+strBaseReloation,L"IMAGE_OPTION_HEADER--IMAGE_DATA_DIRECTORY",L"偏移大小为:"+strBaseReloationSize);

	//7	调试目录	
	CString strDebug,strDebugSize;
	strDebug.Format(L"0x%08x/%d(十进制)",m_stExtPeHeader.DataDirectory[6].VirtualAddress,m_stExtPeHeader.DataDirectory[6].VirtualAddress);
	strSecuritySize.Format(L"0x%08x/%d(十进制)",m_stExtPeHeader.DataDirectory[6].Size,m_stExtPeHeader.DataDirectory[6].Size);
	dlgDirectoryDate->AddToCtrlList(L"07 .debug 调试目录",L"偏移"+strDebug,L"IMAGE_OPTION_HEADER--IMAGE_DATA_DIRECTORY",L"偏移大小为:"+strSecuritySize);

	//8 指定结构数据
	CString strArchitectureData,strArchitectureDataSize;
	strArchitectureData.Format(L"0x%08x/%d(十进制)",m_stExtPeHeader.DataDirectory[7].VirtualAddress,m_stExtPeHeader.DataDirectory[7].VirtualAddress);
	strArchitectureDataSize.Format(L"0x%08x/%d(十进制)",m_stExtPeHeader.DataDirectory[7].Size,m_stExtPeHeader.DataDirectory[7].Size);
	dlgDirectoryDate->AddToCtrlList(L"08.(保留必须为0)  指定结构数据",L"偏移"+strArchitectureData,L"IMAGE_OPTION_HEADER--IMAGE_DATA_DIRECTORY",L"偏移大小为:"+strArchitectureDataSize);

	//9 全局指针
	CString strGlobalPtr,strGlobalPtrSize;
	strGlobalPtr.Format(L"0x%08x/%d(十进制)",m_stExtPeHeader.DataDirectory[8].VirtualAddress,m_stExtPeHeader.DataDirectory[8].VirtualAddress);
	strGlobalPtrSize.Format(L"0x%08x/%d(十进制)",m_stExtPeHeader.DataDirectory[8].Size,m_stExtPeHeader.DataDirectory[8].Size);
	dlgDirectoryDate->AddToCtrlList(L"09 .全局指针",L"偏移"+strGlobalPtr,L"IMAGE_OPTION_HEADER--IMAGE_DATA_DIRECTORY",L"偏移大小为:"+strGlobalPtrSize);

	//10 TLS
	CString strTLS,strTLSsize;
	strTLS.Format(L"0x%08x/%d(十进制)",m_stExtPeHeader.DataDirectory[9].VirtualAddress,m_stExtPeHeader.DataDirectory[9].VirtualAddress);
	strTLSsize.Format(L"0x%08x/%d(十进制)",m_stExtPeHeader.DataDirectory[9].Size,m_stExtPeHeader.DataDirectory[9].Size);
	dlgDirectoryDate->AddToCtrlList(L"10 .tls TLS",L"偏移"+strTLS,L"IMAGE_OPTION_HEADER--IMAGE_DATA_DIRECTORY",L"偏移大小为:"+strTLSsize);

	//11 加载配置
	CString strLoadConfig,strLoadConfigSize;
	strLoadConfig.Format(L"0x%08x/%d(十进制)",m_stExtPeHeader.DataDirectory[10].VirtualAddress,m_stExtPeHeader.DataDirectory[10].VirtualAddress);
	strLoadConfigSize.Format(L"0x%08x/%d(十进制)",m_stExtPeHeader.DataDirectory[10].Size,m_stExtPeHeader.DataDirectory[10].Size);
	dlgDirectoryDate->AddToCtrlList(L"11.加载配置",L"偏移"+strLoadConfig,L"IMAGE_OPTION_HEADER--IMAGE_DATA_DIRECTORY",L"偏移大小为:"+strLoadConfigSize);

	//12 绑定导入表
	CString strBound,strBoundsize;
	strBound.Format(L"0x%08x/%d(十进制)",m_stExtPeHeader.DataDirectory[11].VirtualAddress,m_stExtPeHeader.DataDirectory[11].VirtualAddress);
	strBoundsize.Format(L"0x%08x/%d(十进制)",m_stExtPeHeader.DataDirectory[11].Size,m_stExtPeHeader.DataDirectory[11].Size);
	dlgDirectoryDate->AddToCtrlList(L"12.绑定导入表",L"偏移"+strBound,L"IMAGE_OPTION_HEADER--IMAGE_DATA_DIRECTORY",L"偏移大小为:"+strBoundsize);

	//13 引入表地址
	CString strImportTableAddress,strImportTableAddressSize;
	strImportTableAddress.Format(L"0x%08x/%d(十进制)",m_stExtPeHeader.DataDirectory[12].VirtualAddress,m_stExtPeHeader.DataDirectory[12].VirtualAddress);
	strImportTableAddressSize.Format(L"0x%08x/%d(十进制)",m_stExtPeHeader.DataDirectory[12].Size,m_stExtPeHeader.DataDirectory[12].Size);
	dlgDirectoryDate->AddToCtrlList(L"13 .引入表地址",L"偏移"+strImportTableAddress,L"IMAGE_OPTION_HEADER--IMAGE_DATA_DIRECTORY",L"偏移大小为:"+strImportTableAddressSize);

	//14 延迟导入描述符
	CString strDelayImportTable,strDelayImportTableSize;
	strDelayImportTable.Format(L"0x%08x/%d(十进制)",m_stExtPeHeader.DataDirectory[13].VirtualAddress,m_stExtPeHeader.DataDirectory[13].VirtualAddress);
	strDelayImportTableSize.Format(L"0x%08x/%d(十进制)",m_stExtPeHeader.DataDirectory[13].Size,m_stExtPeHeader.DataDirectory[13].Size);
	dlgDirectoryDate->AddToCtrlList(L"14 .延迟导入表描述符",L"偏移"+strDelayImportTable,L"IMAGE_OPTION_HEADER--IMAGE_DATA_DIRECTORY",L"偏移大小为:"+strDelayImportTableSize);
	
	//15 CLIheader
	CString strCLIheader,strCLIheaderSize;
	strCLIheader.Format(L"0x%08x/%d(十进制)",m_stExtPeHeader.DataDirectory[14].VirtualAddress,m_stExtPeHeader.DataDirectory[14].VirtualAddress);
	strCLIheaderSize.Format(L"0x%08x/%d(十进制)",m_stExtPeHeader.DataDirectory[14].Size,m_stExtPeHeader.DataDirectory[14].Size);
	dlgDirectoryDate->AddToCtrlList(L"15 .cormeta CLI HEADER",L"偏移"+strCLIheader,L"IMAGE_OPTION_HEADER--IMAGE_DATA_DIRECTORY",L"偏移大小为:"+strCLIheaderSize);

	//16 Reserved
	CString strReserved,strReservedSize;
	strReserved.Format(L"0x%08x/%d(十进制)",m_stExtPeHeader.DataDirectory[15].VirtualAddress,m_stExtPeHeader.DataDirectory[15].VirtualAddress);
	strReservedSize.Format(L"0x%08x/%d(十进制)",m_stExtPeHeader.DataDirectory[15].Size,m_stExtPeHeader.DataDirectory[15].Size);
	dlgDirectoryDate->AddToCtrlList(L"15.保留值",L"偏移"+strReserved,L"IMAGE_OPTION_HEADER--IMAGE_DATA_DIRECTORY",L"偏移大小为:"+strReservedSize);

}

输出数据目录;

 

把读到的内容格式化后,添加到列表控件;输出其他项的代码类似;

\

 

 

点击复制链接 与好友分享!回本站首页
相关TAG标签 源码 文件
上一篇:Git 在团队中的最佳实践--如何正确使用Git Flow
下一篇:最后一页
相关文章
图文推荐
文章
推荐
点击排行

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训
版权所有: 红黑联盟--致力于做实用的IT技术学习网站