- Ⅰ. はじめに
- Ⅱ. サンプルプログラム1(EnumProcessModulesExを使用する方法)
- Ⅲ. サンプルプログラム2(CreateToolhelp32Snapshotを使用する方法)
- Ⅳ. サンプルプログラム3(NtQueryInformationProcessを使用する方法)
- Ⅴ. 実行結果
- Ⅵ. 留意点
- 参考
Ⅱ. サンプルプログラム1(EnumProcessModulesExを使用する方法)
#include <windows.h> #include <Psapi.h> #include <iostream> void ShowAllModules(uint32_t processId) { HMODULE hMods[1024]; auto processHandle = OpenProcess(PROCESS_ALL_ACCESS, false, processId); if (processHandle != nullptr) { DWORD cbNeeded; if (EnumProcessModulesEx(processHandle, hMods, sizeof(hMods), &cbNeeded, LIST_MODULES_ALL)) { for (uint32_t i = 0; i < (cbNeeded / sizeof(HMODULE)); i++) { wchar_t filePath[MAX_PATH]; if (GetModuleFileNameEx(processHandle, hMods[i], filePath, sizeof(filePath) / sizeof(wchar_t))) { std::wcout << "BaseAddress: 0x" << hMods[i] << std::endl; std::wcout << "FilePath: " << filePath << std::endl; } } } CloseHandle(processHandle); } } int main(void) { auto processId = 1234; ShowAllModules(processId); return 0; }
Ⅲ. サンプルプログラム2(CreateToolhelp32Snapshotを使用する方法)
#include <windows.h> #include <Psapi.h> #include <TlHelp32.h> #include <iostream> void ShowAllModules(uint32_t processId) { MODULEENTRY32 moduleEntry32 = { 0 }; auto processHandle = OpenProcess(PROCESS_ALL_ACCESS, false, processId); if (processHandle != nullptr) { auto hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, processId); if (hThreadSnap != INVALID_HANDLE_VALUE) { moduleEntry32.dwSize = sizeof(MODULEENTRY32); if (!Module32First(hThreadSnap, &moduleEntry32)) { std::cout << "failed" << std::endl; } else { do { wchar_t filePath[MAX_PATH]; GetModuleFileNameEx(processHandle, moduleEntry32.hModule, filePath, MAX_PATH); std::wcout << "BaseAddress: 0x" << moduleEntry32.modBaseAddr << std::endl; std::wcout << "FilePath: " << filePath << std::endl; } while (Module32Next(hThreadSnap, &moduleEntry32)); } CloseHandle(hThreadSnap); } CloseHandle(processHandle); } } int main(void) { auto processId = 1234; ShowAllModules(processId); return 0; }
Ⅳ. サンプルプログラム3(NtQueryInformationProcessを使用する方法)
※対象がWOW64プロセスの場合はNtWow64QueryInformationProcess64を使用します。
#include <windows.h> #include <winternl.h> #include <iostream> #pragma comment(lib, "ntdll.lib") void ShowAllModules(uint32_t processId) { auto moduleHandle = LoadLibrary(L"ntdll.dll"); if (moduleHandle != nullptr) { auto pNtQueryInformationProcess = reinterpret_cast<decltype(&NtQueryInformationProcess)>(GetProcAddress(moduleHandle, "NtQueryInformationProcess")); auto processHandle = OpenProcess(PROCESS_ALL_ACCESS, false, processId); if (processHandle != nullptr) { PROCESS_BASIC_INFORMATION pbi = { 0 }; if (NT_SUCCESS(pNtQueryInformationProcess(processHandle, PROCESSINFOCLASS::ProcessBasicInformation, &pbi, sizeof(PROCESS_BASIC_INFORMATION), nullptr))) { if (pbi.PebBaseAddress != nullptr) { PEB peb = { 0 }; ReadProcessMemory(processHandle, pbi.PebBaseAddress, &peb, sizeof(PEB), nullptr); PEB_LDR_DATA pebLdrData = { 0 }; ReadProcessMemory(processHandle, peb.Ldr, &pebLdrData, sizeof(PEB_LDR_DATA), nullptr); auto pModuleFirstEntry = pebLdrData.InMemoryOrderModuleList.Flink; auto pModuleCurrentEntry = pebLdrData.InMemoryOrderModuleList.Flink; do { auto pLdrDataTableEntry = CONTAINING_RECORD(pModuleCurrentEntry, LDR_DATA_TABLE_ENTRY, LDR_DATA_TABLE_ENTRY::InMemoryOrderLinks); LDR_DATA_TABLE_ENTRY ldrDataTableEntry = { 0 }; ReadProcessMemory(processHandle, pLdrDataTableEntry, &ldrDataTableEntry, sizeof(LDR_DATA_TABLE_ENTRY), nullptr); wchar_t str[MAX_PATH]; ReadProcessMemory(processHandle, ldrDataTableEntry.FullDllName.Buffer, &str, ldrDataTableEntry.FullDllName.Length, nullptr); auto filePath = std::wstring(str, ldrDataTableEntry.FullDllName.Length / sizeof(wchar_t)); if (ldrDataTableEntry.DllBase != nullptr) { std::wcout << "BaseAddress: 0x" << ldrDataTableEntry.DllBase << std::endl; std::wcout << "FilePath: " << filePath << std::endl; } pModuleCurrentEntry = ldrDataTableEntry.InMemoryOrderLinks.Flink; } while (pModuleCurrentEntry != pModuleFirstEntry); } } CloseHandle(processHandle); } FreeModule(moduleHandle); } } int main(void) { auto processId = 1234; ShowAllModules(processId); return 0; }
Ⅴ. 実行結果
BaseAddress: 0x00007FF699110000 FilePath: C:\WINDOWS\system32\notepad.exe BaseAddress: 0x00007FFBCE1F0000 FilePath: C:\WINDOWS\SYSTEM32\ntdll.dll BaseAddress: 0x00007FFBCE0F0000 FilePath: C:\WINDOWS\System32\KERNEL32.DLL BaseAddress: 0x00007FFBCBC10000 FilePath: C:\WINDOWS\System32\KERNELBASE.dll ... (以下省略)