1.相关函数 相关结构,与主要成员
//导出表结构
struct ExportFunInfor
{
char szFunName[64]; //函数名称
int nExportNumber; //导出编号
DWORD dwFunAddress; //函数所在地址
};
struct ExportTableInfor //导出函数表
{
char szDllTableName[32]; //表名<DLL>
CList<ExportFunInfor,ExportFunInfor> *pEptTableFun; //数据
};
//保存解析DLL的所有函数
CList<ExportTableInfor,ExportTableInfor> m_ExportTableList;
2.设计思路
进入StartDebugDll时,传来一个参数,此参数保存了当前加载DLL的信息,可以通过此信息解析出导出表在文件中的位置,然后可以定位到导出函数的位置,把函数用类成员m_ExportTableList保存。
3.关键代码部分
ExportFunInfor pEptFunInfor;
ZeroMemory(&pEptFunInfor,sizeof(ExportFunInfor));
for ( i = 0; i <= (int)m_DllExportTable.NumberOfFunctions; i++ )
{
ReadProcessMemory(hProcess,(LPCVOID)nStartFunAddr,
&nAllFunOffset,sizeof(int),&dwOldProto);
if ( 0 == nAllFunOffset )
{
//循环读取链表
nStartFunAddr += sizeof(DWORD);
continue;
}
for( j = 0; j <= (int)m_DllExportTable.NumberOfNames; j++)
{
ReadProcessMemory(hProcess,(LPVOID)(nStartFunNameOrd + j*2),
&nFunNameAddr,sizeof(WORD),&dwOldProto);
if(i == (int)nFunNameAddr)
{
memset(szFunName,0,MAX_PATH);
DWORD nAddress = j*sizeof(DWORD) + nStartFunName;
ReadProcessMemory(hProcess,(LPVOID)(nAddress),
CurAddress,sizeof(DWORD),&dwOldProto);
nCurAddress += (DWORD)StartAddress;
ReadProcessMemory(hProcess,(LPVOID)(nCurAddress), szFunName,MAX_PATH,&dwOldProto);
break;
}
}
4.显示解析函数部分
主要对CALL, MOV, JMP, 6个寄存器<eax,ebx,ecx,edx,esi,edi>的函数名称显示进行解析。
处理函数:void CMyDebugInfor::ShowExportFun(char *szBuf)
注意:当CALL/JMP一个指令地址时,又JMP/CALL另一个地址或更深层次的嵌套解析情况下,采用递归来处理这种特殊情况。
附件: