10

We are trying to develop a small application that can monitor the programs/processes that are executing in a windows machine.

If the program/process is not supposed to run, it should be blocked. It works similar to an antivirus.

This is the basic idea.

I want to know the ways to hook into the OS to get notified about every single program/process trying to run in the machine.

Niyaz
  • 53,943
  • 55
  • 151
  • 182

3 Answers3

11

The easiest way is to use WMI. Specifically monitor the Win32_ProcessStartTrace. This is better than Win32_Process, because it is setup to use events whereas Win32_Process requires polling which is more CPU intensive. Below is how to do it in C#. First make sure that System.Management is setup as a reference for your project.

    public System.Management.ManagementEventWatcher mgmtWtch;

    public Form1()
    {
        InitializeComponent();
        mgmtWtch = new System.Management.ManagementEventWatcher("Select * From Win32_ProcessStartTrace");
        mgmtWtch.EventArrived += new System.Management.EventArrivedEventHandler(mgmtWtch_EventArrived);
        mgmtWtch.Start();
    }

    void mgmtWtch_EventArrived(object sender, System.Management.EventArrivedEventArgs e)
    {
        MessageBox.Show((string)e.NewEvent["ProcessName"]);
    }

    private void Form1_FormClosing(object sender, FormClosingEventArgs e)
    {
        mgmtWtch.Stop();
    }

The code will generate a messagebox everytime you launch a new process. From there you can check a whitelist/blacklist and act appropriately.

Rob Haupt
  • 2,104
  • 1
  • 15
  • 24
  • 2
    Unfortunately WMI seems to deliver notifications up to 5 seconds later than the process has been created. Not useful for real-time notifications or doing anything with short-lived tasks. – Vladimir Panteleev Aug 09 '13 at 04:59
  • 1
    I found an example on Microsoft's website for the same task [here](http://msdn.microsoft.com/en-us/library/system.management.managementeventwatcher.waitfornextevent.aspx?cs-save-lang=1&cs-lang=csharp#code-snippet-1), but it has the same problem. – Vladimir Panteleev Aug 09 '13 at 05:08
  • Gah... using WMI is more CPU-intensive than polling the process list manually (it just happens in the WMI service process instead of your process). Furthermore, if your application crashes, the subscription will keep running in the WMI service, sucking CPU... – Vladimir Panteleev Aug 09 '13 at 05:36
0

I havn't tried geting real-time notification. How ever, Here is how to get running processes in C#

using System.Diagnostics;

 //Somewhere in your method

Process[] runningList = Process.GetProcesses();

foreach(Process p in runningList){
Console.WriteLine("Process: {0} ID: {1}", p.ProcessName, p.Id);
}

You can also use the following props of a process

  • StartTime - Shows the time the process started
  • TotalProcessorTime - Shows the amount of CPU time the process has taken
  • Threads - gives access to the collection of threads in the process
amazedsaint
  • 7,642
  • 7
  • 54
  • 83
0

I would check up the Win32-api SetWindowsHookEx with the constant WH_GETMESSAGE to add a callback to your program when a new window is being created.

http://pinvoke.net/default.aspx/user32.SetWindowsHookEx

Google that API and WH_GETMESSAGE to find out more.

Also check out the following articles/code librarys: http://www.vbaccelerator.com/home/Vb/Code/Libraries/Hooks/vbAccelerator_Hook_Library/article.asp

http://www.codeproject.com/KB/DLL/hooks.aspx?fid=2061&df=90&mpp=25&noise=3&sort=Position&view=Quick&fr=76&select=726975

Stefan
  • 11,423
  • 8
  • 50
  • 75