2008-07-11 16:51:25 +00:00
|
|
|
/*
|
|
|
|
* PeLibAux.cpp - Part of the PeLib library.
|
|
|
|
*
|
|
|
|
* Copyright (c) 2004 - 2005 Sebastian Porst (webmaster@the-interweb.com)
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* This software is licensed under the zlib/libpng License.
|
|
|
|
* For more details see http://www.opensource.org/licenses/zlib-license.php
|
|
|
|
* or the license information file (license.htm) in the root directory
|
|
|
|
* of PeLib.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef PELIBAUX_H
|
|
|
|
#define PELIBAUX_H
|
|
|
|
|
|
|
|
//#include "PeLibInc.h"
|
|
|
|
//#include "PeHeader.h"
|
|
|
|
#include "buffer/OutputBuffer.h"
|
|
|
|
#include "buffer/InputBuffer.h"
|
|
|
|
//#include "buffer/ResTree.h"
|
|
|
|
#include <numeric>
|
|
|
|
#include <limits>
|
|
|
|
|
|
|
|
namespace PeLib
|
|
|
|
{
|
|
|
|
enum errorCodes
|
|
|
|
{
|
|
|
|
NO_ERROR = 0,
|
|
|
|
ERROR_OPENING_FILE = -1,
|
|
|
|
ERROR_INVALID_FILE = -2,
|
|
|
|
ERROR_TOO_MANY_SECTIONS = -3,
|
|
|
|
ERROR_NOT_ENOUGH_SPACE = -4,
|
|
|
|
ERROR_NO_FILE_ALIGNMENT = -5,
|
|
|
|
ERROR_NO_SECTION_ALIGNMENT = -6,
|
|
|
|
ERROR_ENTRY_NOT_FOUND = -7,
|
|
|
|
ERROR_DUPLICATE_ENTRY = -8,
|
|
|
|
ERROR_DIRECTORY_DOES_NOT_EXIST = -9
|
|
|
|
};
|
|
|
|
|
|
|
|
class PeFile;
|
|
|
|
bool isEqualNc(const std::string& s1, const std::string& s2);
|
|
|
|
|
|
|
|
// It's necessary to make sure that a byte has 8 bits and that the platform has a 8 bit type,
|
|
|
|
// a 16bit type and a bit type. That's because binary PE files are pretty picky about their
|
|
|
|
// structure.
|
|
|
|
|
|
|
|
#if CHAR_BIT == 8
|
|
|
|
#if UCHAR_MAX == 255
|
|
|
|
typedef unsigned char byte;
|
|
|
|
// typedef std::bitset<8> byte;
|
|
|
|
#else
|
|
|
|
#error You need to change some typedefs (Code: 8). Please read the PeLib documentation.
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if USHRT_MAX == 65535U
|
|
|
|
typedef unsigned short word;
|
|
|
|
// typedef std::bitset<16> word;
|
|
|
|
#else
|
|
|
|
#error You need to change some typedefs (Code: 16). Please read the PeLib documentation.
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if UINT_MAX == 4294967295UL
|
|
|
|
typedef unsigned int dword;
|
|
|
|
// typedef std::bitset<32> dword;
|
|
|
|
#else
|
|
|
|
#error You need to change some typedefs (Code: 32). Please read the PeLib documentation.
|
|
|
|
#endif
|
|
|
|
|
|
|
|
typedef unsigned long long qword;
|
|
|
|
|
|
|
|
// #if ULLONG_MAX == 18446744073709551615
|
|
|
|
// typedef unsigned long long qword;
|
|
|
|
// #else
|
|
|
|
// #error You need to change some typedefs (Code: 32). Please read the PeLib documentation.
|
|
|
|
// #endif
|
|
|
|
#else
|
|
|
|
#error You need to change some typedefs. Please read the PeLib documentation.
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
/* enum bits {BITS_BYTE = 8, BITS_WORD = 16, BITS_DWORD = 32};
|
|
|
|
|
|
|
|
template<bits value>
|
|
|
|
class DataType
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
std::bitset<value> bsValue;
|
|
|
|
unsigned long ulValue;
|
|
|
|
|
|
|
|
public:
|
|
|
|
void operator=(unsigned long ulValue)
|
|
|
|
{
|
|
|
|
bsValue = ulValue;
|
|
|
|
}
|
|
|
|
|
|
|
|
operator unsigned long() const
|
|
|
|
{
|
|
|
|
return bsValue.to_ulong();
|
|
|
|
}
|
|
|
|
|
|
|
|
const int operator&()
|
|
|
|
{
|
|
|
|
ulValue = bsValue;
|
|
|
|
return ulValue;
|
|
|
|
}
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
typedef DataType<BITS_BYTE> byte;
|
|
|
|
typedef DataType<BITS_WORD> word;
|
|
|
|
typedef DataType<BITS_DWORD> dword;
|
|
|
|
*/
|
|
|
|
|
|
|
|
enum {PEFILE32 = 32,
|
|
|
|
PEFILE64 = 64,
|
|
|
|
PEFILE_UNKNOWN = 0};
|
|
|
|
|
|
|
|
enum {BoundImportDirectoryId = 1,
|
|
|
|
ComHeaderDirectoryId,
|
|
|
|
ExportDirectoryId,
|
|
|
|
IatDirectoryId,
|
|
|
|
ImportDirectoryId,
|
|
|
|
MzHeaderId,
|
|
|
|
PeHeaderId,
|
|
|
|
RelocationsId,
|
|
|
|
PeFileId,
|
|
|
|
ResourceDirectoryId,
|
|
|
|
DebugDirectoryId,
|
|
|
|
TlsDirectoryId
|
|
|
|
};
|
|
|
|
|
|
|
|
const word PELIB_IMAGE_DOS_SIGNATURE = 0x5A4D;
|
|
|
|
|
|
|
|
const dword PELIB_IMAGE_NT_SIGNATURE = 0x00004550;
|
|
|
|
|
|
|
|
template<int bits>
|
|
|
|
struct PELIB_IMAGE_ORDINAL_FLAGS;
|
|
|
|
|
|
|
|
template<>
|
|
|
|
struct PELIB_IMAGE_ORDINAL_FLAGS<32>
|
|
|
|
{
|
|
|
|
static const dword IMAGE_ORDINAL_FLAG = 0x80000000;
|
|
|
|
};
|
|
|
|
|
|
|
|
template<>
|
|
|
|
struct PELIB_IMAGE_ORDINAL_FLAGS<64>
|
|
|
|
{
|
|
|
|
static const qword IMAGE_ORDINAL_FLAG;
|
|
|
|
};
|
|
|
|
|
|
|
|
const unsigned long PELIB_IMAGE_NUMBEROF_DIRECTORY_ENTRIES = 16;
|
|
|
|
|
|
|
|
const unsigned long PELIB_IMAGE_RESOURCE_NAME_IS_STRING = 0x80000000;
|
|
|
|
|
|
|
|
const unsigned long PELIB_IMAGE_RESOURCE_DATA_IS_DIRECTORY = 0x80000000;
|
|
|
|
|
|
|
|
enum
|
|
|
|
{
|
|
|
|
PELIB_IMAGE_DIRECTORY_ENTRY_EXPORT, // OK
|
|
|
|
PELIB_IMAGE_DIRECTORY_ENTRY_IMPORT, // OK
|
|
|
|
PELIB_IMAGE_DIRECTORY_ENTRY_RESOURCE, // OK
|
|
|
|
PELIB_IMAGE_DIRECTORY_ENTRY_EXCEPTION,
|
|
|
|
PELIB_IMAGE_DIRECTORY_ENTRY_SECURITY,
|
|
|
|
PELIB_IMAGE_DIRECTORY_ENTRY_BASERELOC, // OK
|
|
|
|
PELIB_IMAGE_DIRECTORY_ENTRY_DEBUG,
|
|
|
|
PELIB_IMAGE_DIRECTORY_ENTRY_ARCHITECTURE,
|
|
|
|
PELIB_IMAGE_DIRECTORY_ENTRY_GLOBALPTR,
|
|
|
|
PELIB_IMAGE_DIRECTORY_ENTRY_TLS,
|
|
|
|
PELIB_IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG,
|
|
|
|
PELIB_IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT, // OK
|
|
|
|
PELIB_IMAGE_DIRECTORY_ENTRY_IAT, // OK
|
|
|
|
PELIB_IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT,
|
|
|
|
PELIB_IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR
|
|
|
|
};
|
|
|
|
|
|
|
|
enum
|
|
|
|
{
|
|
|
|
PELIB_IMAGE_SCN_TYPE_NO_PAD = 0x00000008,
|
|
|
|
PELIB_IMAGE_SCN_CNT_CODE = 0x00000020,
|
|
|
|
PELIB_IMAGE_SCN_CNT_INITIALIZED_DATA = 0x00000040,
|
|
|
|
PELIB_IMAGE_SCN_CNT_UNINITIALIZED_DATA = 0x00000080,
|
|
|
|
PELIB_IMAGE_SCN_LNK_OTHER = 0x00000100,
|
|
|
|
PELIB_IMAGE_SCN_LNK_INFO = 0x00000200,
|
|
|
|
PELIB_IMAGE_SCN_LNK_REMOVE = 0x00000800,
|
|
|
|
PELIB_IMAGE_SCN_LNK_COMDAT = 0x00001000,
|
|
|
|
PELIB_IMAGE_SCN_NO_DEFER_SPEC_EXC = 0x00004000,
|
|
|
|
PELIB_IMAGE_SCN_GPREL = 0x00008000,
|
|
|
|
PELIB_IMAGE_SCN_MEM_FARDATA = 0x00008000,
|
|
|
|
PELIB_IMAGE_SCN_MEM_PURGEABLE = 0x00020000,
|
|
|
|
PELIB_IMAGE_SCN_MEM_16BIT = 0x00020000,
|
|
|
|
PELIB_IMAGE_SCN_MEM_LOCKED = 0x00040000,
|
|
|
|
PELIB_IMAGE_SCN_MEM_PRELOAD = 0x00080000,
|
|
|
|
PELIB_IMAGE_SCN_ALIGN_1BYTES = 0x00100000,
|
|
|
|
PELIB_IMAGE_SCN_ALIGN_2BYTES = 0x00200000,
|
|
|
|
PELIB_IMAGE_SCN_ALIGN_4BYTES = 0x00300000,
|
|
|
|
PELIB_IMAGE_SCN_ALIGN_8BYTES = 0x00400000,
|
|
|
|
PELIB_IMAGE_SCN_ALIGN_16BYTES = 0x00500000,
|
|
|
|
PELIB_IMAGE_SCN_ALIGN_BYTES = 0x00600000,
|
|
|
|
PELIB_IMAGE_SCN_ALIGN_64BYTES = 0x00700000,
|
|
|
|
PELIB_IMAGE_SCN_ALIGN_128BYTES = 0x00800000,
|
|
|
|
PELIB_IMAGE_SCN_ALIGN_256BYTES = 0x00900000,
|
|
|
|
PELIB_IMAGE_SCN_ALIGN_512BYTES = 0x00A00000,
|
|
|
|
PELIB_IMAGE_SCN_ALIGN_1024BYTES = 0x00B00000,
|
|
|
|
PELIB_IMAGE_SCN_ALIGN_2048BYTES = 0x00C00000,
|
|
|
|
PELIB_IMAGE_SCN_ALIGN_4096BYTES = 0x00D00000,
|
|
|
|
PELIB_IMAGE_SCN_ALIGN_8192BYTES = 0x00E00000,
|
|
|
|
PELIB_IMAGE_SCN_LNK_NRELOC_OVFL = 0x01000000,
|
|
|
|
PELIB_IMAGE_SCN_MEM_DISCARDABLE = 0x02000000,
|
|
|
|
PELIB_IMAGE_SCN_MEM_NOT_CACHED = 0x04000000,
|
|
|
|
PELIB_IMAGE_SCN_MEM_NOT_PAGED = 0x08000000,
|
|
|
|
PELIB_IMAGE_SCN_MEM_SHARED = 0x10000000,
|
|
|
|
PELIB_IMAGE_SCN_MEM_EXECUTE = 0x20000000,
|
|
|
|
PELIB_IMAGE_SCN_MEM_READ = 0x40000000,
|
|
|
|
PELIB_IMAGE_SCN_MEM_WRITE = 0x80000000
|
|
|
|
};
|
|
|
|
|
|
|
|
enum
|
|
|
|
{
|
|
|
|
PELIB_IMAGE_FILE_MACHINE_UNKNOWN = 0,
|
|
|
|
PELIB_IMAGE_FILE_MACHINE_I386 = 0x014c,
|
|
|
|
PELIB_IMAGE_FILE_MACHINE_R3000 = 0x0162,
|
|
|
|
PELIB_IMAGE_FILE_MACHINE_R4000 = 0x0166,
|
|
|
|
PELIB_IMAGE_FILE_MACHINE_R10000 = 0x0168,
|
|
|
|
PELIB_IMAGE_FILE_MACHINE_WCEMIPSV2 = 0x0169,
|
|
|
|
PELIB_IMAGE_FILE_MACHINE_ALPHA = 0x0184,
|
|
|
|
PELIB_IMAGE_FILE_MACHINE_POWERPC = 0x01F0,
|
|
|
|
PELIB_IMAGE_FILE_MACHINE_SH3 = 0x01a2,
|
|
|
|
PELIB_IMAGE_FILE_MACHINE_SH3E = 0x01a4,
|
|
|
|
PELIB_IMAGE_FILE_MACHINE_SH4 = 0x01a6,
|
|
|
|
PELIB_IMAGE_FILE_MACHINE_ARM = 0x01c0,
|
|
|
|
PELIB_IMAGE_FILE_MACHINE_THUMB = 0x01c2,
|
|
|
|
PELIB_IMAGE_FILE_MACHINE_IA64 = 0x0200,
|
|
|
|
PELIB_IMAGE_FILE_MACHINE_MIPS16 = 0x0266,
|
|
|
|
PELIB_IMAGE_FILE_MACHINE_MIPSFPU = 0x0366,
|
|
|
|
PELIB_IMAGE_FILE_MACHINE_MIPSFPU16 = 0x0466,
|
|
|
|
PELIB_IMAGE_FILE_MACHINE_ALPHA64 = 0x0284,
|
|
|
|
PELIB_IMAGE_FILE_MACHINE_AXP64 = PELIB_IMAGE_FILE_MACHINE_ALPHA64
|
|
|
|
};
|
|
|
|
|
|
|
|
enum
|
|
|
|
{
|
|
|
|
PELIB_IMAGE_FILE_RELOCS_STRIPPED = 0x0001,
|
|
|
|
PELIB_IMAGE_FILE_EXECUTABLE_IMAGE = 0x0002,
|
|
|
|
PELIB_IMAGE_FILE_LINE_NUMS_STRIPPED = 0x0004,
|
|
|
|
PELIB_IMAGE_FILE_LOCAL_SYMS_STRIPPED = 0x0008,
|
|
|
|
PELIB_IMAGE_FILE_AGGRESIVE_WS_TRIM = 0x0010,
|
|
|
|
PELIB_IMAGE_FILE_LARGE_ADDRESS_AWARE = 0x0020,
|
|
|
|
PELIB_IMAGE_FILE_BYTES_REVERSED_LO = 0x0080,
|
|
|
|
PELIB_IMAGE_FILE_32BIT_MACHINE = 0x0100,
|
|
|
|
PELIB_IMAGE_FILE_DEBUG_STRIPPED = 0x0200,
|
|
|
|
PELIB_IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP = 0x0400,
|
|
|
|
PELIB_IMAGE_FILE_NET_RUN_FROM_SWAP = 0x0800,
|
|
|
|
PELIB_IMAGE_FILE_SYSTEM = 0x1000,
|
|
|
|
PELIB_IMAGE_FILE_DLL = 0x2000,
|
|
|
|
PELIB_IMAGE_FILE_UP_SYSTEM_ONLY = 0x4000,
|
|
|
|
PELIB_IMAGE_FILE_BYTES_REVERSED_HI = 0x8000
|
|
|
|
};
|
|
|
|
|
|
|
|
enum
|
|
|
|
{
|
|
|
|
PELIB_IMAGE_NT_OPTIONAL_HDR32_MAGIC = 0x10b,
|
|
|
|
PELIB_IMAGE_NT_OPTIONAL_HDR64_MAGIC = 0x20b,
|
|
|
|
PELIB_IMAGE_ROM_OPTIONAL_HDR_MAGIC = 0x107
|
|
|
|
};
|
|
|
|
|
|
|
|
enum
|
|
|
|
{
|
|
|
|
PELIB_IMAGE_SUBSYSTEM_UNKNOWN = 0,
|
|
|
|
PELIB_IMAGE_SUBSYSTEM_NATIVE = 1,
|
|
|
|
PELIB_IMAGE_SUBSYSTEM_WINDOWS_GUI = 2,
|
|
|
|
PELIB_IMAGE_SUBSYSTEM_WINDOWS_CUI = 3,
|
|
|
|
PELIB_IMAGE_SUBSYSTEM_OS2_CUI = 5,
|
|
|
|
PELIB_IMAGE_SUBSYSTEM_POSIX_CUI = 7,
|
|
|
|
PELIB_IMAGE_SUBSYSTEM_NATIVE_WINDOWS = 8,
|
|
|
|
PELIB_IMAGE_SUBSYSTEM_WINDOWS_CE_GUI = 9
|
|
|
|
};
|
|
|
|
|
|
|
|
enum
|
|
|
|
{
|
|
|
|
PELIB_RT_CURSOR = 1, // 1
|
|
|
|
PELIB_RT_BITMAP, // 2
|
|
|
|
PELIB_RT_ICON, // 3
|
|
|
|
PELIB_RT_MENU, // 4
|
|
|
|
PELIB_RT_DIALOG, // 5
|
|
|
|
PELIB_RT_STRING, // 6
|
|
|
|
PELIB_RT_FONTDIR, // 7
|
|
|
|
PELIB_RT_FONT, // 8
|
|
|
|
PELIB_RT_ACCELERATOR, // 9
|
|
|
|
PELIB_RT_RCDATA, // 10
|
|
|
|
PELIB_RT_MESSAGETABLE, // 11
|
|
|
|
PELIB_RT_GROUP_CURSOR, // 12
|
|
|
|
PELIB_RT_GROUP_ICON = 14, // 14
|
|
|
|
PELIB_RT_VERSION = 16,
|
|
|
|
PELIB_RT_DLGINCLUDE,
|
|
|
|
PELIB_RT_PLUGPLAY = 19,
|
|
|
|
PELIB_RT_VXD,
|
|
|
|
PELIB_RT_ANICURSOR,
|
|
|
|
PELIB_RT_ANIICON,
|
|
|
|
PELIB_RT_HTML,
|
|
|
|
PELIB_RT_MANIFEST
|
|
|
|
};
|
|
|
|
|
|
|
|
template<typename T>
|
|
|
|
unsigned int accumulate(unsigned int size, const T& v)
|
|
|
|
{
|
|
|
|
return size + v.size();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
struct PELIB_IMAGE_DOS_HEADER
|
|
|
|
{
|
|
|
|
word e_magic;
|
|
|
|
word e_cblp;
|
|
|
|
word e_cp;
|
|
|
|
word e_crlc;
|
|
|
|
word e_cparhdr;
|
|
|
|
word e_minalloc;
|
|
|
|
word e_maxalloc;
|
|
|
|
word e_ss;
|
|
|
|
word e_sp;
|
|
|
|
word e_csum;
|
|
|
|
word e_ip;
|
|
|
|
word e_cs;
|
|
|
|
word e_lfarlc;
|
|
|
|
word e_ovno;
|
|
|
|
word e_res[4];
|
|
|
|
word e_oemid;
|
|
|
|
word e_oeminfo;
|
|
|
|
word e_res2[10];
|
|
|
|
dword e_lfanew;
|
|
|
|
|
|
|
|
PELIB_IMAGE_DOS_HEADER();
|
|
|
|
|
|
|
|
static inline unsigned int size() {return 64;}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct PELIB_IMAGE_FILE_HEADER
|
|
|
|
{
|
|
|
|
word Machine;
|
|
|
|
word NumberOfSections;
|
|
|
|
dword TimeDateStamp;
|
|
|
|
dword PointerToSymbolTable;
|
|
|
|
dword NumberOfSymbols;
|
|
|
|
word SizeOfOptionalHeader;
|
|
|
|
word Characteristics;
|
|
|
|
|
|
|
|
PELIB_IMAGE_FILE_HEADER()
|
|
|
|
{
|
|
|
|
Machine = 0;
|
|
|
|
NumberOfSections = 0;
|
|
|
|
TimeDateStamp = 0;
|
|
|
|
PointerToSymbolTable = 0;
|
|
|
|
NumberOfSymbols = 0;
|
|
|
|
SizeOfOptionalHeader = 0;
|
|
|
|
Characteristics = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline unsigned int size() {return 20;}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct PELIB_IMAGE_DATA_DIRECTORY
|
|
|
|
{
|
|
|
|
dword VirtualAddress;
|
|
|
|
dword Size;
|
|
|
|
|
|
|
|
PELIB_IMAGE_DATA_DIRECTORY()
|
|
|
|
{
|
|
|
|
VirtualAddress = 0;
|
|
|
|
Size = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline unsigned int size() {return 8;}
|
|
|
|
};
|
|
|
|
|
|
|
|
template<int>
|
|
|
|
struct FieldSizes;
|
|
|
|
|
|
|
|
template<>
|
|
|
|
struct FieldSizes<32>
|
|
|
|
{
|
|
|
|
typedef dword VAR4_8;
|
|
|
|
};
|
|
|
|
|
|
|
|
template<>
|
|
|
|
struct FieldSizes<64>
|
|
|
|
{
|
|
|
|
typedef qword VAR4_8;
|
|
|
|
};
|
|
|
|
|
|
|
|
template<int x>
|
|
|
|
struct PELIB_IMAGE_OPTIONAL_HEADER_BASE
|
|
|
|
{
|
|
|
|
typedef typename FieldSizes<x>::VAR4_8 VAR4_8;
|
|
|
|
|
|
|
|
word Magic;
|
|
|
|
byte MajorLinkerVersion;
|
|
|
|
byte MinorLinkerVersion;
|
|
|
|
dword SizeOfCode;
|
|
|
|
dword SizeOfInitializedData;
|
|
|
|
dword SizeOfUninitializedData;
|
|
|
|
dword AddressOfEntryPoint;
|
|
|
|
dword BaseOfCode;
|
|
|
|
dword BaseOfData;
|
|
|
|
VAR4_8 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;
|
|
|
|
VAR4_8 SizeOfStackReserve;
|
|
|
|
VAR4_8 SizeOfStackCommit;
|
|
|
|
VAR4_8 SizeOfHeapReserve;
|
|
|
|
VAR4_8 SizeOfHeapCommit;
|
|
|
|
dword LoaderFlags;
|
|
|
|
dword NumberOfRvaAndSizes;
|
|
|
|
// PELIB_IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
|
|
|
|
|
|
|
|
PELIB_IMAGE_OPTIONAL_HEADER_BASE();
|
|
|
|
};
|
|
|
|
|
|
|
|
template<int x>
|
|
|
|
PELIB_IMAGE_OPTIONAL_HEADER_BASE<x>::PELIB_IMAGE_OPTIONAL_HEADER_BASE()
|
|
|
|
{
|
|
|
|
Magic = 0;
|
|
|
|
MajorLinkerVersion = 0;
|
|
|
|
MinorLinkerVersion = 0;
|
|
|
|
SizeOfCode = 0;
|
|
|
|
SizeOfInitializedData = 0;
|
|
|
|
SizeOfUninitializedData = 0;
|
|
|
|
AddressOfEntryPoint = 0;
|
|
|
|
BaseOfCode = 0;
|
|
|
|
// BaseOfData = 0;
|
|
|
|
ImageBase = 0;
|
|
|
|
SectionAlignment = 0;
|
|
|
|
FileAlignment = 0;
|
|
|
|
MajorOperatingSystemVersion = 0;
|
|
|
|
MinorOperatingSystemVersion = 0;
|
|
|
|
MajorImageVersion = 0;
|
|
|
|
MinorImageVersion = 0;
|
|
|
|
MajorSubsystemVersion = 0;
|
|
|
|
MinorSubsystemVersion = 0;
|
|
|
|
Win32VersionValue = 0;
|
|
|
|
SizeOfImage = 0;
|
|
|
|
SizeOfHeaders = 0;
|
|
|
|
CheckSum = 0;
|
|
|
|
Subsystem = 0;
|
|
|
|
DllCharacteristics = 0;
|
|
|
|
SizeOfStackReserve = 0;
|
|
|
|
SizeOfStackCommit = 0;
|
|
|
|
SizeOfHeapReserve = 0;
|
|
|
|
SizeOfHeapCommit = 0;
|
|
|
|
LoaderFlags = 0;
|
|
|
|
NumberOfRvaAndSizes = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
template<int>
|
|
|
|
struct PELIB_IMAGE_OPTIONAL_HEADER;
|
|
|
|
|
|
|
|
template<>
|
|
|
|
struct PELIB_IMAGE_OPTIONAL_HEADER<32> : public PELIB_IMAGE_OPTIONAL_HEADER_BASE<32>
|
|
|
|
{
|
|
|
|
dword BaseOfData;
|
|
|
|
|
|
|
|
static inline unsigned int size() {return 224 - 0x10 * 8;}
|
|
|
|
};
|
|
|
|
|
|
|
|
template<>
|
|
|
|
struct PELIB_IMAGE_OPTIONAL_HEADER<64> : public PELIB_IMAGE_OPTIONAL_HEADER_BASE<64>
|
|
|
|
{
|
|
|
|
static inline unsigned int size() {return 240 - 0x10 * 8;}
|
|
|
|
};
|
|
|
|
|
|
|
|
template<int x>
|
|
|
|
struct PELIB_IMAGE_NT_HEADERS
|
|
|
|
{
|
|
|
|
dword Signature;
|
|
|
|
PELIB_IMAGE_FILE_HEADER FileHeader;
|
|
|
|
PELIB_IMAGE_OPTIONAL_HEADER<x> OptionalHeader;
|
|
|
|
std::vector<PELIB_IMAGE_DATA_DIRECTORY> dataDirectories;
|
|
|
|
|
|
|
|
unsigned int size() const
|
|
|
|
{
|
|
|
|
return sizeof(dword)
|
|
|
|
+ PELIB_IMAGE_FILE_HEADER::size()
|
|
|
|
+ PELIB_IMAGE_OPTIONAL_HEADER<x>::size()
|
|
|
|
+ static_cast<unsigned int>(dataDirectories.size()) * PELIB_IMAGE_DATA_DIRECTORY::size();
|
|
|
|
}
|
|
|
|
|
|
|
|
PELIB_IMAGE_NT_HEADERS()
|
|
|
|
{
|
|
|
|
Signature = 0;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
const unsigned int PELIB_IMAGE_SIZEOF_SHORT_NAME = 8;
|
|
|
|
|
|
|
|
struct PELIB_IMAGE_SECTION_HEADER
|
|
|
|
{
|
|
|
|
byte Name[PELIB_IMAGE_SIZEOF_SHORT_NAME];
|
|
|
|
dword VirtualSize;
|
|
|
|
dword VirtualAddress;
|
|
|
|
dword SizeOfRawData;
|
|
|
|
dword PointerToRawData;
|
|
|
|
dword PointerToRelocations;
|
|
|
|
dword PointerToLinenumbers;
|
|
|
|
word NumberOfRelocations;
|
|
|
|
word NumberOfLinenumbers;
|
|
|
|
dword Characteristics;
|
|
|
|
|
|
|
|
PELIB_IMAGE_SECTION_HEADER()
|
|
|
|
{
|
|
|
|
VirtualSize = 0;
|
|
|
|
VirtualAddress = 0;
|
|
|
|
SizeOfRawData = 0;
|
|
|
|
PointerToRawData = 0;
|
|
|
|
PointerToRelocations = 0;
|
|
|
|
PointerToLinenumbers = 0;
|
|
|
|
NumberOfRelocations = 0;
|
|
|
|
NumberOfLinenumbers = 0;
|
|
|
|
Characteristics = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline unsigned int size() {return 40;}
|
|
|
|
bool biggerFileOffset(const PELIB_IMAGE_SECTION_HEADER& ish) const;
|
|
|
|
bool biggerVirtualAddress(const PELIB_IMAGE_SECTION_HEADER& ish) const;
|
|
|
|
};
|
|
|
|
|
|
|
|
template<int bits>
|
|
|
|
struct PELIB_IMAGE_THUNK_DATA
|
|
|
|
{
|
|
|
|
typename FieldSizes<bits>::VAR4_8 Ordinal;
|
|
|
|
|
|
|
|
PELIB_IMAGE_THUNK_DATA()
|
|
|
|
{
|
|
|
|
Ordinal = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline unsigned int size() {return 4;}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct PELIB_IMAGE_IMPORT_DESCRIPTOR
|
|
|
|
{
|
|
|
|
dword OriginalFirstThunk;
|
|
|
|
dword TimeDateStamp;
|
|
|
|
dword ForwarderChain;
|
|
|
|
dword Name;
|
|
|
|
dword FirstThunk;
|
|
|
|
|
|
|
|
PELIB_IMAGE_IMPORT_DESCRIPTOR()
|
|
|
|
{
|
|
|
|
OriginalFirstThunk = 0;
|
|
|
|
TimeDateStamp = 0;
|
|
|
|
ForwarderChain = 0;
|
|
|
|
Name = 0;
|
|
|
|
FirstThunk = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline unsigned int size() {return 20;}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct PELIB_IMAGE_EXPORT_DIRECTORY
|
|
|
|
{
|
|
|
|
dword Characteristics;
|
|
|
|
dword TimeDateStamp;
|
|
|
|
word MajorVersion;
|
|
|
|
word MinorVersion;
|
|
|
|
dword Name;
|
|
|
|
dword Base;
|
|
|
|
dword NumberOfFunctions;
|
|
|
|
dword NumberOfNames;
|
|
|
|
dword AddressOfFunctions;
|
|
|
|
dword AddressOfNames;
|
|
|
|
dword AddressOfNameOrdinals;
|
|
|
|
|
|
|
|
PELIB_IMAGE_EXPORT_DIRECTORY()
|
|
|
|
{
|
|
|
|
Characteristics = 0;
|
|
|
|
TimeDateStamp = 0;
|
|
|
|
MajorVersion = 0;
|
|
|
|
MinorVersion = 0;
|
|
|
|
Name = 0;
|
|
|
|
Base = 0;
|
|
|
|
NumberOfFunctions = 0;
|
|
|
|
NumberOfNames = 0;
|
|
|
|
AddressOfFunctions = 0;
|
|
|
|
NumberOfNames = 0;
|
|
|
|
AddressOfNameOrdinals = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline unsigned int size() {return 40;}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct PELIB_IMAGE_BOUND_IMPORT_DESCRIPTOR
|
|
|
|
{
|
|
|
|
dword TimeDateStamp;
|
|
|
|
word OffsetModuleName;
|
|
|
|
word NumberOfModuleForwarderRefs;
|
|
|
|
|
|
|
|
PELIB_IMAGE_BOUND_IMPORT_DESCRIPTOR()
|
|
|
|
{
|
|
|
|
TimeDateStamp = 0;
|
|
|
|
OffsetModuleName = 0;
|
|
|
|
NumberOfModuleForwarderRefs = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static unsigned int size()
|
|
|
|
{
|
|
|
|
return 8;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// Stores all necessary information about a BoundImport field.
|
|
|
|
struct PELIB_IMAGE_BOUND_DIRECTORY
|
|
|
|
{
|
|
|
|
PELIB_IMAGE_BOUND_IMPORT_DESCRIPTOR ibdDescriptor; ///< Information about the imported file.
|
|
|
|
std::string strModuleName; ///< Name of the imported file.
|
|
|
|
std::vector<PELIB_IMAGE_BOUND_DIRECTORY> moduleForwarders;
|
|
|
|
|
|
|
|
// Will be used in std::find_if
|
|
|
|
// Passing by-reference not possible (see C++ Standard Core Language Defect Reports, Revision 29, Issue 106)
|
|
|
|
/// Compares the passed filename to the struct's filename.
|
|
|
|
bool equal(const std::string strModuleName) const;
|
|
|
|
|
|
|
|
unsigned int size() const;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct PELIB_EXP_FUNC_INFORMATION
|
|
|
|
{
|
|
|
|
dword addroffunc;
|
|
|
|
dword addrofname;
|
|
|
|
word ordinal;
|
|
|
|
std::string funcname;
|
|
|
|
|
|
|
|
PELIB_EXP_FUNC_INFORMATION();
|
|
|
|
|
|
|
|
bool equal(const std::string strFunctionName) const;
|
|
|
|
inline unsigned int size() const
|
|
|
|
{
|
|
|
|
unsigned int uiSize = 4;
|
|
|
|
if (addroffunc) uiSize += 2;// + 4;
|
|
|
|
if (!funcname.empty()) uiSize += 4 + (unsigned int)funcname.size() + 1;
|
|
|
|
return uiSize;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct PELIB_IMAGE_RESOURCE_DIRECTORY
|
|
|
|
{
|
|
|
|
dword Characteristics;
|
|
|
|
dword TimeDateStamp;
|
|
|
|
word MajorVersion;
|
|
|
|
word MinorVersion;
|
|
|
|
word NumberOfNamedEntries;
|
|
|
|
word NumberOfIdEntries;
|
|
|
|
|
|
|
|
PELIB_IMAGE_RESOURCE_DIRECTORY();
|
|
|
|
|
|
|
|
static inline unsigned int size() {return 16;}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct PELIB_IMAGE_RESOURCE_DIRECTORY_ENTRY
|
|
|
|
{
|
|
|
|
dword Name;
|
|
|
|
dword OffsetToData;
|
|
|
|
PELIB_IMAGE_RESOURCE_DIRECTORY_ENTRY();
|
|
|
|
static inline unsigned int size() {return 8;}
|
|
|
|
};
|
|
|
|
|
|
|
|
const unsigned int PELIB_IMAGE_SIZEOF_BASE_RELOCATION = 8;
|
|
|
|
|
|
|
|
struct PELIB_IMG_RES_DIR_ENTRY
|
|
|
|
{
|
|
|
|
PELIB_IMAGE_RESOURCE_DIRECTORY_ENTRY irde;
|
|
|
|
std::string wstrName;
|
|
|
|
|
|
|
|
bool operator<(const PELIB_IMG_RES_DIR_ENTRY& first) const;
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
struct PELIB_IMAGE_BASE_RELOCATION
|
|
|
|
{
|
|
|
|
dword VirtualAddress;
|
|
|
|
dword SizeOfBlock;
|
|
|
|
|
|
|
|
PELIB_IMAGE_BASE_RELOCATION();
|
|
|
|
static inline unsigned int size() {return 8;}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct PELIB_IMAGE_COR20_HEADER
|
|
|
|
{
|
|
|
|
dword cb;
|
|
|
|
word MajorRuntimeVersion;
|
|
|
|
word MinorRuntimeVersion;
|
|
|
|
PELIB_IMAGE_DATA_DIRECTORY MetaData;
|
|
|
|
dword Flags;
|
|
|
|
dword EntryPointToken;
|
|
|
|
PELIB_IMAGE_DATA_DIRECTORY Resources;
|
|
|
|
PELIB_IMAGE_DATA_DIRECTORY StrongNameSignature;
|
|
|
|
PELIB_IMAGE_DATA_DIRECTORY CodeManagerTable;
|
|
|
|
PELIB_IMAGE_DATA_DIRECTORY VTableFixups;
|
|
|
|
PELIB_IMAGE_DATA_DIRECTORY ExportAddressTableJumps;
|
|
|
|
PELIB_IMAGE_DATA_DIRECTORY ManagedNativeHeader;
|
|
|
|
|
|
|
|
PELIB_IMAGE_COR20_HEADER();
|
|
|
|
static inline unsigned int size() {return 72;}
|
|
|
|
};
|
|
|
|
|
|
|
|
// Used to store a file's export table.
|
|
|
|
struct PELIB_IMAGE_EXP_DIRECTORY
|
|
|
|
{
|
|
|
|
/// The IMAGE_EXPORTED_DIRECTORY of a file's export table.
|
|
|
|
PELIB_IMAGE_EXPORT_DIRECTORY ied;
|
|
|
|
/// The original filename of current file.
|
|
|
|
std::string name;
|
|
|
|
std::vector<PELIB_EXP_FUNC_INFORMATION> functions;
|
|
|
|
inline unsigned int size() const
|
|
|
|
{
|
|
|
|
return PELIB_IMAGE_EXPORT_DIRECTORY::size() + name.size() + 1 +
|
|
|
|
std::accumulate(functions.begin(), functions.end(), 0, accumulate<PELIB_EXP_FUNC_INFORMATION>);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// Used for parsing a file's import table. It combines the function name, the hint
|
|
|
|
// and the IMAGE_THUNK_DATA of an imported function.
|
|
|
|
template<int bits>
|
|
|
|
struct PELIB_THUNK_DATA
|
|
|
|
{
|
|
|
|
/// The IMAGE_THUNK_DATA struct of an imported function.
|
|
|
|
PELIB_IMAGE_THUNK_DATA<bits> itd;
|
|
|
|
/// The hint of an imported function.
|
|
|
|
word hint;
|
|
|
|
/// The function name of an imported function.
|
|
|
|
std::string fname;
|
|
|
|
|
|
|
|
bool equalHint(word wHint) const
|
|
|
|
{
|
|
|
|
return hint == wHint;
|
|
|
|
// return itd.Ordinal == (wHint | IMAGE_ORDINAL_FLAGS<bits>::IMAGE_ORDINAL_FLAG);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool equalFunctionName(std::string strFunctionName) const
|
|
|
|
{
|
|
|
|
return isEqualNc(fname, strFunctionName);
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned int size() const {return PELIB_IMAGE_THUNK_DATA<bits>::size() + fname.size() + 1 + sizeof(hint);}
|
|
|
|
};
|
|
|
|
|
|
|
|
// Used to store a file's import table. Every struct of this sort
|
|
|
|
// can store import information of one DLL.
|
|
|
|
template<int bits>
|
|
|
|
struct PELIB_IMAGE_IMPORT_DIRECTORY
|
|
|
|
{
|
|
|
|
/// The IMAGE_IMPORT_DESCRIPTOR of an imported DLL.
|
|
|
|
PELIB_IMAGE_IMPORT_DESCRIPTOR impdesc;
|
|
|
|
/// The name of an imported DLL.
|
|
|
|
std::string name;
|
|
|
|
/// All original first thunk values of an imported DLL.
|
|
|
|
std::vector<PELIB_THUNK_DATA<bits> > originalfirstthunk;
|
|
|
|
/// All first thunk value of an imported DLL.
|
|
|
|
std::vector<PELIB_THUNK_DATA<bits> > firstthunk;
|
|
|
|
|
|
|
|
// bool operator==(std::string strFilename) const;
|
|
|
|
inline unsigned int size() const
|
|
|
|
{
|
|
|
|
return PELIB_IMAGE_IMPORT_DESCRIPTOR::size() + name.size() + 1 + // descriptor + dllname
|
|
|
|
std::accumulate(originalfirstthunk.begin(), originalfirstthunk.end(), 0, accumulate<PELIB_THUNK_DATA<bits> >) + // thunks (PeLib uses only one thunk)
|
|
|
|
PELIB_IMAGE_THUNK_DATA<bits>::size(); // zero-termination
|
|
|
|
}
|
|
|
|
|
|
|
|
bool operator==(std::string strFilename) const
|
|
|
|
{
|
|
|
|
return isEqualNc(this->name, strFilename);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct PELIB_IMAGE_RESOURCE_DATA_ENTRY
|
|
|
|
{
|
|
|
|
dword OffsetToData;
|
|
|
|
dword Size;
|
|
|
|
dword CodePage;
|
|
|
|
dword Reserved;
|
|
|
|
|
|
|
|
static inline unsigned int size() {return 16;}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct PELIB_IMAGE_RESOURCE_DATA
|
|
|
|
{
|
|
|
|
PELIB_IMAGE_RESOURCE_DATA_ENTRY irdEntry;
|
|
|
|
std::vector<byte> vData;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct IMG_BASE_RELOC
|
|
|
|
{
|
|
|
|
PELIB_IMAGE_BASE_RELOCATION ibrRelocation;
|
|
|
|
std::vector<word> vRelocData;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct PELIB_IMAGE_DEBUG_DIRECTORY
|
|
|
|
{
|
|
|
|
dword Characteristics;
|
|
|
|
dword TimeDateStamp;
|
|
|
|
word MajorVersion;
|
|
|
|
word MinorVersion;
|
|
|
|
dword Type;
|
|
|
|
dword SizeOfData;
|
|
|
|
dword AddressOfRawData;
|
|
|
|
dword PointerToRawData;
|
|
|
|
|
|
|
|
static unsigned int size() {return 28;}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct PELIB_IMG_DEBUG_DIRECTORY
|
|
|
|
{
|
|
|
|
PELIB_IMAGE_DEBUG_DIRECTORY idd;
|
|
|
|
std::vector<byte> data;
|
|
|
|
};
|
|
|
|
|
|
|
|
template<int bits>
|
|
|
|
struct PELIB_IMAGE_TLS_DIRECTORY_BASE
|
|
|
|
{
|
|
|
|
typename FieldSizes<bits>::VAR4_8 StartAddressOfRawData;
|
|
|
|
typename FieldSizes<bits>::VAR4_8 EndAddressOfRawData;
|
|
|
|
typename FieldSizes<bits>::VAR4_8 AddressOfIndex;
|
|
|
|
typename FieldSizes<bits>::VAR4_8 AddressOfCallBacks;
|
|
|
|
dword SizeOfZeroFill;
|
|
|
|
dword Characteristics;
|
|
|
|
};
|
|
|
|
|
|
|
|
template<int bits>
|
|
|
|
struct PELIB_IMAGE_TLS_DIRECTORY;// : public PELIB_IMAGE_TLS_DIRECTORY_BASE<bits>
|
|
|
|
|
|
|
|
template<>
|
|
|
|
struct PELIB_IMAGE_TLS_DIRECTORY<32> : public PELIB_IMAGE_TLS_DIRECTORY_BASE<32>
|
|
|
|
{
|
|
|
|
// enum {size = 24};
|
|
|
|
static unsigned int size(){return 24;}
|
|
|
|
};
|
|
|
|
|
|
|
|
template<>
|
|
|
|
struct PELIB_IMAGE_TLS_DIRECTORY<64> : public PELIB_IMAGE_TLS_DIRECTORY_BASE<64>
|
|
|
|
{
|
|
|
|
// enum {size = 40};
|
|
|
|
static unsigned int size(){return 40;}
|
|
|
|
};
|
|
|
|
|
|
|
|
unsigned int fileSize(const std::string& filename);
|
|
|
|
unsigned int fileSize(std::ifstream& file);
|
|
|
|
unsigned int fileSize(std::ofstream& file);
|
|
|
|
unsigned int fileSize(std::fstream& file);
|
|
|
|
unsigned int alignOffset(unsigned int uiOffset, unsigned int uiAlignment);
|
|
|
|
|
|
|
|
/// Determines if a file is a 32bit or 64bit PE file.
|
|
|
|
unsigned int getFileType(const std::string strFilename);
|
|
|
|
|
|
|
|
/// Opens a PE file.
|
|
|
|
PeFile* openPeFile(const std::string& strFilename);
|
|
|
|
|
|
|
|
/* enum MzHeader_Field {e_magic, e_cblp, e_cp, e_crlc, e_cparhdr, e_minalloc, e_maxalloc,
|
|
|
|
e_ss, e_sp, e_csum, e_ip, e_cs, e_lfarlc, e_ovno, e_res, e_oemid,
|
|
|
|
e_oeminfo, e_res2, e_lfanew};
|
|
|
|
enum PeHeader_Field {NtSignature, Machine, NumberOfSections, TimeDateStamp, PointerToSymbolTable,
|
|
|
|
NumberOfSymbols, SizeOfOptionalHeader, Characteristics, Magic,
|
|
|
|
MajorLinkerVersion, MinorLinkerVersion, SizeOfCode, SizeOfInitializedData,
|
|
|
|
SizeOfUninitializedData, AddressOfEntryPoint, BaseOfCode, BaseOfData, ImageBase,
|
|
|
|
SectionAlignment, FileAlignment, MajorOperatingSystemVersion, MinorOperatingSystemVersion,
|
|
|
|
MajorImageVersion, MinorImageVersion, MajorSubsystemVersion, MinorSubsystemVersion,
|
|
|
|
Win32VersionValue, SizeOfImage, SizeOfHeaders, CheckSum, Subsystem, DllCharacteristics,
|
|
|
|
SizeOfStackReserve, SizeOfStackCommit, SizeOfHeapReserve, SizeOfHeapCommit,
|
|
|
|
LoaderFlags, NumberOfRvaAndSizes, DataDirectoryRva, DataDirectorySize};
|
|
|
|
enum Section_Field {SectionName, VirtualSize, VirtualAddress, SizeOfRawData, PointerToRawData, PointerToRelocations,
|
|
|
|
PointerToLinenumbers, NumberOfRelocations, NumberOfLinenumbers, SectionCharacteristics};
|
|
|
|
*/
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|