所以我最近一直在搞乱Windows API,我遇到了一个需要一点帮助的问题。实际上,确切地说,有两个问题。
我将首先展示代码,然后解释我遇到的困难:
#pragma once
#pragma comment(lib, "Psapi.lib")
#include <stdlib.h>
#include <stdio.h>
#include <Windows.h>
#include <TlHelp32.h>
#include <Psapi.h>
void ProcessError(DWORD error);
int main() {
FILE* file = fopen("C:\\Users\\Administrator\\Desktop\\processes.txt", "w");
DWORD count, i, modulesCount;
WCHAR buffer[128] = {0};
HMODULE modules[128] = {0};
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
PROCESSENTRY32 pEntry;
pEntry.dwSize = sizeof(PROCESSENTRY32);
count = 0;
if(snapshot != INVALID_HANDLE_VALUE) {
if(!Process32First(snapshot, &pEntry)) {
ProcessError(GetLastError());
CloseHandle(snapshot);
ExitProcess(EXIT_FAILURE);
}
do {
HANDLE hProc = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pEntry.th32ProcessID);
GetModuleFileNameEx(hProc, NULL, (LPWSTR)memset(buffer, 0, 128), 128);
fwprintf(file, L"-------------------------------------------------------\n");
fwprintf(file, L"%s\t pid: %d\n", pEntry.szExeFile, pEntry.th32ProcessID);
fwprintf(file, L"%s\n", buffer);
if(hProc != INVALID_HANDLE_VALUE) {
if(EnumProcessModules(hProc, (HMODULE*)memset(modules, 0, 128), 128, &modulesCount)) {
modulesCount = modulesCount <= 128 ? modulesCount : 128;
for(i = 0; i < modulesCount; ++i) {
GetModuleFileName(modules[i], (LPWSTR)memset(buffer, 0, 128), 128);
if(wcslen(buffer) > 0) {
fwprintf(file, L"\t\t0x%X Module: %s\n", modules[i], buffer);
}
}
}
else {
ProcessError(GetLastError());
}
CloseHandle(hProc);
}
else {
ProcessError(GetLastError());
}
count++;
} while(Process32Next(snapshot, &pEntry));
fwprintf(file, L"Process count: %d\n", count);
}
else {
ProcessError(GetLastError());
CloseHandle(snapshot);
ExitProcess(EXIT_FAILURE);
}
fclose(file);
CloseHandle(snapshot);
ExitProcess(EXIT_SUCCESS);
}
void ProcessError(DWORD error) {
printf("Error in thread 0x%X, code: 0x%X\n", GetThreadId(GetCurrentThread()), error);
}
因此,第一个问题与以下内容有关:
if(EnumProcessModules(hProc, (HMODULE*)memset(modules, 0, 128), 128, &modulesCount))
有时我会收到INVALID_HANDLE错误,但我真的不知道为什么。 Process句柄无效,也没有任何其他参数传递给该函数。如果有人可以向我解释或至少指出我的方向(这是更优选的解决方案,因为我更有兴趣学习:D)它会对我有好处。
其次是由于某种原因,当我枚举进程'modules和GetModuleFileName()时,它还包括当前进程的位置。
当我写文件时,我会得到以下信息:
TuneUpUtilitiesApp32.exe pid: 2744 D:\Program Files\TuneUp Utilities 2012\TuneUpUtilitiesApp32.exe 0x76F60000 Module: C:\Windows\SYSTEM32\ntdll.dll 0x75FE0000 Module: C:\Windows\system32\kernel32.dll 0x75370000 Module: C:\Windows\system32\KERNELBASE.dll 0x761A0000 Module: C:\Windows\system32\USER32.dll 0x770D0000 Module: C:\Windows\system32\GDI32.dll 0x77130000 Module: C:\Windows\system32\LPK.dll 0x76EC0000 Module: C:\Windows\system32\USP10.dll 0x75F20000 Module: C:\Windows\system32\msvcrt.dll 0x755D0000 Module: C:\Windows\system32\ADVAPI32.dll 0x75590000 Module: C:\Windows\SYSTEM32\sechost.dll 0x757D0000 Module: C:\Windows\system32\RPCRT4.dll 0x77120000 Module: C:\Windows\system32\PSAPI.DLL 0x755B0000 Module: C:\Windows\system32\IMM32.DLL 0x75670000 Module: C:\Windows\system32\MSCTF.dll 0x10000000 Module: C:\Windows\system32\guard32.dll 0x750D0000 Module: C:\Windows\system32\VERSION.dll 0x750C0000 Module: C:\Windows\system32\fltlib.dll 0x0 Module: C:\Users\Administrator\documents\visual studio 2010\Projects\FunWithWindowsAPI\Release\FunWithWindowsAPI.exe 0x0 Module: C:\Users\Administrator\documents\visual studio 2010\Projects\FunWithWindowsAPI\Release\FunWithWindowsAPI.exe 0x0 Module: C:\Users\Administrator\documents\visual studio 2010\Projects\FunWithWindowsAPI\Release\FunWithWindowsAPI.exe 0x0 Module: C:\Users\Administrator\documents\visual studio 2010\Projects\FunWithWindowsAPI\Release\FunWithWindowsAPI.exe 0x0 Module: C:\Users\Administrator\documents\visual studio 2010\Projects\FunWithWindowsAPI\Release\FunWithWindowsAPI.exe 0x0 Module: C:\Users\Administrator\documents\visual studio 2010\Projects\FunWithWindowsAPI\Release\FunWithWindowsAPI.exe
它确实为我可以从中提取模块的每个进程执行此操作。任何帮助将不胜感激!
答案 0 :(得分:1)
您没有正确使用返回的“modulesCount”。 不是模块的数量,它是以字节为单位的数组大小。你需要除以sizeof(HMODULE)来获得模块的数量。
第二个问题是,当您开始迭代进程条目时,希望 pEntry.th32ProcessID仍然有效。这是空闲的希望,一个过程可以在你迭代时终止。您不检查这一点,您不验证OpenProcess()是否返回有效的句柄。它也可能失败,因为您没有足够的权限来访问该进程。
关注CreateToolhelp32Snapshot()可以做什么,它还支持Module32First / Next()。由于该功能能够创建快照,因此它更可靠。