今天看了下关于windows平台的PE结构,然后通过C++写了一个简单的加载PE信息的程序,只加载了DOS头、NT头、以及节点的信息,以后补上关于加载输出表、输入表的相关代码,详细代码如下:
#include <iostream>
#include <
string>
#include <Windows.h>
using
namespace std;
//Dos Header
typedef
struct _BEGIN09_IMAGE_DOS_HEADER {
// DOS .EXE header
WORD e_magic;
// Magic number
WORD e_cblp;
// Bytes on last page of file
WORD e_cp;
// Pages in file
WORD e_crlc;
// Relocations
WORD e_cparhdr;
// Size of header in paragraphs
WORD e_minalloc;
// Minimum extra paragraphs needed
WORD e_maxalloc;
// Maximum extra paragraphs needed
WORD e_ss;
// Initial (relative) SS value
WORD e_sp;
// Initial SP value
WORD e_csum;
// Checksum
WORD e_ip;
// Initial IP value
WORD e_cs;
// Initial (relative) CS value
WORD e_lfarlc;
// File address of relocation table
WORD e_ovno;
// Overlay number
WORD e_res[4];
// Reserved words
WORD e_oemid;
// OEM identifier (for e_oeminfo)
WORD e_oeminfo;
// OEM information; e_oemid specific
WORD e_res2[10];
// Reserved words
LONG e_lfanew;
// File address of new exe header
} BEGIN09_IMAGE_DOS_HEADER, *PBEGIN09_IMAGE_DOS_HEADER;
//NT_Header
typedef
struct _BEGIN09_IMAGE_NT_HEADERS {
DWORD Signature;
IMAGE_FILE_HEADER FileHeader;
IMAGE_OPTIONAL_HEADER32 OptionalHeader;
} BEGIN09_IMAGE_NT_HEADERS32, *PBEGIN09_IMAGE_NT_HEADERS32;
//File Header
typedef
struct _BEGIN09_IMAGE_FILE_HEADER {
WORD Machine;
WORD NumberOfSections;
DWORD TimeDateStamp;
DWORD PointerToSymbolTable;
DWORD NumberOfSymbols;
WORD SizeOfOptionalHeader;
WORD Characteristics;
} BEGIN09_IMAGE_FILE_HEADER, *PBEGIN09_IMAGE_FILE_HEADER;
//Option Header
typedef
struct _BEGIN09_IMAGE_OPTIONAL_HEADER {
//
// Standard fields.
//
WORD Magic;
BYTE MajorLinkerVersion;
BYTE MinorLinkerVersion;
DWORD SizeOfCode;
DWORD SizeOfInitializedData;
DWORD SizeOfUninitializedData;
DWORD AddressOfEntryPoint;
DWORD BaseOfCode;
DWORD BaseOfData;
//
// NT additional fields.
//
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];
} BEGIN09_IMAGE_OPTIONAL_HEADER32, *PBEGIN09_IMAGE_OPTIONAL_HEADER32;
//Data Dir
typedef
struct _BEGIN09_IMAGE_DATA_DIRECTORY {
DWORD VirtualAddress;
DWORD Size;
} BEGIN09_IMAGE_DATA_DIRECTORY, *PBEGIN09_IMAGE_DATA_DIRECTORY;
//Sec Header
typedef
struct _BEGIN09_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;
} BEGIN09_IMAGE_SECTION_HEADER, *PBEGIN09_IMAGE_SECTION_HEADER;
int main()
{
BEGIN09_IMAGE_DOS_HEADER *pDos_Header = NULL;
BEGIN09_IMAGE_NT_HEADERS32 *pNt_Header = NULL;
BEGIN09_IMAGE_SECTION_HEADER *pSection_Header = NULL;
int nFileSize = 0x400;
int nRetCode = 0;
BYTE *pByteBuffer = NULL;
size_t nReadBytes = 0;
FILE *pFileOpen = fopen(
"C:\\Documents and Settings\\Administrator\\桌面\\PE\\PE\\ASM.exe" ,
"r+b" );
if ( NULL == pFileOpen )
{
goto Exit0;
}
pByteBuffer =
new BYTE[ nFileSize + 1 ];
if ( NULL == pByteBuffer )
{
goto Exit0;
}
memset( pByteBuffer, 0, nFileSize + 1);
nReadBytes = fread( pByteBuffer,
sizeof(BYTE), nFileSize, pFileOpen);
if ( nReadBytes == 0 )
{
goto Exit0;
}
pDos_Header = (BEGIN09_IMAGE_DOS_HEADER*) (pByteBuffer);
if ( NULL == pDos_Header )
{
goto Exit0;
}
pNt_Header = ( BEGIN09_IMAGE_NT_HEADERS32* ) ( pByteBuffer + pDos_Header->e_lfanew );
if ( NULL == pNt_Header )
{
goto Exit0;
}
pSection_Header = ( BEGIN09_IMAGE_SECTION_HEADER* ) ( pByteBuffer + pDos_Header->e_lfanew +
sizeof(DWORD) +
sizeof(BEGIN09_IMAGE_FILE_HEADER) + pNt_Header->FileHeader.SizeOfOptionalHeader );
if ( NULL == pSection_Header)
{
goto Exit0;
}
nRetCode = 1;
cout<<
"此程序的运行平台为:"<<endl;
if ( 0x014C == pNt_Header->FileHeader.Machine )
{
cout<<
"运行平台为 Intel 386"<<endl;
}
else
{
cout<<
"未知的运行平台"<<endl;
}
cout<<
"此文件程序入口为:"<<endl;
cout<<pNt_Header->OptionalHeader.AddressOfEntryPoint;
cout<<
"此程序一共有多少个节:"<<endl;
cout<<pNt_Header->FileHeader.NumberOfSections<<endl;
cout<<
"此程序的基地址为:"<<endl;
cout<<pNt_Header->OptionalHeader.ImageBase<<endl;
Exit0:
return nRetCode;
}
此程序用了静态的文件路径以及文件记载信息的大小申请空间都是用的固定的数值,比较山寨,呵呵以后写一个详细的加载PE信息的程序.
本文转自wiliiwin 51CTO博客,原文链接:http://blog.51cto.com/wiliiwin/236425