Introduction
Back in my college days, I remember the way I used to manually fight with viruses. When I used to kill the first virus,
a second one restarted it, and vice versa.
On an XP based system one barely had any tool by default to suspend any process. Even today if we want to suspend multiple processes instantaneously, it’s not possible. I am sorry for this delay but I designed this software a few years ago (in
a console subsystem with unmanaged code) but never got time to post it. I used this application to hunt viruses, restrict data voracious MS processes, etc.
Background
On a Windows system, processes may run as single thread or may contain multiple threads running simultaneously. Hence to suspend a process it’s a prerequisite
to suspend all the threads associated with that particular process. In .NET I don’t find any facility already provided to suspend a thread. So I switched to WinAPI for this purpose.
Using the Code
The code contains nothing big but just a couple of small files. One for the GUI event handling and another for the declaration of Win32 functions. I will basically avoid talking about the GUI thing as most of us are already aware of it. If someone is not understanding the design, I’ll suggest opening
this project in VS and iterating through the code.
On the left side of the application is a ListBox containing process name comma separated process ID. Using the move button,
we can fetch the selected processes from the left listbox to the right listbox. Operations (Suspend, Resume, Kill) will only execute
on the processes enlisted in the right listbox.
Once the user opens the application all the processes automatically get populated in the right listbox but they are not refreshed until done manually using
the Refresh button.
To get the list of running processes, following is the code sample:
Process[] prcs = Process.GetProcesses();
Plist.Items.Clear();
foreach (Process pn in prcs)
{
Plist.Items.Add(String.Format("{0}, ({1})",pn.ProcessName, pn.Id ));
}
Now the only thing of our interest is pn.Id(Process Id)
. With this we can do anything we like.
We’ll be passing this pn.Id
to the thread suspending routine. Inside the suspend routine,
Process.Thread
gives out the thread collection. By enumerating the thread collection, each thread can be brought to a halt.
The SuspendThread
function suspends the thread until it is directed to
be resumed by ResumeThread
.
A brief code view is provided for declaring and using the suspending and resuming routines.
using System.Runtime.InteropServices;
using System.Diagnostics;
class KernelCalls
{
[DllImport("kernel32.dll")]
static extern IntPtr OpenThread(Int32 dwDesiredAccess,
bool bInheritHandle, UInt32 dwThreadId);
[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);
}
}
After this the only thing required to be done is setting the GUI logic. After
implementing GUI handling routines the application becomes ready to be launched live.
Points of Interest
Although the code doesn’t look so useful, suppose a condition where a virus infected
the system:
- Doesn’t allow you to open cmd, regedit, Task Manager, etc.
- If somehow you kill the first viral process, the second associated viral process restarts it.
What will you do????!!!!!!!!!!!
That’s what I did when I faced this situation the first time. I made this program, took it in a pen drive, and launched it on my friend’s infected system, enlisted all those ill-natured processes, and fired the "Kill". After a little change in the
Registry values, his computer came back to track…..