深入学习PE文件结构系列五自己实现一个PE解析器

admin 2026-02-10 14:15:15 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结:综合评分: 86 文章分类:,score:0}。无markdown代码块,无解释,无额外文本。>>**起草Summary:**该文章介绍了如何使用C++实现一个PE解析器。它涵盖了解析DOS头、Rich头、NT头、节头、导入表和重定位表等结构。代码支持PE32和PE32+格式。文章提供了结构体定义和解析逻辑,并输出文件详情,包括节信息和导入函数。它还包含了指向GitHub仓库的链接。>>_草稿1:_本文介绍了使用C++实现PE32和PE32+文件解析器的过程,涵盖DOS头、Rich头、NT头、节头、导入表及重定位表的解析。文章详细定义了所需的数据结构,通过读取二进制文件并校验签名来判断架构,最终输出文件的各种元数据和依赖信息。代码示例完整,适合逆向工程初学者深入理解PE格式。(约140字符-有点长,需要删减)。>>_草稿2:_文章介绍了使用C++实现PE32及PE32+解析器的方法,涵盖DOS头、Rich头、NT头、节表、导入表与重定位表的解析。文中提供了完整的数据结构定义与解析逻辑,通过读取二进制数据并校验签名来识别文件架构,最终输出文件详细结构信息。代码示例有助于理解PE文件格式底层原理。(约128字符-长度合适,涵盖关键点)。>>_检查约束:_无双引号,无换行符。>>**起草Type:**相关类别:>>*逆向分析-这是关于解析二进制文件结构。>*二进制安全-PE格式是二进制安全的核心。>*代码审计-严格来说不是审计,而是理解二进制结构,通常属于该领域。>*安全工具-它是一个工具。>*安全开发-开发安全工具。>>选择:“逆向分析”是最强的。“二进制安全”很宽泛但正确。“安全工具”也适用。让我们从列表中精确匹配:列表:渗透测试,代码审计,应急响应,漏洞分析,威胁情报,恶意软件,安全意识,实战经验,SRC活动,软文广告,产品介绍,AI安全,二进制安全,CTF,WEB安全,红队,内网渗透,IoT安全,移动安全,安全建设,安全工具,技术标准,政策法规,供应链安全,漏洞预警,解决方案,数据安全,应用安全,网络安全,办公安全,终端安全,云安全,区块链安全,安全培训,安全运营,社会工程学,安全招聘,数据泄露,车联网安全,逆向分析,爬虫,免杀,安全开发,漏洞POC,安全大事件,娱乐吃瓜,其他。>>匹配:>>1.逆向分析-直接匹配。>2.二进制安全-广泛的类别。>3.安全工具-它是一个工具。>4.代码审计-较弱,但相关。>5.安全开发-开发工具。>>顺序:逆向分析,二进制安全,安全工具,安全开发。>>**起草Score:**>>*准确性(20):代码看起来基于标准PE定义是正确的。20/20。>*深度/洞见(35):它涵盖了Rich头和标准表,这是不错的,但它是一个基础实现。对于一篇教程来说,它没有提供高深的洞见。25/35。>*结构/可读性(20):组织良好(头文件、cpp文件、解释)。18/20。>*可操作性(15):代码可直接复制粘贴/编译。15/15。>*原创性(10):PE解析器是标准练习,但实现是作者自己的。8/10。>>总计:20+25+18+15+8=86。四舍五入到86。>>**优化JSON:**Summary:文章介绍了使用C++实现PE32及PE32+解析器的方法,涵盖DOS头、Rich头、NT头、节表、导入表与重定位表的解析。文中提供了完整的数据结构定义与解析逻辑,通过读取二进制数据并校验签名来识别文件架构,最终输出文件详细结构信息。代码示例有助于理解PE文件格式底层原理。Type:逆向分析,二进制安全,安全工具,安全开发Score:86>>**最终验证:**>>*Summary长度:\~130字符。很好。>*无双引号?已检查。>*无换行符?已检查。>*Type来自列表?是。>*最多5个类型?是(4个)。>*Score是整数?是。>>让我们把Summary稍微缩短一点,以确保其更接近100字符的要求(100+/-20%->80-120)。当前长度:\~130。缩短后:文章介绍使用C++实现PE32及PE32+解析器,涵盖DOS头、Rich头、NT头、节表、导入表与重定位表解析。文中提供完整结构体定义与解析逻辑,通过读取二进制数据校验签名识别架构并输出详情。该代码示例有助于深入理解PE文件格式底层原理。长度:115字符。完美。>>Type:逆向分析,二进制安全,安全工具,安全开发Score:86>>构建JSON。{summary:文章介绍使用C++实现PE32及PE32+解析器,涵盖DOS头、Rich头、NT头、节表、导入表与重定位表解析。文中提供完整结构体定义与解析逻辑,通过读取二进制数据校验签名识别架构并输出详情。该代码示例有助于深入理解PE文件格式底层原理。,type:逆向分析,二进制安全,安全工具,安全开发


cover_image

深入学习PE文件结构系列五自己实现一个PE解析器

原创

ybdt ybdt

卡卡罗特取西经

2026年2月9日 21:33 吉林

0x1 前言

之前几篇文章讲述了Windows PE结构的各个部分,本篇文章会应用前文中的知识,借助C++实现一个PE Parser,可以解析PE32和PE32+,可以解析PE文件中的下列部分

  • • DOS Header
  • • Rich Header
  • • NT Headers
  • • Data Directory
  • • Section Headers
  • • Import Table
  • • Relocation Table

0x2 PE Parser Readme

  1. 1. 以二进制形式读取一个PE文件
  2. 2. 通过校验DOS头中的Signature和NT头中的Signature这两个固定值,判断它是否有效的PE文件
  3. 3. 通过PE可选头中的字段判断它是32位PE还是64位PE
  4. 4. 解析下列结构
  • • DOS Header
  • • Rich Header
  • • NT Headers
  • • Section Headers
  • • Import Data Directory
  • • Relocation Data Directory
  1. 5. 输出下列信息
  • • 文件名和类型
  • • DOS头中的签名以及PE文件的实际起始地址
  • • 富有头中的每一项
  • • PE文件Signature
  • • PE文件头中节的数量、PE可选头的大小
  • • PE可选头中代码节的大小、初始化数据节的大小、未初始化数据节的大小、入口点的地址、代码节的起始RVA、期望的映像基址、节对齐、文件对齐、映像文件大小、各类头的大小
  • • 数据目录中每一项的名字、RVA、大小
  • • 节头中节的名字、节在文件中的起始地址和大小、节在内存中的起始地址和大小、节的属性
  • • 导入表中每个DLL的名字、ILT和IAT、是否使用绑定导入、使用名称还是需要搜索函数、函数名称表的RVA
  • • 重定位表中每个块对应的页面RVA、块大小、块项的数量

0x3 整理用到的结构体

代码实现中会用到定义在winnt.h中的类型、常量、结构体,整理后放到winntdef.h中,代码如下

typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned long DWORD;
typedef unsigned long long QWORD;
typedef unsigned long LONG;
typedef __int64 LONGLONG;
typedef unsigned __int64 ULONGLONG;

#define ___IMAGE_NT_OPTIONAL_HDR32_MAGIC       0x10b
#define ___IMAGE_NT_OPTIONAL_HDR64_MAGIC       0x20b
#define ___IMAGE_NUMBEROF_DIRECTORY_ENTRIES    16
#define ___IMAGE_DOS_SIGNATURE                 0x5A4D

#define ___IMAGE_DIRECTORY_ENTRY_EXPORT          0
#define ___IMAGE_DIRECTORY_ENTRY_IMPORT          1
#define ___IMAGE_DIRECTORY_ENTRY_RESOURCE        2
#define ___IMAGE_DIRECTORY_ENTRY_EXCEPTION       3
#define ___IMAGE_DIRECTORY_ENTRY_SECURITY        4
#define ___IMAGE_DIRECTORY_ENTRY_BASERELOC       5
#define ___IMAGE_DIRECTORY_ENTRY_DEBUG           6
#define ___IMAGE_DIRECTORY_ENTRY_ARCHITECTURE    7
#define ___IMAGE_DIRECTORY_ENTRY_GLOBALPTR       8
#define ___IMAGE_DIRECTORY_ENTRY_TLS             9
#define ___IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG    10
#define ___IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT   11
#define ___IMAGE_DIRECTORY_ENTRY_IAT            12
#define ___IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT   13
#define ___IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR 14

#define ___IMAGE_SIZEOF_SHORT_NAME              8
#define ___IMAGE_SIZEOF_SECTION_HEADER          40

typedef struct __IMAGE_DOS_HEADER {
    WORD   e_magic;
    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;
} ___IMAGE_DOS_HEADER, * ___PIMAGE_DOS_HEADER;

typedef struct __IMAGE_DATA_DIRECTORY {
    DWORD   VirtualAddress;
    DWORD   Size;
} ___IMAGE_DATA_DIRECTORY, * ___PIMAGE_DATA_DIRECTORY;

typedef struct __IMAGE_OPTIONAL_HEADER {
    WORD    Magic;
    BYTE    MajorLinkerVersion;
    BYTE    MinorLinkerVersion;
    DWORD   SizeOfCode;
    DWORD   SizeOfInitializedData;
    DWORD   SizeOfUninitializedData;
    DWORD   AddressOfEntryPoint;
    DWORD   BaseOfCode;
    DWORD   BaseOfData;
    DWORD   ImageBase;
    DWORD   SectionAlignment;
    DWORD   FileAlignment;
    WORD    MajorOperatingSystemVersion;
    WORD    MinorOperatingSystemVersion;
    WORD    MajorImageVersion;
    WORD    MinorImageVersion;
    WORD    MajorSubsystemVersion;
    WORD    MinorSubsystemVersion;
    DWORD   Win32VersionValue;
    DWORD   SizeOfImage;
    DWORD   SizeOfHeaders;
    DWORD   CheckSum;
    WORD    Subsystem;
    WORD    DllCharacteristics;
    DWORD   SizeOfStackReserve;
    DWORD   SizeOfStackCommit;
    DWORD   SizeOfHeapReserve;
    DWORD   SizeOfHeapCommit;
    DWORD   LoaderFlags;
    DWORD   NumberOfRvaAndSizes;
    ___IMAGE_DATA_DIRECTORY DataDirectory[___IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
} ___IMAGE_OPTIONAL_HEADER32, * ___PIMAGE_OPTIONAL_HEADER32;

typedef struct __IMAGE_OPTIONAL_HEADER64 {
    WORD        Magic;
    BYTE        MajorLinkerVersion;
    BYTE        MinorLinkerVersion;
    DWORD       SizeOfCode;
    DWORD       SizeOfInitializedData;
    DWORD       SizeOfUninitializedData;
    DWORD       AddressOfEntryPoint;
    DWORD       BaseOfCode;
    ULONGLONG   ImageBase;
    DWORD       SectionAlignment;
    DWORD       FileAlignment;
    WORD        MajorOperatingSystemVersion;
    WORD        MinorOperatingSystemVersion;
    WORD        MajorImageVersion;
    WORD        MinorImageVersion;
    WORD        MajorSubsystemVersion;
    WORD        MinorSubsystemVersion;
    DWORD       Win32VersionValue;
    DWORD       SizeOfImage;
    DWORD       SizeOfHeaders;
    DWORD       CheckSum;
    WORD        Subsystem;
    WORD        DllCharacteristics;
    ULONGLONG   SizeOfStackReserve;
    ULONGLONG   SizeOfStackCommit;
    ULONGLONG   SizeOfHeapReserve;
    ULONGLONG   SizeOfHeapCommit;
    DWORD       LoaderFlags;
    DWORD       NumberOfRvaAndSizes;
    ___IMAGE_DATA_DIRECTORY DataDirectory[___IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
} ___IMAGE_OPTIONAL_HEADER64, * ___PIMAGE_OPTIONAL_HEADER64;

typedef struct __IMAGE_FILE_HEADER {
    WORD    Machine;
    WORD    NumberOfSections;
    DWORD   TimeDateStamp;
    DWORD   PointerToSymbolTable;
    DWORD   NumberOfSymbols;
    WORD    SizeOfOptionalHeader;
    WORD    Characteristics;
} ___IMAGE_FILE_HEADER, * ___PIMAGE_FILE_HEADER;

typedef struct __IMAGE_NT_HEADERS64 {
    DWORD Signature;
    ___IMAGE_FILE_HEADER FileHeader;
    ___IMAGE_OPTIONAL_HEADER64 OptionalHeader;
} ___IMAGE_NT_HEADERS64, * ___PIMAGE_NT_HEADERS64;

typedef struct __IMAGE_NT_HEADERS {
    DWORD Signature;
    ___IMAGE_FILE_HEADER FileHeader;
    ___IMAGE_OPTIONAL_HEADER32 OptionalHeader;
} ___IMAGE_NT_HEADERS32, * ___PIMAGE_NT_HEADERS32;

typedef struct __IMAGE_IMPORT_DESCRIPTOR {
    union {
        DWORD   Characteristics;
        DWORD   OriginalFirstThunk;
    } DUMMYUNIONNAME;
    DWORD   TimeDateStamp;
    DWORD   ForwarderChain;
    DWORD   Name;
    DWORD   FirstThunk;
} ___IMAGE_IMPORT_DESCRIPTOR, * ___PIMAGE_IMPORT_DESCRIPTOR;

typedef struct __IMAGE_IMPORT_BY_NAME {
    WORD    Hint;
    char   Name[100];
} ___IMAGE_IMPORT_BY_NAME, * ___PIMAGE_IMPORT_BY_NAME;

typedef struct __IMAGE_BASE_RELOCATION {
    DWORD   VirtualAddress;
    DWORD   SizeOfBlock;
} ___IMAGE_BASE_RELOCATION, * ___PIMAGE_BASE_RELOCATION;

typedef struct __IMAGE_SECTION_HEADER {
    BYTE    Name[___IMAGE_SIZEOF_SHORT_NAME];
    union {
        DWORD   PhysicalAddress;
        DWORD   VirtualSize;
    } Misc;
    DWORD   VirtualAddress;
    DWORD   SizeOfRawData;
    DWORD   PointerToRawData;
    DWORD   PointerToRelocations;
    DWORD   PointerToLinenumbers;
    WORD    NumberOfRelocations;
    WORD    NumberOfLinenumbers;
    DWORD   Characteristics;
} ___IMAGE_SECTION_HEADER, * ___PIMAGE_SECTION_HEADER;

0x4 自定义结构体

自定义一些结构体,方便解析PE文件,放到PEFILE_CUSTOM_STRUCTS.h中

#pragma once
#include "winntdef.h"

typedef struct __RICH_HEADER_INFO {
    int size;
    char* ptrToBuffer;
    int entries;
} RICH_HEADER_INFO, * PRICH_HEADER_INFO;

typedef struct __RICH_HEADER_ENTRY {
    WORD  prodID;
    WORD  buildID;
    DWORD useCount;
} RICH_HEADER_ENTRY, * PRICH_HEADER_ENTRY;

typedef struct __RICH_HEADER {
    PRICH_HEADER_ENTRY entries;
} RICH_HEADER, * PRICH_HEADER;

typedef struct __ILT_ENTRY_64 {
    union {
        DWORD ORDINAL : 16;
        DWORD HINT_NAME_TABE : 32;
    } FIELD_2;
    DWORD ORDINAL_NAME_FLAG : 1;
} ILT_ENTRY_64, * PILT_ENTRY_64;

typedef struct __ILT_ENTRY_32 {
    union {
        DWORD ORDINAL : 16;
        DWORD HINT_NAME_TABE : 32;
        DWORD ORDINAL_NAME_FLAG : 1;
    } FIELD_1;
} ILT_ENTRY_32, * PILT_ENTRY_32;

typedef struct __BASE_RELOC_ENTRY {
    WORD OFFSET : 12;
    WORD TYPE : 4;
} BASE_RELOC_ENTRY, * PBASE_RELOC_ENTRY;

0x5 代码实现

整理逻辑是PE-Parser.cpp调用PEFILE,PEFILE根据PE文件是32位还是64位,传给PE32FILE还是PE64FILE,定义在.h文件中,实现在.cpp文件中

PE-Parser.cpp

#include&nbsp;<iostream>
#include&nbsp;<fstream>
#include&nbsp;"PEFILE.h"

int main(int argc, char* argv[])
{
&nbsp; &nbsp; if (argc != 2) {
&nbsp; &nbsp; &nbsp; &nbsp; printf("Usage: %s [path to executable]\n", argv[0]);
&nbsp; &nbsp; &nbsp; &nbsp; return 1;
&nbsp; &nbsp; }

&nbsp; &nbsp; FILE* PpeFile;
&nbsp; &nbsp; fopen_s(&PpeFile, argv[1], "rb");

&nbsp; &nbsp; if (PpeFile == NULL) {
&nbsp; &nbsp; &nbsp; &nbsp; printf("Can't open file.\n");
&nbsp; &nbsp; &nbsp; &nbsp; return 1;
&nbsp; &nbsp; }

&nbsp; &nbsp; if (INITPARSE(PpeFile) == 1) {
&nbsp; &nbsp; &nbsp; &nbsp; exit(1);
&nbsp; &nbsp; }
&nbsp; &nbsp; else if (INITPARSE(PpeFile) == 32) {
&nbsp; &nbsp; &nbsp; &nbsp; PE32FILE PeFile_1(argv[1], PpeFile);
&nbsp; &nbsp; &nbsp; &nbsp; PeFile_1.PrintInfo();
&nbsp; &nbsp; &nbsp; &nbsp; fclose(PpeFile);
&nbsp; &nbsp; &nbsp; &nbsp; exit(0);
&nbsp; &nbsp; }
&nbsp; &nbsp; else if (INITPARSE(PpeFile) == 64) {
&nbsp; &nbsp; &nbsp; &nbsp; PE64FILE PeFile_1(argv[1], PpeFile);
&nbsp; &nbsp; &nbsp; &nbsp; PeFile_1.PrintInfo();
&nbsp; &nbsp; &nbsp; &nbsp; fclose(PpeFile);
&nbsp; &nbsp; &nbsp; &nbsp; exit(0);
&nbsp; &nbsp; }

&nbsp; &nbsp; return 0;
}

PEFILE.h

#pragma&nbsp;once
#include&nbsp;"PE32FILE.h"
#include&nbsp;"PE64FILE.h"

int INITPARSE(FILE* PpeFile);

PEFILE.cpp

#include&nbsp;"PEFILE.h"

// INITIAL PARSE //

int INITPARSE(FILE* PpeFile) {
&nbsp; &nbsp; ___IMAGE_DOS_HEADER TMP_DOS_HEADER;
&nbsp; &nbsp; WORD PEFILE_TYPE;

&nbsp; &nbsp; fseek(PpeFile, 0, SEEK_SET);
&nbsp; &nbsp; fread(&TMP_DOS_HEADER, sizeof(___IMAGE_DOS_HEADER), 1, PpeFile);

&nbsp; &nbsp; if (TMP_DOS_HEADER.e_magic != ___IMAGE_DOS_SIGNATURE) {
&nbsp; &nbsp; &nbsp; &nbsp; printf("Error. Not a PE file.\n");
&nbsp; &nbsp; &nbsp; &nbsp; return 1;
&nbsp; &nbsp; }

&nbsp; &nbsp; fseek(PpeFile, (TMP_DOS_HEADER.e_lfanew + sizeof(DWORD) + sizeof(___IMAGE_FILE_HEADER)), SEEK_SET);
&nbsp; &nbsp; fread(&PEFILE_TYPE, sizeof(WORD), 1, PpeFile);

&nbsp; &nbsp; if (PEFILE_TYPE == ___IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
&nbsp; &nbsp; &nbsp; &nbsp; return 32;
&nbsp; &nbsp; }
&nbsp; &nbsp; else if (PEFILE_TYPE == ___IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
&nbsp; &nbsp; &nbsp; &nbsp; return 64;
&nbsp; &nbsp; }
&nbsp; &nbsp; else {
&nbsp; &nbsp; &nbsp; &nbsp; printf("Error while parsing IMAGE_OPTIONAL_HEADER.Magic. Unknown Type.\n");
&nbsp; &nbsp; &nbsp; &nbsp; return 1;
&nbsp; &nbsp; }

}

PE32FILE.h

#pragma&nbsp;once
#include&nbsp;"winntdef.h"
#include&nbsp;"PEFILE_CUSTOM_STRUCTS.h"
#include&nbsp;<string>

class PE32FILE
{
public:
&nbsp; &nbsp; PE32FILE(char* _NAME, FILE* Ppefile);

&nbsp; &nbsp; void PrintInfo();

private:
&nbsp; &nbsp; char* NAME;
&nbsp; &nbsp; FILE* Ppefile;
&nbsp; &nbsp; int _import_directory_count, _import_directory_size;
&nbsp; &nbsp; int _basreloc_directory_count;

&nbsp; &nbsp; // HEADERS
&nbsp; &nbsp; ___IMAGE_DOS_HEADER &nbsp; &nbsp; PEFILE_DOS_HEADER;
&nbsp; &nbsp; ___IMAGE_NT_HEADERS32 &nbsp; PEFILE_NT_HEADERS;

&nbsp; &nbsp; // DOS HEADER
&nbsp; &nbsp; DWORD PEFILE_DOS_HEADER_EMAGIC;
&nbsp; &nbsp; LONG &nbsp;PEFILE_DOS_HEADER_LFANEW;

&nbsp; &nbsp; // RICH HEADER
&nbsp; &nbsp; RICH_HEADER_INFO PEFILE_RICH_HEADER_INFO;
&nbsp; &nbsp; RICH_HEADER PEFILE_RICH_HEADER;

&nbsp; &nbsp; // NT_HEADERS.Signature
&nbsp; &nbsp; DWORD PEFILE_NT_HEADERS_SIGNATURE;

&nbsp; &nbsp; // NT_HEADERS.FileHeader
&nbsp; &nbsp; WORD PEFILE_NT_HEADERS_FILE_HEADER_MACHINE;
&nbsp; &nbsp; WORD PEFILE_NT_HEADERS_FILE_HEADER_NUMBER0F_SECTIONS;
&nbsp; &nbsp; WORD PEFILE_NT_HEADERS_FILE_HEADER_SIZEOF_OPTIONAL_HEADER;

&nbsp; &nbsp; // NT_HEADERS.OptionalHeader
&nbsp; &nbsp; DWORD PEFILE_NT_HEADERS_OPTIONAL_HEADER_MAGIC;
&nbsp; &nbsp; DWORD PEFILE_NT_HEADERS_OPTIONAL_HEADER_SIZEOF_CODE;
&nbsp; &nbsp; DWORD PEFILE_NT_HEADERS_OPTIONAL_HEADER_SIZEOF_INITIALIZED_DATA;
&nbsp; &nbsp; DWORD PEFILE_NT_HEADERS_OPTIONAL_HEADER_SIZEOF_UNINITIALIZED_DATA;
&nbsp; &nbsp; DWORD PEFILE_NT_HEADERS_OPTIONAL_HEADER_ADDRESSOF_ENTRYPOINT;
&nbsp; &nbsp; DWORD PEFILE_NT_HEADERS_OPTIONAL_HEADER_BASEOF_CODE;
&nbsp; &nbsp; ULONGLONG PEFILE_NT_HEADERS_OPTIONAL_HEADER_IMAGEBASE;
&nbsp; &nbsp; DWORD PEFILE_NT_HEADERS_OPTIONAL_HEADER_SECTION_ALIGNMENT;
&nbsp; &nbsp; DWORD PEFILE_NT_HEADERS_OPTIONAL_HEADER_FILE_ALIGNMENT;
&nbsp; &nbsp; DWORD PEFILE_NT_HEADERS_OPTIONAL_HEADER_SIZEOF_IMAGE;
&nbsp; &nbsp; DWORD PEFILE_NT_HEADERS_OPTIONAL_HEADER_SIZEOF_HEADERS;

&nbsp; &nbsp; ___IMAGE_DATA_DIRECTORY PEFILE_EXPORT_DIRECTORY;
&nbsp; &nbsp; ___IMAGE_DATA_DIRECTORY PEFILE_IMPORT_DIRECTORY;
&nbsp; &nbsp; ___IMAGE_DATA_DIRECTORY PEFILE_RESOURCE_DIRECTORY;
&nbsp; &nbsp; ___IMAGE_DATA_DIRECTORY PEFILE_EXCEPTION_DIRECTORY;
&nbsp; &nbsp; ___IMAGE_DATA_DIRECTORY PEFILE_SECURITY_DIRECTORY;
&nbsp; &nbsp; ___IMAGE_DATA_DIRECTORY PEFILE_BASERELOC_DIRECTORY;
&nbsp; &nbsp; ___IMAGE_DATA_DIRECTORY PEFILE_DEBUG_DIRECTORY;
&nbsp; &nbsp; ___IMAGE_DATA_DIRECTORY PEFILE_ARCHITECTURE_DIRECTORY;
&nbsp; &nbsp; ___IMAGE_DATA_DIRECTORY PEFILE_GLOBALPTR_DIRECTORY;
&nbsp; &nbsp; ___IMAGE_DATA_DIRECTORY PEFILE_TLS_DIRECTORY;
&nbsp; &nbsp; ___IMAGE_DATA_DIRECTORY PEFILE_LOAD_CONFIG_DIRECTORY;
&nbsp; &nbsp; ___IMAGE_DATA_DIRECTORY PEFILE_BOUND_IMPORT_DIRECTORY;
&nbsp; &nbsp; ___IMAGE_DATA_DIRECTORY PEFILE_IAT_DIRECTORY;
&nbsp; &nbsp; ___IMAGE_DATA_DIRECTORY PEFILE_DELAY_IMPORT_DIRECTORY;
&nbsp; &nbsp; ___IMAGE_DATA_DIRECTORY PEFILE_COM_DESCRIPTOR_DIRECTORY;

&nbsp; &nbsp; // SECTION HEADERS
&nbsp; &nbsp; ___PIMAGE_SECTION_HEADER PEFILE_SECTION_HEADERS;

&nbsp; &nbsp; // IMPORT TABLE
&nbsp; &nbsp; ___PIMAGE_IMPORT_DESCRIPTOR PEFILE_IMPORT_TABLE;

&nbsp; &nbsp; // BASE RELOCATION TABLE
&nbsp; &nbsp; ___PIMAGE_BASE_RELOCATION PEFILE_BASERELOC_TABLE;

&nbsp; &nbsp; // FUNCTIONS

&nbsp; &nbsp; // ADDRESS RESOLVERS
&nbsp; &nbsp; int &nbsp;locate(DWORD VA);
&nbsp; &nbsp; DWORD resolve(DWORD VA, int index);

&nbsp; &nbsp; // PARSERS
&nbsp; &nbsp; void ParseFile();
&nbsp; &nbsp; void ParseDOSHeader();
&nbsp; &nbsp; void ParseNTHeaders();
&nbsp; &nbsp; void ParseSectionHeaders();
&nbsp; &nbsp; void ParseImportDirectory();
&nbsp; &nbsp; void ParseBaseReloc();
&nbsp; &nbsp; void ParseRichHeader();

&nbsp; &nbsp; // PRINT INFO
&nbsp; &nbsp; void PrintFileInfo();
&nbsp; &nbsp; void PrintDOSHeaderInfo();
&nbsp; &nbsp; void PrintRichHeaderInfo();
&nbsp; &nbsp; void PrintNTHeadersInfo();
&nbsp; &nbsp; void PrintSectionHeadersInfo();
&nbsp; &nbsp; void PrintImportTableInfo();
&nbsp; &nbsp; void PrintBaseRelocationsInfo();
};

PE32FILE.cpp

#include&nbsp;"PE32FILE.h"

// CONSTRUCTOR
PE32FILE::PE32FILE(char* _NAME, FILE* _Ppefile) {

&nbsp; &nbsp; NAME = _NAME;
&nbsp; &nbsp; Ppefile = _Ppefile;

&nbsp; &nbsp; ParseFile();

}

// ADDRESS RESOLVERS
int PE32FILE::locate(DWORD VA) {

&nbsp; &nbsp; int index;

&nbsp; &nbsp; for (int i = 0; i < PEFILE_NT_HEADERS_FILE_HEADER_NUMBER0F_SECTIONS; i++) {
&nbsp; &nbsp; &nbsp; &nbsp; if (VA >= PEFILE_SECTION_HEADERS[i].VirtualAddress
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; && VA < (PEFILE_SECTION_HEADERS[i].VirtualAddress + PEFILE_SECTION_HEADERS[i].Misc.VirtualSize)) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; index = i;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;
&nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; }
&nbsp; &nbsp; return index;

}

DWORD PE32FILE::resolve(DWORD VA, int index) {

&nbsp; &nbsp; return (VA - PEFILE_SECTION_HEADERS[index].VirtualAddress) + PEFILE_SECTION_HEADERS[index].PointerToRawData;

}

// PARSERS
void PE32FILE::ParseDOSHeader() {

&nbsp; &nbsp; fseek(Ppefile, 0, SEEK_SET);
&nbsp; &nbsp; fread(&PEFILE_DOS_HEADER, sizeof(___IMAGE_DOS_HEADER), 1, Ppefile);

&nbsp; &nbsp; PEFILE_DOS_HEADER_EMAGIC = PEFILE_DOS_HEADER.e_magic;
&nbsp; &nbsp; PEFILE_DOS_HEADER_LFANEW = PEFILE_DOS_HEADER.e_lfanew;

}

void PE32FILE::ParseNTHeaders() {

&nbsp; &nbsp; fseek(Ppefile, PEFILE_DOS_HEADER.e_lfanew, SEEK_SET);
&nbsp; &nbsp; fread(&PEFILE_NT_HEADERS, sizeof(PEFILE_NT_HEADERS), 1, Ppefile);

&nbsp; &nbsp; PEFILE_NT_HEADERS_SIGNATURE = PEFILE_NT_HEADERS.Signature;

&nbsp; &nbsp; PEFILE_NT_HEADERS_FILE_HEADER_MACHINE = PEFILE_NT_HEADERS.FileHeader.Machine;
&nbsp; &nbsp; PEFILE_NT_HEADERS_FILE_HEADER_NUMBER0F_SECTIONS = PEFILE_NT_HEADERS.FileHeader.NumberOfSections;
&nbsp; &nbsp; PEFILE_NT_HEADERS_FILE_HEADER_SIZEOF_OPTIONAL_HEADER = PEFILE_NT_HEADERS.FileHeader.SizeOfOptionalHeader;

&nbsp; &nbsp; PEFILE_NT_HEADERS_OPTIONAL_HEADER_MAGIC = PEFILE_NT_HEADERS.OptionalHeader.Magic;
&nbsp; &nbsp; PEFILE_NT_HEADERS_OPTIONAL_HEADER_SIZEOF_CODE = PEFILE_NT_HEADERS.OptionalHeader.SizeOfCode;
&nbsp; &nbsp; PEFILE_NT_HEADERS_OPTIONAL_HEADER_SIZEOF_INITIALIZED_DATA = PEFILE_NT_HEADERS.OptionalHeader.SizeOfInitializedData;
&nbsp; &nbsp; PEFILE_NT_HEADERS_OPTIONAL_HEADER_SIZEOF_UNINITIALIZED_DATA = PEFILE_NT_HEADERS.OptionalHeader.SizeOfUninitializedData;
&nbsp; &nbsp; PEFILE_NT_HEADERS_OPTIONAL_HEADER_ADDRESSOF_ENTRYPOINT = PEFILE_NT_HEADERS.OptionalHeader.AddressOfEntryPoint;
&nbsp; &nbsp; PEFILE_NT_HEADERS_OPTIONAL_HEADER_BASEOF_CODE = PEFILE_NT_HEADERS.OptionalHeader.BaseOfCode;
&nbsp; &nbsp; PEFILE_NT_HEADERS_OPTIONAL_HEADER_IMAGEBASE = PEFILE_NT_HEADERS.OptionalHeader.ImageBase;
&nbsp; &nbsp; PEFILE_NT_HEADERS_OPTIONAL_HEADER_SECTION_ALIGNMENT = PEFILE_NT_HEADERS.OptionalHeader.SectionAlignment;
&nbsp; &nbsp; PEFILE_NT_HEADERS_OPTIONAL_HEADER_FILE_ALIGNMENT = PEFILE_NT_HEADERS.OptionalHeader.FileAlignment;
&nbsp; &nbsp; PEFILE_NT_HEADERS_OPTIONAL_HEADER_SIZEOF_IMAGE = PEFILE_NT_HEADERS.OptionalHeader.SizeOfImage;
&nbsp; &nbsp; PEFILE_NT_HEADERS_OPTIONAL_HEADER_SIZEOF_HEADERS = PEFILE_NT_HEADERS.OptionalHeader.SizeOfHeaders;

&nbsp; &nbsp; PEFILE_EXPORT_DIRECTORY = PEFILE_NT_HEADERS.OptionalHeader.DataDirectory[___IMAGE_DIRECTORY_ENTRY_EXPORT];
&nbsp; &nbsp; PEFILE_IMPORT_DIRECTORY = PEFILE_NT_HEADERS.OptionalHeader.DataDirectory[___IMAGE_DIRECTORY_ENTRY_IMPORT];
&nbsp; &nbsp; PEFILE_RESOURCE_DIRECTORY = PEFILE_NT_HEADERS.OptionalHeader.DataDirectory[___IMAGE_DIRECTORY_ENTRY_RESOURCE];
&nbsp; &nbsp; PEFILE_EXCEPTION_DIRECTORY = PEFILE_NT_HEADERS.OptionalHeader.DataDirectory[___IMAGE_DIRECTORY_ENTRY_EXCEPTION];
&nbsp; &nbsp; PEFILE_SECURITY_DIRECTORY = PEFILE_NT_HEADERS.OptionalHeader.DataDirectory[___IMAGE_DIRECTORY_ENTRY_SECURITY];
&nbsp; &nbsp; PEFILE_BASERELOC_DIRECTORY = PEFILE_NT_HEADERS.OptionalHeader.DataDirectory[___IMAGE_DIRECTORY_ENTRY_BASERELOC];
&nbsp; &nbsp; PEFILE_DEBUG_DIRECTORY = PEFILE_NT_HEADERS.OptionalHeader.DataDirectory[___IMAGE_DIRECTORY_ENTRY_DEBUG];
&nbsp; &nbsp; PEFILE_ARCHITECTURE_DIRECTORY = PEFILE_NT_HEADERS.OptionalHeader.DataDirectory[___IMAGE_DIRECTORY_ENTRY_ARCHITECTURE];
&nbsp; &nbsp; PEFILE_GLOBALPTR_DIRECTORY = PEFILE_NT_HEADERS.OptionalHeader.DataDirectory[___IMAGE_DIRECTORY_ENTRY_GLOBALPTR];
&nbsp; &nbsp; PEFILE_TLS_DIRECTORY = PEFILE_NT_HEADERS.OptionalHeader.DataDirectory[___IMAGE_DIRECTORY_ENTRY_TLS];
&nbsp; &nbsp; PEFILE_LOAD_CONFIG_DIRECTORY = PEFILE_NT_HEADERS.OptionalHeader.DataDirectory[___IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG];
&nbsp; &nbsp; PEFILE_BOUND_IMPORT_DIRECTORY = PEFILE_NT_HEADERS.OptionalHeader.DataDirectory[___IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT];
&nbsp; &nbsp; PEFILE_IAT_DIRECTORY = PEFILE_NT_HEADERS.OptionalHeader.DataDirectory[___IMAGE_DIRECTORY_ENTRY_IAT];
&nbsp; &nbsp; PEFILE_DELAY_IMPORT_DIRECTORY = PEFILE_NT_HEADERS.OptionalHeader.DataDirectory[___IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT];
&nbsp; &nbsp; PEFILE_COM_DESCRIPTOR_DIRECTORY = PEFILE_NT_HEADERS.OptionalHeader.DataDirectory[___IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR];

}

void PE32FILE::ParseSectionHeaders() {

&nbsp; &nbsp; PEFILE_SECTION_HEADERS = new ___IMAGE_SECTION_HEADER[PEFILE_NT_HEADERS_FILE_HEADER_NUMBER0F_SECTIONS];
&nbsp; &nbsp; for (int i = 0; i < PEFILE_NT_HEADERS_FILE_HEADER_NUMBER0F_SECTIONS; i++) {
&nbsp; &nbsp; &nbsp; &nbsp; int offset = (PEFILE_DOS_HEADER.e_lfanew + sizeof(PEFILE_NT_HEADERS)) + (i * ___IMAGE_SIZEOF_SECTION_HEADER);
&nbsp; &nbsp; &nbsp; &nbsp; fseek(Ppefile, offset, SEEK_SET);
&nbsp; &nbsp; &nbsp; &nbsp; fread(&PEFILE_SECTION_HEADERS[i], ___IMAGE_SIZEOF_SECTION_HEADER, 1, Ppefile);
&nbsp; &nbsp; }

}

void PE32FILE::ParseImportDirectory() {

&nbsp; &nbsp; DWORD _import_directory_address = resolve(PEFILE_IMPORT_DIRECTORY.VirtualAddress, locate(PEFILE_IMPORT_DIRECTORY.VirtualAddress));
&nbsp; &nbsp; _import_directory_count = 0;

&nbsp; &nbsp; while (true) {
&nbsp; &nbsp; &nbsp; &nbsp; ___IMAGE_IMPORT_DESCRIPTOR tmp;
&nbsp; &nbsp; &nbsp; &nbsp; int offset = (_import_directory_count * sizeof(___IMAGE_IMPORT_DESCRIPTOR)) + _import_directory_address;
&nbsp; &nbsp; &nbsp; &nbsp; fseek(Ppefile, offset, SEEK_SET);
&nbsp; &nbsp; &nbsp; &nbsp; fread(&tmp, sizeof(___IMAGE_IMPORT_DESCRIPTOR), 1, Ppefile);

&nbsp; &nbsp; &nbsp; &nbsp; if (tmp.Name == 0x00000000 && tmp.FirstThunk == 0x00000000) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; _import_directory_count -= 1;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; _import_directory_size = _import_directory_count * sizeof(___IMAGE_IMPORT_DESCRIPTOR);
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;
&nbsp; &nbsp; &nbsp; &nbsp; }

&nbsp; &nbsp; &nbsp; &nbsp; _import_directory_count++;
&nbsp; &nbsp; }

&nbsp; &nbsp; PEFILE_IMPORT_TABLE = new ___IMAGE_IMPORT_DESCRIPTOR[_import_directory_count];

&nbsp; &nbsp; for (int i = 0; i < _import_directory_count; i++) {
&nbsp; &nbsp; &nbsp; &nbsp; int offset = (i * sizeof(___IMAGE_IMPORT_DESCRIPTOR)) + _import_directory_address;
&nbsp; &nbsp; &nbsp; &nbsp; fseek(Ppefile, offset, SEEK_SET);
&nbsp; &nbsp; &nbsp; &nbsp; fread(&PEFILE_IMPORT_TABLE[i], sizeof(___IMAGE_IMPORT_DESCRIPTOR), 1, Ppefile);
&nbsp; &nbsp; }

}

void PE32FILE::ParseBaseReloc() {

&nbsp; &nbsp; DWORD _basereloc_directory_address = resolve(PEFILE_BASERELOC_DIRECTORY.VirtualAddress, locate(PEFILE_BASERELOC_DIRECTORY.VirtualAddress));
&nbsp; &nbsp; _basreloc_directory_count = 0;
&nbsp; &nbsp; int _basereloc_size_counter = 0;

&nbsp; &nbsp; while (true) {
&nbsp; &nbsp; &nbsp; &nbsp; ___IMAGE_BASE_RELOCATION tmp;

&nbsp; &nbsp; &nbsp; &nbsp; int offset = (_basereloc_size_counter + _basereloc_directory_address);

&nbsp; &nbsp; &nbsp; &nbsp; fseek(Ppefile, offset, SEEK_SET);
&nbsp; &nbsp; &nbsp; &nbsp; fread(&tmp, sizeof(___IMAGE_BASE_RELOCATION), 1, Ppefile);

&nbsp; &nbsp; &nbsp; &nbsp; if (tmp.VirtualAddress == 0x00000000 &&
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; tmp.SizeOfBlock == 0x00000000) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;
&nbsp; &nbsp; &nbsp; &nbsp; }

&nbsp; &nbsp; &nbsp; &nbsp; _basreloc_directory_count++;
&nbsp; &nbsp; &nbsp; &nbsp; _basereloc_size_counter += tmp.SizeOfBlock;
&nbsp; &nbsp; }

&nbsp; &nbsp; PEFILE_BASERELOC_TABLE = new ___IMAGE_BASE_RELOCATION[_basreloc_directory_count];

&nbsp; &nbsp; _basereloc_size_counter = 0;

&nbsp; &nbsp; for (int i = 0; i < _basreloc_directory_count; i++) {
&nbsp; &nbsp; &nbsp; &nbsp; int offset = _basereloc_directory_address + _basereloc_size_counter;
&nbsp; &nbsp; &nbsp; &nbsp; fseek(Ppefile, offset, SEEK_SET);
&nbsp; &nbsp; &nbsp; &nbsp; fread(&PEFILE_BASERELOC_TABLE[i], sizeof(___IMAGE_BASE_RELOCATION), 1, Ppefile);
&nbsp; &nbsp; &nbsp; &nbsp; _basereloc_size_counter += PEFILE_BASERELOC_TABLE[i].SizeOfBlock;
&nbsp; &nbsp; }

}

void PE32FILE::ParseRichHeader() {

&nbsp; &nbsp; char* dataPtr = new char[PEFILE_DOS_HEADER_LFANEW];
&nbsp; &nbsp; fseek(Ppefile, 0, SEEK_SET);
&nbsp; &nbsp; fread(dataPtr, PEFILE_DOS_HEADER_LFANEW, 1, Ppefile);

&nbsp; &nbsp; int index_ = 0;

&nbsp; &nbsp; for (int i = 0; i <= PEFILE_DOS_HEADER_LFANEW; i++) {
&nbsp; &nbsp; &nbsp; &nbsp; if (dataPtr[i] == 0x52 && dataPtr[i + 1] == 0x69) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; index_ = i;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;
&nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; }

&nbsp; &nbsp; if (index_ == 0) {
&nbsp; &nbsp; &nbsp; &nbsp; printf("Error while parsing Rich Header.");
&nbsp; &nbsp; &nbsp; &nbsp; PEFILE_RICH_HEADER_INFO.entries = 0;
&nbsp; &nbsp; &nbsp; &nbsp; return;
&nbsp; &nbsp; }

&nbsp; &nbsp; char key[4];
&nbsp; &nbsp; memcpy(key, dataPtr + (index_ + 4), 4);

&nbsp; &nbsp; int indexpointer = index_ - 4;
&nbsp; &nbsp; int RichHeaderSize = 0;

&nbsp; &nbsp; while (true) {
&nbsp; &nbsp; &nbsp; &nbsp; char tmpchar[4];
&nbsp; &nbsp; &nbsp; &nbsp; memcpy(tmpchar, dataPtr + indexpointer, 4);

&nbsp; &nbsp; &nbsp; &nbsp; for (int i = 0; i < 4; i++) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; tmpchar[i] = tmpchar[i] ^ key[i];
&nbsp; &nbsp; &nbsp; &nbsp; }

&nbsp; &nbsp; &nbsp; &nbsp; indexpointer -= 4;
&nbsp; &nbsp; &nbsp; &nbsp; RichHeaderSize += 4;

&nbsp; &nbsp; &nbsp; &nbsp; if (tmpchar[1] = 0x61 && tmpchar[0] == 0x44) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;
&nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; }

&nbsp; &nbsp; char* RichHeaderPtr = new char[RichHeaderSize];
&nbsp; &nbsp; memcpy(RichHeaderPtr, dataPtr + (index_ - RichHeaderSize), RichHeaderSize);

&nbsp; &nbsp; for (int i = 0; i < RichHeaderSize; i += 4) {

&nbsp; &nbsp; &nbsp; &nbsp; for (int x = 0; x < 4; x++) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; RichHeaderPtr[i + x] = RichHeaderPtr[i + x] ^ key[x];
&nbsp; &nbsp; &nbsp; &nbsp; }

&nbsp; &nbsp; }

