Suspender proceso en C#
.net (5)
Aquí está mi sugerencia:
[Flags]
public enum ThreadAccess : int
{
TERMINATE = (0x0001),
SUSPEND_RESUME = (0x0002),
GET_CONTEXT = (0x0008),
SET_CONTEXT = (0x0010),
SET_INFORMATION = (0x0020),
QUERY_INFORMATION = (0x0040),
SET_THREAD_TOKEN = (0x0080),
IMPERSONATE = (0x0100),
DIRECT_IMPERSONATION = (0x0200)
}
[DllImport("kernel32.dll")]
static extern IntPtr OpenThread(ThreadAccess dwDesiredAccess, bool bInheritHandle, uint dwThreadId);
[DllImport("kernel32.dll")]
static extern uint SuspendThread(IntPtr hThread);
[DllImport("kernel32.dll")]
static extern int ResumeThread(IntPtr hThread);
[DllImport("kernel32", CharSet = CharSet.Auto,SetLastError = true)]
static extern bool CloseHandle(IntPtr handle);
private static void SuspendProcess(int pid)
{
var process = Process.GetProcessById(pid);
if (process.ProcessName == string.Empty)
return;
foreach (ProcessThread pT in process.Threads)
{
IntPtr pOpenThread = OpenThread(ThreadAccess.SUSPEND_RESUME, false, (uint)pT.Id);
if (pOpenThread == IntPtr.Zero)
{
continue;
}
SuspendThread(pOpenThread);
CloseHandle(pOpenThread);
}
}
public static void ResumeProcess(int pid)
{
var process = Process.GetProcessById(pid);
if (process.ProcessName == string.Empty)
return;
foreach (ProcessThread pT in process.Threads)
{
IntPtr pOpenThread = OpenThread(ThreadAccess.SUSPEND_RESUME, false, (uint)pT.Id);
if (pOpenThread == IntPtr.Zero)
{
continue;
}
var suspendCount = 0;
do
{
suspendCount = ResumeThread(pOpenThread);
} while (suspendCount > 0);
CloseHandle(pOpenThread);
}
}
¿Cómo puedo suspender todo un proceso (como el Process Explorer cuando hago clic en Suspender) en C #.
Estoy comenzando el Proceso con Process.Start, y en cierto caso, quiero suspender el proceso para poder investigar un "snapshot" de él.
Entonces, realmente, lo que muestran las otras respuestas es suspender el hilo en el proceso, no hay forma de suspender realmente el proceso (es decir, en una llamada) ...
Una solución un poco diferente sería depurar realmente el proceso objetivo que está iniciando, vea el blog de Mike Stall para obtener algunos consejos sobre cómo implementar esto desde un contexto administrado.
Si implementa un depurador, podrá escanear la memoria o qué otras instantáneas desea.
Sin embargo, me gustaría señalar que, técnicamente, ahora hay una manera de realmente hacer esto. Incluso si depura un proceso de depuración de destino, otro proceso en su sistema puede inyectar un hilo y se le dará la posibilidad de ejecutar el código independientemente del estado del proceso objetivo (incluso digamos si llega a un punto de interrupción debido a una violación de acceso) ), si tiene suspendido todo el hilo hasta un conteo de suspensión súper alto, actualmente se encuentra en un punto de quiebre en el hilo de proceso principal y en cualquier otro estado de presunta congelación, aún es posible que el sistema inyecte otro hilo en ese proceso y ejecuta algunas instrucciones. También puede pasar por la molestia de modificar o reemplazar todos los puntos de entrada que el kernel usualmente llama y demás, pero ahora ha ingresado en la raza de MALWARE del brazo viscoso;) ...
En cualquier caso, el uso de las interfaces administradas para la depuración parece ''mucho más fácil que p / invocar una gran cantidad de llamadas a la API nativa, lo que hará un mal trabajo al emular lo que probablemente realmente quieras hacer ... usar depug api''s ;)
Gracias a Magnus
Después de incluir los Flags, modifiqué un poco el código para ser un método de extensión en mi proyecto. Ahora podría usar
var process = Process.GetProcessById(param.PId);
process.Suspend();
Aquí está el código para aquellos que puedan estar interesados.
public static class ProcessExtension
{
[DllImport("kernel32.dll")]
static extern IntPtr OpenThread(ThreadAccess dwDesiredAccess, bool bInheritHandle, uint dwThreadId);
[DllImport("kernel32.dll")]
static extern uint SuspendThread(IntPtr hThread);
[DllImport("kernel32.dll")]
static extern int ResumeThread(IntPtr hThread);
public static void Suspend(this Process process)
{
foreach (ProcessThread thread in process.Threads)
{
var pOpenThread = OpenThread(ThreadAccess.SUSPEND_RESUME, false, (uint)thread.Id);
if (pOpenThread == IntPtr.Zero)
{
break;
}
SuspendThread(pOpenThread);
}
}
public static void Resume(this Process process)
{
foreach (ProcessThread thread in process.Threads)
{
var pOpenThread = OpenThread(ThreadAccess.SUSPEND_RESUME, false, (uint)thread.Id);
if (pOpenThread == IntPtr.Zero)
{
break;
}
ResumeThread(pOpenThread);
}
}
}
Tengo una utilidad que uso para generalmente suspender / matar / enumerar un proceso. La fuente completa está en Git
Puede encontrar una solución detallada usando Win32 p / CodeProject en CodeProject .
Vea este artículo de CodeProject para los conceptos básicos de win32: CodeProject . Este código de ejemplo hace uso de la biblioteca ToolHelp32 del SDK, por lo que recomendaría convertir este código de muestra en una biblioteca no administrada de C ++ / CLI con una interfaz simple como "SuspendProcess (uint processID).
Process.Start le devolverá un objeto de proceso, desde el que puede obtener la identificación del proceso, y luego pasarlo a su nueva biblioteca en función de lo anterior.
Dave