How to retrieve process handle by using application name in c++?
Is there any windows API is there?
Example: Sample.exe
I have to get the handle of this sample.exe and I need to call Terminate process on that handle.
Any one suggest a good solution for this.
Note: its should support winxp and win8
Thanks in Advance
You should use toolhelp API's:
HANDLE OpenProcessByName(LPCTSTR Name, DWORD dwAccess)
{
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnap != INVALID_HANDLE_VALUE)
{
PROCESSENTRY32 pe;
ZeroMemory(&pe, sizeof(PROCESSENTRY32));
pe.dwSize = sizeof(PROCESSENTRY32);
Process32First(hSnap, &pe);
do
{
if (!lstrcmpi(pe.szExeFile, Name))
{
return OpenProcess(dwAccess, 0, pe.th32ProcessID);
}
} while (Process32Next(hSnap, &pe));
}
return INVALID_HANDLE_VALUE;
}
For example:
#include <windows.h>
#include <tlhelp32.h>
//...
int main()
{
HANDLE hFire = OpenProcessByName("firefox.exe", PROCESS_VM_READ);
cout << "Handle: " << hFire << endl;
CloseHandle(hFire);
cin.get();
return 0;
}
But you should be careful because if there are more than 1 copy of process you will get a handle of the first. To handle all processes in "return OpenProcess" use call of some function like Handler(OpenProcess(dwAccess, 0, pe.th32ProcessID)):
void Handler(HANDLE hndl)
{
//... work with your Handle
CloseHandle(hndl);
}
//...
if (!lstrcmpi(pe.szExeFile, Name))
{
Handler(OpenProcess(dwAccess, 0, pe.th32ProcessID)):
}
//...
To fetch the process name from process id see quiestions: get process name from process id (win32) or How to get the process name in C++
Enumerate process documentation https://msdn.microsoft.com/en-us/library/windows/desktop/ms682629%28v=vs.85%29.aspx Example code: https://msdn.microsoft.com/ru-ru/library/windows/desktop/ms682623%28v=vs.85%29.aspx
EDIT: There is solution that does not have problem "return the hanlde of the first matching found, whereas there may be multiple instances". This solution return array of pairs ProcessId and names, and you can select that you need in simple loop.
#include <windows.h>
#include <tlhelp32.h>
#include <iostream>
#include <utility>
#include <vector>
#include <string>
#include <map>
typedef std::pair<DWORD,std::string> ProcessVectorEntry;
typedef std::vector<ProcessVectorEntry> ProcessVector;
void getProcessInformation( ProcessVector& processVector ) {
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if(hSnapshot) {
PROCESSENTRY32 pe32;
pe32.dwSize = sizeof(PROCESSENTRY32);
if(Process32First(hSnapshot, &pe32)) {
do {
processVector.push_back( ProcessVectorEntry( pe32.th32ProcessID, pe32.szExeFile ) );
} while(Process32Next(hSnapshot, &pe32));
}
CloseHandle(hSnapshot);
}
}
And simple search in main
int main() {
std::string search = "firefox.exe";
ProcessVector processVector;
getProcessInformation( processVector );
std::cout << "Process IDs contains " << search << " in name:" << std::endl;
for( int i=0; i<processVector.size(); ++i )
if( processVector[i].second.find(search) != std::string::npos )
std::cout << processVector[i].first << std::endl;
return 0;
}
Related
So basically, I'm listing all of the files in my temp directory, and then deleting them. Obviously, some of the files are in use and the program itself is using the files that it's deleting. I tried fiddling around with SHFileOperation with no success. (tbh I got no idea how to use it). How do I make it check if the file is in use by another program before deleting it? Thanks!
This is giving me the error: fs::remove_all(entry.path());
Code:
#include <iostream>
#include <Windows.h>
#include <filesystem>
#include <lmcons.h>
#include <fileapi.h>
#include "cColors.h"
using namespace std;
namespace fs = filesystem;
char type;
int main()
{
SetConsoleTextAttribute(h, 15);
while (true)
{
cout << "[~] Are you sure you want to run Windows Cleaner? [Y/N]";
cin >> type;
if (type == 'n')
{
break;
exit(0);
}
else if (type == 'y')
{
cout << "[#] Cleaning temp directory\n";
for (const auto& entry : fs::directory_iterator(fs::temp_directory_path()))
{
cout << "[#] Deleting " << entry.path();
fs::remove_all(entry.path()); //This is giving me the error
}
}
else
{
break;
exit(0);
}
}
}
Here's what I came up with. A recursive delete function which uses CreateFile. My original comment
Maybe you could use CreateFile with desired access 0 and share mode OPEN_EXISTING. Then you have to check the failing reason. If it doesn't fail; close and delete.
wasn't 100% correct. dwDesiredAccess should be 0, dwShareMode should be FILE_SHARE_DELETE, dwCreationDisposition should be OPEN_EXISTING and dwFlagsAndAttributes should be FILE_FLAG_DELETE_ON_CLOSE. If then a valid handle is received the last CloseHandle on the file will lead to deletion (see here).
Here's an example:
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <tchar.h>
#include <iostream>
#include <filesystem>
#ifdef _UNICODE
auto& cout = std::wcout;
#else
using std::cout;
#endif // _UNICODE
using std::endl;
namespace fs=std::filesystem;
void deleteRecursive(const fs::path& path);
void tryDeleteFile(const fs::path& path);
int main(int argc, char* argv[])
{
TCHAR tempDir[255];
GetEnvironmentVariable(_T("TEMP"), tempDir, 255);
deleteRecursive(fs::path(tempDir));
return 0;
}
void deleteRecursive(const fs::path& path)
{
fs::directory_iterator dirs(path);
for (const auto& entry : dirs)
{
const auto& path = entry.path();
if (entry.is_directory())
{
deleteRecursive(path);
if (fs::is_empty(path))
{
if (!RemoveDirectory(path.c_str()))
{
cout << _T("Can't delete dir: ") << path << endl;
}
}
}
else
{
tryDeleteFile(path);
}
}
}
void tryDeleteFile(const fs::path& path)
{
const auto file = path.c_str();
HANDLE fileHandle = CreateFile(
file, // lpFileName,
0, // dwDesiredAccess,
FILE_SHARE_DELETE, // dwShareMode,
NULL, // lpSecurityAttributes,
OPEN_EXISTING, // dwCreationDisposition,
FILE_FLAG_DELETE_ON_CLOSE, // dwFlagsAndAttributes,
NULL // hTemplateFile
);
if (fileHandle == INVALID_HANDLE_VALUE)
{
DWORD lastErr = GetLastError();
if (lastErr != ERROR_FILE_NOT_FOUND) // gone in the mean time
{
cout << _T("Can't delete file: ") << file << endl;
}
}
else
{
CloseHandle(fileHandle);
}
}
tryDeleteFile contains the crucial part.
Catch the exception Just ignore the error and continue. Or use the second form and pass an error_code argument. Than you get no exception and you can check the reason why it failed.
If the file is in use you get an error. So you can't delete it. If you have no rights you can't delete it too.
Checking the usage first is a race condition. After the check, the file might get closed and you may be able to delete it safely. There is no difference in checking first and than delete it or trying to delete it and it fails.
I am trying to create a simple word highlighter for browsers (Chrome and Firefox) and I would like my program to use the process name (chrome.exe or firefox.exe) and then get their process ID.
I've found code that lets me get the process ID, but it requires a user to type the process name manually:
#include "pch.h"
#include <iostream>
#include <string>
#include <windows.h>
#include <tlhelp32.h>
DWORD FindProcessId(const std::wstring& processName);
int main()
{
std::wstring processName;
std::wcout << "Enter the process name: ";
std::getline(std::wcin, processName);
DWORD processID = FindProcessId(processName);
if (processID == 0)
std::wcout << "Could not find " << processName.c_str() << std::endl;
else
std::wcout << "Process ID is " << processID << std::endl;
system("PAUSE");
return 0;
}
DWORD FindProcessId(const std::wstring& processName)
{
PROCESSENTRY32 processInfo;
processInfo.dwSize = sizeof(processInfo);
HANDLE processesSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
if (processesSnapshot == INVALID_HANDLE_VALUE)
return 0;
Process32First(processesSnapshot, &processInfo);
if (!processName.compare(processInfo.szExeFile))
{
CloseHandle(processesSnapshot);
return processInfo.th32ProcessID;
}
while (Process32Next(processesSnapshot, &processInfo))
{
if (!processName.compare(processInfo.szExeFile))
{
CloseHandle(processesSnapshot);
return processInfo.th32ProcessID;
}
}
CloseHandle(processesSnapshot);
return 0;
}
Now, is there a way to manipulate this code for it to get the process ID automatically by checking whether the user is running firefox.exe or chrome.exe?
And after getting the process ID, how do I make my program understand that it needs to focus on said ID?
Now, is there a way to manipulate this code for it to get the process ID automatically by checking whether the user is running firefox.exe or chrome.exe?
#include <iostream>
#include <string>
#include <windows.h>
#include <tlhelp32.h>
DWORD FindProcessId(const std::wstring& processName);
int main()
{
std::wstring fifi = L"firefox.exe";
std::wstring gogo = L"chrome.exe";
auto fifi_proc_id = FindProcessId(fifi);
auto gogo_proc_id = FindProcessId(gogo);
if(fifi_proc_id && gogo_proc_id) {
// both runnin O.O what now?
}
else if(fifi_proc_id) {
// firefox running ... do stuff
}
else if(gogo_proc_id) {
// chrome running ... do stuff
}
else {
// none of both :(
}
}
And after getting the process ID, how do I make my program understand that it needs to focus on said ID?
I am sorry, but I don't know what you mean by "make my program understand that it needs to focus on said ID".
I'm trying to get the process dump. But when I use flag MiniDumpWithFullMemory the function crashes.
Maybe I use DuplicateHandle wrong... I don't know.
Is MiniDumpWithFullMemory is necessary flag to obtain general information or I can use only other flags (like in code listing below) ??
I need to get the dump in order to send it to VirusTotal...
Here is the code:
#include <iostream>
#include <windows.h>
using namespace std;
#pragma comment(lib, "dbghelp.lib")
#include <dbghelp.h>
#include <stdio.h>
void WriteFullDump(wchar_t* path_to_dump, HANDLE hProc)
{
const DWORD Flags = MiniDumpWithHandleData|
MiniDumpWithHandleData|
MiniDumpWithDataSegs|
MiniDumpScanMemory |
MiniDumpFilterMemory|
MiniDumpNormal|
MiniDumpWithUnloadedModules|
MiniDumpWithThreadInfo;
HANDLE hFile = CreateFile(path_to_dump, GENERIC_WRITE, 0, nullptr,CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
BOOL Result = MiniDumpWriteDump(hProc,
GetProcessId(hProc),
hFile,
(MINIDUMP_TYPE)Flags,
nullptr,
nullptr,
nullptr);
CloseHandle(hFile);
if (!Result)
{
cout << Result << endl;
std::cerr << "Looks like an error: MiniDumpWriteDump failed" << endl;
cout << GetLastError() << endl;
}
CloseHandle(hFile);
return;
}
int main()
{
wchar_t* path = L"C:\\C++\\122332.txt";
int pid;
cin >> pid;
HANDLE proc = OpenProcess(PROCESS_DUP_HANDLE, 1, pid);
HANDLE pseudoproc;
HANDLE my = GetCurrentProcess();
DuplicateHandle(proc, proc, my, &pseudoproc, PROCESS_QUERY_INFORMATION, 1, DUPLICATE_SAME_ACCESS);
WriteFullDump(path,proc);
CloseHandle(proc);
cout << "Finished!" << endl;
char g;
cin >> g;
return 0;
}
I tried to create a little project in C++ . My program should be able to read the currently running processes in Windows and send information about the processes to my private MySQL database every 5 minutes. In this amount of time I can read the processes.
See code below:
#include <stdio.h>
#include <iostream>
#include <windows.h>
#include <tlhelp32.h>
bool getAllProcesses(void);
int main(void){
getAllProcesses();
}
bool getAllProcesses(){
HANDLE WINAPI snapshot = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
LPPROCESSENTRY32 pe32;
Process32First(snapshot, pe32);
while(Process32Next(snapshot, pe32)){
std::cout << pe32->szExeFile << "\n";
}
std::cout << "End of list";
CloseHandle( snapshot );
return true;
}
The code above is working fine.
But if I add the code "int i;i=1;" like this:
#include <stdio.h>
#include <iostream>
#include <windows.h>
#include <tlhelp32.h>
bool getAllProcesses(void);
int main(void){
getAllProcesses();
}
bool getAllProcesses(){
int i;
i=0;
HANDLE WINAPI snapshot = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
LPPROCESSENTRY32 pe32;
Process32First(snapshot, pe32);
while(Process32Next(snapshot, pe32)){
std::cout << pe32->szExeFile << "\n";
}
std::cout << "End of list";
CloseHandle( snapshot );
return true;
}
With this change the program will crash, showing the alert "Program stop the work".
I tried to find the problem and I've determined the following :
If I use the function Process32First() OR Process32Next() I can't declare the same int in all of the program.
What is the problem?
You have a lot of issues going on here. I tried this on VS 2008 Win7.
The "i" declaration has nothing to do with the problem, but may just be moving the stack a bit to hide the real problems. See my comments in the corrected code below.
bool getAllProcesses(){
int i;
i=0;
HANDLE WINAPI snapshot = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
/* replace LPPROCESSENTRY32 with PROCESSENTRY32. LP is just a define as
a pointer to a structure, so you did not actually allocate any memory for the
return of Process32First() to return the result into.
So you were probably overwriting stuff in the stack. */
PROCESSENTRY32 pe32;
/* need to initialize the structure properly. Memset may be overkill,
but better to see all zeros than garbage. dwSize must be
initialized as per the SDK documentation. */
memset(&pe32,0,sizeof(pe32) );
pe32.dwSize = sizeof(pe32);
BOOL result;
/* did not check the result from the call if TRUE/FALSE */
result = Process32First(snapshot, &pe32);
std::cout << "result =" << result << "\n";
while(Process32Next(snapshot, &pe32)){
std::cout << pe32.szExeFile << "\n";
}
std::cout << "End of list";
CloseHandle( snapshot );
return true;
}
The addition of those 2 lines making the program not able to run is just a coincidence. The program should not be running at all, since there are 2 major mistakes:
pe32 is an uninitialized pointer
dwSize member of PROCESSENTRY32 structure is not initialized as described in the [MS.Docs]: Process32First function:
The calling application must set the dwSize member of PROCESSENTRY32 to the size, in bytes, of the structure.
And a third, smaller mistake is that you are ignoring the process data returned by Process32First.
In order to make things work correctly, replace the following lines of your code:
LPPROCESSENTRY32 pe32;
Process32First(snapshot, pe32);
while(Process32Next(snapshot, pe32)){
std::cout << pe32->szExeFile << "\n";
, with:
PROCESSENTRY32 pe32;
pe32.dwSize = sizeof(PROCESSENTRY32);
if (Process32First(snapshot, &pe32))
{
do {
std::cout << pe32.szExeFile << "\n";
}
while (Process32Next(snapshot, &pe32));
}
I need to open a certain named pipe so I can fuzz test it, however my test code does not have access to the same data used to generate the name of the named pipe. However I can recognize the name of the pipe and then use that name to open up the pipe for fuzzing.
I used this forum post to start enumerating names of the handles on the system:
http://forum.sysinternals.com/howto-enumerate-handles_topic18892.html
However it seems that won't work with named pipes for some reason.
TL;DR: What API(s) do I need to use to list the names of all named pipes in the current process on Windows?
This will enumerate all named pipes in the system, or at the very least put you a step in the right direction.
This works in MinGW when built with -fpermissive. It should work with similar settings in MSVC.
#ifndef _WIN32_WINNT
// Windows XP
#define _WIN32_WINNT 0x0501
#endif
#include <Windows.h>
#include <Psapi.h>
// mycreatepipeex.c is at http://www.davehart.net/remote/PipeEx.c
// I created a simple header based on that.
#include "mycreatepipeex.h"
#include <iostream>
#include <cstdio>
#include <errno.h>
void EnumeratePipes()
{
WIN32_FIND_DATA FindFileData;
HANDLE hFind;
#define TARGET_PREFIX "//./pipe/"
const char *target = TARGET_PREFIX "*";
memset(&FindFileData, 0, sizeof(FindFileData));
hFind = FindFirstFileA(target, &FindFileData);
if (hFind == INVALID_HANDLE_VALUE)
{
std::cerr << "FindFirstFileA() failed: " << GetLastError() << std::endl;
return;
}
else
{
do
{
std::cout << "Pipe: " << TARGET_PREFIX << FindFileData.cFileName << std::endl;
}
while (FindNextFile(hFind, &FindFileData));
FindClose(hFind);
}
#undef TARGET_PREFIX
return;
}
int main(int argc, char**argv)
{
HANDLE read = INVALID_HANDLE_VALUE;
HANDLE write = INVALID_HANDLE_VALUE;
unsigned char pipe_name[MAX_PATH+1];
BOOL success = MyCreatePipeEx(&read, &write, NULL, 0, 0, 0, pipe_name);
EnumeratePipes();
if ( success == FALSE )
{
std::cerr << "MyCreatePipeEx() failed: " << GetLastError() << std::endl;
return 1;
}
FILE *f = fopen((const char*)pipe_name, "rwb");
if ( f == NULL )
{
std::cerr << "fopen(\"" << pipe_name << "\") failed: " << (int)errno << std::endl;
}
CloseHandle(read);
CloseHandle(write);
return 0;
}