&nbsp; &nbsp; PEFILE_RICH_HEADER_INFO.size = RichHeaderSize;
&nbsp; &nbsp; PEFILE_RICH_HEADER_INFO.ptrToBuffer = RichHeaderPtr;
&nbsp; &nbsp; PEFILE_RICH_HEADER_INFO.entries = (RichHeaderSize - 16) / 8;

&nbsp; &nbsp; delete[] dataPtr;

&nbsp; &nbsp; PEFILE_RICH_HEADER.entries = new RICH_HEADER_ENTRY[PEFILE_RICH_HEADER_INFO.entries];

&nbsp; &nbsp; for (int i = 16; i < RichHeaderSize; i += 8) {
&nbsp; &nbsp; &nbsp; &nbsp; WORD PRODID = (uint16_t)((unsigned char)RichHeaderPtr[i + 3] << 8) | (unsigned char)RichHeaderPtr[i + 2];
&nbsp; &nbsp; &nbsp; &nbsp; WORD BUILDID = (uint16_t)((unsigned char)RichHeaderPtr[i + 1] << 8) | (unsigned char)RichHeaderPtr[i];
&nbsp; &nbsp; &nbsp; &nbsp; DWORD USECOUNT = (uint32_t)((unsigned char)RichHeaderPtr[i + 7] << 24) | (unsigned char)RichHeaderPtr[i + 6] << 16 | (unsigned char)RichHeaderPtr[i + 5] << 8 | (unsigned char)RichHeaderPtr[i + 4];
&nbsp; &nbsp; &nbsp; &nbsp; PEFILE_RICH_HEADER.entries[(i / 8) - 2] = {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; PRODID,
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; BUILDID,
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; USECOUNT
&nbsp; &nbsp; &nbsp; &nbsp; };

&nbsp; &nbsp; &nbsp; &nbsp; if (i + 8 >= RichHeaderSize) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; PEFILE_RICH_HEADER.entries[(i / 8) - 1] = { 0x0000, 0x0000, 0x00000000 };
&nbsp; &nbsp; &nbsp; &nbsp; }

&nbsp; &nbsp; }

&nbsp; &nbsp; delete[] PEFILE_RICH_HEADER_INFO.ptrToBuffer;

}

// PRINT INFO
void PE32FILE::PrintFileInfo() {

&nbsp; &nbsp; printf(" FILE: %s\n", NAME);
&nbsp; &nbsp; printf(" TYPE: 0x%X (PE32)\n", PEFILE_NT_HEADERS_OPTIONAL_HEADER_MAGIC);

}

void PE32FILE::PrintDOSHeaderInfo() {

&nbsp; &nbsp; printf(" DOS HEADER:\n");
&nbsp; &nbsp; printf(" -----------\n\n");

&nbsp; &nbsp; printf(" Magic: 0x%X\n", PEFILE_DOS_HEADER_EMAGIC);
&nbsp; &nbsp; printf(" File address of new exe header: 0x%X\n", PEFILE_DOS_HEADER_LFANEW);

}

void PE32FILE::PrintRichHeaderInfo() {

&nbsp; &nbsp; printf(" RICH HEADER:\n");
&nbsp; &nbsp; printf(" ------------\n\n");

&nbsp; &nbsp; for (int i = 0; i < PEFILE_RICH_HEADER_INFO.entries; i++) {
&nbsp; &nbsp; &nbsp; &nbsp; printf(" 0x%X 0x%X 0x%X: %d.%d.%d\n",
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; PEFILE_RICH_HEADER.entries[i].buildID,
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; PEFILE_RICH_HEADER.entries[i].prodID,
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; PEFILE_RICH_HEADER.entries[i].useCount,
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; PEFILE_RICH_HEADER.entries[i].buildID,
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; PEFILE_RICH_HEADER.entries[i].prodID,
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; PEFILE_RICH_HEADER.entries[i].useCount);
&nbsp; &nbsp; }

}

