EternalWindows
DLL / 関数の列挙

今回のプログラムは、DLLのエクスポートセクションに記述されている関数名を列挙します。 グローバルに定義しているg_lpszModuleに含まれるDLLをコンボボックスで表示し、 そこで選択されたDLLのエクスポートセクションの関数をリストボックスに表示します。 調査したいDLLを追加する場合は、g_lpszModuleの要素数を増やします。

#include <windows.h>
#include <dbghelp.h>

#pragma comment (lib, "dbghelp.lib")

const LPTSTR g_lpszModule[] = {
	TEXT("kernel32.dll"),
	TEXT("user32.dll"),
	TEXT("gdi32.dll"),
	TEXT("advapi32.dll"),
	TEXT("comctl32.dll"),
	TEXT("shell32.dll"),
	TEXT("shlwapi.dll"),
	TEXT("ole32.dll"),
	TEXT("oleaut32.dll"),
	TEXT("winmm.dll"),
	TEXT("ws2_32.dll"),
	TEXT("wininet.dll"),
	TEXT("uxtheme.dll"),
	TEXT("mscoree.dll"),
	TEXT("ntdll.dll")
};
const int g_nModuleCount = sizeof(g_lpszModule) / sizeof(g_lpszModule[0]);

void EnumFunction(HWND hwndListBox, LPBYTE lp);
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

int WINAPI WinMain(HINSTANCE hinst, HINSTANCE hinstPrev, LPSTR lpszCmdLine, int nCmdShow)
{
	TCHAR      szAppName[] = TEXT("sample");
	HWND       hwnd;
	MSG        msg;
	WNDCLASSEX wc;

	wc.cbSize        = sizeof(WNDCLASSEX);
	wc.style         = 0;
	wc.lpfnWndProc   = WindowProc;
	wc.cbClsExtra    = 0;
	wc.cbWndExtra    = 0;
	wc.hInstance     = hinst;
	wc.hIcon         = (HICON)LoadImage(NULL, IDI_APPLICATION, IMAGE_ICON, 0, 0, LR_SHARED);
	wc.hCursor       = (HCURSOR)LoadImage(NULL, IDC_ARROW, IMAGE_CURSOR, 0, 0, LR_SHARED);
	wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
	wc.lpszMenuName  = NULL;
	wc.lpszClassName = szAppName;
	wc.hIconSm       = (HICON)LoadImage(NULL, IDI_APPLICATION, IMAGE_ICON, 0, 0, LR_SHARED);
	
	if (RegisterClassEx(&wc) == 0)
		return 0;

	hwnd = CreateWindowEx(0, szAppName, szAppName, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hinst, NULL);
	if (hwnd == NULL)
		return 0;

	ShowWindow(hwnd, nCmdShow);
	UpdateWindow(hwnd);
	
	while (GetMessage(&msg, NULL, 0, 0) > 0) {
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}

	return (int)msg.wParam;
}

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	static HWND hwndComboBox = NULL;
	static HWND hwndListBox = NULL;

	switch (uMsg) {

	case WM_CREATE: {
		int i;

		hwndComboBox = CreateWindowEx(0, TEXT("COMBOBOX"), TEXT(""), WS_CHILD | WS_VISIBLE | CBS_DROPDOWN, 0, 0, 0, 0, hwnd, (HMENU)1, ((LPCREATESTRUCT)lParam)->hInstance, NULL);
		hwndListBox = CreateWindowEx(0, TEXT("LISTBOX"), TEXT(""), WS_CHILD | WS_VISIBLE | WS_VSCROLL, 0, 0, 0, 0, hwnd, (HMENU)2, ((LPCREATESTRUCT)lParam)->hInstance, NULL);
		
		for (i = 0; i < g_nModuleCount; i++)
			SendMessage(hwndComboBox, CB_ADDSTRING, 0, (LPARAM)g_lpszModule[i]);
		SendMessage(hwndComboBox, CB_SETCURSEL, 0, 0);

		SendMessage(hwndListBox, WM_SETFONT, (WPARAM)GetStockObject(ANSI_FIXED_FONT), 0);
		
		return 0;
	}

	case WM_COMMAND:
		if (HIWORD(wParam) == CBN_SELCHANGE && (HWND)lParam == hwndComboBox) {
			int     i;
			int     nIndex;
			HMODULE hmod;
			
			SendMessage(hwndListBox, LB_RESETCONTENT, 0, 0);
			
			nIndex = (int)SendMessage(hwndComboBox, CB_GETCURSEL, 0, 0);

			for (i = 0;  i < g_nModuleCount; i++) {
				if (i == nIndex) {
					hmod = GetModuleHandle(g_lpszModule[i]);
					if (hmod == NULL) {
						hmod = LoadLibrary(g_lpszModule[i]);
						if (hmod == NULL) {
							SendMessage(hwndListBox, LB_ADDSTRING, 0, (LPARAM)TEXT("モジュールがロードできません。"));
							break;
						}
					}
					EnumFunction(hwndListBox, (LPBYTE)hmod);
					break;
				}
			}

			SetFocus(hwndListBox);
		}
		return 0;
	
	case WM_SIZE:
		MoveWindow(hwndComboBox, 0, 0, LOWORD(lParam) / 3, HIWORD(lParam), TRUE);
		MoveWindow(hwndListBox, LOWORD(lParam) / 3, 0, LOWORD(lParam) - LOWORD(lParam) / 3, HIWORD(lParam), TRUE);
		return 0;

	case WM_DESTROY:
		PostQuitMessage(0);
		return 0;

	default:
		break;

	}

	return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

void EnumFunction(HWND hwndListBox, LPBYTE lp)
{
	PIMAGE_EXPORT_DIRECTORY pExportDirectory;
	LPDWORD                 lpdwEat, lpdwEnt;
	LPWORD                  lpwEot;
	ULONG                   uSize;
	DWORD                   i, j;
	TCHAR                   szBuf[256], szBuf2[256];
	LPSTR                   lpszFunctionA;
	LPWSTR                  lpszFunctionW;
	
	pExportDirectory = (PIMAGE_EXPORT_DIRECTORY)ImageDirectoryEntryToData(lp, TRUE, IMAGE_DIRECTORY_ENTRY_EXPORT, &uSize);

	lpdwEat = (LPDWORD)((LPBYTE)lp + pExportDirectory->AddressOfFunctions);
	lpdwEnt = (LPDWORD)((LPBYTE)lp + pExportDirectory->AddressOfNames);
	lpwEot = (LPWORD)((LPBYTE)lp + pExportDirectory->AddressOfNameOrdinals);

	for (i = 0; i < pExportDirectory->NumberOfFunctions; i++) {
		wsprintf(szBuf, TEXT("%#06x %3x"), lpdwEat[i], pExportDirectory->Base + i);
		for (j = 0; j < pExportDirectory->NumberOfNames; j++) {
			if (lpwEot[j] == i) {
				lpszFunctionA = (LPSTR)((LPBYTE)lp + lpdwEnt[j]);
#ifdef UNICODE
				uSize = (lstrlenA(lpszFunctionA) + 1) * sizeof(WCHAR);
				lpszFunctionW = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, uSize);
				MultiByteToWideChar(CP_ACP, 0, lpszFunctionA, -1, lpszFunctionW, uSize);
				wsprintf(szBuf2, TEXT(" %s"), lpszFunctionW);
#else
				wsprintf(szBuf2, TEXT(" %s"), lpszFunctionA);
#endif			
				lstrcat(szBuf, szBuf2);
				break;
			}
		}

		SendMessage(hwndListBox, LB_ADDSTRING, 0, (LPARAM)szBuf);
	}
}

戻る