#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdint.h>
#include <windows.h>
size_t get_file_size(const char *filename)
{
FILE *file = fopen(filename, "r");
if(!file)
return -1;
fseek(file, 0, SEEK_END);
size_t size = ftell(file);
fclose(file);
return size;
}
bool read_file(const char *filename, uint8_t *buff, size_t size)
{
FILE *file = fopen(filename, "rb");
if(!file)
return false;
fread(buff, 1, size, file);
fclose(file);
return true;
}
void print_image_dos_header(IMAGE_DOS_HEADER *idh)
{
printf("IMAGE_DOS_HEADER\n");
printf("e_magic: %.4x\n", idh->e_magic);
printf("e_cblp: %.4x\n", idh->e_cblp);
printf("e_cp: %.4x\n", idh->e_cp);
printf("e_crlc: %.4x\n", idh->e_crlc);
printf("e_cparhdr: %.4x\n", idh->e_cparhdr);
printf("e_minalloc: %.4x\n", idh->e_minalloc);
printf("e_maxalloc: %.4x\n", idh->e_maxalloc);
printf("e_ss: %.4x\n", idh->e_ss);
printf("e_sp: %.4x\n", idh->e_sp);
printf("e_csum: %.4x\n", idh->e_csum);
printf("e_ip: %.4x\n", idh->e_ip);
printf("e_cs: %.4x\n", idh->e_cs);
printf("e_lfarlc: %.4x\n", idh->e_lfarlc);
printf("e_ovno: %.4x\n", idh->e_ovno);
printf("e_res[0]: %.2x\n", idh->e_res[0]);
printf("e_res[1]: %.2x\n", idh->e_res[1]);
printf("e_res[2]: %.2x\n", idh->e_res[2]);
printf("e_res[3]: %.2x\n", idh->e_res[3]);
printf("e_oemid: %.4x\n", idh->e_oemid);
printf("e_oeminfo: %.4x\n", idh->e_oeminfo);
printf("e_res2[0]: %.2x\n", idh->e_res2[0]);
printf("e_res2[1]: %.2x\n", idh->e_res2[1]);
printf("e_res2[2]: %.2x\n", idh->e_res2[2]);
printf("e_res2[3]: %.2x\n", idh->e_res2[3]);
printf("e_res2[4]: %.2x\n", idh->e_res2[4]);
printf("e_res2[5]: %.2x\n", idh->e_res2[5]);
printf("e_res2[6]: %.2x\n", idh->e_res2[6]);
printf("e_res2[7]: %.2x\n", idh->e_res2[7]);
printf("e_res2[8]: %.2x\n", idh->e_res2[8]);
printf("e_res2[9]: %.2x\n", idh->e_res2[9]);
printf("e_lfanew: %.8x\n", idh->e_lfanew);
}
void print_image_nt_headers(IMAGE_NT_HEADERS *inh, uint8_t *base)
{
printf("IMAGE_NT_HEADERS\n");
printf("Signature: %.8x\n", inh->Signature);
// 下面这两个结构,这里只打印出在文件中的偏移
printf("FileHeader: %.8x\n", (uint8_t *)&inh->FileHeader - base);
printf("OptionalHeader: %.8x\n", (uint8_t *)&inh->OptionalHeader - base);
}
void print_image_file_header(IMAGE_FILE_HEADER *ifh)
{
printf("IMAGE_FILE_HEADER\n");
printf("Machine: %.4x\n", ifh->Machine);
printf("NumberOfSections: %.4x\n", ifh->NumberOfSections);
printf("TimeDateStamp: %.8x\n", ifh->TimeDateStamp);
printf("PointerToSymbolTable: %.8x\n", ifh->PointerToSymbolTable);
printf("NumberOfSymbols: %.8x\n", ifh->NumberOfSymbols);
printf("SizeOfOptionalHeader: %.4x\n", ifh->SizeOfOptionalHeader);
printf("Characteristics: %.4x\n", ifh->Characteristics);
}
void print_image_optional_header(IMAGE_OPTIONAL_HEADER *ioh, uint8_t *base)
{
printf("IMAGE_OPTIONAL_HEADER\n");
printf("Magic: %.4x\n", ioh->Magic);
printf("MajorLinkerVersion: %.2x\n", ioh->MajorLinkerVersion);
printf("MinorLinkerVersion: %.2x\n", ioh->MinorLinkerVersion);
printf("SizeOfCode: %.8x\n", ioh->SizeOfCode);
printf("SizeOfInitializedData: %.8x\n", ioh->SizeOfInitializedData);
printf("SizeOfUninitializedData: %.8x\n", ioh->SizeOfUninitializedData);
printf("AddressOfEntryPoint: %.8x\n", ioh->AddressOfEntryPoint);
printf("BaseOfCode: %.8x\n", ioh->BaseOfCode);
printf("BaseOfData: %.8x\n", ioh->BaseOfData);
printf("ImageBase: %.8x\n", ioh->ImageBase);
printf("SectionAlignment: %.8x\n", ioh->SectionAlignment);
printf("FileAlignment: %.8x\n", ioh->FileAlignment);
printf("MajorOperatingSystemVersion: %.4x\n", ioh->MajorOperatingSystemVersion);
printf("MinorOperatingSystemVersion: %.4x\n", ioh->MinorOperatingSystemVersion);
printf("MajorImageVersion: %.4x\n", ioh->MajorImageVersion);
printf("MinorImageVersion: %.4x\n", ioh->MinorImageVersion);
printf("MajorSubsystemVersion: %.4x\n", ioh->MajorSubsystemVersion);
printf("MinorSubsystemVersion: %.4x\n", ioh->MinorSubsystemVersion);
printf("Win32VersionValue: %.8x\n", ioh->Win32VersionValue);
printf("SizeOfImage: %.8x\n", ioh->SizeOfImage);
printf("SizeOfHeaders: %.8x\n", ioh->SizeOfHeaders);
printf("CheckSum: %.8x\n", ioh->CheckSum);
printf("Subsystem: %.4x\n", ioh->Subsystem);
printf("DllCharacteristics: %.4x\n", ioh->DllCharacteristics);
printf("SizeOfStackReserve: %.8x\n", ioh->SizeOfStackReserve);
printf("SizeOfStackCommit: %.8x\n", ioh->SizeOfStackCommit);
printf("SizeOfHeapReserve: %.8x\n", ioh->SizeOfHeapReserve);
printf("SizeOfHeapCommit: %.8x\n", ioh->SizeOfHeapCommit);
printf("LoaderFlags: %.8x\n", ioh->LoaderFlags);
printf("NumberOfRvaAndSizes: %.8x\n", ioh->NumberOfRvaAndSizes);
// 下面这个数组,我还没有想好要以什么样的形式展开,如何展开,现在只是打印文件偏移
printf("DataDirectory: %.8x\n", (uint8_t *)&ioh->DataDirectory - base);
}
int main(void)
{
const char *filename = "print_pe.exe";
size_t size = get_file_size(filename);
uint8_t *buff = malloc(size);
read_file(filename, buff, size);
IMAGE_DOS_HEADER *idh = (IMAGE_DOS_HEADER *)buff;
IMAGE_NT_HEADERS *inh = (IMAGE_NT_HEADERS *)(buff + idh->e_lfanew);
print_image_dos_header(idh); printf("\n");
print_image_nt_headers(inh, buff); printf("\n");
print_image_file_header(&inh->FileHeader); printf("\n");
print_image_optional_header(&inh->OptionalHeader, buff); printf("\n");
free(buff);
return 0;
}