//导出表信息
typedef struct _EXPORT_INFO
{
char cDllName[256]; //用于保存DLL库名
pFuncInfo pFunctionInfo; //指向FUNC_INFO结构体数组,用于保存若干个函数信息
long lFuncNum; //pFunctionInfo所指向数组的个数
_EXPORT_INFO()
{
pFunctionInfo = NULL;
lFuncNum = 0;
memset(cDllName, '\0', 256);
}
}*pExportInfo, EXPORT_INFO;
//得到导出表的信息:导出库名,导出函数ID,导出函数地址
void CPe32 ::GetExportTableInfo()
{
if (m_bSuccess)
{
//得到导出目录结构
IMAGE_DATA_DIRECTORY ExportDataDirectory = m_pPeHeader->OptionalHeader.DataDirectory[0];
//如果不存在导出表则返回
if (ExportDataDirectory.VirtualAddress == 0)
{
return ;
}
//得到文件中导出表结构指针
IMAGE_EXPORT_DIRECTORY *pExportDescriptor =
( IMAGE_EXPORT_DIRECTORY *)(GetFileOffsetFromRva(ExportDataDirectory.VirtualAddress) + m_pFileBuffer);
//判断得到的导出表指针是否合法
if ((DWORD )pExportDescriptor>(DWORD)m_pFileBuffer+m_iFileSize)
{
return;
}
//pExportDescriptor->Name 库名字符串所在地址的Rva
DWORD dwDllNameFileOffset = GetFileOffsetFromRva(pExportDescriptor->Name);
//保存该库名
if (dwDllNameFileOffset >= (DWORD)m_iFileSize)
{
strcpy(m_ExportInfo.cDllName, (const char *)"NULL");
}
else
{
unsigned int iLen = strlen((const char*)(m_pFileBuffer + dwDllNameFileOffset ));
if (iLen < 256) //判断库名是否合法
{
strcpy(m_ExportInfo.cDllName, (const char *)(m_pFileBuffer + dwDllNameFileOffset ));
}
else
{
strcpy(m_ExportInfo.cDllName, (const char *)"NULL");
}
}
//判断导出表导出函数个数是否过多
if (pExportDescriptor->NumberOfFunctions > 2048)
{
return ;
}
//保存导出函数总个数
m_ExportInfo.lFuncNum = pExportDescriptor->NumberOfFunctions;
//保存所有导出函数所在内存地址指针
m_ExportInfo.pFunctionInfo = new FUNC_INFO [m_ExportInfo.lFuncNum];
//获得按名字导出函数的序号表在文件中的偏移
DWORD dwNameOrdinalsInFileOffset = GetFileOffsetFromRva(pExportDescriptor->AddressOfNameOrdinals);
if (dwNameOrdinalsInFileOffset > (DWORD)m_iFileSize) //判断序号表文件偏移是否合法
{
return;
}
//得到按名字导出函数的序号表
WORD * pNameOrdinalsTable = (WORD *)(m_pFileBuffer + dwNameOrdinalsInFileOffset);
int nBase = pExportDescriptor->Base; //得到导出序号的基数
int nFuncNum = m_ExportInfo.lFuncNum;
int iNameOrdinalsIndex = -1;
for (int i = 0; i < nFuncNum; i++)
{
bool bFind = FALSE ;
//遍历函数名称序号表,此表和导出函数名表一一对应。
for (int j = 0; j < (int)pExportDescriptor->NumberOfNames; j++)
{
//获得函数名称序号表中序号
int iIndex = pNameOrdinalsTable[j] + pExportDescriptor->Base;
//判断变量i所对应的导出地址中对应的函数的序号是否存在于函数名称序号表中
if (iIndex == i+nBase)
{
iNameOrdinalsIndex++;
bFind = TRUE;
break;
}
}
//找到名字
if (bFind)
{
//获得导出函数名称地址表在文件中的偏移
DWORD dwAddressOfNamesInFileOffset = GetFileOffsetFromRva(pExportDescriptor->AddressOfNames);
if (dwAddressOfNamesInFileOffset > (DWORD)m_iFileSize) //判断名称地址表在文件中的偏移是否合法
{
continue; //不合法放弃当前的继续遍历下一个
}
//获得导出函数名称地址表
long *pAddressOfNamesInFileOffset = (long *)(m_pFileBuffer + dwAddressOfNamesInFileOffset);
//取出与函数名称序号对应的函数名称字符串所在文件中的偏移
DWORD dwFunctionNameInFileOffset = GetFileOffsetFromRva(pAddressOfNamesInFileOffset[iNameOrdinalsIndex]);
if (dwFunctionNameInFileOffset < (DWORD)m_iFileSize)
{
unsigned int iLen = strlen((const char*)(m_pFileBuffer + dwFunctionNameInFileOffset));
if (iLen < 256)
{
strcpy(m_ExportInfo.pFunctionInfo[i-nBase].cFunctionName,
( const char *)(m_pFileBuffer + dwFunctionNameInFileOffset));
}
else
{
continue; //函数名称字符串不合法,放弃当前的,继续遍历下一个
}
}
}
//保存导出序号
m_ExportInfo.pFunctionInfo[i-nBase].lOrdinal = i+nBase;
//获得导出地址表在文件中的偏移
DWORD dwAddressInFileOffset = GetFileOffsetFromRva(pExportDescriptor->AddressOfFunctions);
if (dwAddressInFileOffset > (DWORD )m_iFileSize) //判断导出地址表在文件中的偏移是否合法
{
continue;
}
//保存导出函数地址
m_ExportInfo.pFunctionInfo[i].pdwRva = (DWORD *)*((DWORD *)(m_pFileBuffer + dwAddressInFileOffset) + i);
}
}
}