PE檔案結構解析 C、C++程式 vc2008編譯
//MyPeFile.h------------------------------------------------------------------------------------------------------
typedef unsigned short USHORT;
typedef unsigned long ULONG;
typedef unsigned char UCHAR;
typedef unsigned short WCHAR; // wc, 16-bit UNICODE character
// 目錄入口
// 匯出目錄
#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_COPYRIGHT 7
// 機器值(MIPS GP)
#define IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8
// TLS目錄
#define IMAGE_DIRECTORY_ENTRY_TLS 9
// 載入配置目錄
#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10
/*
* 預定義的資源種類
*/
#define RT_CURSOR MAKEINTRESOURCE(1)
#define RT_BITMAP MAKEINTRESOURCE(2)
#define RT_ICON MAKEINTRESOURCE(3)
#define RT_MENU MAKEINTRESOURCE(4)
#define RT_DIALOG MAKEINTRESOURCE(5)
#define RT_STRING MAKEINTRESOURCE(6)
#define RT_FONTDIR MAKEINTRESOURCE(7)
#define RT_FONT MAKEINTRESOURCE(8)
#define RT_ACCELERATOR MAKEINTRESOURCE(9)
#define RT_RCDATA MAKEINTRESOURCE(10)
#define RT_MESSAGETABLE MAKEINTRESOURCE(11)
typedef struct _IMAGE_DOS_HEADER { // DOS的.EXE頭部
USHORT e_magic; // 魔術數字
USHORT e_cblp; // 檔案最後頁的位元組數
USHORT e_cp; // 檔案頁數
USHORT e_crlc; // 重定義元素個數
USHORT e_cparhdr; // 頭部尺寸,以段落為單位
USHORT e_minalloc; // 所需的最小附加段
USHORT e_maxalloc; // 所需的最大附加段
USHORT e_ss; // 初始的SS值(相對偏移量)
USHORT e_sp; // 初始的SP值
USHORT e_csum; // 校驗和
USHORT e_ip; // 初始的IP值
USHORT e_cs; // 初始的CS值(相對偏移量)
USHORT e_lfarlc; // 重分配表文件地址
USHORT e_ovno; // 覆蓋號
USHORT e_res[4]; // 保留字
USHORT e_oemid; // OEM識別符號(相對e_oeminfo)
USHORT e_oeminfo; // OEM資訊
USHORT e_res2[10]; // 保留字
long e_lfanew; // 新exe頭部的檔案地址
} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
typedef struct _IMAGE_FILE_HEADER {
USHORT Machine;
USHORT NumberOfSections;
ULONG TimeDateStamp;
ULONG PointerToSymbolTable;
ULONG NumberOfSymbols;
USHORT SizeOfOptionalHeader;
USHORT Characteristics;
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
#define IMAGE_SIZEOF_FILE_HEADER 20
typedef struct _IMAGE_DATA_DIRECTORY {
ULONG VirtualAddress;
ULONG Size;
} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;
#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16
typedef struct _IMAGE_OPTIONAL_HEADER {
//
// 標準域
//
USHORT Magic;
UCHAR MajorLinkerVersion;
UCHAR MinorLinkerVersion;
ULONG SizeOfCode;
ULONG SizeOfInitializedData;
ULONG SizeOfUninitializedData;
ULONG AddressOfEntryPoint;
ULONG BaseOfCode;
ULONG BaseOfData;
//
// NT附加域
//
ULONG ImageBase;
ULONG SectionAlignment;
ULONG FileAlignment;
USHORT MajorOperatingSystemVersion;
USHORT MinorOperatingSystemVersion;
USHORT MajorImageVersion;
USHORT MinorImageVersion;
USHORT MajorSubsystemVersion;
USHORT MinorSubsystemVersion;
ULONG Reserved1;
ULONG SizeOfImage;
ULONG SizeOfHeaders;
ULONG CheckSum;
USHORT Subsystem;
USHORT DllCharacteristics;
ULONG SizeOfStackReserve;
ULONG SizeOfStackCommit;
ULONG SizeOfHeapReserve;
ULONG SizeOfHeapCommit;
ULONG LoaderFlags;
ULONG NumberOfRvaAndSizes;
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
} IMAGE_OPTIONAL_HEADER, *PIMAGE_OPTIONAL_HEADER;
#define IMAGE_SIZEOF_SHORT_NAME 8
typedef struct _IMAGE_SECTION_HEADER {
UCHAR Name[IMAGE_SIZEOF_SHORT_NAME];
union {
ULONG PhysicalAddress;
ULONG VirtualSize;
} Misc;
ULONG VirtualAddress;
ULONG SizeOfRawData;
ULONG PointerToRawData;
ULONG PointerToRelocations;
ULONG PointerToLinenumbers;
USHORT NumberOfRelocations;
USHORT NumberOfLinenumbers;
ULONG Characteristics;
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
/*
0x00000020 程式碼段
0x00000040 已初始化資料段
0x00000080 未初始化資料段
0x04000000 該段資料不能被快取
0x08000000 該段不能被分頁
0x10000000 共享段
0x20000000 可執行段
0x40000000 可讀段
0x80000000 可寫段
*/
typedef struct _IMAGE_RESOURCE_DIRECTORY {
ULONG Characteristics;
ULONG TimeDateStamp;
USHORT MajorVersion;
USHORT MinorVersion;
USHORT NumberOfNamedEntries;
USHORT NumberOfIdEntries;
} IMAGE_RESOURCE_DIRECTORY, *PIMAGE_RESOURCE_DIRECTORY;
typedef struct _IMAGE_RESOURCE_DIRECTORY_ENTRY {
ULONG Name;
ULONG OffsetToData;
} IMAGE_RESOURCE_DIRECTORY_ENTRY, *PIMAGE_RESOURCE_DIRECTORY_ENTRY;
typedef struct _IMAGE_RESOURCE_DATA_ENTRY {
ULONG OffsetToData;
ULONG Size;
ULONG CodePage;
ULONG Reserved;
} IMAGE_RESOURCE_DATA_ENTRY, *PIMAGE_RESOURCE_DATA_ENTRY;
typedef struct _IMAGE_RESOURCE_DIR_STRING_U {
USHORT Length;
WCHAR NameString[1];
} IMAGE_RESOURCE_DIR_STRING_U, *PIMAGE_RESOURCE_DIR_STRING_U;
typedef struct _IMAGE_EXPORT_DIRECTORY {
ULONG Characteristics;
ULONG TimeDateStamp;
USHORT MajorVersion;
USHORT MinorVersion;
ULONG Name;
ULONG Base;
ULONG NumberOfFunctions;
ULONG NumberOfNames;
int *AddressOfFunctions;
int *AddressOfNames;
int *AddressOfNameOrdinals;
} IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;
//PE_Test1.cpp-----------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------------------------------------------------
#include"iostream"
#include"fstream"
#include"string"
#include"vector"
#include"iomanip"
#include"MyPeFile.h"
using namespace std;
int main(void)
{
int PeFlag=0;//Pe檔案標誌
char DosStub[100];
vector<char> DosStub2(40,0);
string str;
char dos[3];
int i=0;
ifstream fin("KillVirus.exe",ios::binary);//開啟 檔案
IMAGE_DOS_HEADER Image_dos_header;
IMAGE_FILE_HEADER Image_file_header;
IMAGE_OPTIONAL_HEADER Image_Optional_header;
IMAGE_SECTION_HEADER Image_section_header[20];
fin.read((char *)&Image_dos_header,sizeof(Image_dos_header));//MS—DOS MZ頭部
// fin>>Image_dos_header;
cout<<"MZ頭部:0x"<<hex<<Image_dos_header.e_magic<<endl;
cout<<"PE_Addr:0x"<<hex<<Image_dos_header.e_lfanew<<endl;
fin.seekg(0x50,ios::beg);//真實模式的殘餘部份用WinHex查詢的地址
fin.read(DosStub,40);
cout<<"DOS殘餘部分(用WinHex):";
for(i=0;i<36;i++)
{
cout<<DosStub[i];
}
cout<<endl;
fin.seekg(Image_dos_header.e_lfanew,ios::beg);//PE標誌
fin.read((char *)&PeFlag,sizeof(PeFlag));
cout<<"PE檔案標誌:0x"<<hex<<PeFlag<<endl;
fin.read((char *)&Image_file_header,sizeof(Image_file_header));//PE檔案頭
cout<<"Machine:0x"<<hex<<Image_file_header.Machine<<endl;
cout<<"NumberOfSections:0x"<<hex<<Image_file_header.NumberOfSections<<endl;
// cout<<dec<<sizeof(Image_file_header)<<endl;
fin.read((char *)&Image_Optional_header,sizeof(Image_Optional_header));//PE檔案
cout<<"Magic:0x"<<hex<<Image_Optional_header.Magic<<endl;
cout<<"可執行程式碼的大小:0x"<<hex<<Image_Optional_header.SizeOfCode<<endl;
cout<<"應用程式入口的位置:0x"<<hex<<Image_Optional_header.AddressOfEntryPoint<<endl;
cout<<".text:0x"<<hex<<Image_Optional_header.BaseOfCode<<endl;
cout<<".data:0x"<<hex<<Image_Optional_header.BaseOfData<<endl;
cout<<"FileAlignment:"<<hex<<Image_Optional_header.FileAlignment<<endl;
cout<<"Name/t"<<"SizeOfRawData/t"<<"PointerToRawData/t"<<"Characteristics/t"<<endl;
for(i=0;i<Image_file_header.NumberOfSections;i++)
{
fin.read((char *)&Image_section_header[i],sizeof(Image_section_header[i]));
cout<<Image_section_header[i].Name<<"/t";
cout<<hex<<Image_section_header[i].SizeOfRawData<<"/t";
cout<<hex<<Image_section_header[i].PointerToRawData<<"/t";
cout<<hex<<Image_section_header[i].Characteristics<<endl;
}
cout<<"********************************/n";
/*
fin.read(dos,3);//dos_mz
for(i=0;i<3;i++)
{
cout<<dos[i];
}
fin.seekg(0x50,ios::beg);//dos stub
fin.read(DosStub,40);
cout<<endl;
for(i=0;i<36;i++)
{
cout<<DosStub[i];
}
fin.seekg(0x100,ios::beg);//dos stub
fin.read(DosStub,2);
cout<<endl;
for(i=0;i<2;i++)
{
cout<<DosStub[i];
}
cout<<endl;
short m;
cout<<sizeof(m)<<endl;*/
fin.close();
while(1);
return 0;
}