VC编程之图解VC++版PE文件解析器源码分析
小标 2018-08-14 来源 : 阅读 1368 评论 0

摘要:本文主要向大家介绍了VC编程之图解VC++版PE文件解析器源码分析,通过具体的内容向大家展示,希望对大家学习VC编程有所帮助。

本文主要向大家介绍了VC编程之图解VC++版PE文件解析器源码分析,通过具体的内容向大家展示,希望对大家学习VC编程有所帮助。

1 Understand 分析的图表

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

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_stpeheader.numberofsections;i++) pre="" stsection_header="">

 

解析节头;读入对应内容到m_stSectionHeader;<p> </p><p> </p><p> </p><pre class="brush:java;">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;

}</pre>

<br>

RVA转换;

<p> </p>

<p> </p>

<p> </p>

<pre class="brush:java;">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);

 

}</pre>

<br>

输出数据目录;

<p> </p>

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

<p><img alt="\" src="/uploadfile/Collfiles/20160714/20160714091533616.png" style="width: 476px; height: 446px;"></p>

<p> </p>

<p> </p>

</m_stpeheader.numberofsections;i++)>

   

本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标编程语言VC/MFC频道!

本文由 @小标 发布于职坐标。未经许可,禁止转载。
喜欢 | 1 不喜欢 | 0
看完这篇文章有何感觉?已经有1人表态,100%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式AI+学习就业服务平台 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved