版权声明:本文为YuanChuang文章,未经博主允许转载。 https://blog.csdn.net/zzy1448331580/article/details/90714368
typedef struct _IMAGE_EXPORT_DIRECTORY
{
DWORD Characteristics;//保留,一直都是00000000
DWORD TimeDateStamp;//导出表创建的时间(GMT)
WORD MajorVersion;//导出表的主版本号
WORD MinorVersion;//导出表的次版本号
DWORD Name;//导出表的名字
DWORD Base;//函数索引=导出函数索引-Base
DWORD NumberOfFunctions;//EAT的数量
DWORD NumberOfNames;//ENA的数量
DWORD AddressOfFunctions; // RVA from base of image
DWORD AddressOfNames; // RVA from base of image
DWORD AddressOfNameOrdinals; // RVA from base of image
} IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;
#include <Windows.h>
#include <iostream>
#include <string>
#include <fstream>
#include <memory>
using namespace std;
int rva_to_file(PIMAGE_SECTION_HEADER pSection,int nSectionNum,int nRva)
{
int nRet = 0;
for (int nIndex = 0; nIndex < nSectionNum; nIndex++)
{
if (pSection[nIndex].VirtualAddress <= nRva && nRva < pSection[nIndex + 1].VirtualAddress)
{
nRet = nRva - pSection[nIndex].VirtualAddress + pSection[nIndex].PointerToRawData;
break;
}
}
return nRet;
}
void analizy_to_cout(const string& strFilePath)
{
if (strFilePath.empty())
{
cout << "input file is null" << endl;
return;
}
fstream cFile(strFilePath, ios::binary | ios::in);
if (!cFile)
{
cout << "file open fail" << endl;
return;
}
IMAGE_DOS_HEADER stDos;
cFile.read((char*)&stDos,sizeof(IMAGE_DOS_HEADER));
IMAGE_NT_HEADERS stNt;
cFile.seekg(stDos.e_lfanew, ios::beg);
cFile.read((char*)&stNt, sizeof(IMAGE_NT_HEADERS));
if (!stNt.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress)
{
cout << "the file has not export" << endl;
cFile.close();
return;
}
int nSectionNum = stNt.FileHeader.NumberOfSections;
shared_ptr<IMAGE_SECTION_HEADER> pShareSection(new IMAGE_SECTION_HEADER[nSectionNum]);
PIMAGE_SECTION_HEADER pSection = pShareSection.get();
cFile.read((char*)pSection, sizeof(IMAGE_SECTION_HEADER)*nSectionNum);
IMAGE_EXPORT_DIRECTORY stExport;
int nExportOffset = rva_to_file(pSection, nSectionNum, stNt.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
if (!nExportOffset)
{
cout << "export offset fail" << endl;
cFile.close();
return;
}
cFile.seekg(nExportOffset, ios::beg);
cFile.read((char*)&stExport, sizeof(IMAGE_EXPORT_DIRECTORY));
cFile.seekg(rva_to_file(pSection, nSectionNum, stExport.Name), ios::beg);
char szExportName[50];
cFile.get(szExportName,50);
cout << "export name is " << szExportName << endl;
int nAddressNum = stExport.NumberOfFunctions;
shared_ptr<int> pShareName(new int[nAddressNum]);
int* pName = pShareName.get();
cFile.seekg(rva_to_file(pSection, nSectionNum, stExport.AddressOfNames), ios::beg);
cFile.read((char*)pName, sizeof(int)*nAddressNum);
shared_ptr<short> pShareOrder(new short[nAddressNum]);
short* pOrder = pShareOrder.get();
cFile.seekg(rva_to_file(pSection, nSectionNum, stExport.AddressOfNameOrdinals), ios::beg);
cFile.read((char*)pOrder, sizeof(short)*nAddressNum);
shared_ptr<int> pShareFunc(new int[nAddressNum]);
int* pFunc = pShareFunc.get();
cFile.seekg(rva_to_file(pSection, nSectionNum, stExport.AddressOfFunctions), ios::beg);
cFile.read((char*)pFunc, sizeof(int)*nAddressNum);
char szFuncName[50];
for (int nIndex = 0; nIndex < nAddressNum; nIndex++)
{
cFile.seekg(rva_to_file(pSection, nSectionNum, pName[nIndex]), ios::beg);
cFile.get(szFuncName, 50);
cout << "[Index:" << dec << nIndex << "]\t"
<< "[ID:" << hex << pOrder[nIndex] << "]\t"
<< "[RVA:" << pFunc[nIndex] << "]\t"
<< "[Name:" << szFuncName << "]\t"
<< endl;
}
cFile.close();
}
int main(_In_ int argc,
_In_reads_(argc) _Pre_z_ char** argv,
_In_z_ char** envp)
{
cout << "Please input target file" << endl;
string strFilePath;
cin >> strFilePath;
analizy_to_cout(strFilePath);
system("pause");
return 0;
}
实际效果: