I have written two functions which they can kill a process by its name. You can specify the name of a process, and after the execution of the program, that process will kill.
These two functions are working fine, but when I decided to run them via threads, they didn't execute. What is the problem with the following code:
#include <iostream>
#include <string>
#include <tchar.h>
#include <process.h>
#include <windows.h>
#include <tlhelp32.h>
BOOL TerminateMyProcess(DWORD dwProcessId, UINT uExitCode)
{
DWORD dwDesiredAccess = PROCESS_TERMINATE;
BOOL bInheritHandle = FALSE;
HANDLE hProcess = OpenProcess(dwDesiredAccess, bInheritHandle, dwProcessId);
if (hProcess == NULL)
return FALSE;
BOOL result = TerminateProcess(hProcess, uExitCode);
CloseHandle(hProcess);
return result;
}
DWORD GetProcessList()
{
HANDLE hProcessSnap;
HANDLE hProcess;
PROCESSENTRY32 pe32;
DWORD dwPriorityClass;
// Take a snapshot of all processes in the system.
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hProcessSnap == INVALID_HANDLE_VALUE)
{
return(FALSE);
}
// Set the size of the structure before using it.
pe32.dwSize = sizeof(PROCESSENTRY32);
// Retrieve information about the first process,
// and exit if unsuccessful
if (!Process32First(hProcessSnap, &pe32))
{
CloseHandle(hProcessSnap); // clean the snapshot object
return(FALSE);
}
// Now walk the snapshot of processes
do
{
std::string str(pe32.szExeFile);
if (str == "notepad.exe") // put the name of your process you want to kill
{
TerminateMyProcess(pe32.th32ProcessID, 1);
}
} while (Process32Next(hProcessSnap, &pe32));
CloseHandle(hProcessSnap);
return(TRUE);
}
DWORD WINAPI ThreadingOne(LPVOID arg_param) {
return GetProcessList();
}
auto main(int argc, const char* argv[]) -> decltype(0)
{
DWORD ThreadId;
HANDLE ThreadHandle = CreateThread(NULL, 0, ThreadingOne, (LPVOID)0, CREATE_SUSPENDED, &ThreadId);
ResumeThread(ThreadHandle);
return 0;
}
The thread function didn't start anyway. I didn't know what is the mistake with this threading. I should mention here, I just started multithreading earlier, so it is maybe a simple question but I am a newbie in threads world.
Related
I want to get the process and thread handles about some games to inject dll, and I used OpenProcess() and OpenThread() to obtain these handles. But I found that I just get different handles each time I use these functions. And they are useless for me because they arent the true handles. Please tell me how I can get the true handles?
Thanks for your answers and comments! And I found that I did not describe my problem very well. Sorry.
Actually, if i used CreateProcess() funtion to launch a process and get handles from parameter lpProcessInformation pi. I could inject my dll into game through these handles named pi.hProcess and pi.hThread. And these handles seem like would not change during the program's runtime.
But if I got handles from OpenProcess() and OpenThread(), the process handle and thread handle were not same as the handle from CreateProcess() even though I got them in same run from a process.
So I thought that the handle from pi is the true handle, and the handle from OpenProcess() are fake. I dont know why they are different and why only handles from pi can work well.
Please tell me the difference about handles from OpenProcess() and
CreateProcess(). Or how I can get the handles same as CreateProcess() through PID.
This is the code how inject dll. And ony handles from pi.hProcess and pi.hThread can work.
void KInject::InjectDll(HANDLE hProcess, HANDLE hThread, ULONG_PTR param){
QueueUserAPC(
(PAPCFUNC)GetProcAddress(GetModuleHandleA("kernel32.dll"), "LoadLibraryA"),
hThread,
(ULONG_PTR)param
);
}
void KInject::Inject2(HANDLE hProcess, HANDLE hThread, const char* szDLL ){
SIZE_T len = strlen(szDLL) + 1;
PVOID param = VirtualAllocEx(hProcess, NULL, len, MEM_COMMIT | MEM_TOP_DOWN /*MEM_RESERVE*/, PAGE_READWRITE);
if (param != NULL)
{
SIZE_T ret;
if (WriteProcessMemory(hProcess, param, szDLL, len, &ret)) {
InjectDll(hProcess, hThread, (ULONG_PTR)param );
}
}
}
This is the code how i get handles.
#include <Windows.h>
#include "tlhelp32.h"
#include <stdio.h>
#include <string.h>
#include <iostream>
using namespace std;
int main(int argc, char* argv[])
{
HWND hq = FindWindow(NULL, "Temp");
RECT rect;
DWORD dwThreadID;
DWORD dwProcessId;
GetWindowThreadProcessId(hq, &dwProcessId);
GetWindowRect(hq, &rect);
DWORD a = GetWindowThreadProcessId(hq, &dwProcessId);
THREADENTRY32 te32 = { sizeof(te32) };
HANDLE hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
if (Thread32First(hThreadSnap, &te32))
{
do {
if (dwProcessId == te32.th32OwnerProcessID)
{
dwThreadID = te32.th32ThreadID;
break;
}
} while (Thread32Next(hThreadSnap, &te32));
}
CloseHandle(hThreadSnap);
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, dwThreadID);
CloseHandle(hThread);
CloseHandle(hProcess);
return 0;
}
There is nothing wrong with the API in this regard. Their return values are just what they are supposed to be, i.e. "handles" to the actual processes and threads. Exactly the same way as when you open a file, you get a handle to it, and if you open the same file multiple times, you may get different handles.
Having said that, just in the same way that files do have a more permanent name—which is their paths—processes and threads also do have a more permanent name and its called their "ID".
You can use the Win32 functions GetProcessId(HANDLE handle) and GetThreadId(HANDLE handle) to get to these more permanent identifiers.
I'm stuck on this since days, i'm goind crazy.
Basically i'm trying to open cmd.exe in a thread and give it input and read output from it, from the parent. Like, assigning a tty in linux, since there's no such thing in windows. I have a good understanding of linux systems but can't say the same thing about windows.
So, here's "my" code:
#undef UNICODE
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <strsafe.h>
//using namespace std;
#define BUFFER_SIZE 99
// handles for cmd thread pipes
HANDLE cmd_in_rd = NULL;
HANDLE cmd_in_wr = NULL;
HANDLE cmd_out_rd = NULL;
HANDLE cmd_out_wr = NULL;
HANDLE cmd_thread_handle;
void PrintError(char *text, int err) {
DWORD retSize;
LPTSTR pTemp = NULL;
if (!err) return;
retSize = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_ARGUMENT_ARRAY,
NULL,
err,
LANG_NEUTRAL,
(LPTSTR)&pTemp,
0,
NULL);
if (pTemp) printf("%s: %s\n", text, pTemp);
LocalFree((HLOCAL)pTemp);
return;
}
int pipewrite(char *command) {
DWORD dwRead, dwWritten;
BOOL bSuccess = FALSE;
SetLastError(0);
WriteFile(cmd_in_wr, command, strlen(command), &dwWritten, NULL);
bSuccess = GetLastError();
PrintError("WriteToPipe", bSuccess);
return (bSuccess == 0) || (bSuccess == ERROR_IO_PENDING);
}
int __stdcall cmd_thread(int arg) {
// this function only prints when data is ready
DWORD dwRead, dwWritten;
CHAR chBuf[BUFFER_SIZE];
BOOL bSuccess = FALSE;
HANDLE hParentStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
int rf_ret, wf_ret;
//CloseHandle(cmd_out_wr); makes readfile fail!!
SetLastError(0);
while (1) { // only executes once!!!!!!!
(rf_ret = ReadFile(cmd_out_rd, chBuf, BUFFER_SIZE, &dwRead, NULL))
&&
(wf_ret = WriteFile(hParentStdOut, chBuf, dwRead, &dwWritten, NULL));
printf("ReadFile returned: %d\nWriteFile returned: %d\n", rf_ret, wf_ret);
bSuccess = GetLastError();
PrintError("ReadingFromPipe", bSuccess);
}
bSuccess = GetLastError();
return (bSuccess == 0) || (bSuccess == ERROR_IO_PENDING);
}
int main(void) {
char buffer[BUFFER_SIZE];
// init the pipes
SECURITY_ATTRIBUTES cmd_sa;
cmd_sa.nLength = sizeof(SECURITY_ATTRIBUTES);
cmd_sa.bInheritHandle = TRUE;
cmd_sa.lpSecurityDescriptor = NULL;
if (!CreatePipe(&cmd_out_rd, &cmd_out_wr, &cmd_sa, 0)) {
printf("%s\n", "Error creating pipes");
return 1;
}
if (!SetHandleInformation(cmd_out_rd, HANDLE_FLAG_INHERIT, 0)) {
printf("%s\n", "Error setting handle infos");
return 1;
}
if (!CreatePipe(&cmd_in_rd, &cmd_in_wr, &cmd_sa, 0)) {
printf("%s\n", "Error creating pipes");
return 1;
}
if (!SetHandleInformation(cmd_in_rd, HANDLE_FLAG_INHERIT, 0)) {
printf("%s\n", "Error setting handle infos");
return 1;
}
// create the cmd thread
PROCESS_INFORMATION cmd_pi;
STARTUPINFO cmd_si;
ZeroMemory(&cmd_pi, sizeof(PROCESS_INFORMATION));
ZeroMemory(&cmd_si, sizeof(STARTUPINFO));
cmd_si.cb = sizeof(STARTUPINFO);
cmd_si.hStdError = cmd_out_wr;
cmd_si.hStdOutput = cmd_out_wr;
cmd_si.hStdInput = cmd_in_rd;
cmd_si.dwFlags |= STARTF_USESTDHANDLES;
TCHAR comm[] = TEXT("cmd.exe");
BOOL th = CreateProcess(NULL,
comm,
NULL,
NULL,
TRUE, // handles are inherited
0,
NULL,
NULL,
&cmd_si,
&cmd_pi);
if (th) {
CloseHandle(cmd_pi.hProcess);
CloseHandle(cmd_pi.hThread);
}
cmd_thread_handle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)cmd_thread, NULL, 0, NULL);
// read commands from shell and send them to cmd
ZeroMemory(&buffer, BUFFER_SIZE);
while (1) {
fgets(buffer, BUFFER_SIZE, stdin);
if (!pipewrite(buffer)) break;
}
printf("Program terminated\n");
return 0;
}
I actually, for testing purposes, copied a lot from another question on stackoverflow and from MSDN since i couldn't get it to work on my main program. The things I don't understand are:
Why the while loop inside cmd_thread gets executed at startup and then hangs there waiting for the end of the world? I tried to close the pipe out_write handle from the parent before reading, but that makes other parts not working.
pipewrite() seems to work, but I can't be sure that the cmd.exe thread receives and works the input... Since i get no output :/
I thought about stracing/ltracing the program or running it into a debugger, but I know no tool for that...
The strange thing is that the original works (the one from where i got the code). I tried to spot the difference between the two, but even when I look to them side by side, they seem to do the exact same things.
The child process is dying as soon as it attempts to read from standard input, because:
if (!SetHandleInformation(cmd_in_rd, HANDLE_FLAG_INHERIT, 0)) {
This should have been:
if (!SetHandleInformation(cmd_in_wr, HANDLE_FLAG_INHERIT, 0)) {
like in the original code.
Also, your error handling is largely incorrect; you don't consistently check for errors and you sometimes call GetLastError() when no error has occurred. (Those problems are in the original code too.)
You also need to put the call to CloseHandle(cmd_out_wr); back in because otherwise you won't be able to tell when the child exits.
Oh, and incidentally, cmd.exe is a process, not a thread.
I found this code on the Internet but it says that is to be run on Windows XP.
I tried to run it on Windows 7 and it worked, but I wonder if it is safe, not just running this code, but also doing it on Windows 7.
//
// Self-deleting exe under Windows XP
//
#include <windows.h>
#include <tchar.h>
// get this right!
#define EXPLORER_PID 1444
typedef UINT (WINAPI * WAIT_PROC)(HANDLE, DWORD); // WaitForSingleObject
typedef BOOL (WINAPI * CLOSE_PROC)(HANDLE); // CloseHandle
typedef BOOL (WINAPI * DELETE_PROC)(LPCTSTR); // DeleteFile
typedef VOID (WINAPI * EXIT_PROC)(DWORD); // ExitProcess
typedef struct
{
WAIT_PROC fnWaitForSingleObject;
CLOSE_PROC fnCloseHandle;
DELETE_PROC fnDeleteFile;
EXIT_PROC fnExitProcess;
HANDLE hProcess;
TCHAR szFileName[MAX_PATH];
} INJECT;
#pragma optimize("gsy", off)
#pragma check_stack(off) // doesn't work :-(
DWORD WINAPI RemoteThread(INJECT *remote)
{
remote->fnWaitForSingleObject(remote->hProcess, INFINITE);
remote->fnCloseHandle(remote->hProcess);
remote->fnDeleteFile(remote->szFileName);
remote->fnExitProcess(0);
return 0;
}
#pragma check_stack
HANDLE GetRemoteProcess()
{
STARTUPINFO si = { sizeof(si) };
PROCESS_INFORMATION pi;
//return OpenProcess(PROCESS_ALL_ACCESS, FALSE, EXPLORER_PID);
if(CreateProcess(0, "explorer.exe", 0, 0, FALSE, CREATE_SUSPENDED|CREATE_NO_WINDOW|IDLE_PRIORITY_CLASS, 0, 0, &si, &pi))
{
CloseHandle(pi.hThread);
return pi.hProcess;
}
else
{
return 0;
}
}
PVOID GetFunctionAddr(PVOID func)
{
#ifdef _DEBUG
// get address of function from the JMP <relative> instruction
DWORD *offset = (BYTE *)func + 1;
return (PVOID)(*offset + (BYTE *)func + 5);
#else
return func;
#endif
}
BOOL SelfDelete()
{
INJECT local, *remote;
BYTE *code;
HMODULE hKernel32;
HANDLE hRemoteProcess;
HANDLE hCurProc;
DWORD dwThreadId;
HANDLE hThread = 0;
char ach[80];
hRemoteProcess = GetRemoteProcess();
if(hRemoteProcess == 0)
return FALSE;
// Allocate memory in remote process
code = VirtualAllocEx(hRemoteProcess, 0, sizeof(INJECT) + 128, MEM_RESERVE|MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if(code == 0)
{
CloseHandle(hRemoteProcess);
return FALSE;
}
hKernel32 = GetModuleHandle(_T("kernel32.dll"));
// setup remote structure
remote = (INJECT *)(code + 128);
local.fnWaitForSingleObject = (WAIT_PROC)GetProcAddress(hKernel32, "WaitForSingleObject");
local.fnCloseHandle = (CLOSE_PROC)GetProcAddress(hKernel32, "CloseHandle");
local.fnExitProcess = (EXIT_PROC)GetProcAddress(hKernel32, "ExitProcess");
#ifdef UNICODE
local.fnDeleteFile = (DELETE_PROC)GetProcAddress(hKernel32, "DeleteFileW");
#else
local.fnDeleteFile = (DELETE_PROC)GetProcAddress(hKernel32, "DeleteFileA");
#endif
// duplicate our own process handle for remote process to wait on
hCurProc = GetCurrentProcess();
DuplicateHandle(hCurProc, hCurProc, hRemoteProcess, &local.hProcess, 0, FALSE, DUPLICATE_SAME_ACCESS);
// find name of current executable
GetModuleFileName(NULL, local.szFileName, MAX_PATH);
// write in code to execute, and the remote structure
WriteProcessMemory(hRemoteProcess, code, GetFunctionAddr(RemoteThread), 128, 0);
WriteProcessMemory(hRemoteProcess, remote, &local, sizeof(local), 0);
wsprintf(ach, "%x %x\n", code, remote);
OutputDebugString(ach);
// execute the code in remote process
hThread = CreateRemoteThread(hRemoteProcess, 0, 0, code, remote, 0, &dwThreadId);
if(hThread != 0)
{
CloseHandle(hThread);
}
return TRUE;
}
int main(void)
{
SelfDelete();
return 0;
}
By the way, how could this be used as a library in C/C++?
My goal is to just use, for example,
#include "selfdel.h" so I can use just the function SelfDelete() in a C++ program.
You should realize what this code is. It's an injection of a code into another process which will be executed as that process and then the process will exit. It should just work (though look at the comments below). I think the author of this code snippet had written it before Win Vista was released, therefore the concern you have.
You can declare SelfDelete() in your "selfdel.h". Calling this function and exiting right away should do the trick.
The implementation doesn't require any input from user of the library since it gets everything it needs.
// duplicate our own process handle for remote process to wait on
hCurProc = GetCurrentProcess();
...
// find name of current executable
GetModuleFileName(NULL, local.szFileName, MAX_PATH);
Some comments:
Your process should have enough rights to create the other one
Such activity may be treated as suspicious by anti-virus software
Don't forget that "zombie" process will wait as long as your process lives after calling SelfDelete()
Consider other approaches: How can a program delete its own executable
I try to use information from this post: https://stackoverflow.com/a/251267/393087
And the code I came up with is:
HANDLE hToken;
OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES, &hToken);
DWORD dwSize;
TOKEN_INFORMATION_CLASS tokenInformationClass;
GetTokenInformation(hToken, tokenInformationClass, NULL, sizeof(TOKEN_INFORMATION_CLASS), &dwSize);
Ok, so I got TOKEN_INFORMATION_CLASS, but how to get from this to PSID that ConvertSidToStringSid() needs ? There is nowhere PSID word in tic manual page ( http://msdn.microsoft.com/en-us/library/windows/desktop/aa379626(v=vs.85).aspx ).
Well actually this is trivial. Pick whatever token information class you want (my guess is you want TokenUser) and then make sure you pass the matching TOKEN_USER struct to GetTokenInformation, then reach into the TOKEN_USER struct to access TOKEN_USER::User::Sid to get the PSID.
Of course you may also want another token information class, but the principle is the same. Complete sample program (compiled as .cpp file in MSVC):
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0500
#endif
#include <stdio.h>
#include <tchar.h>
#include <Windows.h>
#include <Sddl.h> // for ConvertSidToStringSid()
BOOL printTokenUserSid(HANDLE hToken)
{
PTOKEN_USER ptu = NULL;
DWORD dwSize = 0;
if(!GetTokenInformation(hToken, TokenUser, NULL, 0, &dwSize)
&& ERROR_INSUFFICIENT_BUFFER != GetLastError())
{
return FALSE;
}
if(NULL != (ptu = (PTOKEN_USER)LocalAlloc(LPTR, dwSize)))
{
LPTSTR StringSid = NULL;
if(!GetTokenInformation(hToken, TokenUser, ptu, dwSize, &dwSize))
{
LocalFree((HLOCAL)ptu);
return FALSE;
}
if(ConvertSidToStringSid(ptu->User.Sid, &StringSid))
{
_tprintf(_T("%s\n"), StringSid);
LocalFree((HLOCAL)StringSid);
LocalFree((HLOCAL)ptu);
return TRUE;
}
LocalFree((HLOCAL)ptu);
}
return FALSE;
}
int _tmain(int argc, _TCHAR* argv[])
{
HANDLE hToken = NULL;
if(OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, FALSE, &hToken)
|| OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
{
if(!printTokenUserSid(hToken))
{
_tprintf(_T("Something failed, Win32 error: %d\n"), GetLastError());
}
CloseHandle(hToken);
}
return 0;
}
I am currently writing a very lightweight program so I have to use C++ since it is not bound to .NET framework which drastically increases size of the program.
I need to be able to terminate process and to do that I need to get a process handle. Unfortuanately I haven't figured how to do that yet.
P.S. I know that to kill a process you have to use TerminateProcess.
The following code works:
const auto explorer = OpenProcess(PROCESS_TERMINATE, false, process_id);
TerminateProcess(explorer, 1);
CloseHandle(explorer);
The PID you need for OpenProcess() is not normally easy to get a hold of. If all you got is a process name then you need to iterate the running processes on the machine. Do so with CreateToolhelp32Snapshot, followed by Process32First and loop with Process32Next. The PROCESSENTRY32.szExeFile gives you the process name (not path!), th32ProcessID gives you the PID.
The next consideration is that the process may appear more than once. And there's a chance that the same process name is used for very different programs. Like "Setup". If you don't just want to kill them all, you'll need to try to obtain some runtime info from them. Window caption bar text, perhaps. GetProcessImageFileName() can give you the path to the .exe. It uses the native kernel format, you'd need QueryDosDevice to map a disk drive device name to a drive letter.
The next consideration is the rights you ask for in OpenProcess(). You are unlikely to get PROCESS_ALL_ACCESS, all you need is PROCESS_TERMINATE. Although that's privileged as well. Ensure the account you use to run your program can obtain that right.
Rather than going through all that pain to kill a process with a known name, why not simply call out to "system" and ask the command-line to kill it?
For example,
int retval = ::_tsystem( _T("taskkill /F /T /IM MyProcess.exe") );
To get a handle to pass to TerminateProcess, use OpenProcess in combination with some other function like EnumProcesses.
Here is the full example for Visual Studio 2010 C++ project how to kill the process by the EXE file name.
In order to check it just run Internet Explorer and after this execute following code.
#include <iostream>
#include <string>
#include<tchar.h>
#include <process.h>
#include <windows.h>
#include <tlhelp32.h>
using namespace std;
// Forward declarations:
BOOL GetProcessList();
BOOL TerminateMyProcess(DWORD dwProcessId, UINT uExitCode);
int main( void )
{
GetProcessList( );
return 0;
}
BOOL GetProcessList( )
{
HANDLE hProcessSnap;
HANDLE hProcess;
PROCESSENTRY32 pe32;
DWORD dwPriorityClass;
// Take a snapshot of all processes in the system.
hProcessSnap = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
if( hProcessSnap == INVALID_HANDLE_VALUE )
{
return( FALSE );
}
// Set the size of the structure before using it.
pe32.dwSize = sizeof( PROCESSENTRY32 );
// Retrieve information about the first process,
// and exit if unsuccessful
if( !Process32First( hProcessSnap, &pe32 ) )
{
CloseHandle( hProcessSnap ); // clean the snapshot object
return( FALSE );
}
// Now walk the snapshot of processes
do
{
string str(pe32.szExeFile);
if(str == "iexplore.exe") // put the name of your process you want to kill
{
TerminateMyProcess(pe32.th32ProcessID, 1);
}
} while( Process32Next( hProcessSnap, &pe32 ) );
CloseHandle( hProcessSnap );
return( TRUE );
}
BOOL TerminateMyProcess(DWORD dwProcessId, UINT uExitCode)
{
DWORD dwDesiredAccess = PROCESS_TERMINATE;
BOOL bInheritHandle = FALSE;
HANDLE hProcess = OpenProcess(dwDesiredAccess, bInheritHandle, dwProcessId);
if (hProcess == NULL)
return FALSE;
BOOL result = TerminateProcess(hProcess, uExitCode);
CloseHandle(hProcess);
return result;
}
Imagine in C# it looks like
using System;
using System.Collections.Generic;
using System.Text;
namespace MyProcessKiller
{
class Program
{
static void Main(string[] args)
{
foreach (System.Diagnostics.Process myProc in System.Diagnostics.Process.GetProcesses())
{
if (myProc.ProcessName == "iexplore")
{
myProc.Kill();
}
}
}
}
}
windows only
system("taskkill /f /im servicetokill.exe")
Here are some working sample codes to kill a process called "ShouldBeDead.exe":
// you will need these headers, and you also need to link to Psapi.lib
#include <tchar.h>
#include <psapi.h>
...
// first get all the process so that we can get the process id
DWORD processes[1024], count;
if( !EnumProcesses( processes, sizeof(processes), &count ) )
{
return false;
}
count /= sizeof(DWORD);
for(unsigned int i = 0; i < count; i++)
{
TCHAR szProcessName[MAX_PATH] = TEXT("<unknown>");
if(processes[i] != 0)
{
// remember to open with PROCESS_ALL_ACCESS, otherwise you will not be able to kill it
HANDLE hProcess = OpenProcess( PROCESS_ALL_ACCESS, FALSE, processes[i] );
if(NULL != hProcess)
{
HMODULE hMod;
DWORD cbNeeded;
if(EnumProcessModules(hProcess, &hMod, sizeof(hMod), &cbNeeded))
{
GetModuleBaseName(hProcess, hMod, szProcessName, sizeof(szProcessName)/sizeof(TCHAR));
// find the process and kill it
if(strcmp(szProcessName, "ShouldBeDead.exe") == 0)
{
DWORD result = WAIT_OBJECT_0;
while(result == WAIT_OBJECT_0)
{
// use WaitForSingleObject to make sure it's dead
result = WaitForSingleObject(hProcess, 100);
TerminateProcess(hProcess, 0);
}
CloseHandle(hProcess);
}
}
}
}
}
CreateProcess and OpenProcess return process handles.
Here's some sample code to find a process by asking the system to list all processes and then searching the list for the process you want.
Task Killer using Modern C++
Below is the code I've created for my Terminator Program
//_____________________________________________
// |
// TheNexGen of Terminator (inclusion version) |
// ------------------------------------------- |
// |
// Add your Programs in the 'if' check as I've |
// listed below, and compile using c++17 flag |
// or higher |
//_____________________________________________|
#include <process.h>
#include <windows.h>
#include <tlhelp32.h>
#include <string_view>
using namespace std;
int main()
{
HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hProcessSnap == INVALID_HANDLE_VALUE) return 0;
PROCESSENTRY32W pe32{ .dwSize = sizeof(PROCESSENTRY32) };
if (!Process32First(hProcessSnap, &pe32)) return CloseHandle(hProcessSnap), 0;
do
{
wstring_view str = pe32.szExeFile;
if
(
str == L"chrome.exe"
|| str == L"AAM Update Notifier.exe"
|| str == L"About.exe"
|| str == L"ActionCenterDownloader.exe"
|| str == L"adb.exe"
|| str == L"AdobeARM.exe"
)
{
if (HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, 0, pe32.th32ProcessID))
{
TerminateProcess(hProcess, 1);
CloseHandle(hProcess);
}
}
}
while (Process32Next(hProcessSnap, &pe32));
CloseHandle(hProcessSnap);
}
Description
Increased Execution Speed 100x of the Code provided by #DmitryBoyko.