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
Related
Im making a DLL in c++ that is injected into another program.
When injecting more than once the program crashes so I want the DLL to first check if it was already injected and if so it will do some code like showing a message box or just quitting
This can be done using EnumProcessModules
BOOL isInjected() {
const char ProcessName = "Process.exe";
std::string DllName = "MyDll.dll";
DWORD dwProcessId = NULL;
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnapshot == INVALID_HANDLE_VALUE)
return false;
PROCESSENTRY32 pe{};
pe.dwSize = sizeof(PROCESSENTRY32);
if (Process32First(hSnapshot, &pe))
{
do
{
if (_tcsicmp(pe.szExeFile, _T(ProcessName)) == 0)
{
dwProcessId = pe.th32ProcessID;
break;
}
} while (Process32Next(hSnapshot, &pe));
}
CloseHandle(hSnapshot);
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, dwProcessId);
if (hProcess == NULL)
{
return false;
}
HMODULE hMods[1024];
DWORD cbNeeded;
if (EnumProcessModules(hProcess, hMods, sizeof(hMods), &cbNeeded))
{
int amount = 0;
for (unsigned int i = 0; i < (cbNeeded / sizeof(HMODULE)); i++)
{
TCHAR szModName[MAX_PATH];
if (GetModuleFileNameEx(hProcess, hMods[i], szModName, sizeof(szModName) / sizeof(TCHAR)))
{
std::string str1 = szModName;
if (str1.find(DllName) != std::string::npos) amount++;
}
}
if (amount >= 2) return true;
}
return false;
}
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;
}
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 using QT to check if process is running and i used the same code in msdn site.
It worked fine on Visual Studio but i'm having a problem making it work on QT.
Here's the code :
bool matchProcessName( DWORD processID, std::string processName)
{
TCHAR szProcessName[MAX_PATH] = TEXT(L"notepad.exe");
// Get a handle to the process.
HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION |
PROCESS_VM_READ,
FALSE, processID );
// Get the process name.
if (NULL != hProcess )
{
HMODULE hMod;
DWORD cbNeeded;
if ( EnumProcessModules( hProcess, &hMod, sizeof(hMod),
&cbNeeded) )
{
GetModuleBaseName( hProcess, hMod, szProcessName,
sizeof(szProcessName)/sizeof(TCHAR) );
}
}
// Compare process name with your string
bool matchFound = !_tcscmp(szProcessName, processName.c_str() );
// Release the handle to the process.
CloseHandle( hProcess );
return matchFound;
}
The Error i'm getting is this :
error: cannot convert 'TCHAR*' to 'const char*' for argument '1' to 'int strcmp(const char*, const char*)'
How can i make this work on QT ?
Thanks alot.
Update
I also tried this code :
DWORD FindProcessId(char* processName)
{
char* p = strrchr(processName, '\\');
if(p)
processName = p+1;
PROCESSENTRY32 processInfo;
processInfo.dwSize = sizeof(processInfo);
HANDLE processesSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
if ( processesSnapshot == INVALID_HANDLE_VALUE )
return 0;
Process32First(processesSnapshot, &processInfo);
if ( !strcmp(processName, processInfo.szExeFile) )
{
CloseHandle(processesSnapshot);
return processInfo.th32ProcessID;
}
while ( Process32Next(processesSnapshot, &processInfo) )
{
if ( !strcmp(processName, processInfo.szExeFile) )
{
CloseHandle(processesSnapshot);
return processInfo.th32ProcessID;
}
}
CloseHandle(processesSnapshot);
return 0;
}
I'm also getting an error :cannot convert 'WCHAR*' to 'const char*' for argument '2' to 'int strcmp(const char*, const char*)'
I prefer if i can make 2nd method work !
Thanks again
It has nothing to do with Qt.
In the updated code, PROCESSENTRY32.szExeFile is a TCHAR[],
i.e. it is a WCHAR[] if the macro _UNCODE is defined else is a char[].
So you have to transfer your char *processName to TCHAR[] and use _tcscmp(...) to compare TCHAR[].
Modified code:
#include <Windows.h>
#include <TlHelp32.h>
#include <tchar.h>
#include <Psapi.h>
#include <cstring>
#include <string>
#define MIN(x, y) ((x) > (y)) ? (y) : (x)
void cstringToTCHAR(TCHAR *dst, const char *src, size_t l) {
#if defined(_UNICODE) || defined(UNICODE
mbstowcs(dst, src, l);
#else
memcpy(dst, src, l);
#endif
}
bool matchProcessName( DWORD processID, std::string processName)
{
TCHAR szProcessName[MAX_PATH] = _T("notepad.exe");
// Get a handle to the process.
HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION |
PROCESS_VM_READ,
FALSE, processID );
// Get the process name.
if (NULL != hProcess )
{
HMODULE hMod;
DWORD cbNeeded;
if ( EnumProcessModules( hProcess, &hMod, sizeof(hMod),
&cbNeeded) )
{
GetModuleBaseName( hProcess, hMod, szProcessName,
sizeof(szProcessName)/sizeof(TCHAR) );
}
}
// Compare process name with your string
TCHAR systemEncodeProcessName[30];
size_t processNameLen = MIN((processName.size() + 1), 30);
cstringToTCHAR(systemEncodeProcessName, processName.c_str(), processNameLen);
bool matchFound = !_tcscmp(szProcessName, systemEncodeProcessName);
// Release the handle to the process.
CloseHandle( hProcess );
return matchFound;
}
DWORD FindProcessId(char* processName) {
char* p = strrchr(processName, '\\');
if(p) {
processName = p+1;
}
PROCESSENTRY32 processInfo;
processInfo.dwSize = sizeof(processInfo);
HANDLE processesSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
if (processesSnapshot == INVALID_HANDLE_VALUE) {
return 0;
}
//Transfer char array to TCHAR array.
TCHAR systemEncodeProcessName[30];//Maybe need more or dynamic allocation.
size_t processNameLen = MIN((strlen(processName) + 1), 30);
cstringToTCHAR(systemEncodeProcessName, processName, processNameLen);
Process32First(processesSnapshot, &processInfo);
if (!_tcscmp(systemEncodeProcessName, processInfo.szExeFile)) {
CloseHandle(processesSnapshot);
return processInfo.th32ProcessID;
}
while ( Process32Next(processesSnapshot, &processInfo) ) {
if ( !_tcscmp(systemEncodeProcessName, processInfo.szExeFile) ) {
CloseHandle(processesSnapshot);
return processInfo.th32ProcessID;
}
}
CloseHandle(processesSnapshot);
return 0;
}
Update
In Qt creator(3.3.0), the _UNICODE macro looks like missing in Windows platform, just add
DEFINES += _UNICODE
in your .pro file and then run qmake && build.
I have a foreign process (exe-file DllProj.exe is running), that has SampleDll.dll linked to it (implicit linking). I can find the base address of the linked dll with the help of my function imageBase(), but not the base address of the process itself! What is the difference and why it's not working as is?
I mean, this code returns pBase with correct DOS/NT-headers:
LPVOID pBase = imageBase("DllProj.exe", "SampleDll.dll");
if (!pBase)
return false;
PIMAGE_DOS_HEADER pDosHeader = PIMAGE_DOS_HEADER((HMODULE)pBase);
if (::IsBadReadPtr(pDosHeader, sizeof(IMAGE_DOS_HEADER)) ||
IMAGE_DOS_SIGNATURE != pDosHeader->e_magic)
return false;
but this code return is FALSE:
LPVOID pBase = imageBase("DllProj.exe", "DllProj.exe");
//and so on...
Here is my procedure:
LPVOID imageBase(LPSTR szVictimProcess, LPSTR szVictim)
{
//находим процесс szVictimProcess
DWORD aProcesses[1024], cbNeeded, nProcesses;
unsigned int i;
if (!EnumProcesses(aProcesses, sizeof(aProcesses), &cbNeeded))
return NULL;
nProcesses = cbNeeded / sizeof(DWORD);
HANDLE ProcHandle = 0;
TCHAR szProcessName[MAX_PATH] = TEXT("<unknown>");
for (i = 0; i < nProcesses; i++)
{
ProcHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, false, aProcesses[i]);
if (NULL != ProcHandle)
{
HMODULE hMod[1024];
if ( EnumProcessModules(ProcHandle, hMod, sizeof(hMod), &cbNeeded) )
{
GetModuleBaseName(ProcHandle, hMod[0], szProcessName, sizeof(szProcessName)/sizeof(TCHAR)); // Get the process name
if (0 == lstrcmpiA(szVictimProcess, szProcessName))
{
//находим модуль szVictim
DWORD nModules = cbNeeded / sizeof(HMODULE);
char szModName[MAX_PATH];
for (unsigned int j = 0; j < nModules; j++)
{
if (GetModuleFileNameEx(ProcHandle, hMod[j], szModName, sizeof(szModName))) // Get the module name
{
shortName(szModName);
if (0 == lstrcmpiA(szModName, szVictim))
{
MODULEINFO info;
GetModuleInformation(ProcHandle, hMod[j], &info, sizeof(info));
return info.lpBaseOfDll;
//Equal To:
//return hMod[j];
//Debug:
//LPSTR string = new char[256];
//wsprintf(string,"\t%s (0x%08X)\n", szModName, hMod[j]);
}
}
}
break;
}
}
}
CloseHandle(ProcHandle);
}
return NULL;
}
P.S.: My next goal is to get import-table of DllProj.exe (where Sample.dll is) and hiijack dll's function call
What about using this:
#pragma comment( lib, "psapi" )
DWORD GetModuleBase(HANDLE hProc, string &sModuleName)
{
HMODULE *hModules;
char szBuf[50];
DWORD cModules;
DWORD dwBase = -1;
//------
EnumProcessModules(hProc, hModules, 0, &cModules);
hModules = new HMODULE[cModules/sizeof(HMODULE)];
if(EnumProcessModules(hProc, hModules, cModules/sizeof(HMODULE), &cModules)) {
for(int i = 0; i < cModules/sizeof(HMODULE); i++) {
if(GetModuleBaseName(hProc, hModules[i], szBuf, sizeof(szBuf))) {
if(sModuleName.compare(szBuf) == 0) {
dwBase = (DWORD)hModules[i];
break;
}
}
}
}
delete[] hModules;
return dwBase;
}
Credit to answer here
There is nothing wrong with your code, I compiled your code and it works fine and outputs the correct address to console. Make sure you run as administrator. This is the project using your code which I tested working:
#include <windows.h>
#include <iostream>
#include <psapi.h>
#include <string>
void shortName(LPSTR strToChange)
{
std::string path(strToChange);
std::string filename;
size_t pos = path.find_last_of("\\");
if (pos != std::string::npos)
filename.assign(path.begin() + pos + 1, path.end());
else
filename = path;
lstrcpy(strToChange, filename.data());
}
LPVOID imageBase(LPSTR szVictimProcess, LPSTR szVictim)
{
DWORD aProcesses[1024], cbNeeded, nProcesses;
unsigned int i;
if (!EnumProcesses(aProcesses, sizeof(aProcesses), &cbNeeded))
return NULL;
nProcesses = cbNeeded / sizeof(DWORD);
HANDLE ProcHandle = 0;
TCHAR szProcessName[MAX_PATH] = TEXT("<unknown>");
for (i = 0; i < nProcesses; i++)
{
ProcHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, false, aProcesses[i]);
if (NULL != ProcHandle)
{
HMODULE hMod[1024];
if (EnumProcessModules(ProcHandle, hMod, sizeof(hMod), &cbNeeded))
{
GetModuleBaseName(ProcHandle, hMod[0], szProcessName, sizeof(szProcessName) / sizeof(TCHAR)); // Get the process name
if (0 == lstrcmpiA(szVictimProcess, szProcessName))
{
DWORD nModules = cbNeeded / sizeof(HMODULE);
char szModName[MAX_PATH];
for (unsigned int j = 0; j < nModules; j++)
{
if (GetModuleFileNameEx(ProcHandle, hMod[j], szModName, sizeof(szModName))) // Get the module name
{
shortName(szModName);
if (0 == lstrcmpiA(szModName, szVictim))
{
MODULEINFO info;
GetModuleInformation(ProcHandle, hMod[j], &info, sizeof(info));
return info.lpBaseOfDll;
}
}
}
break;
}
}
}
CloseHandle(ProcHandle);
}
return NULL;
}
int main(void)
{
void* base = imageBase((char*)"ac_client.exe", (char*)"ac_client.exe");
std::cout << "0x" << std::hex << base;
}