现在的位置: 首页 > 综合 > 正文

用MFC输出所有导入函数名称时遇到的问题。

2013年11月27日 ⁄ 综合 ⁄ 共 1747字 ⁄ 字号 评论关闭

         用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库。这样也会因为导入段中不存在此库,不会出现错误。

抱歉!评论已关闭.