PE工具编写
主要源代码参考《加密与解密 第四版》书中内容,把它改装成了命令行程序,简化了一些编程步骤:peload.h:
#pragma once
#define _PEFUNCS_H_
#pragma comment(lib,"imageHlp.lib")
#define GETTHUNK(pImportDesc) ((DWORD) \
((PIMAGE_IMPORT_DESCRIPTOR)pImportDesc->OriginalFirstThunk ? \
(PIMAGE_IMPORT_DESCRIPTOR)pImportDesc->OriginalFirstThunk:(PIMAGE_IMPORT_DESCRIPTOR)pImportDesc->FirstThunk \
))
#include<imagehlp.h>
#include <iostream>
using namespace std;
typedef struct _MAP_FILE_STRUCT
{
HANDLE hFile;
HANDLE hMapping;
HANDLE ImageBase;
} MAP_FILE_STRUCT, *PMAP_FILE_STRUCT;
BOOL LoadPEFile(LPTSTR lpFilename, PMAP_FILE_STRUCT pstMapFile)
{
PIMAGE_DOS_HEADER pDH = NULL;
PIMAGE_NT_HEADERS pNtH = NULL;
HANDLE hFile;
HANDLE hMapping;
LPVOID ImageBase;
//HANDLE ImageBase;
hFile = CreateFile(lpFilename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, 0);
if (!hFile)
return FALSE;
hMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
if (!hMapping)
{
CloseHandle(hFile);
return FALSE;
}
//获得映像基址
ImageBase = MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0);
if (!ImageBase)
{
CloseHandle(hMapping);
CloseHandle(hFile);
return FALSE;
}
pstMapFile->hFile = hFile;
pstMapFile->hMapping = hMapping;
pstMapFile->ImageBase = ImageBase;
return TRUE;
}
BOOL IsPEFile(LPVOID ImageBase)
{
PIMAGE_DOS_HEADERpDH = NULL;
PIMAGE_NT_HEADERSpNtH = NULL;
pDH = (PIMAGE_DOS_HEADER)ImageBase;
if (pDH->e_magic != IMAGE_DOS_SIGNATURE) //判断是否'MZ'
{
printf("不是有效的PE文件!\n");
return FALSE;
}
pNtH = (PIMAGE_NT_HEADERS)((DWORD)pDH + pDH->e_lfanew); //判断是否'PE'格式
if (pNtH->Signature != IMAGE_NT_SIGNATURE)
{
printf("不是有效的PE文件!\n");
return FALSE;
}
return true;
}
PIMAGE_NT_HEADERS GetNTHeaders(LPVOID ImageBase)
{
PIMAGE_DOS_HEADER pDH = NULL;
PIMAGE_NT_HEADERS pNtH = NULL;
if (!IsPEFile(ImageBase))
return NULL;
pDH = (PIMAGE_DOS_HEADER)ImageBase;
pNtH = (PIMAGE_NT_HEADERS)((DWORD)pDH + pDH->e_lfanew);
return pNtH;
}
PIMAGE_FILE_HEADER GetFileHeader(LPVOID ImageBase)
{
PIMAGE_NT_HEADERS pNtH = NULL;
PIMAGE_FILE_HEADER pFH = NULL;
pNtH = GetNTHeaders(ImageBase);
if (!pNtH)
return NULL;
pFH = &pNtH->FileHeader;
return pFH;
}
PIMAGE_OPTIONAL_HEADER WINAPI GetOptionalHeader(LPVOID ImageBase)
{
PIMAGE_OPTIONAL_HEADER pOH = NULL;
PIMAGE_NT_HEADERS pNtH = NULL;
pNtH = GetNTHeaders(ImageBase);
if (!pNtH)
return NULL;
pOH = &pNtH->OptionalHeader;
return pOH;
}
void ShowFileHeaderInfo(LPVOID LocalImageBase)
{
PIMAGE_DOS_HEADER pDH = NULL;
PIMAGE_NT_HEADERS pNTH = NULL;
PIMAGE_FILE_HEADER pFH = NULL;
pDH = (PIMAGE_DOS_HEADER)LocalImageBase;
pNTH = (PIMAGE_NT_HEADERS)((DWORD)pDH + pDH->e_lfanew);
pFH = &pNTH->FileHeader;
cout << "Machine:" << hex << pFH->Machine << endl;
cout << "NumberOfSections:" << hex << pFH->NumberOfSections << endl;
cout << "TimeDateStamp:" << hex << pFH->TimeDateStamp << endl;
cout << "NumberOfSymbols:" << hex << pFH->NumberOfSymbols << endl;
cout << "SizeOfOptionalHeader:" << hex << pFH->SizeOfOptionalHeader << endl;
cout << "Characteristics:" << hex << pFH->Characteristics << endl;
}
void ShowOptionalHeaderInfo(LPVOID LocalImageBase)
{
PIMAGE_DOS_HEADER pDH = NULL;
PIMAGE_NT_HEADERS pNTH = NULL;
PIMAGE_OPTIONAL_HEADER pOH = NULL;
pDH = (PIMAGE_DOS_HEADER)LocalImageBase;
pNTH = (PIMAGE_NT_HEADERS)((DWORD)pDH + pDH->e_lfanew);
pOH = &pNTH->OptionalHeader;
cout << "AddressOfEntryPoint:" << hex << pOH->AddressOfEntryPoint << endl;
cout << "BaseOfCode:" << hex << pOH->BaseOfCode << endl;
cout << "BaseOfData:" << hex << pOH->BaseOfData << endl;
cout << "ImageBase:" << hex << pOH->ImageBase << endl;
cout << "SectionAlignmet:" << hex << pOH->SectionAlignment << endl;
cout << "FileAlignment:" << hex << pOH->FileAlignment << endl;
cout << "SizeOfHeaders:" << hex << pOH->SizeOfHeaders << endl;
cout << "NumberOfRvaAndSizes:" << hex << pOH->NumberOfRvaAndSizes << endl;
}
void ShowDataDirInfo(LPVOID ImageBase)
{
PIMAGE_DOS_HEADER pDH = NULL;
PIMAGE_NT_HEADERS pNTH = NULL;
PIMAGE_OPTIONAL_HEADER pOH = NULL;
pDH = (PIMAGE_DOS_HEADER)ImageBase;
pNTH = (PIMAGE_NT_HEADERS)((DWORD)pDH + pDH->e_lfanew);
pOH = &pNTH->OptionalHeader;
cout << "Export Table Rva:" << hex << pOH->DataDirectory.VirtualAddress << endl;
cout << "Export Table Size:" << hex << pOH->DataDirectory.Size << endl;
cout << "Import Table Rva:" << hex << pOH->DataDirectory.VirtualAddress << endl;
cout << "Import Table Size:" << hex << pOH->DataDirectory.Size << endl;
cout << "Resourse Table Rva:" << hex << pOH->DataDirectory.VirtualAddress << endl;
cout << "Resourse Table Size:" << hex << pOH->DataDirectory.Size << endl;
cout << "Exception Table Rva:" << hex << pOH->DataDirectory.VirtualAddress << endl;
cout << "Exception Table Size:" << hex << pOH->DataDirectory.Size << endl;
cout << "Security Table Rva:" << hex << pOH->DataDirectory.VirtualAddress << endl;
cout << "Security Table Size:" << hex << pOH->DataDirectory.Size << endl;
}
PIMAGE_SECTION_HEADER GetFirstSectionHeader(LPVOID ImageBase)
{
PIMAGE_NT_HEADERS pNtH;
pNtH = GetNTHeaders(ImageBase);
PIMAGE_SECTION_HEADER pSH;
pSH = IMAGE_FIRST_SECTION(pNtH);
return pSH;
}
void ShowSectionHeaderInfo(LPVOID ImageNase)
{
WORD i;
PIMAGE_FILE_HEADER pFH = NULL;
PIMAGE_SECTION_HEADER pSH = NULL;
pFH = GetFileHeader(ImageNase);
if (!pFH)
return;
pSH = GetFirstSectionHeader(ImageNase);
for (i = 0; i<pFH->NumberOfSections; i++)
{
cout << "["<< i <<"]Section Name:" << pSH->Name << endl;
cout << " VirtualAddress:" << hex << pSH->VirtualAddress << endl;
cout << " SizeOfRawData:" << hex << pSH->SizeOfRawData << endl;
cout << " PointerToRelocations:" << hex << pSH->PointerToRelocations << endl;
cout << " NumberOfLinenumbers:" << hex << pSH->NumberOfLinenumbers << endl;
cout << " Characteristics:" << hex << pSH->Characteristics << endl;
cout << endl;
++pSH;
}
}
LPVOID RvaToPtr(PIMAGE_NT_HEADERS pNtH, LPVOID ImageBase, DWORD dwRVA)
{
return ImageRvaToVa(pNtH, ImageBase, dwRVA, NULL);
}
PIMAGE_EXPORT_DIRECTORYGetExportDirectory(LPVOID ImageBase)
{
PIMAGE_DOS_HEADER pDH = NULL;
PIMAGE_NT_HEADERS pNTH = NULL;
PIMAGE_OPTIONAL_HEADER pOH = NULL;
PIMAGE_EXPORT_DIRECTORY pExportDir = NULL;
pDH = (PIMAGE_DOS_HEADER)ImageBase;
pNTH = (PIMAGE_NT_HEADERS)((DWORD)pDH + pDH->e_lfanew);
pOH = &pNTH->OptionalHeader;
//theRVA addr must be turn to VA
pExportDir = (PIMAGE_EXPORT_DIRECTORY)RvaToPtr(pNTH, ImageBase, pOH->DataDirectory.VirtualAddress);
if (!pExportDir)
return NULL;
returnpExportDir;
}
int ShowExportDirInfo(LPVOID ImageBase)
{
PIMAGE_DOS_HEADER pDH = NULL;
PIMAGE_NT_HEADERS pNTH = NULL;
PIMAGE_OPTIONAL_HEADER pOH = NULL;
PIMAGE_EXPORT_DIRECTORY pExportDir = NULL;
pDH = (PIMAGE_DOS_HEADER)ImageBase;
pNTH = (PIMAGE_NT_HEADERS)((DWORD)pDH + pDH->e_lfanew);
pOH = &pNTH->OptionalHeader;
pExportDir = GetExportDirectory(ImageBase);
if (!pExportDir)
{
int error = GetLastError();
if (error == 0)
cout << "This File is not include Export Table!" << endl;
else
cout << "Can't get Export Directory:( ,error code:" << error << endl;
return 0;
}
cout << "AddressOfFunctions: " << hex << pExportDir->AddressOfFunctions << endl;
cout << "AddressOfNameOrdinals: " << hex << pExportDir->AddressOfNameOrdinals << endl;
cout << "AddressOfNames: " << hex << pExportDir->AddressOfNames << endl;
cout << "Base: " << hex << pExportDir->Base << endl;
cout << "MajorVersion: " << hex << pExportDir->MajorVersion << endl;
cout << "MinorVersion: " << hex << pExportDir->MinorVersion << endl;
cout << "Characteristics: " << hex << pExportDir->Characteristics << endl;
cout << "Name: " << hex << pExportDir->Name << endl;
cout << "NumberOfFunctions: " << hex << pExportDir->NumberOfFunctions << endl;
cout << "NumberOfNames: " << hex << pExportDir->NumberOfNames << endl;
cout << "TimeDateStamp: " << hex << pExportDir->TimeDateStamp << endl;
//Sometime the string of namewill be error here
cout << " pExportDir->Name: " << (char *)ImageRvaToVa(pNTH, ImageBase, pExportDir->Name, NULL) << endl;
return 1;
}
void ShowExportFuncsInfo(LPVOID ImageBase)
{
char*szFuncName;
UINT iNumOfName = 0;
PDWORD pdwRvas, pdwNames;
PWORD pwOrds;
UINT i = 0, j = 0, k = 0;
PIMAGE_DOS_HEADER pDH = NULL;
PIMAGE_NT_HEADERS pNTH = NULL;
PIMAGE_OPTIONAL_HEADER pOH = NULL;
PIMAGE_EXPORT_DIRECTORY pExportDir = NULL;
pDH = (PIMAGE_DOS_HEADER)ImageBase;
pNTH = (PIMAGE_NT_HEADERS)((DWORD)pDH + pDH->e_lfanew);
pOH = &pNTH->OptionalHeader;
pExportDir = GetExportDirectory(ImageBase);
if (!pNTH)
return;
pExportDir = (PIMAGE_EXPORT_DIRECTORY)GetExportDirectory(ImageBase);
if (!pExportDir)
return;
pwOrds = (PWORD)RvaToPtr(pNTH,ImageBase, pExportDir->AddressOfNameOrdinals);
pdwRvas = (PDWORD)RvaToPtr(pNTH, ImageBase, pExportDir->AddressOfFunctions);
pdwNames = (PDWORD)RvaToPtr(pNTH, ImageBase, pExportDir->AddressOfNames);
if (!pdwRvas)
return;
iNumOfName = pExportDir->NumberOfNames;
printf("123456798");
for (i = 0; i<pExportDir->NumberOfFunctions; i++)
{
if (*pdwRvas)
{
for (j = 0; j<iNumOfName; j++)
{
if (i == pwOrds)
{
szFuncName = (char*)RvaToPtr(pNTH, ImageBase, pdwNames);
cout<<" pExportDir->Name ["<<i+1<<"]: "<<szFuncName<<endl;
}
}
}
++pdwRvas;
}
}
void ShowImportDirInfo(LPVOID ImageBase)
{
DWORD dwDataStartRVA;
PIMAGE_DOS_HEADER pDH = NULL;
PIMAGE_NT_HEADERS pNTH = NULL;
PIMAGE_OPTIONAL_HEADER pOH = NULL;
PIMAGE_IMPORT_DESCRIPTOR pImportDir = NULL;
pDH = (PIMAGE_DOS_HEADER)ImageBase;
pNTH = (PIMAGE_NT_HEADERS)((DWORD)pDH + pDH->e_lfanew);
pOH = &pNTH->OptionalHeader;
dwDataStartRVA = pOH->DataDirectory.VirtualAddress;
pImportDir = (PIMAGE_IMPORT_DESCRIPTOR)RvaToPtr(pNTH, ImageBase, dwDataStartRVA);
if (!pImportDir)
{
int error = GetLastError();
if (error == 0)
cout << "This File is not include Import Table!" << endl;
else
cout << "Can't get Import Directory:( ,error code:" << error << endl;
return;
}
while (pImportDir->FirstThunk)
{
cout << "Characteristics: " << hex << pImportDir->Characteristics << endl;
cout << "FirstThunk(IAT): " << hex << pImportDir->FirstThunk << endl;
cout << "ForwarderChain: " << hex << pImportDir->ForwarderChain << endl;
cout << "TimeDateStamp: " << hex << pImportDir->TimeDateStamp << endl;
cout << "Name: " << hex << pImportDir->Name << endl;
cout << "OriginalFirstThunk(INT): " << hex << pImportDir->OriginalFirstThunk << endl;
//Sometime the string of namewill be error here
cout << " pImportDir->Name: " << (char *)ImageRvaToVa(pNTH, ImageBase, pImportDir->Name, NULL) << endl;
++pImportDir;
}
}
void ShowImportFuncsByDllIndex(LPVOID ImageBase)
{
char * szFuncName;
DWORD dwThunk, *pdwThunk = NULL;
int i = 0;
DWORD dwDataStartRVA;
PIMAGE_DOS_HEADER pDH = NULL;
PIMAGE_NT_HEADERS pNTH = NULL;
PIMAGE_OPTIONAL_HEADER pOH = NULL;
PIMAGE_IMPORT_DESCRIPTOR pImportDir = NULL;
pDH = (PIMAGE_DOS_HEADER)ImageBase;
pNTH = (PIMAGE_NT_HEADERS)((DWORD)pDH + pDH->e_lfanew);
pOH = &pNTH->OptionalHeader;
//Get Import Table Addr
dwDataStartRVA = pOH->DataDirectory.VirtualAddress;
pImportDir = (PIMAGE_IMPORT_DESCRIPTOR)RvaToPtr(pNTH, ImageBase, dwDataStartRVA);
PIMAGE_IMPORT_BY_NAME pByName = NULL;
dwThunk = GETTHUNK(pImportDir);
pdwThunk = (DWORD*)RvaToPtr(pNTH, ImageBase, dwThunk);
if (!pdwThunk)
return;
while (*pdwThunk)
{
pByName = (PIMAGE_IMPORT_BY_NAME)RvaToPtr(pNTH, ImageBase, (DWORD)(*pdwThunk));
if (pByName)
{
szFuncName = (char *)pByName->Name;
cout << " ImportFuncsByDllIndex : " << szFuncName << endl;
}
++pdwThunk;
}
}
PEload.cpp:
// PEload.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <Windows.h>
#include<CommCtrl.h>
#include"peload.h"
#include <iostream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
LPTSTR lpFilename = argv;
LPVOID ImageBase;
PMAP_FILE_STRUCT pstMapFile;
if (argc == 1)
{
printf("没有文件!\n");
return 0;
}
if (LoadPEFile(lpFilename, pstMapFile))
{
ImageBase = pstMapFile->ImageBase;
if (IsPEFile(ImageBase))
{
printf("****************ShowFileHeaderInfo*******************\n");
ShowFileHeaderInfo(ImageBase);
printf("****************ShowOptionalHeaderInfo***************\n");
ShowOptionalHeaderInfo(ImageBase);
printf("****************ShowDataDirInfo**********************\n");
ShowDataDirInfo(ImageBase);
printf("****************ShowSectionHeaderInfo****************\n");
ShowSectionHeaderInfo(ImageBase);
printf("****************ShowExportDirInfo********************\n");
if (ShowExportDirInfo(ImageBase))
{
printf("****************ShowExportFuncsInfo******************\n");
ShowExportFuncsInfo(ImageBase);
}
printf("****************ShowImportDirInfo********************\n");
ShowImportDirInfo(ImageBase);
printf("****************ShowImportFuncsByDllIndex************\n");
ShowImportFuncsByDllIndex(ImageBase);
}
}
system("pause");
return 0;
}
stdafx.h:
// stdafx.h : 标准系统包含文件的包含文件,
// 或是经常使用但不常更改的
// 特定于项目的包含文件
//
#pragma once
#include "targetver.h"
#include <stdio.h>
#include <tchar.h>
// TODO:在此处引用程序需要的其他头文件
运行效果:
页:
[1]