i wanted to try to build a little program which can read the memory of other programs and dump it into a text file(if it has access obviously). But the access seems to be a problem right beforehand to me. I first tried a bit around and wanted to print a list of all processes currently running but apparently i haven't even access to open some of the processes. However if i open the list in a program like Cheat Engine, it shows all process names (the system process for example mainly PID 4 if i have seen correctly). Now have i just messed up the desired access level while opening the process, or does Cheat Engine just use some tricks or reads the names from somewhere else? I tried both QueryFullProcessImageName
and GetBaseModuleName
where the latter requires PROCESS_VM_READ
access thats why i used QueryFullProcessImageName
because i tried to minimize my access level.
main.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;
}
There where many helpful information commented here so i can answer the question myself. The problem was, as stated, that i will never have sufficient permission to open protected system processes. The solution is to gather the information on another way. As commented this can be done much easier with
CreateToolhelp32Snapshot
to get a snapshot of all current running processes. Then i can iterate over them viaProcess32First
and then all following withProcess32Next
and then just read thePROCESSENTRY32::szExeFile
of the structure to get the name of the process.The code i now use:
Note that the snapshot is a snapshot of the current state and if any processes are opened or closed, the snapshot needs to be taken again to get the information of the new state and new processes.