我编写了一个程序,将一个可执行文件(主要是.exe,.dll )映射到程序的内存空间,这样可以更容易地提取PE头信息。我通过简单地将某个头的结构转换到映射文件的内存位置来提取信息。
可读性和一般结构。有些命名是可怕的,我不知道哪一个是正确的选择。主要功能看起来好像因为某种原因到处都是,感觉很难读懂。当然,还有其他的事情,我肯定有很多不好的事情我没有意识到。
#include <windows.h>
#include <stdio.h>
#include "pe32inf.h"
void Terminate(const char *s);
LPCTSTR DecodeInput(int argc, char *argv[]);
LPVOID Map(LPCTSTR lpFileName);
MZ_DOS SetDOSheader(LPVOID lpFileBase);
COFF SetCOFFheader(LPVOID lpCOFFoffset);
SectionTable SetSectionTable(LPVOID SectionTableOffset, int NumberOfSections);
int main(int argc, char *argv[])
{
LPCTSTR lpFileName;
LPVOID lpFileBase;
MZ_DOS DOSheader; //Naming issues with the headers.
COFF COFFheader;
OptionalHeader OPTheader; //I tried to get around the 2 declarations because 1 is going to be unused.
OptionalHeader64 OPTheader64; //However, I can only think of malloc and then there's inconsistency since this will be a PTR.
SectionTable SECtable;
lpFileName = DecodeInput(argc, argv);
lpFileBase = Map(lpFileName);
DOSheader = SetDOSheader(lpFileBase);
COFFheader = SetCOFFheader(lpFileBase + DOSheader.pe_offset + 0x4); //0x4 To skip PE sig.
LPVOID lpOptionalHeader = lpFileBase + DOSheader.pe_offset + 0x4 + sizeof(COFF);
WORD magic = *(WORD*)lpOptionalHeader;
if (magic == 0x10b) { //PE32
OPTheader = *(OptionalHeader*)lpOptionalHeader;
} else if (magic == 0x20b) { //PE32+
OPTheader64 = *(OptionalHeader64*)lpOptionalHeader;
} else {
Terminate("Unknown PE magic.");
}
LPVOID SectionTableOffset = lpOptionalHeader + COFFheader.SizeOfOptionalHeader;
SECtable = SetSectionTable(SectionTableOffset, COFFheader.NumberOfSections);
return 0;
}
COFF SetCOFFheader(LPVOID lpCOFFoffset)
{
COFF COFFheader;
COFFheader = *(COFF*)lpCOFFoffset;
return COFFheader;
}
SectionTable SetSectionTable(LPVOID SectionTableOffset, int NumberOfSections)
{
SectionTable SECtable;
SECtable.NumberOfSections = NumberOfSections;
SECtable.sectionHeader = malloc(sizeof(SectionHeader) * SECtable.NumberOfSections);
for (int i = 0; i < SECtable.NumberOfSections; i++) {
SECtable.sectionHeader[i] = *(SectionHeader*)(SectionTableOffset + (i * sizeof(SectionHeader)));
}
return SECtable;
}
MZ_DOS SetDOSheader(LPVOID lpFileBase)
{
MZ_DOS DOSheader = *(MZ_DOS*)lpFileBase;
if (DOSheader.signature != 0x5a4D) { //MZ
Terminate("MZ signature not found. File is not an executable image.");
}
if (*(DWORD*)(DOSheader.pe_offset + lpFileBase) != 0x4550) { //PE\0\0
Terminate("PE signature not found. File is not an executable image.\n");
}
return DOSheader;
}
LPCTSTR DecodeInput(int argc, char *argv[]){
if (argc < 2) {
Terminate("No file name specified.");
}
LPCTSTR lpFileName = argv[argc - 1];
if (lpFileName == NULL) {
Terminate("I mean, it probably won't even be NULL.");
}
return lpFileName;
}
LPVOID Map(LPCTSTR lpFileName)
{
HANDLE hFile;
HANDLE hFileMapping;
LPVOID lpFileBase;
hFile = CreateFile(lpFileName, GENERIC_READ, FILE_SHARE_READ,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if (hFile == INVALID_HANDLE_VALUE) {
Terminate("Could not open file.\n");
}
hFileMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY,
0, 0, NULL);
if (hFileMapping == NULL) {
Terminate("Could not create Mapping.\n");
}
lpFileBase = MapViewOfFile(hFileMapping, FILE_MAP_READ, 0, 0, 0);
if (lpFileBase == NULL) {
Terminate("Could not Map view of file.\n");
}
return lpFileBase;
}
void Terminate(const char *s)
{
//Windows will take care of closing the handles. *gasp*
printf("%s", s);
exit(0);
}#include <WinDef.h>
typedef struct //http://www.delorie.com/djgpp/doc/exe/
{
WORD signature; /* == 0x5a4D */
WORD bytes_in_last_block;
WORD blocks_in_file;
WORD num_relocs;
WORD header_paragraphs;
WORD min_extra_paragraphs;
WORD max_extra_paragraphs;
WORD ss;
WORD sp;
WORD checksum;
WORD ip;
WORD cs;
WORD reloc_table_offset;
WORD overlay_number;
BYTE padding[0x1F];
DWORD pe_offset;
} MZ_DOS;
typedef struct
{
WORD Machine;
WORD NumberOfSections;
DWORD TimeDateStamp;
DWORD PointerToSymbolTable;
DWORD NumberOfSymbols;
WORD SizeOfOptionalHeader;
WORD Characteristics;
} COFF;
typedef struct
{
WORD Magic;
BYTE MajorLinkerVersion;
BYTE MinorLinkerVersion;
DWORD SizeOfCode;
DWORD SizeOfInitializedData;
DWORD SizeOfUninitializedData;
DWORD AddressOfEntryPoint;
DWORD BaseOfCode;
DWORD BaseOfData;
} StandardFields;
typedef struct
{
WORD Magic;
BYTE MajorLinkerVersion;
BYTE MinorLinkerVersion;
DWORD SizeOfCode;
DWORD SizeOfInitializedData;
DWORD SizeOfUninitializedData;
DWORD AddressOfEntryPoint;
DWORD BaseOfCode;
} StandardFields64;
typedef struct
{
DWORD ImageBase;
DWORD SectionAlignment;
DWORD FileAlignment;
WORD MajorOperatingSystemVersion;
WORD MinorOperatingSystemVersion;
WORD MajorImageVersion;
WORD MinorImageVersion;
WORD MajorSubsystemVersion;
WORD MinorSubsystemVersion;
DWORD Win64VersionValue;
DWORD SizeOfImage;
DWORD SizeOfHeaders;
DWORD CheckSum;
WORD Subsystem;
WORD DllCharacteristics;
DWORD SizeOfStackReserve;
DWORD SizeOfStackCommit;
DWORD SizeOfHeapReserve;
DWORD SizeOfHeapCommit;
DWORD LoaderFlags;
DWORD NumberOfRvaAndSizes;
} WindowsFields;
typedef struct
{
DWORDLONG ImageBase;
DWORD SectionAlignment;
DWORD FileAlignment;
WORD MajorOperatingSystemVersion;
WORD MinorOperatingSystemVersion;
WORD MajorImageVersion;
WORD MinorImageVersion;
WORD MajorSubsystemVersion;
WORD MinorSubsystemVersion;
DWORD Win64VersionValue;
DWORD SizeOfImage;
DWORD SizeOfHeaders;
DWORD CheckSum;
WORD Subsystem;
WORD DllCharacteristics;
DWORDLONG SizeOfStackReserve;
DWORDLONG SizeOfStackCommit;
DWORDLONG SizeOfHeapReserve;
DWORDLONG SizeOfHeapCommit;
DWORD LoaderFlags;
DWORD NumberOfRvaAndSizes;
} WindowsFields64;
typedef struct
{
IMAGE_DATA_DIRECTORY ExportTable;
IMAGE_DATA_DIRECTORY ImportTable;
IMAGE_DATA_DIRECTORY ResourceTable;
IMAGE_DATA_DIRECTORY ExceptionTable;
IMAGE_DATA_DIRECTORY CertificateTable;
IMAGE_DATA_DIRECTORY BaseRelocationTable;
IMAGE_DATA_DIRECTORY Debug;
IMAGE_DATA_DIRECTORY Architecture;
IMAGE_DATA_DIRECTORY GlobalPTR;
IMAGE_DATA_DIRECTORY TLStable;
IMAGE_DATA_DIRECTORY LoadConfigTable;
IMAGE_DATA_DIRECTORY BoundImport;
IMAGE_DATA_DIRECTORY IAT;
IMAGE_DATA_DIRECTORY DelayImportDescriptor;
IMAGE_DATA_DIRECTORY CLRruntimeHeader;
IMAGE_DATA_DIRECTORY Reserved;
} DataDirectories;
typedef struct
{
StandardFields standardFields;
WindowsFields windowsFields;
DataDirectories dataDirectories;
} OptionalHeader;
typedef struct
{
StandardFields64 standardFields; //Naming issue?
WindowsFields64 windowsFields;
DataDirectories dataDirectories;
} OptionalHeader64;
typedef struct
{
DWORDLONG Name;
DWORD VirtualSize;
DWORD VirtualAddress;
DWORD SizeOfRawData;
DWORD PointerToRawData;
DWORD PointerToRelocations;
DWORD PointerToLinenumbers;
WORD NumberOfRelocations;
WORD NumberOfLinenumbers;
DWORD Characteristics;
} SectionHeader;
typedef struct
{
int NumberOfSections;
SectionHeader *sectionHeader;
} SectionTable;发布于 2015-09-29 19:12:02
0x4,根据评论,它是PE签名的大小。我建议显式定义一个struct PE_signature,取其sizeof并删除注释。typedef void *LPVOID;。我感到惊讶的是,lpFileBase + smth竟然会编译。lpFileName == NULL是可能的。https://codereview.stackexchange.com/questions/106037
复制相似问题