void PE32FILE::PrintNTHeadersInfo() {

&nbsp; &nbsp; printf(" NT HEADERS:\n");
&nbsp; &nbsp; printf(" -----------\n\n");

&nbsp; &nbsp; printf(" PE Signature: 0x%X\n", PEFILE_NT_HEADERS_SIGNATURE);

&nbsp; &nbsp; printf("\n File Header:\n\n");
&nbsp; &nbsp; printf(" &nbsp; Machine: 0x%X\n", PEFILE_NT_HEADERS_FILE_HEADER_MACHINE);
&nbsp; &nbsp; printf(" &nbsp; Number of sections: 0x%X\n", PEFILE_NT_HEADERS_FILE_HEADER_NUMBER0F_SECTIONS);
&nbsp; &nbsp; printf(" &nbsp; Size of optional header: 0x%X\n", PEFILE_NT_HEADERS_FILE_HEADER_SIZEOF_OPTIONAL_HEADER);

&nbsp; &nbsp; printf("\n Optional Header:\n\n");
&nbsp; &nbsp; printf(" &nbsp; Magic: 0x%X\n", PEFILE_NT_HEADERS_OPTIONAL_HEADER_MAGIC);
&nbsp; &nbsp; printf(" &nbsp; Size of code section: 0x%X\n", PEFILE_NT_HEADERS_OPTIONAL_HEADER_SIZEOF_CODE);
&nbsp; &nbsp; printf(" &nbsp; Size of initialized data: 0x%X\n", PEFILE_NT_HEADERS_OPTIONAL_HEADER_SIZEOF_INITIALIZED_DATA);
&nbsp; &nbsp; printf(" &nbsp; Size of uninitialized data: 0x%X\n", PEFILE_NT_HEADERS_OPTIONAL_HEADER_SIZEOF_UNINITIALIZED_DATA);
&nbsp; &nbsp; printf(" &nbsp; Address of entry point: 0x%X\n", PEFILE_NT_HEADERS_OPTIONAL_HEADER_ADDRESSOF_ENTRYPOINT);
&nbsp; &nbsp; printf(" &nbsp; RVA of start of code section: 0x%X\n", PEFILE_NT_HEADERS_OPTIONAL_HEADER_BASEOF_CODE);
&nbsp; &nbsp; printf(" &nbsp; Desired image base: 0x%X\n", PEFILE_NT_HEADERS_OPTIONAL_HEADER_IMAGEBASE);
&nbsp; &nbsp; printf(" &nbsp; Section alignment: 0x%X\n", PEFILE_NT_HEADERS_OPTIONAL_HEADER_SECTION_ALIGNMENT);
&nbsp; &nbsp; printf(" &nbsp; File alignment: 0x%X\n", PEFILE_NT_HEADERS_OPTIONAL_HEADER_FILE_ALIGNMENT);
&nbsp; &nbsp; printf(" &nbsp; Size of image: 0x%X\n", PEFILE_NT_HEADERS_OPTIONAL_HEADER_SIZEOF_IMAGE);
&nbsp; &nbsp; printf(" &nbsp; Size of headers: 0x%X\n", PEFILE_NT_HEADERS_OPTIONAL_HEADER_SIZEOF_HEADERS);

&nbsp; &nbsp; printf("\n Data Directories:\n");
&nbsp; &nbsp; printf("\n &nbsp; * Export Directory:\n");
&nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; RVA: 0x%X\n", PEFILE_EXPORT_DIRECTORY.VirtualAddress);
&nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; Size: 0x%X\n", PEFILE_EXPORT_DIRECTORY.Size);

&nbsp; &nbsp; printf("\n &nbsp; * Import Directory:\n");
&nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; RVA: 0x%X\n", PEFILE_IMPORT_DIRECTORY.VirtualAddress);
&nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; Size: 0x%X\n", PEFILE_IMPORT_DIRECTORY.Size);

&nbsp; &nbsp; printf("\n &nbsp; * Resource Directory:\n");
&nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; RVA: 0x%X\n", PEFILE_RESOURCE_DIRECTORY.VirtualAddress);
&nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; Size: 0x%X\n", PEFILE_RESOURCE_DIRECTORY.Size);

&nbsp; &nbsp; printf("\n &nbsp; * Exception Directory:\n");
&nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; RVA: 0x%X\n", PEFILE_EXCEPTION_DIRECTORY.VirtualAddress);
&nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; Size: 0x%X\n", PEFILE_EXCEPTION_DIRECTORY.Size);

&nbsp; &nbsp; printf("\n &nbsp; * Security Directory:\n");
&nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; RVA: 0x%X\n", PEFILE_SECURITY_DIRECTORY.VirtualAddress);
&nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; Size: 0x%X\n", PEFILE_SECURITY_DIRECTORY.Size);

&nbsp; &nbsp; printf("\n &nbsp; * Base Relocation Table:\n");
&nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; RVA: 0x%X\n", PEFILE_BASERELOC_DIRECTORY.VirtualAddress);
&nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; Size: 0x%X\n", PEFILE_BASERELOC_DIRECTORY.Size);

&nbsp; &nbsp; printf("\n &nbsp; * Debug Directory:\n");
&nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; RVA: 0x%X\n", PEFILE_DEBUG_DIRECTORY.VirtualAddress);
&nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; Size: 0x%X\n", PEFILE_DEBUG_DIRECTORY.Size);

&nbsp; &nbsp; printf("\n &nbsp; * Architecture Specific Data:\n");
&nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; RVA: 0x%X\n", PEFILE_ARCHITECTURE_DIRECTORY.VirtualAddress);
&nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; Size: 0x%X\n", PEFILE_ARCHITECTURE_DIRECTORY.Size);

&nbsp; &nbsp; printf("\n &nbsp; * RVA of GlobalPtr:\n");
&nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; RVA: 0x%X\n", PEFILE_GLOBALPTR_DIRECTORY.VirtualAddress);
&nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; Size: 0x%X\n", PEFILE_GLOBALPTR_DIRECTORY.Size);

&nbsp; &nbsp; printf("\n &nbsp; * TLS Directory:\n");
&nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; RVA: 0x%X\n", PEFILE_TLS_DIRECTORY.VirtualAddress);
&nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; Size: 0x%X\n", PEFILE_TLS_DIRECTORY.Size);

&nbsp; &nbsp; printf("\n &nbsp; * Load Configuration Directory:\n");
&nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; RVA: 0x%X\n", PEFILE_LOAD_CONFIG_DIRECTORY.VirtualAddress);
&nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; Size: 0x%X\n", PEFILE_LOAD_CONFIG_DIRECTORY.Size);

&nbsp; &nbsp; printf("\n &nbsp; * Bound Import Directory:\n");
&nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; RVA: 0x%X\n", PEFILE_BOUND_IMPORT_DIRECTORY.VirtualAddress);
&nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; Size: 0x%X\n", PEFILE_BOUND_IMPORT_DIRECTORY.Size);

&nbsp; &nbsp; printf("\n &nbsp; * Import Address Table:\n");
&nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; RVA: 0x%X\n", PEFILE_IAT_DIRECTORY.VirtualAddress);
&nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; Size: 0x%X\n", PEFILE_IAT_DIRECTORY.Size);

&nbsp; &nbsp; printf("\n &nbsp; * Delay Load Import Descriptors:\n");
&nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; RVA: 0x%X\n", PEFILE_DELAY_IMPORT_DIRECTORY.VirtualAddress);
&nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; Size: 0x%X\n", PEFILE_DELAY_IMPORT_DIRECTORY.Size);

&nbsp; &nbsp; printf("\n &nbsp; * COM Runtime Descriptor:\n");
&nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; RVA: 0x%X\n", PEFILE_COM_DESCRIPTOR_DIRECTORY.VirtualAddress);
&nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; Size: 0x%X\n", PEFILE_COM_DESCRIPTOR_DIRECTORY.Size);

}

