#include <iostream>
#include <Windows.h>
#include <fstream>
#include "ku.h"
using namespace std;
int main(int argc, char** argv)
{
char pepath[MAX_PATH]={0};
cout<<"输入要解析的pe文件:<<endl;
cin>>pepath;
UINT l;
cout.setf(ios::hex, ios_base::showbase);
fstream file;
file.open(pepath, ios::in | ios::binary);//打开pe文件
if (!file)
{
return 3;
}
file.clear();
file.seekg(0);
IMAGE_DOS_HEADER dos = { 0 };
file.read((char*)(void*)&dos, sizeof(IMAGE_DOS_HEADER));
//cout <<"0x" << hex << dos.e_lfanew << '\n';//定位pe头
if (dos.e_magic != 0x5A4D)
{
file.close();
return 4;
}
file.clear();
file.seekg(dos.e_lfanew);
file.read((char*)(void*)&l, sizeof(l));
if (l != 0x4550)
{
return 5;
}
file.clear();
l = dos.e_lfanew + (LONG)sizeof(LONG);
file.seekg(l);
IMAGE_FILE_HEADER ntfile32 = { 0 };
file.read((char*)(void*) & ntfile32, sizeof(IMAGE_FILE_HEADER));//读nt file头
void* vpntop = new BYTE[ntfile32.SizeOfOptionalHeader];
file.read((char*)vpntop, ntfile32.SizeOfOptionalHeader);//读可选头
cout << "0x" << hex << ntfile32.SizeOfOptionalHeader << '\n'; sizeof(WORD);
PIMAGE_OPTIONAL_HEADER32 pntop = (PIMAGE_OPTIONAL_HEADER32)vpntop;
if (pntop->Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC)
{
return 6;
}
cout << "0x" << hex<<pntop->ImageBase << endl;//输出基地址
cout << "0x" << hex << pntop->DataDirectory[0].VirtualAddress << endl;
cout << "0x" << hex << pntop->DataDirectory[0].Size << endl;
file.clear();
l = dos.e_lfanew + sizeof(LONG) + sizeof(IMAGE_FILE_HEADER) + ntfile32.SizeOfOptionalHeader;//定位到第一个节区
file.seekg(l);
PIMAGE_SECTION_HEADER psech = new IMAGE_SECTION_HEADER[ntfile32.NumberOfSections+1];
l = sizeof(IMAGE_SECTION_HEADER) * ntfile32.NumberOfSections;
file.read((char*)(void*)psech, l);
for (int i = 0; i < ntfile32.NumberOfSections; i++)
{
cout << psech[i].Name << endl;//输出节区名字
}
importanalysis(&file, &ntfile32, pntop, psech);
delete[] psech;
psech = nullptr;
delete[] vpntop;
vpntop = nullptr;
pntop = nullptr;
file.close();
system("pause");
return 0;
}
#include"ku.h"
#include<iostream>
DWORD RvaToFov(ULONG rva,PIMAGE_FILE_HEADER pntfile32,PIMAGE_OPTIONAL_HEADER32 pntop ,PIMAGE_SECTION_HEADER psech)
{
WORD secnum=pntfile32->NumberOfSections;
int i = 0;
for (; i < secnum; i++)
{
if (i == secnum - 1)
{
break;
}
if(rva>=psech[i].VirtualAddress&&rva<psech[i+1].VirtualAddress)
{
break;
}
}
return rva - psech[i].VirtualAddress + psech[i].PointerToRawData;
}
void importanalysis(fstream* hfile, PIMAGE_FILE_HEADER pntfile32, PIMAGE_OPTIONAL_HEADER32 pntop, PIMAGE_SECTION_HEADER psech)
{
using std::iostream;
using std::cout;
using std::endl;
using std::hex;
ULONG l = 0;
//导入表解析
cout << "0x" << hex << pntop->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress << endl;
DWORD imfov = RvaToFov(pntop->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress, pntfile32, pntop, psech);
cout << "imfov:" << "0x" << hex << imfov << endl;
hfile->clear();
hfile->seekg(imfov);//定位到第一个导入表
IMAGE_IMPORT_DESCRIPTOR imdata = { 0 };
WORD imnum = 0;
while (true)//统计导入表个数
{
hfile->read((char*)(void*)&imdata, sizeof(IMAGE_IMPORT_DESCRIPTOR));
if (imdata.Characteristics == 0 &&
imdata.ForwarderChain == 0 &&
imdata.Name == 0 &&
imdata.FirstThunk == 0 &&
imdata.TimeDateStamp == 0)//判断导入表是否结束
{
break;
}
imnum++;
}
PIMAGE_IMPORT_DESCRIPTOR pim = nullptr;//将导入表读入内存
pim = new IMAGE_IMPORT_DESCRIPTOR[imnum + 1];
hfile->clear();
hfile->seekg(imfov);
for (int i = 0; i < imnum; i++)
{
hfile->read((char*)(void*)&pim[i], sizeof(IMAGE_IMPORT_DESCRIPTOR));
}
for (int i = 0; i < imnum; i++)
{
char dllname[MAX_PATH] = { 0 };//输出dll名称
DWORD fovdllname = 0;
fovdllname = RvaToFov(pim[i].Name, pntfile32, pntop, psech);
hfile->clear();
hfile->seekg(fovdllname);
for (int i = 0; i < MAX_PATH; i++)
{
hfile->read(&dllname[i], sizeof(char));
if (dllname[i] == 0)
{
break;
}
}
cout << "dllname:" << dllname << endl;
if (pim[i].OriginalFirstThunk == 0)
{
cout << "FirstThunk:" << "0x" << hex << pim[i].FirstThunk << endl;
}
else
{
//cout << "Characteristics:" << "0x" << hex << pim[i].Characteristics << endl;
DWORD fovthfirst = RvaToFov(pim[i].Characteristics, pntfile32, pntop, psech);//定位到第一个导入函数表
DWORD signthunk = 0;
WORD thnum = 0;
PIMAGE_THUNK_DATA32 pthunk = nullptr;
IMAGE_THUNK_DATA32 thunk = { 0 };
hfile->clear();
hfile->seekg(fovthfirst);
for (;; thnum++)//遍历导入函数表
{
hfile->read((char*)(void*)&thunk, sizeof(IMAGE_THUNK_DATA32));
if (thunk.u1.AddressOfData == 0)
{
break;
}
}
pthunk = new IMAGE_THUNK_DATA32[thnum + 1];
hfile->clear();
hfile->seekg(fovthfirst);
for (int i = 0; i < thnum; i++)//将导入函数表写入内存
{
hfile->read((char*)(void*)&pthunk[i], sizeof(IMAGE_THUNK_DATA32));
}
DWORD thunksign = 0;
DWORD funfov = 0;
IMAGE_IMPORT_BY_NAME funbyname = { 0 };
for (int i = 0; i < thnum; i++)//输出dll的导入函数名称
{
thunksign = 0;
thunksign = pthunk[i].u1.AddressOfData >> 31;//判断是否以字符串为导入方式
if (!thunksign)
{
funfov = RvaToFov(pthunk[i].u1.AddressOfData, pntfile32, pntop, psech);
hfile->clear();
hfile->read((char*)(void*)&funbyname, sizeof(IMAGE_IMPORT_BY_NAME));//读函数名表
hfile->clear();
l = funfov + sizeof(funbyname.Hint);//定位到函数名
hfile->seekg(l);
char funname[MAX_PATH] = { 0 };
for (int i = 0; i < MAX_PATH; i++)//统计函数名大小
{
hfile->read(&funname[i], sizeof(char));
if (funname[i] == 0)
{
break;
}
}
cout << funname << endl;
}
else
{
DWORD funimno = 0;
funimno = (pthunk[i].u1.Ordinal << 1) >> 1;
cout << "0x" << hex << funimno << endl;
}
}
delete[] pthunk;
pthunk = nullptr;
}
cout << endl;
}
delete[] pim;
pim = nullptr;
}
#pragma once
#include<Windows.h>
#include<fstream>
using std::fstream;
using std::ios;
DWORD RvaToFov(ULONG rva, PIMAGE_FILE_HEADER pntfile32, PIMAGE_OPTIONAL_HEADER32 pntop, PIMAGE_SECTION_HEADER psech);
void importanalysis(fstream* hfile, PIMAGE_FILE_HEADER pntfile32, PIMAGE_OPTIONAL_HEADER32 pntop, PIMAGE_SECTION_HEADER psech);