Write process/thread Monitor

Source: Internet
Author: User

Author: sinister
Email: sinister@whitecell.org
Homepage: http://www.whitecell.org

(Describe it first. Many may ask how some process/thread monitoring tools are implemented.
I wrote it to give those friends a better understanding and save my mails. If you
If you are familiar with the NT driver, you may have mastered the method mentioned in this article and can skip it .)

Sometimes we want to dynamically monitor the creation and destruction of any process/thread in the system. To achieve
For this purpose, I have read the DDK manual and found the pssetcreateprocesspolicyroutine () provided by it (),
Pssetcreatethreadpolicyroutine (), and other functions can implement this function. These two functions can

Register a callbalck function with the system to monitor processes, threads, and other operations. The original function is as follows:

NTSTATUS    PsSetCreateProcessNotifyRoutine(    IN PCREATE_PROCESS_NOTIFY_ROUTINE   NotifyRoutine,    IN BOOLEAN   Remove    ); VOID (*PCREATE_PROCESS_NOTIFY_ROUTINE) (      IN HANDLE   ParentId,      IN HANDLE   ProcessId,      IN BOOLEAN   Create      ); NTSTATUS    PsSetCreateThreadNotifyRoutine(    IN PCREATE_THREAD_NOTIFY_ROUTINE   NotifyRoutine    ); VOID (*PCREATE_THREAD_NOTIFY_ROUTINE) (      IN HANDLE   ProcessId,      IN HANDLE   ThreadId,      IN BOOLEAN   Create      );

The original form shows that the callback function only provides the process ID/thread ID. Not provided
Process name. Then we need to further obtain the process name through the process ID. This requires an undisclosed
Function pslookupprocessbyprocessid (). The original function is as follows:

NTSTATUS PsLookupProcessByProcessId(       IN ULONG ulProcId,        OUT PEPROCESS * pEProcess       );

The eprocess structure of function output is also an undisclosed kernel process structure. Many people call it kpeb.
The offset 0x1fc in the eprocess structure points to the offset of the current process name. (Although this structure can be found in
Directly used in the driver. However, its structure has not been published. Many experts on the Internet have already provided its structure. Yes
If you are interested, you can search by yourself or get it from ifs DDK. The structure is too long, so you will not post it here)
With this structure, we can get the process name. The NT System also provides a function for dynamic monitoring.
Load the image according to the process. This function can obtain the DLL name and full path called when the process is planted.
Some image information. It provides us with more detailed process loading information and better help.

The original function is as follows:

NTSTATUS    PsSetLoadImageNotifyRoutine(    IN PLOAD_IMAGE_NOTIFY_ROUTINE   NotifyRoutine    ); VOID (*PLOAD_IMAGE_NOTIFY_ROUTINE) (      IN PUNICODE_STRING   FullImageName,      IN HANDLE   ProcessId, // where image is mapped      IN PIMAGE_INFO   ImageInfo      ); typedef struct   _IMAGE_INFO {      union {          ULONG   Properties;          struct {              ULONG ImageAddressingMode   : 8; //code addressing mode              ULONG SystemModeImage       : 1; //system mode image              ULONG ImageMappedToAllPids : 1; //mapped in all processes              ULONG Reserved              : 22;          };      };      PVOID   ImageBase;      ULONG   ImageSelector;      ULONG   ImageSize;      ULONG   ImageSectionNumber; } IMAGE_INFO, *PIMAGE_INFO;

With the functions and structures provided above, we can implement a process/thread monitor. The following section
The Code demonstrates how to implement this function.

/*************************************** * ************************* File Name: wssprocmon. c Description: Process/thread monitor Author: sinister last modification date: *************************************** * *************************/# include "ntddk. H "# include" string. H "# define processnameoffset 0x1fc static ntstatus mydrvdispatch (in pdevice_object deviceobject, in pirirp IRP); ntstatus pslookupprocessbyprocessid (in ulong ulproci D, out peprocess * peprocess); void processcreatemon (in handle hparentid, in handle PID, in Boolean bcreate); void threadcreatemon (in handle PID, in handle tid, in Boolean bcreate ); void imagecreatemon (in punicode_string fullimagename, in handle processid, in pimage_info imageinfo); // driver entry ntstatus DriverEntry (in pdriver_object driverobject, in punicode_string registrypath) {unicode_string Namestring, linkstring; pdevice_object deviceobject; ntstatus status; int I; // create a device rtlinitunicodestring (& namestring, l "\ device \ wssprocmon"); status = iocreatedevice (driverobject, 0, & namestring, file_device_unknown, 0, true, & deviceobject); If (! Nt_success (Status) return status; rtlinitunicodestring (& linkstring, l "\ dosdevices \ wssprocmon"); status = iocreatesymboliclink (& linkstring, & namestring); If (! Nt_success (Status) {iodeletedevice (driverobject-> deviceobject); Return status;} status = pssetloadimagenotifyroutine (imagecreatemon); If (! Nt_success (Status) {dbuplint ("pssetloadimagenotifyroutine () \ n"); Return status;} status = pssetcreatethreadpolicyroutine (threadcreatemon); If (! Nt_success (Status) {dbuplint ("pssetcreatethreadpolicyroutine () \ n"); Return status ;}status = pssetcreateprocesspolicyroutine (processcreatemon, false); If (! Nt_success (Status) {dbuplint ("pssetcreateprocesspolicyroutine () \ n"); Return status ;}for (I = 0; I <irp_mj_maximum_function; I ++) {driverobject-> majorfunction [I] = mydrvdispatch;} return STATUS_SUCCESS;} // process static ntstatus mydrvdispatch (in pdevice_object deviceobject, in pirp) {IRP-> iostatus. status = STATUS_SUCCESS; IRP-> iostatus. information = 0l; iocompleterequest (IRP, 0); Return IRP-> iostatus. status;} void processcreatemon (in handle hparentid, in handle PID, in Boolean bcreate) {peprocess eprocess; ulong ulcurrentprocessid; lptstr lpcurproc; ntstatus; status = running (ulong) PID, & eprocess); If (! Nt_success (Status) {dbuplint ("pslookupprocessbyprocessid () \ n"); Return ;}if (bcreate) {lpcurproc = (lptstr) eprocess; lpcurproc = lpcurproc + processnameoffset; dbuplint ("create process = process name: % s, process parentid: % d, process ID: % d, process address % x: \ n", lpcurproc, hparentid, PID, eprocess);} else {dbuplint ("terminated = process ID: % d \ n", pid) ;}} void threadcreatemon (In handle PID, in handle tid, in Boolean bcreate) {peprocess eprocess; ulong ulcurrentprocessid; lptstr lpcurproc; ntstatus status; status = pslookupprocessbyprocessid (ulong) PID, & eprocess ); if (! Nt_success (Status) {dbuplint ("pslookupprocessbyprocessid () \ n"); Return ;}if (bcreate) {lpcurproc = (lptstr) eprocess; lpcurproc = lpcurproc + processnameoffset; dbuplint ("create thread = process name: % s process ID: % d, thread ID: % d \ n", lpcurproc, PID, tid );} else {dbuplint ("terminated = thread ID: % d \ n", tid) ;}} void imagecreatemon (in punicode_string fullimagename, in handle processid, in pimage_info imageinfo) {dbuplint ("fullimagename: % s, process ID: % d \ n", fullimagename-> buffer, processid); dbuplint ("imagebase: % x, imagesize: % d \ n ", imageinfo-> imagebase, imageinfo-> imagesize );}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.