void PE32FILE::PrintSectionHeadersInfo() {

&nbsp; &nbsp; printf(" SECTION HEADERS:\n");
&nbsp; &nbsp; printf(" ----------------\n\n");

&nbsp; &nbsp; for (int i = 0; i < PEFILE_NT_HEADERS_FILE_HEADER_NUMBER0F_SECTIONS; i++) {
&nbsp; &nbsp; &nbsp; &nbsp; printf(" &nbsp; * %.8s:\n", PEFILE_SECTION_HEADERS[i].Name);
&nbsp; &nbsp; &nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; &nbsp;VirtualAddress: 0x%X\n", PEFILE_SECTION_HEADERS[i].VirtualAddress);
&nbsp; &nbsp; &nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; &nbsp;VirtualSize: 0x%X\n", PEFILE_SECTION_HEADERS[i].Misc.VirtualSize);
&nbsp; &nbsp; &nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; &nbsp;PointerToRawData: 0x%X\n", PEFILE_SECTION_HEADERS[i].PointerToRawData);
&nbsp; &nbsp; &nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; &nbsp;SizeOfRawData: 0x%X\n", PEFILE_SECTION_HEADERS[i].SizeOfRawData);
&nbsp; &nbsp; &nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; &nbsp;Characteristics: 0x%X\n\n", PEFILE_SECTION_HEADERS[i].Characteristics);
&nbsp; &nbsp; }

}

void PE32FILE::PrintImportTableInfo() {

&nbsp; &nbsp; printf(" IMPORT TABLE:\n");
&nbsp; &nbsp; printf(" ----------------\n\n");

&nbsp; &nbsp; for (int i = 0; i < _import_directory_count; i++) {
&nbsp; &nbsp; &nbsp; &nbsp; DWORD NameAddr = resolve(PEFILE_IMPORT_TABLE[i].Name, locate(PEFILE_IMPORT_TABLE[i].Name));
&nbsp; &nbsp; &nbsp; &nbsp; int NameSize = 0;

&nbsp; &nbsp; &nbsp; &nbsp; while (true) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; char tmp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fseek(Ppefile, (NameAddr + NameSize), SEEK_SET);
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fread(&tmp, sizeof(char), 1, Ppefile);

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (tmp == 0x00) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; NameSize++;
&nbsp; &nbsp; &nbsp; &nbsp; }

&nbsp; &nbsp; &nbsp; &nbsp; char* Name = new char[NameSize + 2];
&nbsp; &nbsp; &nbsp; &nbsp; fseek(Ppefile, NameAddr, SEEK_SET);
&nbsp; &nbsp; &nbsp; &nbsp; fread(Name, (NameSize * sizeof(char)) + 1, 1, Ppefile);
&nbsp; &nbsp; &nbsp; &nbsp; printf(" &nbsp; * %s:\n", Name);
&nbsp; &nbsp; &nbsp; &nbsp; delete[] Name;

&nbsp; &nbsp; &nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; ILT RVA: 0x%X\n", PEFILE_IMPORT_TABLE[i].DUMMYUNIONNAME.OriginalFirstThunk);
&nbsp; &nbsp; &nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; IAT RVA: 0x%X\n", PEFILE_IMPORT_TABLE[i].FirstThunk);

&nbsp; &nbsp; &nbsp; &nbsp; if (PEFILE_IMPORT_TABLE[i].TimeDateStamp == 0) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; Bound: FALSE\n");
&nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; &nbsp; &nbsp; else if (PEFILE_IMPORT_TABLE[i].TimeDateStamp == -1) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; Bound: TRUE\n");
&nbsp; &nbsp; &nbsp; &nbsp; }

&nbsp; &nbsp; &nbsp; &nbsp; printf("\n");

&nbsp; &nbsp; &nbsp; &nbsp; DWORD ILTAddr = resolve(PEFILE_IMPORT_TABLE[i].DUMMYUNIONNAME.OriginalFirstThunk, locate(PEFILE_IMPORT_TABLE[i].DUMMYUNIONNAME.OriginalFirstThunk));
&nbsp; &nbsp; &nbsp; &nbsp; int entrycounter = 0;

&nbsp; &nbsp; &nbsp; &nbsp; while (true) {

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ILT_ENTRY_32 entry;

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fseek(Ppefile, (ILTAddr + (entrycounter * sizeof(DWORD))), SEEK_SET);
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fread(&entry, sizeof(ILT_ENTRY_32), 1, Ppefile);

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; BYTE flag = entry.FIELD_1.ORDINAL_NAME_FLAG;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DWORD HintRVA = 0x0;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WORD ordinal = 0x0;

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (flag == 0x0) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; HintRVA = entry.FIELD_1.HINT_NAME_TABE;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else if (flag == 0x01) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ordinal = entry.FIELD_1.ORDINAL;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (flag == 0x0 && HintRVA == 0x0 && ordinal == 0x0) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; printf("\n &nbsp; &nbsp; &nbsp; Entry:\n");

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (flag == 0x0) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ___IMAGE_IMPORT_BY_NAME hint;

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DWORD HintAddr = resolve(HintRVA, locate(HintRVA));
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fseek(Ppefile, HintAddr, SEEK_SET);
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fread(&hint, sizeof(___IMAGE_IMPORT_BY_NAME), 1, Ppefile);
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; &nbsp; Name: %s\n", hint.Name);
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; &nbsp; Hint RVA: 0x%X\n", HintRVA);
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; &nbsp; Hint: 0x%X\n", hint.Hint);
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else if (flag == 1) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; &nbsp; Ordinal: 0x%X\n", ordinal);
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; entrycounter++;
&nbsp; &nbsp; &nbsp; &nbsp; }

&nbsp; &nbsp; &nbsp; &nbsp; printf("\n &nbsp; ----------------------\n\n");

&nbsp; &nbsp; }

}

