I am trying to get total number of modules of a running process by passing process ID
This is function that return total number of modules in a process
int size(DWORD processID)
{
HMODULE hMods[1024];
HANDLE hProcess;
DWORD cbNeeded;
// Print the process identifier.
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION |
PROCESS_VM_READ,
FALSE, processID);
// Get a list of all the modules in this process.
EnumProcessModules(hProcess, hMods, sizeof(hMods), &cbNeeded);
int j = (cbNeeded / sizeof(HMODULE));
return j;
// Release the handle to the process.
}
this is main
int main()
{
DWORD aProcesses[1024];
DWORD cbNeeded;
DWORD cProcesses;
unsigned int i;
// Get the list of process identifiers.
if (!EnumProcesses(aProcesses, sizeof(aProcesses), &cbNeeded))
return 1;
// Calculate how many process identifiers were returned.
cProcesses = cbNeeded / sizeof(DWORD);
// Print the names of the modules for each process.
for (int i = 0; i <= cProcesses; i++) {
int a = size(aProcesses[1]);
//std::string* g = PrintModules(aProcesses[1], a);
cout << a << endl;
}
system("pause");
return 0;
}
when i compile & run this code output is 855987977 etc
I tried multiple ways but all in vain...
Use the standard method of EnumprocessModules, the output argument is the size in bytes of the array:
lpcbNeeded = The number of bytes required to store all module handles in the lphModule array.
Divide it by the size of the element type (HMODULE) and that will yield the number of modules.
int GetNumberOfModules(DWORD processID)
{
HMODULE hMods[1024];
HANDLE hProcess;
DWORD cbNeeded;
unsigned int i;
// Print the process identifier.
printf("\nProcess ID: %u\n", processID);
// Get a handle to the process.
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION |
PROCESS_VM_READ,
FALSE, processID);
if (NULL == hProcess)
return 1;
// Get a list of all the modules in this process.
if (EnumProcessModules(hProcess, hMods, sizeof(hMods), &cbNeeded))
{
//return number of modules by dividing size of array by element size
return cbNeeded / sizeof(HMODULE);
}
// Release the handle to the process.
CloseHandle(hProcess);
return 0;
}
Related
I have a list of executable names inside a textfile called b.txt, eg:
notepad.exe, chrome.exe
I need to compare them to the current process name, then do something if the application is a match:
DWORD aProcesses[1024], cbNeeded, cProcesses;
unsigned int i;
EnumProcesses(aProcesses, sizeof(aProcesses), &cbNeeded);
cProcesses = cbNeeded / sizeof(DWORD);
for (i = 0; i < cProcesses; i++)
{
if (aProcesses[i] != 0)
{
DWORD processID = aProcesses[i];
wchar_t szProcessName[MAX_PATH] = TEXT("<unknown>");
HMODULE hMod;
DWORD cbNeeded;
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION |
PROCESS_VM_READ,
FALSE, processID);
if (EnumProcessModules(hProcess, &hMod, sizeof(hMod),
&cbNeeded))
{
GetModuleBaseName(hProcess, hMod, szProcessName,
sizeof(szProcessName) / sizeof(TCHAR));
_wcslwr_s(szProcessName, wcslen(szProcessName) + 1);
FILE *pFile;
wchar_t *file = L"c:\\b.txt";
wchar_t line[100][44];
unsigned int i = 0;
if (_wfopen_s(&pFile, file, L"r, ccs = UNICODE") == 0)
{
while (fgetws(line[i], 100, pFile))
{
i++;
}
}
if (line[i] == szProcessName)
{
cout << szProcessName + "It's Found";
}
}
}
}
I don't know why this code is not working. If I test each by std::wcout it outputs correctly, but the compare always fails.
The line:
if (line[i] == szProcessName)
Only compares the addresses of the two strings, which of course are different. You want to compare the contents of these addresses. Try using wcsncmp() instead:
if (wcsncmp(line[I], szProcessName, 44) == 0)
i'm trying to read the memory of a game called: "Prison Architect",
but i always have this value: "Money :-858993460"
I lost 2 days without have found any solutions.
I hope you can help me.
Pointer Info:
BaseAddress: "prison architect.exe"+00075140
Pointer1: 300
Pointer2: 88
Pointer3: 26c
Pointer4: 70
Pointer5: 328
int FindPointer(int offset, HANDLE pHandle, int baseaddr, int offsets[])
{
int Address = baseaddr;
int total = offset;
for (int i = 0; i < total; i++) //Loop trough the offsets
{
ReadProcessMemory(pHandle, (LPCVOID)Address, &Address, 4, NULL);
Address += offsets[i];
}
return Address;
}
int main()
{
int value = 0; // This will store our value. In my case, its an integer, which is the timer
DWORD pid; //This will store our Process ID, used to read/write into the memory
HWND hwnd; //Finally a handle to our window
hwnd = FindWindow(NULL, L"Prison Architect"); //Finds the Window
if (!hwnd) //If none, display an error
{
cout << "Window not found!\n";
cin.get();
}
GetWindowThreadProcessId(hwnd, &pid); //Get the process id and place it in pid
HANDLE phandle = OpenProcess(PROCESS_VM_READ, 0, pid); //Get permission to read
if (!phandle) //Once again, if it fails, tell us
{
cout << "Could not get handle!\n";
cin.get();
}
int baseAddress = 0x00197BE8;
int offsets[] = { 0x300, 0x88, 0x26c, 0x70, 0x328 };
while (1) {
int moneyRead = FindPointer(5, phandle, baseAddress, offsets); //number of offsets, HANDLE, base address, offsets
//reading
int money;
ReadProcessMemory(phandle, (LPVOID)moneyRead, &money, sizeof(money), 0);
cout << "\nMoney :" << money;
Sleep(3000);
}
return 0;
}
int baseAddress = 0x00197BE8;
You're using a hard coded address, which is bad practice because it may only work for this one instance of running the game process. When you re-open the game it probably will change.
The pointer must begin with an address that has a relative offset from a module. You then add the relative offset to the address of the module which you have calculated at run time. This will make it so your final address that is calculated always works correctly, regardless of ASLR.
You can use this function to find the base address of a module
uintptr_t GetModuleBaseAddress(DWORD procId, const wchar_t* modName)
{
uintptr_t modBaseAddr = 0;
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, procId);
if (hSnap != INVALID_HANDLE_VALUE)
{
MODULEENTRY32 modEntry;
modEntry.dwSize = sizeof(modEntry);
if (Module32First(hSnap, &modEntry))
{
do
{
if (!_wcsicmp(modEntry.szModule, modName))
{
modBaseAddr = (uintptr_t)modEntry.modBaseAddr;
break;
}
} while (Module32Next(hSnap, &modEntry));
}
}
CloseHandle(hSnap);
return modBaseAddr;
}
Add the relative offset to the return value and use this as the base address of the pointer you pass into your FindPointer() function.
Here is my function that is supposed to find the first encountered process with the given name and returns a handle to it. however in the process i require to allocate some data on the heap which throws an error when i try to delete.
HANDLE GetProcessHandleByName(CHAR procName[])
{
DWORD pProcessIds[1024];
DWORD pBytesReturned;
::EnumProcesses(pProcessIds, sizeof(pProcessIds), &pBytesReturned);
int noOfProcs = pBytesReturned / sizeof(DWORD);
if (noOfProcs)
{
for (int i = 0; i < noOfProcs; i++)
{
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION |
PROCESS_VM_READ,
FALSE, pProcessIds[i]);
if (!hProcess) continue;
HMODULE hMod;
DWORD cbNeeded;
CHAR strBuffer[MAX_PATH];
if (::EnumProcessModules(hProcess, &hMod, sizeof(hMod), &cbNeeded))
{
auto length = ::GetModuleBaseName(hProcess, hMod, strBuffer, sizeof(strBuffer) / sizeof(CHAR));
CHAR *str = new CHAR[length];
::strcpy(str, strBuffer);
if (::strcmp(str, procName) == 0)
{
delete[] str; //can't delete -> Exception CRT detected that the application wrote to memory after end of heap buffer.
return hProcess;
}
}
}
}
}
You shouldn't have to allocate, copy, and delete it. Also, it causes memory leak if ::strcmp(str, procName) != 0.
Try this:
if (::EnumProcessModules(hProcess, &hMod, sizeof(hMod), &cbNeeded))
{
auto length = ::GetModuleBaseName(hProcess, hMod, strBuffer, sizeof(strBuffer) / sizeof(CHAR));
if (::strcmp(strBuffer, procName) == 0)
{
return hProcess;
}
}
Similar to C++ Windows - How to get process path from its PID but the reverse: How can I get a pid from a given path?
I am trying to write an update tool, and I want to see if the exe is in use. Then if it is in use, I want to wait for the process to exit. Therefore, I want to get the process PID belonging to the file.
Here is a quick and simple way to do what you are looking for. By using the QueryFullProcessImageName, you can do a quick check.
Things that can cause the following code not to work as desired:
If you do not have permissions to view a process, you will not be
able to see the information.
If the process is 64bit and you are running your application as 32 bit, you will see the process ID, but you can not open a process handle to it.
Example:
BOOL GetProcessName(LPTSTR szFilename, DWORD dwSize, DWORD dwProcID)
{
BOOLEAN retVal = FALSE;
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, dwProcID);
DWORD dwPathSize = dwSize;
if (hProcess == 0)
return retVal; // You should check for error code, if you are concerned about this
retVal = QueryFullProcessImageName(hProcess, 0, szFilename, &dwPathSize);
CloseHandle(hProcess);
return retVal;
}
BOOL IsProcessInUse(LPCTSTR process_name)
{
DWORD* pProcs = NULL;
DWORD dwSize = 0;
DWORD dwRealSize = 0;
TCHAR szCompareName[MAX_PATH + 1];
int nCount = 0;
int nResult = 0;
dwSize = 1024;
pProcs = new DWORD[dwSize];
EnumProcesses(pProcs, dwSize*sizeof(DWORD), &dwRealSize);
dwSize = dwRealSize / sizeof(DWORD);
for (DWORD nCount = 0; nCount < dwSize; nCount++)
{
ZeroMemory(szCompareName, MAX_PATH + 1 * (sizeof(TCHAR)));
if (GetProcessName(szCompareName, MAX_PATH, pProcs[nCount]))
{
if (_tcscmp(process_name, szCompareName) == 0)
{
delete[] pProcs;
return true;
}
}
}
delete[] pProcs;
return FALSE;
}
You would then use something simple like the following to test it:
if (IsProcessInUse(your_file))
AfxMessageBox(_T("The process is still running"));
else
AfxMessageBox(_T("The process has been closed"));
The above answers your indirect question. To answer your literal question, you would change the IsProcessInUse as follows:
DWORD GetNamedProcessID(LPCTSTR process_name)
{
DWORD* pProcs = NULL;
DWORD retVal = 0;
DWORD dwSize = 0;
DWORD dwRealSize = 0;
TCHAR szCompareName[MAX_PATH + 1];
int nCount = 0;
int nResult = 0;
dwSize = 1024;
pProcs = new DWORD[dwSize];
EnumProcesses(pProcs, dwSize*sizeof(DWORD), &dwRealSize);
dwSize = dwRealSize / sizeof(DWORD);
for (DWORD nCount = 0; nCount < dwSize; nCount++)
{
ZeroMemory(szCompareName, MAX_PATH + 1 * (sizeof(TCHAR)));
if (GetProcessName(szCompareName, MAX_PATH, pProcs[nCount]))
{
if (_tcscmp(process_name, szCompareName) == 0)
{
retVal = pProcs[nCount];
delete[] pProcs;
return retVal;
}
}
}
delete[] pProcs;
return 0;
}
One last important thing to note is the fact that this will only return a single instance (or PID) for a file, and this does not look for Modules that are used by process (so any DLL in use by process will not be identified, however, from the link you provided, you can see ways of utilizing that to get that level of functionality.
In Visual C++, am getting the title of the current window using
::GetWindowText(wnd, str, 290);
strcpy(curr_wnd_txt, str);
But how can i get the Process Name of the Application for example "Iexplore" for Using Internet Explorer, "Skype" for window with tile "Skype - username", "Explorer" for using windows explorer ?
This is what i tried :
void CMainWndDlg::Monitor_ActiveWindowCaptions()
{
HWND hwnd;
DWORD process_id=0;
GetWindowThreadProcessId(hwnd, &process_id);
CString strEXEName = GetEXEName (process_id);
}
CString GetEXEName(DWORD dwProcessID)
{
DWORD aProcesses [1024], cbNeeded, cProcesses;
unsigned int i;
if (!EnumProcesses(aProcesses, sizeof(aProcesses), &cbNeeded))
return "";
cProcesses = cbNeeded / sizeof(DWORD);
TCHAR szEXEName[MAX_PATH];
for (i = 0; i < cProcesses; i++)
{
if (aProcesses [i] == dwProcessID)
{
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION |
PROCESS_VM_READ, FALSE, dwProcessID);
if (NULL != hProcess)
{
HMODULE hMod;
DWORD cbNeeded;
if(EnumProcessModules(hProcess, &hMod,
sizeof(hMod), &cbNeeded))
{
GetModuleBaseName(hProcess, hMod, szEXEName,
sizeof(szEXEName)/sizeof(TCHAR));
return CString (szEXEName);
}
}
}
}
return "";
}
GetModuleFileName() can be used to retrieve the path of the executable file of the current process.
http://msdn.microsoft.com/en-gb/library/windows/desktop/ms683197(v=vs.85).aspx
You will have to enumerate the windows, get the process handle, and then get the name of the executable from the function below.
#include "psapi.h"
#pragma comment(lib, "psapi.lib")
CString GetEXEName(DWORD dwProcessID)
{
DWORD aProcesses [1024], cbNeeded, cProcesses;
unsigned int i;
//Enumerate all processes
if (!EnumProcesses(aProcesses, sizeof(aProcesses), &cbNeeded))
return NULL;
// Calculate how many process identifiers were returned.
cProcesses = cbNeeded / sizeof(DWORD);
TCHAR szEXEName[MAX_PATH];
//Loop through all process to find the one that matches
//the one we are looking for
for (i = 0; i < cProcesses; i++)
{
if (aProcesses [i] == dwProcessID)
{
// Get a handle to the process
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION |
PROCESS_VM_READ, FALSE, dwProcessID);
// Get the process name
if (NULL != hProcess)
{
HMODULE hMod;
DWORD cbNeeded;
if(EnumProcessModules(hProcess, &hMod,
sizeof(hMod), &cbNeeded))
{
//Get the name of the exe file
GetModuleBaseName(hProcess, hMod, szEXEName,
sizeof(szEXEName)/sizeof(TCHAR));
return CString (szEXEName);
}
}
}
}
return NULL;
}
Refer here: http://www.codeproject.com/Articles/14843/Finding-module-name-from-the-window-handle