进程挂起器和高级终止器






4.94/5 (10投票s)
本文档介绍了使用非托管 API 来挂起和终止进程的方法。
引言
回想我的大学时代,我记得我手动对抗病毒的方式。当我杀死第一个病毒时,第二个病毒会重新启动它,反之亦然。在基于 XP 的系统上,默认情况下几乎没有工具可以挂起任何进程。即使今天,如果我们想立即挂起多个进程,也是不可能的。我很抱歉延迟了发布,但我几年前(在控制台子系统中,使用非托管代码)设计了这个软件,但一直没有时间发布。我使用这个应用程序来清除病毒,限制数据占用大的 MS 进程等。
背景
在 Windows 系统上,进程可以作为单线程运行,也可以包含多个同时运行的线程。因此,要挂起一个进程,前提是挂起与其关联的所有线程。在 .NET 中,我没有找到任何现成的设施来挂起线程。因此,我切换到 WinAPI 来实现这个目的。
Using the Code
代码内容并不庞大,只有几个小文件。一个用于 GUI 事件处理,另一个用于 Win32 函数的声明。我基本上会避免讨论 GUI 部分,因为我们大多数人都已经了解它。如果有人不理解设计,我建议在 VS 中打开这个项目并遍历代码。
在应用程序的左侧是一个 ListBox,其中包含进程名称和以逗号分隔的进程 ID。使用“移动”按钮,我们可以将选定的进程从左侧 ListBox 移动到右侧 ListBox。操作(挂起、恢复、终止)将仅对右侧 ListBox 中列出的进程执行。
一旦用户打开应用程序,所有进程都会自动填充到右侧 ListBox 中,但除非使用“刷新”按钮手动完成,否则它们不会被刷新。
要获取正在运行的进程列表,以下是代码示例
Process[] prcs = Process.GetProcesses();
Plist.Items.Clear();
foreach (Process pn in prcs)
{
Plist.Items.Add(String.Format("{0}, ({1})",pn.ProcessName, pn.Id ));
}
现在我们感兴趣的唯一内容是 pn.Id(进程 ID)
。有了它,我们可以做任何我们想做的事情。
我们将把这个 pn.Id
传递给线程挂起例程。在挂起例程内部,Process.Thread
会给出线程集合。通过枚举线程集合,可以将每个线程置于停止状态。
SuspendThread
函数会挂起线程,直到它被 ResumeThread
指示恢复为止。
提供了一个简短的代码视图,用于声明和使用挂起和恢复例程。
using System.Runtime.InteropServices;
using System.Diagnostics;
class KernelCalls
{
[DllImport("kernel32.dll")]
static extern IntPtr OpenThread(Int32 dwDesiredAccess,
bool bInheritHandle, UInt32 dwThreadId);
//http://msdn.microsoft.com/en-us/library/windows/desktop/ms684335(v=vs.85).aspx
[DllImport("kernel32.dll")]
static extern UInt32 SuspendThread(IntPtr hThread);
[DllImport("kernel32.dll")]
static extern UInt32 ResumeThread(IntPtr hThread);
foreach (ProcessThread procthr in proc.Threads)
{
IntPtr pOpenThread = OpenThread(0x0002, false, (UInt32)procthr.Id);
if (pOpenThread == IntPtr.Zero)
{
break;
}
SuspendThread(pOpenThread);
}
}
在此之后,唯一需要做的事情就是设置 GUI 逻辑。在实现 GUI 处理例程后,应用程序就可以启动了。
关注点
虽然代码看起来用处不大,但假设一种情况,病毒感染了系统
- 不允许你打开 cmd、regedit、任务管理器等。
- 如果你设法杀死了第一个病毒进程,第二个关联的病毒进程会重新启动它。
你会怎么做????!!!!!!!!!!!
当我第一次遇到这种情况时,我就是这么做的。我制作了这个程序,把它放在了 U 盘里,并在我朋友的感染系统中启动它,列出了所有那些恶意进程,然后执行了“终止”。在稍微修改了一些注册表值后,他的电脑恢复了正常……