void PE32FILE::PrintBaseRelocationsInfo() {

&nbsp; &nbsp; printf(" BASE RELOCATIONS TABLE:\n");
&nbsp; &nbsp; printf(" -----------------------\n");

&nbsp; &nbsp; int szCounter = sizeof(___IMAGE_BASE_RELOCATION);

&nbsp; &nbsp; for (int i = 0; i < _basreloc_directory_count; i++) {

&nbsp; &nbsp; &nbsp; &nbsp; DWORD PAGERVA, BLOCKSIZE, BASE_RELOC_ADDR;
&nbsp; &nbsp; &nbsp; &nbsp; int ENTRIES;

&nbsp; &nbsp; &nbsp; &nbsp; BASE_RELOC_ADDR = resolve(PEFILE_BASERELOC_DIRECTORY.VirtualAddress, locate(PEFILE_BASERELOC_DIRECTORY.VirtualAddress));
&nbsp; &nbsp; &nbsp; &nbsp; PAGERVA = PEFILE_BASERELOC_TABLE[i].VirtualAddress;
&nbsp; &nbsp; &nbsp; &nbsp; BLOCKSIZE = PEFILE_BASERELOC_TABLE[i].SizeOfBlock;
&nbsp; &nbsp; &nbsp; &nbsp; ENTRIES = (BLOCKSIZE - sizeof(___IMAGE_BASE_RELOCATION)) / sizeof(WORD);

&nbsp; &nbsp; &nbsp; &nbsp; printf("\n &nbsp; Block 0x%X: \n", i);
&nbsp; &nbsp; &nbsp; &nbsp; printf(" &nbsp; &nbsp; Page RVA: 0x%X\n", PAGERVA);
&nbsp; &nbsp; &nbsp; &nbsp; printf(" &nbsp; &nbsp; Block size: 0x%X\n", BLOCKSIZE);
&nbsp; &nbsp; &nbsp; &nbsp; printf(" &nbsp; &nbsp; Number of entries: 0x%X\n", ENTRIES);
&nbsp; &nbsp; &nbsp; &nbsp; printf("\n &nbsp; &nbsp; Entries:\n");

&nbsp; &nbsp; &nbsp; &nbsp; for (int i = 0; i < ENTRIES; i++) {

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; BASE_RELOC_ENTRY entry;

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; int offset = (BASE_RELOC_ADDR + szCounter + (i * sizeof(WORD)));

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fseek(Ppefile, offset, SEEK_SET);
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fread(&entry, sizeof(WORD), 1, Ppefile);

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; printf("\n &nbsp; &nbsp; &nbsp; * Value: 0x%X\n", entry);
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; &nbsp; Relocation Type: 0x%X\n", entry.TYPE);
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; &nbsp; Offset: 0x%X\n", entry.OFFSET);

&nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; &nbsp; &nbsp; printf("\n &nbsp; ----------------------\n\n");
&nbsp; &nbsp; &nbsp; &nbsp; szCounter += BLOCKSIZE;
&nbsp; &nbsp; }

}

// MAIN
void PE32FILE::ParseFile() {

&nbsp; &nbsp; // PARSE DOS HEADER
&nbsp; &nbsp; ParseDOSHeader();

&nbsp; &nbsp; // PARSE RICH HEADER
&nbsp; &nbsp; ParseRichHeader();

&nbsp; &nbsp; //PARSE NT HEADERS
&nbsp; &nbsp; ParseNTHeaders();

&nbsp; &nbsp; // PARSE SECTION HEADERS
&nbsp; &nbsp; ParseSectionHeaders();

&nbsp; &nbsp; // PARSE IMPORT DIRECTORY
&nbsp; &nbsp; ParseImportDirectory();

&nbsp; &nbsp; // PARSE BASE RELOCATIONS
&nbsp; &nbsp; ParseBaseReloc();

}

void PE32FILE::PrintInfo() {

&nbsp; &nbsp; printf("\n\n");

&nbsp; &nbsp; PrintFileInfo();
&nbsp; &nbsp; printf("\n ----------------------------------\n\n");

&nbsp; &nbsp; PrintDOSHeaderInfo();
&nbsp; &nbsp; printf("\n ----------------------------------\n\n");

&nbsp; &nbsp; PrintRichHeaderInfo();
&nbsp; &nbsp; printf("\n ----------------------------------\n\n");

&nbsp; &nbsp; PrintNTHeadersInfo();
&nbsp; &nbsp; printf("\n ----------------------------------\n\n");

&nbsp; &nbsp; PrintSectionHeadersInfo();
&nbsp; &nbsp; printf("\n ----------------------------------\n\n");

&nbsp; &nbsp; PrintImportTableInfo();
&nbsp; &nbsp; printf("\n ----------------------------------\n\n");

&nbsp; &nbsp; PrintBaseRelocationsInfo();
&nbsp; &nbsp; printf("\n ----------------------------------\n\n");

&nbsp; &nbsp; return;

}

PE64FILE.h

#pragma&nbsp;once
#include&nbsp;"winntdef.h"
#include&nbsp;"PEFILE_CUSTOM_STRUCTS.h"
#include&nbsp;<string>

class PE64FILE
{
public:
&nbsp; &nbsp; PE64FILE(char* _NAME, FILE* Ppefile);

&nbsp; &nbsp; void PrintInfo();

private:
&nbsp; &nbsp; char* NAME;
&nbsp; &nbsp; FILE* Ppefile;
&nbsp; &nbsp; int _import_directory_count, _import_directory_size;
&nbsp; &nbsp; int _basreloc_directory_count;

&nbsp; &nbsp; // HEADERS
&nbsp; &nbsp; ___IMAGE_DOS_HEADER &nbsp; &nbsp; PEFILE_DOS_HEADER;
&nbsp; &nbsp; ___IMAGE_NT_HEADERS64 &nbsp; PEFILE_NT_HEADERS;

&nbsp; &nbsp; // DOS HEADER
&nbsp; &nbsp; DWORD PEFILE_DOS_HEADER_EMAGIC;
&nbsp; &nbsp; LONG &nbsp;PEFILE_DOS_HEADER_LFANEW;

&nbsp; &nbsp; // RICH HEADER
&nbsp; &nbsp; RICH_HEADER_INFO PEFILE_RICH_HEADER_INFO;
&nbsp; &nbsp; RICH_HEADER PEFILE_RICH_HEADER;

&nbsp; &nbsp; // NT_HEADERS.Signature
&nbsp; &nbsp; DWORD PEFILE_NT_HEADERS_SIGNATURE;

&nbsp; &nbsp; // NT_HEADERS.FileHeader
&nbsp; &nbsp; WORD PEFILE_NT_HEADERS_FILE_HEADER_MACHINE;
&nbsp; &nbsp; WORD PEFILE_NT_HEADERS_FILE_HEADER_NUMBER0F_SECTIONS;
&nbsp; &nbsp; WORD PEFILE_NT_HEADERS_FILE_HEADER_SIZEOF_OPTIONAL_HEADER;

&nbsp; &nbsp; // NT_HEADERS.OptionalHeader
&nbsp; &nbsp; DWORD PEFILE_NT_HEADERS_OPTIONAL_HEADER_MAGIC;
&nbsp; &nbsp; DWORD PEFILE_NT_HEADERS_OPTIONAL_HEADER_SIZEOF_CODE;
&nbsp; &nbsp; DWORD PEFILE_NT_HEADERS_OPTIONAL_HEADER_SIZEOF_INITIALIZED_DATA;
&nbsp; &nbsp; DWORD PEFILE_NT_HEADERS_OPTIONAL_HEADER_SIZEOF_UNINITIALIZED_DATA;
&nbsp; &nbsp; DWORD PEFILE_NT_HEADERS_OPTIONAL_HEADER_ADDRESSOF_ENTRYPOINT;
&nbsp; &nbsp; DWORD PEFILE_NT_HEADERS_OPTIONAL_HEADER_BASEOF_CODE;
&nbsp; &nbsp; ULONGLONG PEFILE_NT_HEADERS_OPTIONAL_HEADER_IMAGEBASE;
&nbsp; &nbsp; DWORD PEFILE_NT_HEADERS_OPTIONAL_HEADER_SECTION_ALIGNMENT;
&nbsp; &nbsp; DWORD PEFILE_NT_HEADERS_OPTIONAL_HEADER_FILE_ALIGNMENT;
&nbsp; &nbsp; DWORD PEFILE_NT_HEADERS_OPTIONAL_HEADER_SIZEOF_IMAGE;
&nbsp; &nbsp; DWORD PEFILE_NT_HEADERS_OPTIONAL_HEADER_SIZEOF_HEADERS;

&nbsp; &nbsp; ___IMAGE_DATA_DIRECTORY PEFILE_EXPORT_DIRECTORY;
&nbsp; &nbsp; ___IMAGE_DATA_DIRECTORY PEFILE_IMPORT_DIRECTORY;
&nbsp; &nbsp; ___IMAGE_DATA_DIRECTORY PEFILE_RESOURCE_DIRECTORY;
&nbsp; &nbsp; ___IMAGE_DATA_DIRECTORY PEFILE_EXCEPTION_DIRECTORY;
&nbsp; &nbsp; ___IMAGE_DATA_DIRECTORY PEFILE_SECURITY_DIRECTORY;
&nbsp; &nbsp; ___IMAGE_DATA_DIRECTORY PEFILE_BASERELOC_DIRECTORY;
&nbsp; &nbsp; ___IMAGE_DATA_DIRECTORY PEFILE_DEBUG_DIRECTORY;
&nbsp; &nbsp; ___IMAGE_DATA_DIRECTORY PEFILE_ARCHITECTURE_DIRECTORY;
&nbsp; &nbsp; ___IMAGE_DATA_DIRECTORY PEFILE_GLOBALPTR_DIRECTORY;
&nbsp; &nbsp; ___IMAGE_DATA_DIRECTORY PEFILE_TLS_DIRECTORY;
&nbsp; &nbsp; ___IMAGE_DATA_DIRECTORY PEFILE_LOAD_CONFIG_DIRECTORY;
&nbsp; &nbsp; ___IMAGE_DATA_DIRECTORY PEFILE_BOUND_IMPORT_DIRECTORY;
&nbsp; &nbsp; ___IMAGE_DATA_DIRECTORY PEFILE_IAT_DIRECTORY;
&nbsp; &nbsp; ___IMAGE_DATA_DIRECTORY PEFILE_DELAY_IMPORT_DIRECTORY;
&nbsp; &nbsp; ___IMAGE_DATA_DIRECTORY PEFILE_COM_DESCRIPTOR_DIRECTORY;

&nbsp; &nbsp; // SECTION HEADERS
&nbsp; &nbsp; ___PIMAGE_SECTION_HEADER PEFILE_SECTION_HEADERS;

&nbsp; &nbsp; // IMPORT TABLE
&nbsp; &nbsp; ___PIMAGE_IMPORT_DESCRIPTOR PEFILE_IMPORT_TABLE;

&nbsp; &nbsp; // BASE RELOCATION TABLE
&nbsp; &nbsp; ___PIMAGE_BASE_RELOCATION PEFILE_BASERELOC_TABLE;

&nbsp; &nbsp; // FUNCTIONS

&nbsp; &nbsp; // ADDRESS RESOLVERS
&nbsp; &nbsp; int &nbsp;locate(DWORD VA);
&nbsp; &nbsp; DWORD resolve(DWORD VA, int index);

&nbsp; &nbsp; // PARSERS
&nbsp; &nbsp; void ParseFile();
&nbsp; &nbsp; void ParseDOSHeader();
&nbsp; &nbsp; void ParseNTHeaders();
&nbsp; &nbsp; void ParseSectionHeaders();
&nbsp; &nbsp; void ParseImportDirectory();
&nbsp; &nbsp; void ParseBaseReloc();
&nbsp; &nbsp; void ParseRichHeader();

&nbsp; &nbsp; // PRINT INFO
&nbsp; &nbsp; void PrintFileInfo();
&nbsp; &nbsp; void PrintDOSHeaderInfo();
&nbsp; &nbsp; void PrintRichHeaderInfo();
&nbsp; &nbsp; void PrintNTHeadersInfo();
&nbsp; &nbsp; void PrintSectionHeadersInfo();
&nbsp; &nbsp; void PrintImportTableInfo();
&nbsp; &nbsp; void PrintBaseRelocationsInfo();
};

PE64FILE.cpp

#include&nbsp;"PE64FILE.h"

// CONSTRUCTOR
PE64FILE::PE64FILE(char* _NAME, FILE* _Ppefile) {

&nbsp; &nbsp; NAME = _NAME;
&nbsp; &nbsp; Ppefile = _Ppefile;

&nbsp; &nbsp; ParseFile();

}

// ADDRESS RESOLVERS
int PE64FILE::locate(DWORD VA) {

&nbsp; &nbsp; int index;

&nbsp; &nbsp; for (int i = 0; i < PEFILE_NT_HEADERS_FILE_HEADER_NUMBER0F_SECTIONS; i++) {
&nbsp; &nbsp; &nbsp; &nbsp; if (VA >= PEFILE_SECTION_HEADERS[i].VirtualAddress
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; && VA < (PEFILE_SECTION_HEADERS[i].VirtualAddress + PEFILE_SECTION_HEADERS[i].Misc.VirtualSize)) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; index = i;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;
&nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; }
&nbsp; &nbsp; return index;
}

DWORD PE64FILE::resolve(DWORD VA, int index) {

&nbsp; &nbsp; return (VA - PEFILE_SECTION_HEADERS[index].VirtualAddress) + PEFILE_SECTION_HEADERS[index].PointerToRawData;

}

// PARSERS
void PE64FILE::ParseDOSHeader() {

&nbsp; &nbsp; fseek(Ppefile, 0, SEEK_SET);
&nbsp; &nbsp; fread(&PEFILE_DOS_HEADER, sizeof(___IMAGE_DOS_HEADER), 1, Ppefile);

&nbsp; &nbsp; PEFILE_DOS_HEADER_EMAGIC = PEFILE_DOS_HEADER.e_magic;
&nbsp; &nbsp; PEFILE_DOS_HEADER_LFANEW = PEFILE_DOS_HEADER.e_lfanew;

}

void PE64FILE::ParseNTHeaders() {

&nbsp; &nbsp; fseek(Ppefile, PEFILE_DOS_HEADER.e_lfanew, SEEK_SET);
&nbsp; &nbsp; fread(&PEFILE_NT_HEADERS, sizeof(PEFILE_NT_HEADERS), 1, Ppefile);

&nbsp; &nbsp; PEFILE_NT_HEADERS_SIGNATURE = PEFILE_NT_HEADERS.Signature;

&nbsp; &nbsp; PEFILE_NT_HEADERS_FILE_HEADER_MACHINE = PEFILE_NT_HEADERS.FileHeader.Machine;
&nbsp; &nbsp; PEFILE_NT_HEADERS_FILE_HEADER_NUMBER0F_SECTIONS = PEFILE_NT_HEADERS.FileHeader.NumberOfSections;
&nbsp; &nbsp; PEFILE_NT_HEADERS_FILE_HEADER_SIZEOF_OPTIONAL_HEADER = PEFILE_NT_HEADERS.FileHeader.SizeOfOptionalHeader;

&nbsp; &nbsp; PEFILE_NT_HEADERS_OPTIONAL_HEADER_MAGIC = PEFILE_NT_HEADERS.OptionalHeader.Magic;
&nbsp; &nbsp; PEFILE_NT_HEADERS_OPTIONAL_HEADER_SIZEOF_CODE = PEFILE_NT_HEADERS.OptionalHeader.SizeOfCode;
&nbsp; &nbsp; PEFILE_NT_HEADERS_OPTIONAL_HEADER_SIZEOF_INITIALIZED_DATA = PEFILE_NT_HEADERS.OptionalHeader.SizeOfInitializedData;
&nbsp; &nbsp; PEFILE_NT_HEADERS_OPTIONAL_HEADER_SIZEOF_UNINITIALIZED_DATA = PEFILE_NT_HEADERS.OptionalHeader.SizeOfUninitializedData;
&nbsp; &nbsp; PEFILE_NT_HEADERS_OPTIONAL_HEADER_ADDRESSOF_ENTRYPOINT = PEFILE_NT_HEADERS.OptionalHeader.AddressOfEntryPoint;
&nbsp; &nbsp; PEFILE_NT_HEADERS_OPTIONAL_HEADER_BASEOF_CODE = PEFILE_NT_HEADERS.OptionalHeader.BaseOfCode;
&nbsp; &nbsp; PEFILE_NT_HEADERS_OPTIONAL_HEADER_IMAGEBASE = PEFILE_NT_HEADERS.OptionalHeader.ImageBase;
&nbsp; &nbsp; PEFILE_NT_HEADERS_OPTIONAL_HEADER_SECTION_ALIGNMENT = PEFILE_NT_HEADERS.OptionalHeader.SectionAlignment;
&nbsp; &nbsp; PEFILE_NT_HEADERS_OPTIONAL_HEADER_FILE_ALIGNMENT = PEFILE_NT_HEADERS.OptionalHeader.FileAlignment;
&nbsp; &nbsp; PEFILE_NT_HEADERS_OPTIONAL_HEADER_SIZEOF_IMAGE = PEFILE_NT_HEADERS.OptionalHeader.SizeOfImage;
&nbsp; &nbsp; PEFILE_NT_HEADERS_OPTIONAL_HEADER_SIZEOF_HEADERS = PEFILE_NT_HEADERS.OptionalHeader.SizeOfHeaders;

&nbsp; &nbsp; PEFILE_EXPORT_DIRECTORY = PEFILE_NT_HEADERS.OptionalHeader.DataDirectory[___IMAGE_DIRECTORY_ENTRY_EXPORT];
&nbsp; &nbsp; PEFILE_IMPORT_DIRECTORY = PEFILE_NT_HEADERS.OptionalHeader.DataDirectory[___IMAGE_DIRECTORY_ENTRY_IMPORT];
&nbsp; &nbsp; PEFILE_RESOURCE_DIRECTORY = PEFILE_NT_HEADERS.OptionalHeader.DataDirectory[___IMAGE_DIRECTORY_ENTRY_RESOURCE];
&nbsp; &nbsp; PEFILE_EXCEPTION_DIRECTORY = PEFILE_NT_HEADERS.OptionalHeader.DataDirectory[___IMAGE_DIRECTORY_ENTRY_EXCEPTION];
&nbsp; &nbsp; PEFILE_SECURITY_DIRECTORY = PEFILE_NT_HEADERS.OptionalHeader.DataDirectory[___IMAGE_DIRECTORY_ENTRY_SECURITY];
&nbsp; &nbsp; PEFILE_BASERELOC_DIRECTORY = PEFILE_NT_HEADERS.OptionalHeader.DataDirectory[___IMAGE_DIRECTORY_ENTRY_BASERELOC];
&nbsp; &nbsp; PEFILE_DEBUG_DIRECTORY = PEFILE_NT_HEADERS.OptionalHeader.DataDirectory[___IMAGE_DIRECTORY_ENTRY_DEBUG];
&nbsp; &nbsp; PEFILE_ARCHITECTURE_DIRECTORY = PEFILE_NT_HEADERS.OptionalHeader.DataDirectory[___IMAGE_DIRECTORY_ENTRY_ARCHITECTURE];
&nbsp; &nbsp; PEFILE_GLOBALPTR_DIRECTORY = PEFILE_NT_HEADERS.OptionalHeader.DataDirectory[___IMAGE_DIRECTORY_ENTRY_GLOBALPTR];
&nbsp; &nbsp; PEFILE_TLS_DIRECTORY = PEFILE_NT_HEADERS.OptionalHeader.DataDirectory[___IMAGE_DIRECTORY_ENTRY_TLS];
&nbsp; &nbsp; PEFILE_LOAD_CONFIG_DIRECTORY = PEFILE_NT_HEADERS.OptionalHeader.DataDirectory[___IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG];
&nbsp; &nbsp; PEFILE_BOUND_IMPORT_DIRECTORY = PEFILE_NT_HEADERS.OptionalHeader.DataDirectory[___IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT];
&nbsp; &nbsp; PEFILE_IAT_DIRECTORY = PEFILE_NT_HEADERS.OptionalHeader.DataDirectory[___IMAGE_DIRECTORY_ENTRY_IAT];
&nbsp; &nbsp; PEFILE_DELAY_IMPORT_DIRECTORY = PEFILE_NT_HEADERS.OptionalHeader.DataDirectory[___IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT];
&nbsp; &nbsp; PEFILE_COM_DESCRIPTOR_DIRECTORY = PEFILE_NT_HEADERS.OptionalHeader.DataDirectory[___IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR];

}

void PE64FILE::ParseSectionHeaders() {

&nbsp; &nbsp; PEFILE_SECTION_HEADERS = new ___IMAGE_SECTION_HEADER[PEFILE_NT_HEADERS_FILE_HEADER_NUMBER0F_SECTIONS];
&nbsp; &nbsp; for (int i = 0; i < PEFILE_NT_HEADERS_FILE_HEADER_NUMBER0F_SECTIONS; i++) {
&nbsp; &nbsp; &nbsp; &nbsp; int offset = (PEFILE_DOS_HEADER.e_lfanew + sizeof(PEFILE_NT_HEADERS)) + (i * ___IMAGE_SIZEOF_SECTION_HEADER);
&nbsp; &nbsp; &nbsp; &nbsp; fseek(Ppefile, offset, SEEK_SET);
&nbsp; &nbsp; &nbsp; &nbsp; fread(&PEFILE_SECTION_HEADERS[i], ___IMAGE_SIZEOF_SECTION_HEADER, 1, Ppefile);
&nbsp; &nbsp; }

}

void PE64FILE::ParseImportDirectory() {

&nbsp; &nbsp; DWORD _import_directory_address = resolve(PEFILE_IMPORT_DIRECTORY.VirtualAddress, locate(PEFILE_IMPORT_DIRECTORY.VirtualAddress));
&nbsp; &nbsp; _import_directory_count = 0;

&nbsp; &nbsp; while (true) {
&nbsp; &nbsp; &nbsp; &nbsp; ___IMAGE_IMPORT_DESCRIPTOR tmp;
&nbsp; &nbsp; &nbsp; &nbsp; int offset = (_import_directory_count * sizeof(___IMAGE_IMPORT_DESCRIPTOR)) + _import_directory_address;
&nbsp; &nbsp; &nbsp; &nbsp; fseek(Ppefile, offset, SEEK_SET);
&nbsp; &nbsp; &nbsp; &nbsp; fread(&tmp, sizeof(___IMAGE_IMPORT_DESCRIPTOR), 1, Ppefile);

&nbsp; &nbsp; &nbsp; &nbsp; if (tmp.Name == 0x00000000 && tmp.FirstThunk == 0x00000000) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; _import_directory_count -= 1;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; _import_directory_size = _import_directory_count * sizeof(___IMAGE_IMPORT_DESCRIPTOR);
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;
&nbsp; &nbsp; &nbsp; &nbsp; }

&nbsp; &nbsp; &nbsp; &nbsp; _import_directory_count++;
&nbsp; &nbsp; }

&nbsp; &nbsp; PEFILE_IMPORT_TABLE = new ___IMAGE_IMPORT_DESCRIPTOR[_import_directory_count];

&nbsp; &nbsp; for (int i = 0; i < _import_directory_count; i++) {
&nbsp; &nbsp; &nbsp; &nbsp; int offset = (i * sizeof(___IMAGE_IMPORT_DESCRIPTOR)) + _import_directory_address;
&nbsp; &nbsp; &nbsp; &nbsp; fseek(Ppefile, offset, SEEK_SET);
&nbsp; &nbsp; &nbsp; &nbsp; fread(&PEFILE_IMPORT_TABLE[i], sizeof(___IMAGE_IMPORT_DESCRIPTOR), 1, Ppefile);
&nbsp; &nbsp; }

}

