Created
December 3, 2024 02:08
-
-
Save jborean93/c04426e88d62d09f539088f5bd54bc7d to your computer and use it in GitHub Desktop.
PowerShell script that can be used to generate an executable that can send CTRL+C or CTRL+BREAK to a target process by id
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<# | |
This must be run in Windows PowerShell (5.1). This will not work in PowerShell 7.x | |
as Add-Type cannot generate an output executable. | |
#> | |
Add-Type -OutputType ConsoleApplication -OutputAssembly kill.exe -TypeDefinition @' | |
using System; | |
using System.ComponentModel; | |
using System.Runtime.InteropServices; | |
namespace Kill | |
{ | |
public static class Program | |
{ | |
private const int CTRL_C_EVENT = 0; | |
private const int CTRL_BREAK_EVENT = 1; | |
[DllImport("kernel32.dll", SetLastError = true)] | |
[return: MarshalAs(UnmanagedType.Bool)] | |
private static extern bool AttachConsole( | |
int dwProcessId); | |
[DllImport("kernel32.dll", SetLastError = true)] | |
[return: MarshalAs(UnmanagedType.Bool)] | |
private static extern bool GenerateConsoleCtrlEvent( | |
int dwCtrlEvent, | |
int dwProcessGroupId); | |
[DllImport("kernel32.dll", SetLastError = true)] | |
[return: MarshalAs(UnmanagedType.Bool)] | |
private static extern bool FreeConsole(); | |
public static int Main(string[] args) | |
{ | |
string help = "usage: kill.exe pid [-ctrl_c|-ctrl_break]"; | |
if (args.Length == 0 || args.Length > 2) | |
{ | |
string msg = string.Format( | |
"Expecting at least 1 argument for the process id to send the signal to{0}{1}", | |
Environment.NewLine, | |
help); | |
Console.Error.WriteLine(msg); | |
return 1; | |
} | |
else if (args[0].ToLowerInvariant() == "--help") | |
{ | |
Console.WriteLine(help); | |
return 0; | |
} | |
int procId; | |
if (!int.TryParse(args[0], out procId)) | |
{ | |
string msg = string.Format("Failed to parse '{0}' as process id.", args[0]); | |
Console.Error.WriteLine(msg); | |
return 1; | |
} | |
int ctrlEvent = CTRL_C_EVENT; | |
if (args.Length == 2) | |
{ | |
string argSignal = args[1].ToLowerInvariant(); | |
if (argSignal == "-ctrl_break") | |
{ | |
ctrlEvent = CTRL_BREAK_EVENT; | |
} | |
else if (argSignal != "-ctrl_c") | |
{ | |
string msg = string.Format("Invalid ctrl event found '{0}', expected -ctrl_c or -ctrl_break.", args[1]); | |
Console.Error.WriteLine(msg); | |
return 1; | |
} | |
} | |
if (!FreeConsole()) | |
{ | |
int errCode = Marshal.GetLastWin32Error(); | |
string errMsg = new Win32Exception(errCode).Message; | |
string msg = string.Format("Failed to free console 0x{0:X8} - {1}", errCode, errMsg); | |
Console.Error.WriteLine(msg); | |
return errCode; | |
} | |
if (!AttachConsole(procId)) | |
{ | |
int errCode = Marshal.GetLastWin32Error(); | |
string errMsg = new Win32Exception(errCode).Message; | |
string msg = string.Format("Failed to attach console to process {0} 0x{1:X8} - {2}", procId, errCode, errMsg); | |
Console.Error.WriteLine(msg); | |
return errCode; | |
} | |
if (!GenerateConsoleCtrlEvent(ctrlEvent, 0)) | |
{ | |
int errCode = Marshal.GetLastWin32Error(); | |
FreeConsole(); | |
string errMsg = new Win32Exception(errCode).Message; | |
string msg = string.Format("Failed generate ctrl event 0x{0:X8} - {1}", errCode, errMsg); | |
Console.Error.WriteLine(msg); | |
return errCode; | |
} | |
FreeConsole(); | |
return 0; | |
} | |
} | |
} | |
'@ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment