PE解析导出表--代码

26 篇文章 0 订阅


//导出表信息
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);
                                }
                }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值