我想尝试构建一个小程序,它可以读取其他程序的内存并将其转储到文本文件中(如果它显然可以访问(。但是访问对我来说似乎是一个问题。我首先尝试了一些,想打印当前正在运行的所有进程的列表,但显然我什至无法访问打开某些进程。但是,如果我在作弊引擎等程序中打开列表,它会显示所有进程名称(例如,如果我没看错的话,系统进程主要是 PID 4(。现在,我只是在打开进程时弄乱了所需的访问级别,还是作弊引擎只是使用了一些技巧或从其他地方读取名称?我尝试了QueryFullProcessImageName
和GetBaseModuleName
后者需要PROCESS_VM_READ
访问权限,这就是我使用QueryFullProcessImageName
的原因,因为我试图最小化我的访问级别。
主.cpp
#include <cstring>
#include <iostream>
#include <iomanip>
#ifdef _WIN32_WINNT
#undef _WIN32_WINNT
#endif
#define _WIN32_WINNT 0x0600 /* Define so QueryFullProcessImageName can be used */
#include <windows.h>
#include <psapi.h>
using namespace std;
WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR cmdLine, int cmdShow) {
DWORD processIds[256]; /* Buffer for the process IDs */
DWORD cbNeeded; /* Space needed from EnumProcesses() to store all IDs */
/*
* I will not check if the space was sufficient or not because this is just a local experiment
* and i can insure it is enough space
*/
if (EnumProcesses(processIds, sizeof(processIds), &cbNeeded) == 0) {
cout << "Error while enumerating processes(" << GetLastError() << ")" << endl;
return 0;
}
for (unsigned int i = 0; i < cbNeeded / sizeof(DWORD); i++) {
DWORD nameBufferSize = 128;
LPSTR processBaseName = new CHAR[128];
/* Open the process; here is where i get access denied */
HANDLE openProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, processIds[i]);
if (openProcess == NULL) {
if(GetLastError() == 5) strcpy(processBaseName, "<denied>");
else strcpy(processBaseName, "<unknown>");
} else if (QueryFullProcessImageName(openProcess, NULL, processBaseName, nameBufferSize) == 0) {
if(GetLastError() == 5) strcpy(processBaseName, "<denied>");
else strcpy(processBaseName, "<unknown>");
}
cout << "PID: " << setw(6) << left << processIds[i] << "t" << processBaseName << endl;
delete processBaseName;
CloseHandle(openProcess);
}
return 0;
}
受保护的进程是您的主要原因。例如,您无法打开 csrss.exe、smss.exe 或 System 的句柄。其次,尝试启用调试权限SeDebugPriviledge
。然后以管理员身份运行,看看您是否再获得进程。但是,即使具有调试权限,您也无法访问受保护的进程。为此,您需要一个内核模式驱动程序 使用SeLocateProcessImageFileName
或PsGetProcessFileName
.
这里有许多有用的信息,所以我可以自己回答这个问题。如前所述,问题是我永远没有足够的权限来打开受保护的系统进程。解决方案是通过另一种方式收集信息。如前所述,使用CreateToolhelp32Snapshot
可以更轻松地完成此操作,以获取所有当前正在运行的进程的快照。然后我可以通过Process32First
迭代它们,然后用Process32Next
来迭代它们,然后只需读取结构的PROCESSENTRY32::szExeFile
即可获得进程的名称。
我现在使用的代码:
HANDLE processSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (processSnapshot == INVALID_HANDLE_VALUE) {
std::cout << "Error while taking process snapshot(" << GetLastError() << ")" << std::endl;
return 0
}
PROCESSENTRY32 process;
process.dwSize = sizeof(PROCESSENTRY32); /* This is neccessary as the Process32First/Next function expects the size of the class in this member before the first call */
if ( ! Process32First(processSnapshot, &process) ) {
std::cout << "Error while accessing first entry of snapshot(" << GetLastError() << ")" << std::endl;
return 0;
}
do {
std::cout << "PID: " << process.th32ProcessID << "t" << process.szExeFile << std::endl;
} while( Process32Next(processSnapshot, &process) );
if (GetLastError() != ERROR_NO_MORE_FILES) { /* The Process32Next function throws the ERROR_NO_MORE_FILES error code when there is no more entry to read. If this is not the last error message something went wrong. */
std::cout << "Error while enumerating processes(" << GetLastError() << ")" << std::endl;
}
请注意,快照是当前状态的快照,如果打开或关闭了任何进程,则需要再次拍摄快照以获取新状态和新进程的信息。