PE解析器


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);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值