用MFC写通过修改导入段的IAT来达到API拦截程序时,写了一个函数列举了所有导入函数的函数名。、
看代码:
HMODULE hModule=GetModuleHandle(NULL);
ULONG size;
PIMAGE_IMPORT_DESCRIPTOR pImport=(PIMAGE_IMPORT_DESCRIPTOR)ImageDirectoryEntryToData
(hModule,true,IMAGE_DIRECTORY_ENTRY_IMPORT,&size);
CString name;
while(pImport->FirstThunk)
{
char *ModuleName=(char*)((BYTE*)hModule+pImport->Name);
name.Format("模块名为:%s\r\n ",ModuleName);
m_output+=name;
PIMAGE_THUNK_DATA pThunk=(PIMAGE_THUNK_DATA)((BYTE*)hModule+pImport->OriginalFirstThunk);
//char Func[150];
while(pThunk->u1.Function)
{
char*Func=(char*)((BYTE*)hModule+pThunk->u1.AddressOfData+2);
m_output+=Func;
m_output+="\r\n";
pThunk++;
}
pImport++;
}
UpdateData(false);
试了很多次都是在运行的时候,由于非法访问导致程序终止。而在使用控制台下输出地时候却没有任何问题。肯定是在输出函数名称的时候由于内存违规访问引起的。
后来使用PEdiy查看下,发现程序中有一个mfc100d.dll的dll。它内部的所有函数都是以序数的形式引用的。终于发现了错误的罪魁祸首。原来是我在输出导入函数名称时,没有判断该导入函数是否是按序数来引出的,只有当不是的话才能输出它的函数名称。由于在控制台下不需要此dll,当然不会引起错误。
改正过后程序运行正常:
HMODULE hModule=GetModuleHandle(NULL);
ULONG size;
PIMAGE_IMPORT_DESCRIPTOR pImport=(PIMAGE_IMPORT_DESCRIPTOR)ImageDirectoryEntryToData
(hModule,true,IMAGE_DIRECTORY_ENTRY_IMPORT,&size);
CString name;
while(pImport->FirstThunk)
{
char *ModuleName=(char*)((BYTE*)hModule+pImport->Name);
name.Format("模块名为:%s\r\n ",ModuleName);
m_output+=name;
PIMAGE_THUNK_DATA pThunk=(PIMAGE_THUNK_DATA)((BYTE*)hModule+pImport->OriginalFirstThunk);
//char Func[150];
while(pThunk->u1.Function)
{
if(IMAGE_ORDINAL_FLAG32&(pThunk->u1.Ordinal))//判断最高位是否为1,是的话按序数引出。
{
WORD hint=(WORD)((BYTE*)hModule+pThunk->u1.AddressOfData);
CString len;
len.Format("hint为:%x\r\n ",hint);
m_output+=len;
}
else//按函数名引出。
{
char*Func=(char*)((BYTE*)hModule+pThunk->u1.AddressOfData+2);
m_output+=Func;
m_output+="\r\n";
}
pThunk++;
}
pImport++;
}
UpdateData(false);
这只是其中的一种方法。另外还可以在工程属性设置中,设置成使用静态链接MFC库。这样也会因为导入段中不存在此库,不会出现错误。