めいくりぷとのブログ

技術的なことをまったりと。

GetProcAddress Emulate

GetProcAddress
https://msdn.microsoft.com/en-us/library/windows/desktop/ms683212(v=vs.85).aspx

FARPROC
WINAPI
GetProcAddress(
	_In_ HMODULE hModule,
	_In_ LPCSTR  lpProcName
	)
{
	PIMAGE_EXPORT_DIRECTORY 	pExportDirectory;
	PIMAGE_NT_HEADERS 		pNtHeaders;
	PIMAGE_DOS_HEADER 		pDosHeader;
	DWORD dwOrdinal;

	if (!hModule)
		hModule = reinterpret_cast<HMODULE>(GetProcessEnvironmentBlock()->ImageBaseAddress);

	pDosHeader = PIMAGE_DOS_HEADER(hModule);
	if (!pDosHeader)
		return NULL;

	pNtHeaders = reinterpret_cast<PIMAGE_NT_HEADERS>(PBYTE(hModule) + pDosHeader->e_lfanew);
	if (!pNtHeaders || pNtHeaders->Signature != IMAGE_NT_SIGNATURE)
		return NULL;

	pExportDirectory = reinterpret_cast<PIMAGE_EXPORT_DIRECTORY>(PBYTE(hModule) + pNtHeaders->EXPORT_DIRECTORY.VirtualAddress);
	if (pExportDirectory == NULL)
		return NULL;

	dwOrdinal = reinterpret_cast<DWORD>(lpProcName);

	if (dwOrdinal < 0x10000)
	{
		if (dwOrdinal < pExportDirectory->Base)
			return NULL;

		dwOrdinal -= pExportDirectory->Base;
	}
	else
	{
		for (int i = 0; i < pExportDirectory->NumberOfNames; ++i)
		{
			if (!_stricmp(reinterpret_cast<LPCSTR>((reinterpret_cast<DWORD*>(PBYTE(hModule) + pExportDirectory->AddressOfNames))[i] + PBYTE(hModule)), lpProcName))
			{
				dwOrdinal = reinterpret_cast<WORD*>(PBYTE(hModule) + pExportDirectory->AddressOfNameOrdinals)[i];
				break;
			}
		}
	}

	return reinterpret_cast<FARPROC>(reinterpret_cast<DWORD*>(PBYTE(hModule) + pExportDirectory->AddressOfFunctions)[dwOrdinal] + PBYTE(hModule));
}