自己實現GetProcAddress


DWORD MyGetProcAddress(  
					   HMODULE hModule,    // handle to DLL module  
					   LPCSTR lpProcName   // function name  
					   )  
{  

	int i=0;  
	PIMAGE_DOS_HEADER pImageDosHeader = NULL;  
	PIMAGE_NT_HEADERS pImageNtHeader = NULL;  
	PIMAGE_EXPORT_DIRECTORY pImageExportDirectory = NULL;  

	pImageDosHeader=(PIMAGE_DOS_HEADER)hModule;  
	pImageNtHeader=(PIMAGE_NT_HEADERS)((DWORD)hModule+pImageDosHeader->e_lfanew);  
	pImageExportDirectory=(PIMAGE_EXPORT_DIRECTORY)((DWORD)hModule+pImageNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);  

	DWORD *pAddressOfFunction = (DWORD*)(pImageExportDirectory->AddressOfFunctions + (DWORD)hModule);  
	DWORD *pAddressOfNames = (DWORD*)(pImageExportDirectory->AddressOfNames + (DWORD)hModule);  
	DWORD dwNumberOfNames = (DWORD)(pImageExportDirectory->NumberOfNames);  
	DWORD dwBase = (DWORD)(pImageExportDirectory->Base);  

	WORD *pAddressOfNameOrdinals = (WORD*)(pImageExportDirectory->AddressOfNameOrdinals + (DWORD)hModule);  

	// 函數名稱 or 函數序號   
	DWORD dwName = (DWORD)lpProcName;  
	if ((dwName & 0xFFFF0000) == 0)  
	{  
		goto Ordinal;  
	}  
	for (i=0; i<(int)dwNumberOfNames; i++)  
	{  
		char *strFunction = (char *)(pAddressOfNames[i] + (DWORD)hModule);  
		if (lstrcmp(lpProcName, strFunction) == 0)  
		{  
			return (pAddressOfFunction[pAddressOfNameOrdinals[i]] + (DWORD)hModule);  
		}  
	}  
	return 0;  

	// 以序號的方式查函數地址  
Ordinal:  
	if (dwName < dwBase || dwName > dwBase + pImageExportDirectory->NumberOfFunctions - 1)  
	{  
		return 0;  
	}  
	return (pAddressOfFunction[dwName - dwBase] + (DWORD)hModule);  
}  

void main()
{
	// 函數名
	DWORD dw1 = MyGetProcAddress(LoadLibrary("user32.dll"), "MessageBoxA"); 
	DWORD dw2 = (DWORD)GetProcAddress(LoadLibrary("user32.dll"), "MessageBoxA");  

	// 序號
	DWORD dw3 = MyGetProcAddress(LoadLibrary("user32.dll"), (LPCSTR)0x110);  
	DWORD dw4 = (DWORD)GetProcAddress(LoadLibrary("user32.dll"), (LPCSTR)0x110); 
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章