void PE64FILE::ParseBaseReloc() {

&nbsp; &nbsp; DWORD _basereloc_directory_address = resolve(PEFILE_BASERELOC_DIRECTORY.VirtualAddress, locate(PEFILE_BASERELOC_DIRECTORY.VirtualAddress));
&nbsp; &nbsp; _basreloc_directory_count = 0;
&nbsp; &nbsp; int _basereloc_size_counter = 0;

&nbsp; &nbsp; while (true) {
&nbsp; &nbsp; &nbsp; &nbsp; ___IMAGE_BASE_RELOCATION tmp;

&nbsp; &nbsp; &nbsp; &nbsp; int offset = (_basereloc_size_counter + _basereloc_directory_address);

&nbsp; &nbsp; &nbsp; &nbsp; fseek(Ppefile, offset, SEEK_SET);
&nbsp; &nbsp; &nbsp; &nbsp; fread(&tmp, sizeof(___IMAGE_BASE_RELOCATION), 1, Ppefile);

&nbsp; &nbsp; &nbsp; &nbsp; if (tmp.VirtualAddress == 0x00000000 &&
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; tmp.SizeOfBlock == 0x00000000) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;
&nbsp; &nbsp; &nbsp; &nbsp; }

&nbsp; &nbsp; &nbsp; &nbsp; _basreloc_directory_count++;
&nbsp; &nbsp; &nbsp; &nbsp; _basereloc_size_counter += tmp.SizeOfBlock;
&nbsp; &nbsp; }

&nbsp; &nbsp; PEFILE_BASERELOC_TABLE = new ___IMAGE_BASE_RELOCATION[_basreloc_directory_count];

&nbsp; &nbsp; _basereloc_size_counter = 0;

&nbsp; &nbsp; for (int i = 0; i < _basreloc_directory_count; i++) {
&nbsp; &nbsp; &nbsp; &nbsp; int offset = _basereloc_directory_address + _basereloc_size_counter;
&nbsp; &nbsp; &nbsp; &nbsp; fseek(Ppefile, offset, SEEK_SET);
&nbsp; &nbsp; &nbsp; &nbsp; fread(&PEFILE_BASERELOC_TABLE[i], sizeof(___IMAGE_BASE_RELOCATION), 1, Ppefile);
&nbsp; &nbsp; &nbsp; &nbsp; _basereloc_size_counter += PEFILE_BASERELOC_TABLE[i].SizeOfBlock;
&nbsp; &nbsp; }

}

void PE64FILE::ParseRichHeader() {

&nbsp; &nbsp; char* dataPtr = new char[PEFILE_DOS_HEADER_LFANEW];
&nbsp; &nbsp; fseek(Ppefile, 0, SEEK_SET);
&nbsp; &nbsp; fread(dataPtr, PEFILE_DOS_HEADER_LFANEW, 1, Ppefile);

&nbsp; &nbsp; int index_ = 0;

&nbsp; &nbsp; for (int i = 0; i <= PEFILE_DOS_HEADER_LFANEW; i++) {
&nbsp; &nbsp; &nbsp; &nbsp; if (dataPtr[i] == 0x52 && dataPtr[i + 1] == 0x69) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; index_ = i;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;
&nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; }

&nbsp; &nbsp; if (index_ == 0) {
&nbsp; &nbsp; &nbsp; &nbsp; printf("Error while parsing Rich Header.");
&nbsp; &nbsp; &nbsp; &nbsp; PEFILE_RICH_HEADER_INFO.entries = 0;
&nbsp; &nbsp; &nbsp; &nbsp; return;
&nbsp; &nbsp; }

&nbsp; &nbsp; char key[4];
&nbsp; &nbsp; memcpy(key, dataPtr + (index_ + 4), 4);

&nbsp; &nbsp; int indexpointer = index_ - 4;
&nbsp; &nbsp; int RichHeaderSize = 0;

&nbsp; &nbsp; while (true) {
&nbsp; &nbsp; &nbsp; &nbsp; char tmpchar[4];
&nbsp; &nbsp; &nbsp; &nbsp; memcpy(tmpchar, dataPtr + indexpointer, 4);

&nbsp; &nbsp; &nbsp; &nbsp; for (int i = 0; i < 4; i++) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; tmpchar[i] = tmpchar[i] ^ key[i];
&nbsp; &nbsp; &nbsp; &nbsp; }

&nbsp; &nbsp; &nbsp; &nbsp; indexpointer -= 4;
&nbsp; &nbsp; &nbsp; &nbsp; RichHeaderSize += 4;

&nbsp; &nbsp; &nbsp; &nbsp; if (tmpchar[1] = 0x61 && tmpchar[0] == 0x44) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;
&nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; }

&nbsp; &nbsp; char* RichHeaderPtr = new char[RichHeaderSize];
&nbsp; &nbsp; memcpy(RichHeaderPtr, dataPtr + (index_ - RichHeaderSize), RichHeaderSize);

&nbsp; &nbsp; for (int i = 0; i < RichHeaderSize; i += 4) {

&nbsp; &nbsp; &nbsp; &nbsp; for (int x = 0; x < 4; x++) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; RichHeaderPtr[i + x] = RichHeaderPtr[i + x] ^ key[x];
&nbsp; &nbsp; &nbsp; &nbsp; }

&nbsp; &nbsp; }

&nbsp; &nbsp; PEFILE_RICH_HEADER_INFO.size = RichHeaderSize;
&nbsp; &nbsp; PEFILE_RICH_HEADER_INFO.ptrToBuffer = RichHeaderPtr;
&nbsp; &nbsp; PEFILE_RICH_HEADER_INFO.entries = (RichHeaderSize - 16) / 8;

&nbsp; &nbsp; delete[] dataPtr;

&nbsp; &nbsp; PEFILE_RICH_HEADER.entries = new RICH_HEADER_ENTRY[PEFILE_RICH_HEADER_INFO.entries];

&nbsp; &nbsp; for (int i = 16; i < RichHeaderSize; i += 8) {
&nbsp; &nbsp; &nbsp; &nbsp; WORD PRODID = (uint16_t)((unsigned char)RichHeaderPtr[i + 3] << 8) | (unsigned char)RichHeaderPtr[i + 2];
&nbsp; &nbsp; &nbsp; &nbsp; WORD BUILDID = (uint16_t)((unsigned char)RichHeaderPtr[i + 1] << 8) | (unsigned char)RichHeaderPtr[i];
&nbsp; &nbsp; &nbsp; &nbsp; DWORD USECOUNT = (uint32_t)((unsigned char)RichHeaderPtr[i + 7] << 24) | (unsigned char)RichHeaderPtr[i + 6] << 16 | (unsigned char)RichHeaderPtr[i + 5] << 8 | (unsigned char)RichHeaderPtr[i + 4];
&nbsp; &nbsp; &nbsp; &nbsp; PEFILE_RICH_HEADER.entries[(i / 8) - 2] = {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; PRODID,
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; BUILDID,
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; USECOUNT
&nbsp; &nbsp; &nbsp; &nbsp; };

&nbsp; &nbsp; &nbsp; &nbsp; if (i + 8 >= RichHeaderSize) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; PEFILE_RICH_HEADER.entries[(i / 8) - 1] = { 0x0000, 0x0000, 0x00000000 };
&nbsp; &nbsp; &nbsp; &nbsp; }

&nbsp; &nbsp; }

&nbsp; &nbsp; delete[] PEFILE_RICH_HEADER_INFO.ptrToBuffer;

}

// PRINT INFO
void PE64FILE::PrintFileInfo() {

&nbsp; &nbsp; printf(" FILE: %s\n", NAME);
&nbsp; &nbsp; printf(" TYPE: 0x%X (PE32+)\n", PEFILE_NT_HEADERS_OPTIONAL_HEADER_MAGIC);

}

void PE64FILE::PrintDOSHeaderInfo() {

&nbsp; &nbsp; printf(" DOS HEADER:\n");
&nbsp; &nbsp; printf(" -----------\n\n");

&nbsp; &nbsp; printf(" Magic: 0x%X\n", PEFILE_DOS_HEADER_EMAGIC);
&nbsp; &nbsp; printf(" File address of new exe header: 0x%X\n", PEFILE_DOS_HEADER_LFANEW);

}

void PE64FILE::PrintRichHeaderInfo() {

&nbsp; &nbsp; printf(" RICH HEADER:\n");
&nbsp; &nbsp; printf(" ------------\n\n");

&nbsp; &nbsp; for (int i = 0; i < PEFILE_RICH_HEADER_INFO.entries; i++) {
&nbsp; &nbsp; &nbsp; &nbsp; printf(" 0x%X 0x%X 0x%X: %d.%d.%d\n",
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; PEFILE_RICH_HEADER.entries[i].buildID,
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; PEFILE_RICH_HEADER.entries[i].prodID,
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; PEFILE_RICH_HEADER.entries[i].useCount,
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; PEFILE_RICH_HEADER.entries[i].buildID,
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; PEFILE_RICH_HEADER.entries[i].prodID,
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; PEFILE_RICH_HEADER.entries[i].useCount);
&nbsp; &nbsp; }

}

void PE64FILE::PrintNTHeadersInfo() {

&nbsp; &nbsp; printf(" NT HEADERS:\n");
&nbsp; &nbsp; printf(" -----------\n\n");

&nbsp; &nbsp; printf(" PE Signature: 0x%X\n", PEFILE_NT_HEADERS_SIGNATURE);

&nbsp; &nbsp; printf("\n File Header:\n\n");
&nbsp; &nbsp; printf(" &nbsp; Machine: 0x%X\n", PEFILE_NT_HEADERS_FILE_HEADER_MACHINE);
&nbsp; &nbsp; printf(" &nbsp; Number of sections: 0x%X\n", PEFILE_NT_HEADERS_FILE_HEADER_NUMBER0F_SECTIONS);
&nbsp; &nbsp; printf(" &nbsp; Size of optional header: 0x%X\n", PEFILE_NT_HEADERS_FILE_HEADER_SIZEOF_OPTIONAL_HEADER);

&nbsp; &nbsp; printf("\n Optional Header:\n\n");
&nbsp; &nbsp; printf(" &nbsp; Magic: 0x%X\n", PEFILE_NT_HEADERS_OPTIONAL_HEADER_MAGIC);
&nbsp; &nbsp; printf(" &nbsp; Size of code section: 0x%X\n", PEFILE_NT_HEADERS_OPTIONAL_HEADER_SIZEOF_CODE);
&nbsp; &nbsp; printf(" &nbsp; Size of initialized data: 0x%X\n", PEFILE_NT_HEADERS_OPTIONAL_HEADER_SIZEOF_INITIALIZED_DATA);
&nbsp; &nbsp; printf(" &nbsp; Size of uninitialized data: 0x%X\n", PEFILE_NT_HEADERS_OPTIONAL_HEADER_SIZEOF_UNINITIALIZED_DATA);
&nbsp; &nbsp; printf(" &nbsp; Address of entry point: 0x%X\n", PEFILE_NT_HEADERS_OPTIONAL_HEADER_ADDRESSOF_ENTRYPOINT);
&nbsp; &nbsp; printf(" &nbsp; RVA of start of code section: 0x%X\n", PEFILE_NT_HEADERS_OPTIONAL_HEADER_BASEOF_CODE);
&nbsp; &nbsp; printf(" &nbsp; Desired image base: 0x%X\n", PEFILE_NT_HEADERS_OPTIONAL_HEADER_IMAGEBASE);
&nbsp; &nbsp; printf(" &nbsp; Section alignment: 0x%X\n", PEFILE_NT_HEADERS_OPTIONAL_HEADER_SECTION_ALIGNMENT);
&nbsp; &nbsp; printf(" &nbsp; File alignment: 0x%X\n", PEFILE_NT_HEADERS_OPTIONAL_HEADER_FILE_ALIGNMENT);
&nbsp; &nbsp; printf(" &nbsp; Size of image: 0x%X\n", PEFILE_NT_HEADERS_OPTIONAL_HEADER_SIZEOF_IMAGE);
&nbsp; &nbsp; printf(" &nbsp; Size of headers: 0x%X\n", PEFILE_NT_HEADERS_OPTIONAL_HEADER_SIZEOF_HEADERS);

&nbsp; &nbsp; printf("\n Data Directories:\n");
&nbsp; &nbsp; printf("\n &nbsp; * Export Directory:\n");
&nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; RVA: 0x%X\n", PEFILE_EXPORT_DIRECTORY.VirtualAddress);
&nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; Size: 0x%X\n", PEFILE_EXPORT_DIRECTORY.Size);

&nbsp; &nbsp; printf("\n &nbsp; * Import Directory:\n");
&nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; RVA: 0x%X\n", PEFILE_IMPORT_DIRECTORY.VirtualAddress);
&nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; Size: 0x%X\n", PEFILE_IMPORT_DIRECTORY.Size);

&nbsp; &nbsp; printf("\n &nbsp; * Resource Directory:\n");
&nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; RVA: 0x%X\n", PEFILE_RESOURCE_DIRECTORY.VirtualAddress);
&nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; Size: 0x%X\n", PEFILE_RESOURCE_DIRECTORY.Size);

&nbsp; &nbsp; printf("\n &nbsp; * Exception Directory:\n");
&nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; RVA: 0x%X\n", PEFILE_EXCEPTION_DIRECTORY.VirtualAddress);
&nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; Size: 0x%X\n", PEFILE_EXCEPTION_DIRECTORY.Size);

&nbsp; &nbsp; printf("\n &nbsp; * Security Directory:\n");
&nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; RVA: 0x%X\n", PEFILE_SECURITY_DIRECTORY.VirtualAddress);
&nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; Size: 0x%X\n", PEFILE_SECURITY_DIRECTORY.Size);

&nbsp; &nbsp; printf("\n &nbsp; * Base Relocation Table:\n");
&nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; RVA: 0x%X\n", PEFILE_BASERELOC_DIRECTORY.VirtualAddress);
&nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; Size: 0x%X\n", PEFILE_BASERELOC_DIRECTORY.Size);

&nbsp; &nbsp; printf("\n &nbsp; * Debug Directory:\n");
&nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; RVA: 0x%X\n", PEFILE_DEBUG_DIRECTORY.VirtualAddress);
&nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; Size: 0x%X\n", PEFILE_DEBUG_DIRECTORY.Size);

&nbsp; &nbsp; printf("\n &nbsp; * Architecture Specific Data:\n");
&nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; RVA: 0x%X\n", PEFILE_ARCHITECTURE_DIRECTORY.VirtualAddress);
&nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; Size: 0x%X\n", PEFILE_ARCHITECTURE_DIRECTORY.Size);

&nbsp; &nbsp; printf("\n &nbsp; * RVA of GlobalPtr:\n");
&nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; RVA: 0x%X\n", PEFILE_GLOBALPTR_DIRECTORY.VirtualAddress);
&nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; Size: 0x%X\n", PEFILE_GLOBALPTR_DIRECTORY.Size);

&nbsp; &nbsp; printf("\n &nbsp; * TLS Directory:\n");
&nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; RVA: 0x%X\n", PEFILE_TLS_DIRECTORY.VirtualAddress);
&nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; Size: 0x%X\n", PEFILE_TLS_DIRECTORY.Size);

&nbsp; &nbsp; printf("\n &nbsp; * Load Configuration Directory:\n");
&nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; RVA: 0x%X\n", PEFILE_LOAD_CONFIG_DIRECTORY.VirtualAddress);
&nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; Size: 0x%X\n", PEFILE_LOAD_CONFIG_DIRECTORY.Size);

&nbsp; &nbsp; printf("\n &nbsp; * Bound Import Directory:\n");
&nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; RVA: 0x%X\n", PEFILE_BOUND_IMPORT_DIRECTORY.VirtualAddress);
&nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; Size: 0x%X\n", PEFILE_BOUND_IMPORT_DIRECTORY.Size);

&nbsp; &nbsp; printf("\n &nbsp; * Import Address Table:\n");
&nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; RVA: 0x%X\n", PEFILE_IAT_DIRECTORY.VirtualAddress);
&nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; Size: 0x%X\n", PEFILE_IAT_DIRECTORY.Size);

&nbsp; &nbsp; printf("\n &nbsp; * Delay Load Import Descriptors:\n");
&nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; RVA: 0x%X\n", PEFILE_DELAY_IMPORT_DIRECTORY.VirtualAddress);
&nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; Size: 0x%X\n", PEFILE_DELAY_IMPORT_DIRECTORY.Size);

&nbsp; &nbsp; printf("\n &nbsp; * COM Runtime Descriptor:\n");
&nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; RVA: 0x%X\n", PEFILE_COM_DESCRIPTOR_DIRECTORY.VirtualAddress);
&nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; Size: 0x%X\n", PEFILE_COM_DESCRIPTOR_DIRECTORY.Size);

}

