65.9K
CodeProject 正在变化。 阅读更多。
Home

进程挂起器和高级终止器

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.94/5 (10投票s)

2012 年 3 月 5 日

CPOL

3分钟阅读

viewsIcon

55359

downloadIcon

4953

本文档介绍了使用非托管 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 盘里,并在我朋友的感染系统中启动它,列出了所有那些恶意进程,然后执行了“终止”。在稍微修改了一些注册表值后,他的电脑恢复了正常……

© . All rights reserved.