mirror of
https://github.com/0xRick/PE-Parser
synced 2026-06-08 10:05:54 +00:00
567 lines
19 KiB
C++
567 lines
19 KiB
C++
#include "PE32FILE.h"
|
|
|
|
// CONSTRUCTOR
|
|
PE32FILE::PE32FILE(char* _NAME, FILE* _Ppefile) {
|
|
|
|
NAME = _NAME;
|
|
Ppefile = _Ppefile;
|
|
|
|
ParseFile();
|
|
|
|
}
|
|
|
|
// ADDRESS RESOLVERS
|
|
int PE32FILE::locate(DWORD VA) {
|
|
|
|
int index;
|
|
|
|
for (int i = 0; i < PEFILE_NT_HEADERS_FILE_HEADER_NUMBER0F_SECTIONS; i++) {
|
|
if (VA >= PEFILE_SECTION_HEADERS[i].VirtualAddress
|
|
&& VA < (PEFILE_SECTION_HEADERS[i].VirtualAddress + PEFILE_SECTION_HEADERS[i].Misc.VirtualSize)) {
|
|
index = i;
|
|
break;
|
|
}
|
|
}
|
|
return index;
|
|
|
|
}
|
|
|
|
DWORD PE32FILE::resolve(DWORD VA, int index) {
|
|
|
|
return (VA - PEFILE_SECTION_HEADERS[index].VirtualAddress) + PEFILE_SECTION_HEADERS[index].PointerToRawData;
|
|
|
|
}
|
|
|
|
// PARSERS
|
|
void PE32FILE::ParseDOSHeader() {
|
|
|
|
fseek(Ppefile, 0, SEEK_SET);
|
|
fread(&PEFILE_DOS_HEADER, sizeof(___IMAGE_DOS_HEADER), 1, Ppefile);
|
|
|
|
PEFILE_DOS_HEADER_EMAGIC = PEFILE_DOS_HEADER.e_magic;
|
|
PEFILE_DOS_HEADER_LFANEW = PEFILE_DOS_HEADER.e_lfanew;
|
|
|
|
}
|
|
|
|
void PE32FILE::ParseNTHeaders() {
|
|
|
|
fseek(Ppefile, PEFILE_DOS_HEADER.e_lfanew, SEEK_SET);
|
|
fread(&PEFILE_NT_HEADERS, sizeof(PEFILE_NT_HEADERS), 1, Ppefile);
|
|
|
|
PEFILE_NT_HEADERS_SIGNATURE = PEFILE_NT_HEADERS.Signature;
|
|
|
|
PEFILE_NT_HEADERS_FILE_HEADER_MACHINE = PEFILE_NT_HEADERS.FileHeader.Machine;
|
|
PEFILE_NT_HEADERS_FILE_HEADER_NUMBER0F_SECTIONS = PEFILE_NT_HEADERS.FileHeader.NumberOfSections;
|
|
PEFILE_NT_HEADERS_FILE_HEADER_SIZEOF_OPTIONAL_HEADER = PEFILE_NT_HEADERS.FileHeader.SizeOfOptionalHeader;
|
|
|
|
PEFILE_NT_HEADERS_OPTIONAL_HEADER_MAGIC = PEFILE_NT_HEADERS.OptionalHeader.Magic;
|
|
PEFILE_NT_HEADERS_OPTIONAL_HEADER_SIZEOF_CODE = PEFILE_NT_HEADERS.OptionalHeader.SizeOfCode;
|
|
PEFILE_NT_HEADERS_OPTIONAL_HEADER_SIZEOF_INITIALIZED_DATA = PEFILE_NT_HEADERS.OptionalHeader.SizeOfInitializedData;
|
|
PEFILE_NT_HEADERS_OPTIONAL_HEADER_SIZEOF_UNINITIALIZED_DATA = PEFILE_NT_HEADERS.OptionalHeader.SizeOfUninitializedData;
|
|
PEFILE_NT_HEADERS_OPTIONAL_HEADER_ADDRESSOF_ENTRYPOINT = PEFILE_NT_HEADERS.OptionalHeader.AddressOfEntryPoint;
|
|
PEFILE_NT_HEADERS_OPTIONAL_HEADER_BASEOF_CODE = PEFILE_NT_HEADERS.OptionalHeader.BaseOfCode;
|
|
PEFILE_NT_HEADERS_OPTIONAL_HEADER_IMAGEBASE = PEFILE_NT_HEADERS.OptionalHeader.ImageBase;
|
|
PEFILE_NT_HEADERS_OPTIONAL_HEADER_SECTION_ALIGNMENT = PEFILE_NT_HEADERS.OptionalHeader.SectionAlignment;
|
|
PEFILE_NT_HEADERS_OPTIONAL_HEADER_FILE_ALIGNMENT = PEFILE_NT_HEADERS.OptionalHeader.FileAlignment;
|
|
PEFILE_NT_HEADERS_OPTIONAL_HEADER_SIZEOF_IMAGE = PEFILE_NT_HEADERS.OptionalHeader.SizeOfImage;
|
|
PEFILE_NT_HEADERS_OPTIONAL_HEADER_SIZEOF_HEADERS = PEFILE_NT_HEADERS.OptionalHeader.SizeOfHeaders;
|
|
|
|
PEFILE_EXPORT_DIRECTORY = PEFILE_NT_HEADERS.OptionalHeader.DataDirectory[___IMAGE_DIRECTORY_ENTRY_EXPORT];
|
|
PEFILE_IMPORT_DIRECTORY = PEFILE_NT_HEADERS.OptionalHeader.DataDirectory[___IMAGE_DIRECTORY_ENTRY_IMPORT];
|
|
PEFILE_RESOURCE_DIRECTORY = PEFILE_NT_HEADERS.OptionalHeader.DataDirectory[___IMAGE_DIRECTORY_ENTRY_RESOURCE];
|
|
PEFILE_EXCEPTION_DIRECTORY = PEFILE_NT_HEADERS.OptionalHeader.DataDirectory[___IMAGE_DIRECTORY_ENTRY_EXCEPTION];
|
|
PEFILE_SECURITY_DIRECTORY = PEFILE_NT_HEADERS.OptionalHeader.DataDirectory[___IMAGE_DIRECTORY_ENTRY_SECURITY];
|
|
PEFILE_BASERELOC_DIRECTORY = PEFILE_NT_HEADERS.OptionalHeader.DataDirectory[___IMAGE_DIRECTORY_ENTRY_BASERELOC];
|
|
PEFILE_DEBUG_DIRECTORY = PEFILE_NT_HEADERS.OptionalHeader.DataDirectory[___IMAGE_DIRECTORY_ENTRY_DEBUG];
|
|
PEFILE_ARCHITECTURE_DIRECTORY = PEFILE_NT_HEADERS.OptionalHeader.DataDirectory[___IMAGE_DIRECTORY_ENTRY_ARCHITECTURE];
|
|
PEFILE_GLOBALPTR_DIRECTORY = PEFILE_NT_HEADERS.OptionalHeader.DataDirectory[___IMAGE_DIRECTORY_ENTRY_GLOBALPTR];
|
|
PEFILE_TLS_DIRECTORY = PEFILE_NT_HEADERS.OptionalHeader.DataDirectory[___IMAGE_DIRECTORY_ENTRY_TLS];
|
|
PEFILE_LOAD_CONFIG_DIRECTORY = PEFILE_NT_HEADERS.OptionalHeader.DataDirectory[___IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG];
|
|
PEFILE_BOUND_IMPORT_DIRECTORY = PEFILE_NT_HEADERS.OptionalHeader.DataDirectory[___IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT];
|
|
PEFILE_IAT_DIRECTORY = PEFILE_NT_HEADERS.OptionalHeader.DataDirectory[___IMAGE_DIRECTORY_ENTRY_IAT];
|
|
PEFILE_DELAY_IMPORT_DIRECTORY = PEFILE_NT_HEADERS.OptionalHeader.DataDirectory[___IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT];
|
|
PEFILE_COM_DESCRIPTOR_DIRECTORY = PEFILE_NT_HEADERS.OptionalHeader.DataDirectory[___IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR];
|
|
|
|
}
|
|
|
|
void PE32FILE::ParseSectionHeaders() {
|
|
|
|
PEFILE_SECTION_HEADERS = new ___IMAGE_SECTION_HEADER[PEFILE_NT_HEADERS_FILE_HEADER_NUMBER0F_SECTIONS];
|
|
for (int i = 0; i < PEFILE_NT_HEADERS_FILE_HEADER_NUMBER0F_SECTIONS; i++) {
|
|
int offset = (PEFILE_DOS_HEADER.e_lfanew + sizeof(PEFILE_NT_HEADERS)) + (i * ___IMAGE_SIZEOF_SECTION_HEADER);
|
|
fseek(Ppefile, offset, SEEK_SET);
|
|
fread(&PEFILE_SECTION_HEADERS[i], ___IMAGE_SIZEOF_SECTION_HEADER, 1, Ppefile);
|
|
}
|
|
|
|
}
|
|
|
|
void PE32FILE::ParseImportDirectory() {
|
|
|
|
DWORD _import_directory_address = resolve(PEFILE_IMPORT_DIRECTORY.VirtualAddress, locate(PEFILE_IMPORT_DIRECTORY.VirtualAddress));
|
|
_import_directory_count = 0;
|
|
|
|
while (true) {
|
|
___IMAGE_IMPORT_DESCRIPTOR tmp;
|
|
int offset = (_import_directory_count * sizeof(___IMAGE_IMPORT_DESCRIPTOR)) + _import_directory_address;
|
|
fseek(Ppefile, offset, SEEK_SET);
|
|
fread(&tmp, sizeof(___IMAGE_IMPORT_DESCRIPTOR), 1, Ppefile);
|
|
|
|
if (tmp.Name == 0x00000000 && tmp.FirstThunk == 0x00000000) {
|
|
_import_directory_count -= 1;
|
|
_import_directory_size = _import_directory_count * sizeof(___IMAGE_IMPORT_DESCRIPTOR);
|
|
break;
|
|
}
|
|
|
|
_import_directory_count++;
|
|
}
|
|
|
|
PEFILE_IMPORT_TABLE = new ___IMAGE_IMPORT_DESCRIPTOR[_import_directory_count];
|
|
|
|
for (int i = 0; i < _import_directory_count; i++) {
|
|
int offset = (i * sizeof(___IMAGE_IMPORT_DESCRIPTOR)) + _import_directory_address;
|
|
fseek(Ppefile, offset, SEEK_SET);
|
|
fread(&PEFILE_IMPORT_TABLE[i], sizeof(___IMAGE_IMPORT_DESCRIPTOR), 1, Ppefile);
|
|
}
|
|
|
|
}
|
|
|
|
void PE32FILE::ParseBaseReloc() {
|
|
|
|
DWORD _basereloc_directory_address = resolve(PEFILE_BASERELOC_DIRECTORY.VirtualAddress, locate(PEFILE_BASERELOC_DIRECTORY.VirtualAddress));
|
|
_basreloc_directory_count = 0;
|
|
int _basereloc_size_counter = 0;
|
|
|
|
while (true) {
|
|
___IMAGE_BASE_RELOCATION tmp;
|
|
|
|
int offset = (_basereloc_size_counter + _basereloc_directory_address);
|
|
|
|
fseek(Ppefile, offset, SEEK_SET);
|
|
fread(&tmp, sizeof(___IMAGE_BASE_RELOCATION), 1, Ppefile);
|
|
|
|
if (tmp.VirtualAddress == 0x00000000 &&
|
|
tmp.SizeOfBlock == 0x00000000) {
|
|
break;
|
|
}
|
|
|
|
_basreloc_directory_count++;
|
|
_basereloc_size_counter += tmp.SizeOfBlock;
|
|
}
|
|
|
|
PEFILE_BASERELOC_TABLE = new ___IMAGE_BASE_RELOCATION[_basreloc_directory_count];
|
|
|
|
_basereloc_size_counter = 0;
|
|
|
|
for (int i = 0; i < _basreloc_directory_count; i++) {
|
|
int offset = _basereloc_directory_address + _basereloc_size_counter;
|
|
fseek(Ppefile, offset, SEEK_SET);
|
|
fread(&PEFILE_BASERELOC_TABLE[i], sizeof(___IMAGE_BASE_RELOCATION), 1, Ppefile);
|
|
_basereloc_size_counter += PEFILE_BASERELOC_TABLE[i].SizeOfBlock;
|
|
}
|
|
|
|
}
|
|
|
|
void PE32FILE::ParseRichHeader() {
|
|
|
|
char* dataPtr = new char[PEFILE_DOS_HEADER_LFANEW];
|
|
fseek(Ppefile, 0, SEEK_SET);
|
|
fread(dataPtr, PEFILE_DOS_HEADER_LFANEW, 1, Ppefile);
|
|
|
|
int index_ = 0;
|
|
|
|
for (int i = 0; i <= PEFILE_DOS_HEADER_LFANEW; i++) {
|
|
if (dataPtr[i] == 0x52 && dataPtr[i + 1] == 0x69) {
|
|
index_ = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (index_ == 0) {
|
|
printf("Error while parsing Rich Header.");
|
|
PEFILE_RICH_HEADER_INFO.entries = 0;
|
|
return;
|
|
}
|
|
|
|
char key[4];
|
|
memcpy(key, dataPtr + (index_ + 4), 4);
|
|
|
|
int indexpointer = index_ - 4;
|
|
int RichHeaderSize = 0;
|
|
|
|
while (true) {
|
|
char tmpchar[4];
|
|
memcpy(tmpchar, dataPtr + indexpointer, 4);
|
|
|
|
for (int i = 0; i < 4; i++) {
|
|
tmpchar[i] = tmpchar[i] ^ key[i];
|
|
}
|
|
|
|
indexpointer -= 4;
|
|
RichHeaderSize += 4;
|
|
|
|
if (tmpchar[1] = 0x61 && tmpchar[0] == 0x44) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
char* RichHeaderPtr = new char[RichHeaderSize];
|
|
memcpy(RichHeaderPtr, dataPtr + (index_ - RichHeaderSize), RichHeaderSize);
|
|
|
|
for (int i = 0; i < RichHeaderSize; i += 4) {
|
|
|
|
for (int x = 0; x < 4; x++) {
|
|
RichHeaderPtr[i + x] = RichHeaderPtr[i + x] ^ key[x];
|
|
}
|
|
|
|
}
|
|
|
|
PEFILE_RICH_HEADER_INFO.size = RichHeaderSize;
|
|
PEFILE_RICH_HEADER_INFO.ptrToBuffer = RichHeaderPtr;
|
|
PEFILE_RICH_HEADER_INFO.entries = (RichHeaderSize - 16) / 8;
|
|
|
|
delete[] dataPtr;
|
|
|
|
PEFILE_RICH_HEADER.entries = new RICH_HEADER_ENTRY[PEFILE_RICH_HEADER_INFO.entries];
|
|
|
|
for (int i = 16; i < RichHeaderSize; i += 8) {
|
|
WORD PRODID = (uint16_t)((unsigned char)RichHeaderPtr[i + 3] << 8) | (unsigned char)RichHeaderPtr[i + 2];
|
|
WORD BUILDID = (uint16_t)((unsigned char)RichHeaderPtr[i + 1] << 8) | (unsigned char)RichHeaderPtr[i];
|
|
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];
|
|
PEFILE_RICH_HEADER.entries[(i / 8) - 2] = {
|
|
PRODID,
|
|
BUILDID,
|
|
USECOUNT
|
|
};
|
|
|
|
if (i + 8 >= RichHeaderSize) {
|
|
PEFILE_RICH_HEADER.entries[(i / 8) - 1] = { 0x0000, 0x0000, 0x00000000 };
|
|
}
|
|
|
|
}
|
|
|
|
delete[] PEFILE_RICH_HEADER_INFO.ptrToBuffer;
|
|
|
|
}
|
|
|
|
// PRINT INFO
|
|
void PE32FILE::PrintFileInfo() {
|
|
|
|
printf(" FILE: %s\n", NAME);
|
|
printf(" TYPE: 0x%X (PE32)\n", PEFILE_NT_HEADERS_OPTIONAL_HEADER_MAGIC);
|
|
|
|
}
|
|
|
|
void PE32FILE::PrintDOSHeaderInfo() {
|
|
|
|
printf(" DOS HEADER:\n");
|
|
printf(" -----------\n\n");
|
|
|
|
printf(" Magic: 0x%X\n", PEFILE_DOS_HEADER_EMAGIC);
|
|
printf(" File address of new exe header: 0x%X\n", PEFILE_DOS_HEADER_LFANEW);
|
|
|
|
}
|
|
|
|
void PE32FILE::PrintRichHeaderInfo() {
|
|
|
|
printf(" RICH HEADER:\n");
|
|
printf(" ------------\n\n");
|
|
|
|
for (int i = 0; i < PEFILE_RICH_HEADER_INFO.entries; i++){
|
|
printf(" 0x%X 0x%X 0x%X: %d.%d.%d\n",
|
|
PEFILE_RICH_HEADER.entries[i].buildID,
|
|
PEFILE_RICH_HEADER.entries[i].prodID,
|
|
PEFILE_RICH_HEADER.entries[i].useCount,
|
|
PEFILE_RICH_HEADER.entries[i].buildID,
|
|
PEFILE_RICH_HEADER.entries[i].prodID,
|
|
PEFILE_RICH_HEADER.entries[i].useCount);
|
|
}
|
|
|
|
}
|
|
|
|
void PE32FILE::PrintNTHeadersInfo() {
|
|
|
|
printf(" NT HEADERS:\n");
|
|
printf(" -----------\n\n");
|
|
|
|
printf(" PE Signature: 0x%X\n", PEFILE_NT_HEADERS_SIGNATURE);
|
|
|
|
printf("\n File Header:\n\n");
|
|
printf(" Machine: 0x%X\n", PEFILE_NT_HEADERS_FILE_HEADER_MACHINE);
|
|
printf(" Number of sections: 0x%X\n", PEFILE_NT_HEADERS_FILE_HEADER_NUMBER0F_SECTIONS);
|
|
printf(" Size of optional header: 0x%X\n", PEFILE_NT_HEADERS_FILE_HEADER_SIZEOF_OPTIONAL_HEADER);
|
|
|
|
printf("\n Optional Header:\n\n");
|
|
printf(" Magic: 0x%X\n", PEFILE_NT_HEADERS_OPTIONAL_HEADER_MAGIC);
|
|
printf(" Size of code section: 0x%X\n", PEFILE_NT_HEADERS_OPTIONAL_HEADER_SIZEOF_CODE);
|
|
printf(" Size of initialized data: 0x%X\n", PEFILE_NT_HEADERS_OPTIONAL_HEADER_SIZEOF_INITIALIZED_DATA);
|
|
printf(" Size of uninitialized data: 0x%X\n", PEFILE_NT_HEADERS_OPTIONAL_HEADER_SIZEOF_UNINITIALIZED_DATA);
|
|
printf(" Address of entry point: 0x%X\n", PEFILE_NT_HEADERS_OPTIONAL_HEADER_ADDRESSOF_ENTRYPOINT);
|
|
printf(" RVA of start of code section: 0x%X\n", PEFILE_NT_HEADERS_OPTIONAL_HEADER_BASEOF_CODE);
|
|
printf(" Desired image base: 0x%X\n", PEFILE_NT_HEADERS_OPTIONAL_HEADER_IMAGEBASE);
|
|
printf(" Section alignment: 0x%X\n", PEFILE_NT_HEADERS_OPTIONAL_HEADER_SECTION_ALIGNMENT);
|
|
printf(" File alignment: 0x%X\n", PEFILE_NT_HEADERS_OPTIONAL_HEADER_FILE_ALIGNMENT);
|
|
printf(" Size of image: 0x%X\n", PEFILE_NT_HEADERS_OPTIONAL_HEADER_SIZEOF_IMAGE);
|
|
printf(" Size of headers: 0x%X\n", PEFILE_NT_HEADERS_OPTIONAL_HEADER_SIZEOF_HEADERS);
|
|
|
|
printf("\n Data Directories:\n");
|
|
printf("\n * Export Directory:\n");
|
|
printf(" RVA: 0x%X\n", PEFILE_EXPORT_DIRECTORY.VirtualAddress);
|
|
printf(" Size: 0x%X\n", PEFILE_EXPORT_DIRECTORY.Size);
|
|
|
|
printf("\n * Import Directory:\n");
|
|
printf(" RVA: 0x%X\n", PEFILE_IMPORT_DIRECTORY.VirtualAddress);
|
|
printf(" Size: 0x%X\n", PEFILE_IMPORT_DIRECTORY.Size);
|
|
|
|
printf("\n * Resource Directory:\n");
|
|
printf(" RVA: 0x%X\n", PEFILE_RESOURCE_DIRECTORY.VirtualAddress);
|
|
printf(" Size: 0x%X\n", PEFILE_RESOURCE_DIRECTORY.Size);
|
|
|
|
printf("\n * Exception Directory:\n");
|
|
printf(" RVA: 0x%X\n", PEFILE_EXCEPTION_DIRECTORY.VirtualAddress);
|
|
printf(" Size: 0x%X\n", PEFILE_EXCEPTION_DIRECTORY.Size);
|
|
|
|
printf("\n * Security Directory:\n");
|
|
printf(" RVA: 0x%X\n", PEFILE_SECURITY_DIRECTORY.VirtualAddress);
|
|
printf(" Size: 0x%X\n", PEFILE_SECURITY_DIRECTORY.Size);
|
|
|
|
printf("\n * Base Relocation Table:\n");
|
|
printf(" RVA: 0x%X\n", PEFILE_BASERELOC_DIRECTORY.VirtualAddress);
|
|
printf(" Size: 0x%X\n", PEFILE_BASERELOC_DIRECTORY.Size);
|
|
|
|
printf("\n * Debug Directory:\n");
|
|
printf(" RVA: 0x%X\n", PEFILE_DEBUG_DIRECTORY.VirtualAddress);
|
|
printf(" Size: 0x%X\n", PEFILE_DEBUG_DIRECTORY.Size);
|
|
|
|
printf("\n * Architecture Specific Data:\n");
|
|
printf(" RVA: 0x%X\n", PEFILE_ARCHITECTURE_DIRECTORY.VirtualAddress);
|
|
printf(" Size: 0x%X\n", PEFILE_ARCHITECTURE_DIRECTORY.Size);
|
|
|
|
printf("\n * RVA of GlobalPtr:\n");
|
|
printf(" RVA: 0x%X\n", PEFILE_GLOBALPTR_DIRECTORY.VirtualAddress);
|
|
printf(" Size: 0x%X\n", PEFILE_GLOBALPTR_DIRECTORY.Size);
|
|
|
|
printf("\n * TLS Directory:\n");
|
|
printf(" RVA: 0x%X\n", PEFILE_TLS_DIRECTORY.VirtualAddress);
|
|
printf(" Size: 0x%X\n", PEFILE_TLS_DIRECTORY.Size);
|
|
|
|
printf("\n * Load Configuration Directory:\n");
|
|
printf(" RVA: 0x%X\n", PEFILE_LOAD_CONFIG_DIRECTORY.VirtualAddress);
|
|
printf(" Size: 0x%X\n", PEFILE_LOAD_CONFIG_DIRECTORY.Size);
|
|
|
|
printf("\n * Bound Import Directory:\n");
|
|
printf(" RVA: 0x%X\n", PEFILE_BOUND_IMPORT_DIRECTORY.VirtualAddress);
|
|
printf(" Size: 0x%X\n", PEFILE_BOUND_IMPORT_DIRECTORY.Size);
|
|
|
|
printf("\n * Import Address Table:\n");
|
|
printf(" RVA: 0x%X\n", PEFILE_IAT_DIRECTORY.VirtualAddress);
|
|
printf(" Size: 0x%X\n", PEFILE_IAT_DIRECTORY.Size);
|
|
|
|
printf("\n * Delay Load Import Descriptors:\n");
|
|
printf(" RVA: 0x%X\n", PEFILE_DELAY_IMPORT_DIRECTORY.VirtualAddress);
|
|
printf(" Size: 0x%X\n", PEFILE_DELAY_IMPORT_DIRECTORY.Size);
|
|
|
|
printf("\n * COM Runtime Descriptor:\n");
|
|
printf(" RVA: 0x%X\n", PEFILE_COM_DESCRIPTOR_DIRECTORY.VirtualAddress);
|
|
printf(" Size: 0x%X\n", PEFILE_COM_DESCRIPTOR_DIRECTORY.Size);
|
|
|
|
}
|
|
|
|
void PE32FILE::PrintSectionHeadersInfo() {
|
|
|
|
printf(" SECTION HEADERS:\n");
|
|
printf(" ----------------\n\n");
|
|
|
|
for (int i = 0; i < PEFILE_NT_HEADERS_FILE_HEADER_NUMBER0F_SECTIONS; i++) {
|
|
printf(" * %.8s:\n", PEFILE_SECTION_HEADERS[i].Name);
|
|
printf(" VirtualAddress: 0x%X\n", PEFILE_SECTION_HEADERS[i].VirtualAddress);
|
|
printf(" VirtualSize: 0x%X\n", PEFILE_SECTION_HEADERS[i].Misc.VirtualSize);
|
|
printf(" PointerToRawData: 0x%X\n", PEFILE_SECTION_HEADERS[i].PointerToRawData);
|
|
printf(" SizeOfRawData: 0x%X\n", PEFILE_SECTION_HEADERS[i].SizeOfRawData);
|
|
printf(" Characteristics: 0x%X\n\n", PEFILE_SECTION_HEADERS[i].Characteristics);
|
|
}
|
|
|
|
}
|
|
|
|
void PE32FILE::PrintImportTableInfo() {
|
|
|
|
printf(" IMPORT TABLE:\n");
|
|
printf(" ----------------\n\n");
|
|
|
|
for (int i = 0; i < _import_directory_count; i++) {
|
|
DWORD NameAddr = resolve(PEFILE_IMPORT_TABLE[i].Name, locate(PEFILE_IMPORT_TABLE[i].Name));
|
|
int NameSize = 0;
|
|
|
|
while (true) {
|
|
char tmp;
|
|
fseek(Ppefile, (NameAddr + NameSize), SEEK_SET);
|
|
fread(&tmp, sizeof(char), 1, Ppefile);
|
|
|
|
if (tmp == 0x00) {
|
|
break;
|
|
}
|
|
|
|
NameSize++;
|
|
}
|
|
|
|
char* Name = new char[NameSize + 2];
|
|
fseek(Ppefile, NameAddr, SEEK_SET);
|
|
fread(Name, (NameSize * sizeof(char)) + 1, 1, Ppefile);
|
|
printf(" * %s:\n", Name);
|
|
delete[] Name;
|
|
|
|
printf(" ILT RVA: 0x%X\n", PEFILE_IMPORT_TABLE[i].DUMMYUNIONNAME.OriginalFirstThunk);
|
|
printf(" IAT RVA: 0x%X\n", PEFILE_IMPORT_TABLE[i].FirstThunk);
|
|
|
|
if (PEFILE_IMPORT_TABLE[i].TimeDateStamp == 0) {
|
|
printf(" Bound: FALSE\n");
|
|
}
|
|
else if (PEFILE_IMPORT_TABLE[i].TimeDateStamp == -1) {
|
|
printf(" Bound: TRUE\n");
|
|
}
|
|
|
|
printf("\n");
|
|
|
|
DWORD ILTAddr = resolve(PEFILE_IMPORT_TABLE[i].DUMMYUNIONNAME.OriginalFirstThunk, locate(PEFILE_IMPORT_TABLE[i].DUMMYUNIONNAME.OriginalFirstThunk));
|
|
int entrycounter = 0;
|
|
|
|
while (true) {
|
|
|
|
ILT_ENTRY_32 entry;
|
|
|
|
fseek(Ppefile, (ILTAddr + (entrycounter * sizeof(DWORD))), SEEK_SET);
|
|
fread(&entry, sizeof(ILT_ENTRY_32), 1, Ppefile);
|
|
|
|
BYTE flag = entry.FIELD_1.ORDINAL_NAME_FLAG;
|
|
DWORD HintRVA = 0x0;
|
|
WORD ordinal = 0x0;
|
|
|
|
if (flag == 0x0) {
|
|
HintRVA = entry.FIELD_1.HINT_NAME_TABE;
|
|
}
|
|
else if (flag == 0x01) {
|
|
ordinal = entry.FIELD_1.ORDINAL;
|
|
}
|
|
|
|
if (flag == 0x0 && HintRVA == 0x0 && ordinal == 0x0) {
|
|
break;
|
|
}
|
|
|
|
printf("\n Entry:\n");
|
|
|
|
if (flag == 0x0) {
|
|
___IMAGE_IMPORT_BY_NAME hint;
|
|
|
|
DWORD HintAddr = resolve(HintRVA, locate(HintRVA));
|
|
fseek(Ppefile, HintAddr, SEEK_SET);
|
|
fread(&hint, sizeof(___IMAGE_IMPORT_BY_NAME), 1, Ppefile);
|
|
printf(" Name: %s\n", hint.Name);
|
|
printf(" Hint RVA: 0x%X\n", HintRVA);
|
|
printf(" Hint: 0x%X\n", hint.Hint);
|
|
}
|
|
else if (flag == 1) {
|
|
printf(" Ordinal: 0x%X\n", ordinal);
|
|
}
|
|
|
|
entrycounter++;
|
|
}
|
|
|
|
printf("\n ----------------------\n\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
void PE32FILE::PrintBaseRelocationsInfo() {
|
|
|
|
printf(" BASE RELOCATIONS TABLE:\n");
|
|
printf(" -----------------------\n");
|
|
|
|
int szCounter = sizeof(___IMAGE_BASE_RELOCATION);
|
|
|
|
for (int i = 0; i < _basreloc_directory_count; i++) {
|
|
|
|
DWORD PAGERVA, BLOCKSIZE, BASE_RELOC_ADDR;
|
|
int ENTRIES;
|
|
|
|
BASE_RELOC_ADDR = resolve(PEFILE_BASERELOC_DIRECTORY.VirtualAddress, locate(PEFILE_BASERELOC_DIRECTORY.VirtualAddress));
|
|
PAGERVA = PEFILE_BASERELOC_TABLE[i].VirtualAddress;
|
|
BLOCKSIZE = PEFILE_BASERELOC_TABLE[i].SizeOfBlock;
|
|
ENTRIES = (BLOCKSIZE - sizeof(___IMAGE_BASE_RELOCATION)) / sizeof(WORD);
|
|
|
|
printf("\n Block 0x%X: \n", i);
|
|
printf(" Page RVA: 0x%X\n", PAGERVA);
|
|
printf(" Block size: 0x%X\n", BLOCKSIZE);
|
|
printf(" Number of entries: 0x%X\n", ENTRIES);
|
|
printf("\n Entries:\n");
|
|
|
|
for (int i = 0; i < ENTRIES; i++) {
|
|
|
|
BASE_RELOC_ENTRY entry;
|
|
|
|
int offset = (BASE_RELOC_ADDR + szCounter + (i * sizeof(WORD)));
|
|
|
|
fseek(Ppefile, offset, SEEK_SET);
|
|
fread(&entry, sizeof(WORD), 1, Ppefile);
|
|
|
|
printf("\n * Value: 0x%X\n", entry);
|
|
printf(" Relocation Type: 0x%X\n", entry.TYPE);
|
|
printf(" Offset: 0x%X\n", entry.OFFSET);
|
|
|
|
}
|
|
printf("\n ----------------------\n\n");
|
|
szCounter += BLOCKSIZE;
|
|
}
|
|
|
|
}
|
|
|
|
// MAIN
|
|
void PE32FILE::ParseFile() {
|
|
|
|
// PARSE DOS HEADER
|
|
ParseDOSHeader();
|
|
|
|
// PARSE RICH HEADER
|
|
ParseRichHeader();
|
|
|
|
//PARSE NT HEADERS
|
|
ParseNTHeaders();
|
|
|
|
// PARSE SECTION HEADERS
|
|
ParseSectionHeaders();
|
|
|
|
// PARSE IMPORT DIRECTORY
|
|
ParseImportDirectory();
|
|
|
|
// PARSE BASE RELOCATIONS
|
|
ParseBaseReloc();
|
|
|
|
}
|
|
|
|
void PE32FILE::PrintInfo() {
|
|
|
|
printf("\n\n");
|
|
|
|
PrintFileInfo();
|
|
printf("\n ----------------------------------\n\n");
|
|
|
|
PrintDOSHeaderInfo();
|
|
printf("\n ----------------------------------\n\n");
|
|
|
|
PrintRichHeaderInfo();
|
|
printf("\n ----------------------------------\n\n");
|
|
|
|
PrintNTHeadersInfo();
|
|
printf("\n ----------------------------------\n\n");
|
|
|
|
PrintSectionHeadersInfo();
|
|
printf("\n ----------------------------------\n\n");
|
|
|
|
PrintImportTableInfo();
|
|
printf("\n ----------------------------------\n\n");
|
|
|
|
PrintBaseRelocationsInfo();
|
|
printf("\n ----------------------------------\n\n");
|
|
|
|
return;
|
|
|
|
} |