void PE64FILE::PrintSectionHeadersInfo() {

&nbsp; &nbsp; printf(" SECTION HEADERS:\n");
&nbsp; &nbsp; printf(" ----------------\n\n");

&nbsp; &nbsp; for (int i = 0; i < PEFILE_NT_HEADERS_FILE_HEADER_NUMBER0F_SECTIONS; i++) {
&nbsp; &nbsp; &nbsp; &nbsp; printf(" &nbsp; * %.8s:\n", PEFILE_SECTION_HEADERS[i].Name);
&nbsp; &nbsp; &nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; &nbsp;VirtualAddress: 0x%X\n", PEFILE_SECTION_HEADERS[i].VirtualAddress);
&nbsp; &nbsp; &nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; &nbsp;VirtualSize: 0x%X\n", PEFILE_SECTION_HEADERS[i].Misc.VirtualSize);
&nbsp; &nbsp; &nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; &nbsp;PointerToRawData: 0x%X\n", PEFILE_SECTION_HEADERS[i].PointerToRawData);
&nbsp; &nbsp; &nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; &nbsp;SizeOfRawData: 0x%X\n", PEFILE_SECTION_HEADERS[i].SizeOfRawData);
&nbsp; &nbsp; &nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; &nbsp;Characteristics: 0x%X\n\n", PEFILE_SECTION_HEADERS[i].Characteristics);
&nbsp; &nbsp; }

}

void PE64FILE::PrintImportTableInfo() {

&nbsp; &nbsp; printf(" IMPORT TABLE:\n");
&nbsp; &nbsp; printf(" ----------------\n\n");

&nbsp; &nbsp; for (int i = 0; i < _import_directory_count; i++) {
&nbsp; &nbsp; &nbsp; &nbsp; DWORD NameAddr = resolve(PEFILE_IMPORT_TABLE[i].Name, locate(PEFILE_IMPORT_TABLE[i].Name));
&nbsp; &nbsp; &nbsp; &nbsp; int NameSize = 0;

&nbsp; &nbsp; &nbsp; &nbsp; while (true) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; char tmp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fseek(Ppefile, (NameAddr + NameSize), SEEK_SET);
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fread(&tmp, sizeof(char), 1, Ppefile);

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (tmp == 0x00) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; NameSize++;
&nbsp; &nbsp; &nbsp; &nbsp; }

&nbsp; &nbsp; &nbsp; &nbsp; char* Name = new char[NameSize + 2];
&nbsp; &nbsp; &nbsp; &nbsp; fseek(Ppefile, NameAddr, SEEK_SET);
&nbsp; &nbsp; &nbsp; &nbsp; fread(Name, (NameSize * sizeof(char)) + 1, 1, Ppefile);
&nbsp; &nbsp; &nbsp; &nbsp; printf(" &nbsp; * %s:\n", Name);
&nbsp; &nbsp; &nbsp; &nbsp; delete[] Name;

&nbsp; &nbsp; &nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; ILT RVA: 0x%X\n", PEFILE_IMPORT_TABLE[i].DUMMYUNIONNAME.OriginalFirstThunk);
&nbsp; &nbsp; &nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; IAT RVA: 0x%X\n", PEFILE_IMPORT_TABLE[i].FirstThunk);

&nbsp; &nbsp; &nbsp; &nbsp; if (PEFILE_IMPORT_TABLE[i].TimeDateStamp == 0) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; Bound: FALSE\n");
&nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; &nbsp; &nbsp; else if (PEFILE_IMPORT_TABLE[i].TimeDateStamp == -1) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; Bound: TRUE\n");
&nbsp; &nbsp; &nbsp; &nbsp; }

&nbsp; &nbsp; &nbsp; &nbsp; printf("\n");

&nbsp; &nbsp; &nbsp; &nbsp; DWORD ILTAddr = resolve(PEFILE_IMPORT_TABLE[i].DUMMYUNIONNAME.OriginalFirstThunk, locate(PEFILE_IMPORT_TABLE[i].DUMMYUNIONNAME.OriginalFirstThunk));
&nbsp; &nbsp; &nbsp; &nbsp; int entrycounter = 0;

&nbsp; &nbsp; &nbsp; &nbsp; while (true) {

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ILT_ENTRY_64 entry;

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fseek(Ppefile, (ILTAddr + (entrycounter * sizeof(QWORD))), SEEK_SET);
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fread(&entry, sizeof(ILT_ENTRY_64), 1, Ppefile);

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; BYTE flag = entry.ORDINAL_NAME_FLAG;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DWORD HintRVA = 0x0;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WORD ordinal = 0x0;

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (flag == 0x0) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; HintRVA = entry.FIELD_2.HINT_NAME_TABE;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else if (flag == 0x01) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ordinal = entry.FIELD_2.ORDINAL;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (flag == 0x0 && HintRVA == 0x0 && ordinal == 0x0) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; printf("\n &nbsp; &nbsp; &nbsp; Entry:\n");

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (flag == 0x0) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ___IMAGE_IMPORT_BY_NAME hint;

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DWORD HintAddr = resolve(HintRVA, locate(HintRVA));
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fseek(Ppefile, HintAddr, SEEK_SET);
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fread(&hint, sizeof(___IMAGE_IMPORT_BY_NAME), 1, Ppefile);
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; &nbsp; Name: %s\n", hint.Name);
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; &nbsp; Hint RVA: 0x%X\n", HintRVA);
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; &nbsp; Hint: 0x%X\n", hint.Hint);
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else if (flag == 1) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; &nbsp; Ordinal: 0x%X\n", ordinal);
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; entrycounter++;
&nbsp; &nbsp; &nbsp; &nbsp; }

&nbsp; &nbsp; &nbsp; &nbsp; printf("\n &nbsp; ----------------------\n\n");

&nbsp; &nbsp; }

}

void PE64FILE::PrintBaseRelocationsInfo() {

&nbsp; &nbsp; printf(" BASE RELOCATIONS TABLE:\n");
&nbsp; &nbsp; printf(" -----------------------\n");

&nbsp; &nbsp; int szCounter = sizeof(___IMAGE_BASE_RELOCATION);

&nbsp; &nbsp; for (int i = 0; i < _basreloc_directory_count; i++) {

&nbsp; &nbsp; &nbsp; &nbsp; DWORD PAGERVA, BLOCKSIZE, BASE_RELOC_ADDR;
&nbsp; &nbsp; &nbsp; &nbsp; int ENTRIES;

&nbsp; &nbsp; &nbsp; &nbsp; BASE_RELOC_ADDR = resolve(PEFILE_BASERELOC_DIRECTORY.VirtualAddress, locate(PEFILE_BASERELOC_DIRECTORY.VirtualAddress));
&nbsp; &nbsp; &nbsp; &nbsp; PAGERVA = PEFILE_BASERELOC_TABLE[i].VirtualAddress;
&nbsp; &nbsp; &nbsp; &nbsp; BLOCKSIZE = PEFILE_BASERELOC_TABLE[i].SizeOfBlock;
&nbsp; &nbsp; &nbsp; &nbsp; ENTRIES = (BLOCKSIZE - sizeof(___IMAGE_BASE_RELOCATION)) / sizeof(WORD);

&nbsp; &nbsp; &nbsp; &nbsp; printf("\n &nbsp; Block 0x%X: \n", i);
&nbsp; &nbsp; &nbsp; &nbsp; printf(" &nbsp; &nbsp; Page RVA: 0x%X\n", PAGERVA);
&nbsp; &nbsp; &nbsp; &nbsp; printf(" &nbsp; &nbsp; Block size: 0x%X\n", BLOCKSIZE);
&nbsp; &nbsp; &nbsp; &nbsp; printf(" &nbsp; &nbsp; Number of entries: 0x%X\n", ENTRIES);
&nbsp; &nbsp; &nbsp; &nbsp; printf("\n &nbsp; &nbsp; Entries:\n");

&nbsp; &nbsp; &nbsp; &nbsp; for (int i = 0; i < ENTRIES; i++) {

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; BASE_RELOC_ENTRY entry;

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; int offset = (BASE_RELOC_ADDR + szCounter + (i * sizeof(WORD)));

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fseek(Ppefile, offset, SEEK_SET);
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fread(&entry, sizeof(WORD), 1, Ppefile);

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; printf("\n &nbsp; &nbsp; &nbsp; * Value: 0x%X\n", entry);
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; &nbsp; Relocation Type: 0x%X\n", entry.TYPE);
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; printf(" &nbsp; &nbsp; &nbsp; &nbsp; Offset: 0x%X\n", entry.OFFSET);

&nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; &nbsp; &nbsp; printf("\n &nbsp; ----------------------\n\n");
&nbsp; &nbsp; &nbsp; &nbsp; szCounter += BLOCKSIZE;
&nbsp; &nbsp; }

}

// MAIN
void PE64FILE::ParseFile() {

&nbsp; &nbsp; // PARSE DOS HEADER
&nbsp; &nbsp; ParseDOSHeader();

&nbsp; &nbsp; // PARSE RICH HEADER
&nbsp; &nbsp; ParseRichHeader();

&nbsp; &nbsp; //PARSE NT HEADERS
&nbsp; &nbsp; ParseNTHeaders();

&nbsp; &nbsp; // PARSE SECTION HEADERS
&nbsp; &nbsp; ParseSectionHeaders();

&nbsp; &nbsp; // PARSE IMPORT DIRECTORY
&nbsp; &nbsp; ParseImportDirectory();

&nbsp; &nbsp; // PARSE BASE RELOCATIONS
&nbsp; &nbsp; ParseBaseReloc();

}

void PE64FILE::PrintInfo() {

&nbsp; &nbsp; printf("\n\n");

&nbsp; &nbsp; PrintFileInfo();
&nbsp; &nbsp; printf("\n ----------------------------------\n\n");

&nbsp; &nbsp; PrintDOSHeaderInfo();
&nbsp; &nbsp; printf("\n ----------------------------------\n\n");

&nbsp; &nbsp; PrintRichHeaderInfo();
&nbsp; &nbsp; printf("\n ----------------------------------\n\n");

&nbsp; &nbsp; PrintNTHeadersInfo();
&nbsp; &nbsp; printf("\n ----------------------------------\n\n");

&nbsp; &nbsp; PrintSectionHeadersInfo();
&nbsp; &nbsp; printf("\n ----------------------------------\n\n");

&nbsp; &nbsp; PrintImportTableInfo();
&nbsp; &nbsp; printf("\n ----------------------------------\n\n");

&nbsp; &nbsp; PrintBaseRelocationsInfo();
&nbsp; &nbsp; printf("\n ----------------------------------\n\n");

&nbsp; &nbsp; return;

}

最终效果如下

image

代码放到:https://github.com/ybdt/evasion-hub/tree/master/Misc/PE-Parser


免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:卡卡罗特取西经 ybdt ybdt《深入学习PE文件结构系列五自己实现一个PE解析器》

评论:0   参与:  2