DLLなどからエクスポートされている関数を一覧する

test129.gif
DLLからエクスポートされている関数を調べるにはDLLをPEファイルの構造を元にバイナリレベルで解析して調べる方法とAPIを利用して情報を取得する方法とがある。
ここではデバッグ用に用意されているAPIのImageDirectoryEntryToDataを利用して取得した。

依存環境:ATL
#include "atlstr.h"

#include "Dbghelp.h"
#pragma	comment(lib,"Dbghelp.lib")


bool	ShowExportedFunction(LPCTSTR pszDLLPath)
{
	HMODULE	hModule;
	ULONG	nSize;
	DWORD	i;
	DWORD	j;
	char**	ppszFunctionName;
	WORD*	pwFunctionOrdinal;
	IMAGE_EXPORT_DIRECTORY*	pImageExportDir;

	CAtlString	strMessage;

	hModule = ::LoadLibrary(pszDLLPath);
	if(hModule == NULL)
		return	false;

	pImageExportDir = (IMAGE_EXPORT_DIRECTORY*)::ImageDirectoryEntryToData((PVOID)hModule,TRUE,IMAGE_DIRECTORY_ENTRY_EXPORT,&nSize);
	if(pImageExportDir == NULL)
	{
		::FreeLibrary(hModule);
		return	false;
	}

	strMessage.AppendFormat(_T("%sがエクスポートしている関数一覧\n\n"),pszDLLPath);


	//pImageExportDir内のアドレスはhModuleからの相対的なアドレス
	ppszFunctionName	= (char**)(pImageExportDir->AddressOfNames + (ULONGLONG)hModule);
	pwFunctionOrdinal	= (WORD*)(pImageExportDir->AddressOfNameOrdinals + (ULONGLONG)hModule);

	for(i = 0; i < pImageExportDir->NumberOfFunctions; i++)
	{
		strMessage.AppendFormat(_T("序数:%4d(0x%04x)"),pImageExportDir->Base + i,pImageExportDir->Base + i);

		for(j = 0; j < pImageExportDir->NumberOfNames; j++)
		{
			if(pwFunctionOrdinal[j] != i)		//pwFunctionOrdinal[j]は序数ではなくインデックス
				continue;

			//hModuleからの相対アドレスで関数名が格納されている
			strMessage.AppendFormat(_T(" 関数名:%s"),(char*)(ppszFunctionName[j] + (ULONGLONG)hModule));
			break;
		}

		strMessage += _T("\n");
	}

	::FreeLibrary(hModule);

	::MessageBox(NULL,strMessage,_T(""),MB_OK);

	return	true;
}


bool	Test()
{
	return	ShowExportedFunction(_T("hotplug.dll"));
}

プロジェクトファイルをダウンロード


カテゴリー「ファイル・フォルダ」 のエントリー