文章目录
PE解析这东西,记着所有RVA转file offset然后加上缓冲区地址就行了。
main
因为控制台输入是多字节集,所以项目属性要设置为多字节。
#include <iostream>
#include "PE.h"
int main()
{
TCHAR path[MAX_PATH] = { 0 };
printf("input path:");
_tscanf_s(_T("%s"), path, MAX_PATH);
getchar();
PE pe(path);
if (!pe.bIsPe())
{
printf("This is not a PE file.\n");
system("pause");
return 0;
}
int opt = 0;
DWORD dwRVA = 0;
while (1)
{
wprintf(L"-1. exit\n");
wprintf(L"0. dos/nt header info\n");
wprintf(L"1. file header info\n");
wprintf(L"2. optional header info\n");
wprintf(L"3. Section header info\n");
wprintf(L"4. export table info\n");
wprintf(L"5. import table info\n");
wprintf(L"6. resource info\n");
wprintf(L"7. relocation info\n");
wprintf(L"8. TLS info\n");
wprintf(L"9. delay-loaded dll info\n");
scanf_s("%d", &opt);
getchar();
switch (opt)
{
case -1:
system("pause");
exit(0);
case 0:
pe.showDosHeader();
pe.showNtHeader();
break;
case 1:
pe.showFileHeader();
break;
case 2:
pe.showOptHeader();
break;
case 3:
pe.enumSectionHeaders();
break;
case 4:
pe.showExpTable();
break;
case 5:
pe.showImpTable();
break;
case 6:
pe.showRes();
break;
case 7:
pe.showReloc();
break;
case 8:
pe.showTLS();
break;
case 9:
pe.showDelay();
break;
default:
break;
}
getchar();
system("cls");
}
system("pause");
return 0;
}
PE.h
#pragma once
#include <windows.h>
#include <iostream>
#include <tchar.h>
class PE
{
private:
void *m_pFile;
bool m_bIs64;
PIMAGE_DOS_HEADER m_pDosHeader;
PIMAGE_NT_HEADERS m_pNtHeader;
PIMAGE_FILE_HEADER m_pFileHeader;
PIMAGE_OPTIONAL_HEADER32 m_pOptHeader32;
PIMAGE_OPTIONAL_HEADER64 m_pOptHeader64;
PIMAGE_SECTION_HEADER m_pFirstSection;
PIMAGE_EXPORT_DIRECTORY m_pIED;
PIMAGE_IMPORT_DESCRIPTOR m_pIID;
PIMAGE_RESOURCE_DIRECTORY m_pRes;
PIMAGE_BASE_RELOCATION m_pReloc;
PIMAGE_TLS_DIRECTORY32 m_pTLS32;
PIMAGE_TLS_DIRECTORY64 m_pTLS64;
PIMAGE_DELAYLOAD_DESCRIPTOR m_pDelay;
public:
PE(TCHAR* path);
~PE();
bool bIsPe();
//int getDosHeader();
//int getNtHeader();
//int getOptHeader();
void showDosHeader();
void showNtHeader();
void showFileHeader();
void showOptHeader();
void enumSectionHeaders();
void showExpTable();
void showImpTable();
void showRes();
void showReloc();
void showTLS();
void showDelay();
DWORD RVA2FO(ULONGLONG dwRVA);
};
PE.cpp
Constructor_Destructor
#include "PE.h"
PE::PE(TCHAR* path)
{
if (path == NULL) return;
HANDLE hFile = CreateFile(path, GENERIC_READ, FILE_SHARE_READ,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
DWORD dwBytesRW = 0;
DWORD dwFileSize = 0;
if (hFile == INVALID_HANDLE_VALUE)
{
printf("CreateFile() error\n");
system("pause");
exit(0);
}
dwFileSize = GetFileSize(hFile, NULL);
m_pFile = new char[dwFileSize]();
ReadFile(hFile, m_pFile, dwFileSize, &dwBytesRW, NULL);
if (m_pFile)
{
m_pDosHeader = (PIMAGE_DOS_HEADER)(m_pFile);
m_pNtHeader = (PIMAGE_NT_HEADERS)((ULONGLONG)m_pFile + m_pDosHeader->e_lfanew);
m_pFileHeader = (PIMAGE_FILE_HEADER)(&(m_pNtHeader->FileHeader));
if (m_pFileHeader->Machine == 0x014c)
{
printf("x86 program.\n");
m_bIs64 = false;
}
else if (m_pFileHeader->Machine == 0x8664)
{
printf("x64 program.\n");
m_bIs64 = true;
}
m_pFirstSection = IMAGE_FIRST_SECTION(m_pNtHeader);
if (m_bIs64)
{
m_pOptHeader64 = (PIMAGE_OPTIONAL_HEADER64)(&(m_pNtHeader->OptionalHeader));
/*
* Export table.
*/
if (m_pFileHeader->Characteristics & IMAGE_FILE_DLL)
{
m_pIED = (m_pOptHeader64->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]).VirtualAddress ?
(PIMAGE_EXPORT_DIRECTORY)(
RVA2FO((m_pOptHeader64->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]).VirtualAddress)
+ (ULONGLONG)m_pFile)
: NULL;
}
/*
* Import table.
*/
m_pIID = (m_pOptHeader64->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]).VirtualAddress ?
(PIMAGE_IMPORT_DESCRIPTOR)(
RVA2FO((m_pOptHeader64->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]).VirtualAddress)
+ (ULONGLONG)m_pFile)
: NULL;
/*
* Resource.
*/
m_pRes = (m_pOptHeader64->DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE]).VirtualAddress ?
(PIMAGE_RESOURCE_DIRECTORY)(
RVA2FO((m_pOptHeader64->DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE]).VirtualAddress)
+ (ULONGLONG)m_pFile)
: NULL;
/*
* Relocation
*/
m_pReloc = (m_pOptHeader64->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC]).VirtualAddress ?
(PIMAGE_BASE_RELOCATION)(
RVA2FO((m_pOptHeader64->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC]).VirtualAddress)
+ (ULONGLONG)m_pFile)
: NULL;
/*
* TLS
*/
m_pTLS64 = (m_pOptHeader64->DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS]).VirtualAddress ?
(PIMAGE_TLS_DIRECTORY64)(
RVA2FO((m_pOptHeader64->DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS]).VirtualAddress)
+ (ULONGLONG)m_pFile)
: NULL;
/*
* Delay loaded dll
*/
m_pDelay = (m_pOptHeader64->DataDirectory[IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT]).VirtualAddress ?
(PIMAGE_DELAYLOAD_DESCRIPTOR)(
RVA2FO((m_pOptHeader64->DataDirectory[IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT]).VirtualAddress)
+ (ULONGLONG)m_pFile)
: NULL;
}
else
{
m_pOptHeader32 = (PIMAGE_OPTIONAL_HEADER32)(&(m_pNtHeader->OptionalHeader));
/*
* Export table.
*/
if (m_pFileHeader->Characteristics & IMAGE_FILE_DLL)
{
m_pIED = (m_pOptHeader32->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]).VirtualAddress ?
(PIMAGE_EXPORT_DIRECTORY)(
RVA2FO((m_pOptHeader32->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]).VirtualAddress)
+ (ULONGLONG)m_pFile)
: NULL;
}
/*
* Import table.
*/
m_pIID = (m_pOptHeader32->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]).VirtualAddress ?
(PIMAGE_IMPORT_DESCRIPTOR)(
RVA2FO((m_pOptHeader32->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]).VirtualAddress)
+ (ULONGLONG)m_pFile)
: NULL;
/*
* Resource.
*/
m_pRes = (m_pOptHeader32->DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE]).VirtualAddress ?
(PIMAGE_RESOURCE_DIRECTORY)(
RVA2FO((m_pOptHeader32->DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE]).VirtualAddress)
+ (ULONGLONG)m_pFile)
: NULL;
/*
* Relocation
*/
m_pReloc = (m_pOptHeader32->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC]).VirtualAddress ?
(PIMAGE_BASE_RELOCATION)(
RVA2FO((m_pOptHeader32->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC]).VirtualAddress)
+ (ULONGLONG)m_pFile)
: NULL;
/*
* TLS
*/
m_pTLS32 = (m_pOptHeader32->DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS]).VirtualAddress ?
(PIMAGE_TLS_DIRECTORY32)(
RVA2FO((m_pOptHeader32->DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS]).VirtualAddress)
+ (ULONGLONG)m_pFile)
: NULL;
/*
* Delay loaded dll
*/
m_pDelay = (m_pOptHeader32->DataDirectory[IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT]).VirtualAddress ?
(PIMAGE_DELAYLOAD_DESCRIPTOR)(
RVA2FO((m_pOptHeader32->DataDirectory[IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT]).VirtualAddress)
+ (ULONGLONG)m_pFile)
: NULL;
}
}
}
PE::~PE()
{
delete[] m_pFile;
m_pFile = NULL;
m_pDosHeader = NULL;
m_pNtHeader = NULL;
m_pFileHeader = NULL;
m_pOptHeader32 = NULL;
m_pOptHeader64 = NULL;
m_pFirstSection = NULL;
m_pIED = NULL;
m_pIID = NULL;
m_pRes = NULL;
m_pReloc = NULL;
m_pTLS32 = NULL;
m_pTLS64 = NULL;
m_pDelay = NULL;
}
RVA2FO
DWORD PE::RVA2FO(ULONGLONG dwRVA)
{
PIMAGE_SECTION_HEADER pSectionHeader = m_pFirstSection;
if (dwRVA == 0)
{
return 0;
}
while (!(dwRVA >= pSectionHeader->VirtualAddress
&& dwRVA < pSectionHeader->VirtualAddress + pSectionHeader->SizeOfRawData))
{
++pSectionHeader;
/*if (pSectionHeader->SizeOfRawData == 0)
{
return -1;
}*/
}
return pSectionHeader->PointerToRawData
+ (dwRVA - pSectionHeader->VirtualAddress);
}
bIsPe()
bool PE::bIsPe()
{
if (m_pDosHeader->e_magic == IMAGE_DOS_SIGNATURE
&& m_pNtHeader->Signature == IMAGE_NT_SIGNATURE)
{
return true;
}
return false;
}
FILE_HEADER()
/*
* Functions to show PE info.
*/
void PE::showDosHeader()
{
}
void PE::showNtHeader()
{
}
void PE::showFileHeader()
{
char* characteristics[] = {
"IMAGE_FILE_RELOCS_STRIPPED ",
"IMAGE_FILE_EXECUTABLE_IMAGE ",
"IMAGE_FILE_LINE_NUMS_STRIPPED ",
"IMAGE_FILE_LOCAL_SYMS_STRIPPED ",
"IMAGE_FILE_AGGRESIVE_WS_TRIM ",
"IMAGE_FILE_LARGE_ADDRESS_AWARE ",
"",
"IMAGE_FILE_BYTES_REVERSED_LO ",
"IMAGE_FILE_32BIT_MACHINE ",
"IMAGE_FILE_DEBUG_STRIPPED ",
"IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP ",
"IMAGE_FILE_NET_RUN_FROM_SWAP ",
"IMAGE_FILE_SYSTEM ",
"IMAGE_FILE_DLL ",
"IMAGE_FILE_UP_SYSTEM_ONLY ",
"IMAGE_FILE_BYTES_REVERSED_HI "
};
wprintf(L"Machine: %04x\n", m_pFileHeader->Machine);
wprintf(L"NumberOfSections: %04x\n", m_pFileHeader->NumberOfSections);
wprintf(L"SizeOfOptionalHeader: %04x\n", m_pFileHeader->SizeOfOptionalHeader);
wprintf(L"Characteristics: %04x\n", m_pFileHeader->Characteristics);
for (BYTE i = 0; i < 16; ++i)
{
if (m_pFileHeader->Characteristics & (1 << i))
{
printf("\t");
printf(characteristics[i]);
printf("\n");
}
}
}
OptHeader
void PE::showOptHeader()
{
char* dllcharacteristics[] = {
"",
"",
"",
"",
"",
"IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA 0x0020 Image can handle a high entropy 64-bit virtual address space.",
"IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE 0x0040 DLL can move. ",
"IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY 0x0080 Code Integrity Image ",
"IMAGE_DLLCHARACTERISTICS_NX_COMPAT 0x0100 Image is NX compatible ",
"IMAGE_DLLCHARACTERISTICS_NO_ISOLATION 0x0200 Image understands isolation and doesn't want it ",
"IMAGE_DLLCHARACTERISTICS_NO_SEH 0x0400 Image does not use SEH. No SE handler may reside in this image ",
"IMAGE_DLLCHARACTERISTICS_NO_BIND 0x0800 Do not bind this image. ",
"IMAGE_DLLCHARACTERISTICS_APPCONTAINER 0x1000 Image should execute in an AppContainer ",
"IMAGE_DLLCHARACTERISTICS_WDM_DRIVER 0x2000 Driver uses WDM model ",
"IMAGE_DLLCHARACTERISTICS_GUARD_CF 0x4000 Image supports Control Flow Guard. ",
"IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE 0x8000 "
};
if (m_bIs64)
{
wprintf(L"OEP: %08x\n", m_pOptHeader64->AddressOfEntryPoint);
wprintf(L"ImageBase: %016x\n", m_pOptHeader64->ImageBase);
wprintf(L"SectionAlignment: %08x\n", m_pOptHeader64->SectionAlignment);
wprintf(L"FileAlignment: %08x\n", m_pOptHeader64->FileAlignment);
wprintf(L"SizeOfImage: %08x\n", m_pOptHeader64->SizeOfImage);
wprintf(L"SizeOfHeaders: %08x\n", m_pOptHeader64->SizeOfHeaders);
wprintf(L"CheckSum: %08x\n", m_pOptHeader64->CheckSum);
wprintf(L"DllCharacteristics: %08x\n", m_pOptHeader64->DllCharacteristics);
for (BYTE i = 0; i < 16; ++i)
{
if (m_pOptHeader64->DllCharacteristics & (1 << i))
{
printf("\t");
printf(dllcharacteristics[i]);
printf("\n");
}
}
}
else
{
wprintf(L"OEP: %08x\n", m_pOptHeader32->AddressOfEntryPoint);
wprintf(L"ImageBase: %016x\n", m_pOptHeader32->ImageBase);
wprintf(L"SectionAlignment: %08x\n", m_pOptHeader32->SectionAlignment);
wprintf(L"FileAlignment: %08x\n", m_pOptHeader32->FileAlignment);
wprintf(L"SizeOfImage: %08x\n", m_pOptHeader32->SizeOfImage);
wprintf(L"SizeOfHeaders: %08x\n", m_pOptHeader32->SizeOfHeaders);
wprintf(L"CheckSum: %08x\n", m_pOptHeader32->CheckSum);
wprintf(L"DllCharacteristics: %08x\n", m_pOptHeader32->DllCharacteristics);
for(BYTE i = 0; i < 16; ++i)
{
if (m_pOptHeader32->DllCharacteristics & (1 << i))
{
printf("\t");
printf(dllcharacteristics[i]);
printf("\n");
}
}
}
}
SectionHeader
void PE::enumSectionHeaders()
{
PIMAGE_SECTION_HEADER pSectionHeader = m_pFirstSection;
/*char* characteristics[] = {
};
*/
for (int i = 0; i < m_pFileHeader->NumberOfSections;
++i, ++pSectionHeader)
{
printf("section %d\n", i);
printf(" name: %s\n", pSectionHeader->Name);
printf(" VirtualAddress: 0x%p\n", pSectionHeader->VirtualAddress);
printf(" size of raw data: 0x%08x\n", pSectionHeader->SizeOfRawData);
printf(" PointerToRawData: 0x%p\n", pSectionHeader->PointerToRawData);
printf(" Characteristics: 0x%08x\n", pSectionHeader->Characteristics);
//wprintf(L" : %08x\n", i);
}
}
Export
void PE::showExpTable()
{
if (!m_pFile || !m_pIED
|| !(m_pFileHeader->Characteristics & IMAGE_FILE_DLL))
{
printf("No DLL file.\n");
return;
}
PIMAGE_EXPORT_DIRECTORY pExportTab = m_pIED;
DWORD *pFuncAddr = (DWORD *)(RVA2FO(pExportTab->AddressOfFunctions) + (ULONGLONG)m_pFile);
DWORD *pFuncName = (DWORD *)(RVA2FO(pExportTab->AddressOfNames) + (ULONGLONG)m_pFile);
WORD *pFuncOrd = (WORD *)(RVA2FO(pExportTab->AddressOfNameOrdinals) + (ULONGLONG)m_pFile);
DWORD cNames = pExportTab->NumberOfNames;
DWORD cFuncs = pExportTab->NumberOfFunctions;
printf("DLL name: %s\n", RVA2FO(pExportTab->Name) + (ULONGLONG)m_pFile);
for (int nIndexAddr = 0; nIndexAddr < cFuncs; ++nIndexAddr)
{
for (int nIndexOrd = 0; nIndexOrd < cNames; ++nIndexOrd)
{
if (nIndexAddr == pFuncOrd[nIndexOrd])
{
printf(" Ordinal: %d FuncNanme: %s FuncAddr: 0x%p\n",
nIndexOrd, RVA2FO(pFuncName[nIndexOrd]) + (ULONGLONG)m_pFile, pFuncAddr[nIndexAddr]);
break;
}
else if(nIndexOrd == cNames - 1)
{
printf(" FuncAddr: 0x%p\n", pFuncAddr[nIndexAddr]);
}
}
}
}
Import
void PE::showImpTable()
{
PIMAGE_IMPORT_DESCRIPTOR pImpTab = m_pIID;
PIMAGE_THUNK_DATA pINT = NULL, pIAT = NULL;
while (pImpTab->Name)
{
printf("dll name: %s\n", (char*)(RVA2FO(pImpTab->Name) + (ULONGLONG)m_pFile));
/*printf("INT:\n");
pINT = (PIMAGE_THUNK_DATA)(pImpTab->OriginalFirstThunk + (ULONGLONG)pDos);
while (pINT->u1.Ordinal)
{
if (pINT->u1.Ordinal
& 1 << (8 * sizeof(pINT->u1.Ordinal) - 1))
{
printf("ordinal: %d\n", pINT->u1.Ordinal & ~(1 << (8 * sizeof(pINT->u1.Ordinal) - 1)));
}
else
{
PIMAGE_IMPORT_BY_NAME pName = (PIMAGE_IMPORT_BY_NAME)RVA2FO(pINT->u1.AddressOfData);
printf("ordinal: %d func name: %s\n", pName->Hint, pName->Name);
}
++pINT;
}*/
printf("IAT:\n");
pIAT = (PIMAGE_THUNK_DATA)(RVA2FO(pImpTab->FirstThunk) + (ULONGLONG)m_pFile);
while (pIAT->u1.Ordinal)
{
if (pIAT->u1.Ordinal
& 1 << (8 * sizeof(pIAT->u1.Ordinal) - 1))
{
printf(" ordinal: %04x\n", pIAT->u1.Ordinal & ~(1 << (8 * sizeof(pIAT->u1.Ordinal) - 1)));
}
else
{
PIMAGE_IMPORT_BY_NAME pName = (PIMAGE_IMPORT_BY_NAME)(RVA2FO(pIAT->u1.AddressOfData) + (ULONGLONG)m_pFile);
printf(" ordinal: %04x func name: %s\n", pName->Hint, pName->Name);
}
++pIAT;
}
++pImpTab;
}
}
Resource
void PE::showRes()
{
PIMAGE_RESOURCE_DIRECTORY pRes_1 = m_pRes, pRes_2 = NULL, pRes_3 = NULL;
PIMAGE_RESOURCE_DIRECTORY_ENTRY pResEntry_1 = NULL,
pResEntry_2 = NULL,
pResEntry_3 = NULL;
DWORD dwEntry_1 = 0,
dwEntry_2 = 0,
dwEntry_3 = 0;
PIMAGE_RESOURCE_DIR_STRING_U pName = NULL;
PIMAGE_RESOURCE_DATA_ENTRY pData = NULL;
char *aResTypes[] = {
"",
"cursor", "bitmap",
"icon", "menu",
"dialog", "string table",
"font directory", "font",
"accelerator", "unformatted",
"message table", "group cursor",
"",
"group icon",
"",
"version",
};
pRes_1 = m_pRes;
dwEntry_1 = pRes_1->NumberOfIdEntries + pRes_1->NumberOfNamedEntries;
if (!dwEntry_1)
{
printf("No resource\n");
system("pause");
return;
}
printf("There are %d types of resources.\t"
"%d typed hava name\n",
dwEntry_1, pRes_1->NumberOfNamedEntries);
/*
* Layer 1
*/
pResEntry_1 = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(pRes_1 + 1);
for (int i = 0; i < dwEntry_1; ++i)
{
/*
* Layer 2
*/
if (pResEntry_1[i].DataIsDirectory)
{
pRes_2 = (PIMAGE_RESOURCE_DIRECTORY)
(pResEntry_1[i].OffsetToDirectory + (DWORD)pRes_1);
dwEntry_2 = pRes_2->NumberOfIdEntries + pRes_2->NumberOfNamedEntries;
printf("\t%d %s resources .\n"
"\t%d hava name\n",
dwEntry_2,
pResEntry_1[i].Id <= 0x10 ? aResTypes[pResEntry_1[i].Name] : "Unknown type",
pRes_2->NumberOfNamedEntries);
/*
* Layer 3
*/
pResEntry_2 = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(pRes_2 + 1);
for (int j = 0; j < dwEntry_2; ++j)
{
if (pResEntry_2[j].DataIsDirectory)
{
pRes_3 = (PIMAGE_RESOURCE_DIRECTORY)
(pResEntry_2[j].OffsetToDirectory + (DWORD)pRes_1);
dwEntry_3 = pRes_3->NumberOfIdEntries + pRes_3->NumberOfNamedEntries;
/*
* Data layer
*/
pResEntry_3 = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(pRes_3 + 1);
for (int k = 0; k < dwEntry_3; ++k)
{
pData = (PIMAGE_RESOURCE_DATA_ENTRY)(pResEntry_3[k].OffsetToData + (DWORD)pRes_1);
if (pResEntry_2[j].NameIsString)
{
pName = (PIMAGE_RESOURCE_DIR_STRING_U)(pResEntry_2[j].NameOffset + pRes_1);
printf("\t\tRVA: 0x%p size: %08x\t", pData->OffsetToData, pData->Size);
printf("\t\t%s %s ---%08x\n",
pResEntry_1[i].Id <= 0x10 ? aResTypes[pResEntry_1[i].Id] : "Unknown type",
pName->NameString,
pResEntry_3[k].Name);
}
else
{
printf("\t\tRVA: 0x%p size: %08x\t", pData->OffsetToData, pData->Size);
printf("\t\t%s %08x ---%08x\n",
pResEntry_1[i].Id <= 0x10 ? aResTypes[pResEntry_1[i].Id] : "Unknown type",
pResEntry_2[j].Name,
pResEntry_3[k].Name);
}
}
}
}
}
}
}
Relocation
void PE::showReloc()
{
if (!m_pFile || !m_pReloc)
{
printf("No relocation\n");
return;
}
typedef struct {
WORD offset : 12;
WORD type : 4;
}TypeOffset, *PTypeOffset;
PIMAGE_BASE_RELOCATION pReloc = m_pReloc;
DWORD dwCount = ((pReloc->SizeOfBlock) - 8) / 2;
PTypeOffset pTypeOffset = (PTypeOffset)(pReloc + 1);
ULONGLONG RVA = 0;
while (pReloc->SizeOfBlock)
{
printf("Block RVA: %08x\n", pReloc->VirtualAddress);
for (int i = 0; i < dwCount;
++i)
{
RVA = 0;
if (pTypeOffset[i].type == IMAGE_REL_BASED_HIGHLOW)
{
RVA = pTypeOffset[i].offset + pReloc->VirtualAddress;
printf("\tRVA : %08X\n\tFOA : %08X\n\n", RVA, RVA2FO(RVA));
}
else if (pTypeOffset[i].type == IMAGE_REL_BASED_DIR64)
{
RVA = pTypeOffset[i].offset + pReloc->VirtualAddress;
printf("\tRVA : %016X\n\tFOA : %016X\n\n", RVA, RVA2FO(RVA));
}
}
pReloc = (PIMAGE_BASE_RELOCATION)((ULONGLONG)pReloc + pReloc->SizeOfBlock);
}
}
TLS
void PE::showTLS()
{
if (m_pTLS32)
{
printf("TLS Directory:");
printf("\tStartAddressOfRawData : 0x%p\n", m_pTLS32->StartAddressOfRawData);
printf("\tEndAddressOfRawData : 0x%p\n", m_pTLS32->EndAddressOfRawData);
printf("\tAddressOfCallBacks : 0x%p\n", m_pTLS32->AddressOfCallBacks);
}
else if(m_pTLS64)
{
printf("TLS Directory:");
printf("\tStartAddressOfRawData : 0x%p\n", m_pTLS64->StartAddressOfRawData);
printf("\tEndAddressOfRawData : 0x%p\n", m_pTLS64->EndAddressOfRawData);
printf("\tAddressOfCallBacks : 0x%p\n", m_pTLS64->AddressOfCallBacks);
}
else
{
printf("No TLS\n");
}
}
delay
void PE::showDelay()
{
if (m_pDelay)
{
printf("Delay-loaded dll name: %s\n", RVA2FO(m_pDelay->DllNameRVA) + (ULONGLONG)m_pFile);
printf("RVA to IAT: %p\n", m_pDelay->ImportAddressTableRVA);
printf("RVA to INT: %p\n", m_pDelay->ImportNameTableRVA);
printf("RVA to bound IAT: %p\n", m_pDelay->BoundImportAddressTableRVA);
printf("RVA to unload IAT: %p\n", m_pDelay->UnloadInformationTableRVA);
}
else
{
printf("No dalay-loaded dll.\n");
}
}
RVA2FO
DWORD PE::RVA2FO(ULONGLONG dwRVA)
{
PIMAGE_SECTION_HEADER pSectionHeader = m_pFirstSection;
if (dwRVA == 0)
{
return 0;
}
while (!(dwRVA >= pSectionHeader->VirtualAddress
&& dwRVA < pSectionHeader->VirtualAddress + pSectionHeader->SizeOfRawData))
{
++pSectionHeader;
/*if (pSectionHeader->SizeOfRawData == 0)
{
return -1;
}*/
}
return pSectionHeader->PointerToRawData
+ (dwRVA - pSectionHeader->VirtualAddress);
}