(Reproduced) security and stability implementation of threading monitoring

xiaoxiao2021-03-06  20

Security and stability implementation of threading monitoring

Creation time: 2005-03-24

Article attribute: original

Article submission:

SUEI8423 (SUEI8423_AT_163.COM)

Security and stability implementation of threading monitoring

Author: ZwelL

Using PSSetCreateProcessNotifyRoutine, PSSetCreatethreadNotifyRoutine to make process thread monitoring. I think everyone is already very skilled. Sinister is already very good in << Writing process / thread monitor >> One article is very good. I saw someone on the Internet for a long time. Thread articles, more interesting. Write code to play. There are some problems. For example, if you use the code of the SINISTER, you can't be dynamically uninstalled because he did not carry out that after installation of the threading monitoring function Clearing the action, caused by blue screen when dynamically uninstalled, bugcheck is: driver_unding_without_cancelling_pended_operations. It is clear that some of the incoming operations are still accessed by the original address after the driver exit, causing errors. After XP, Microsoft gives it. A function psremovecreatethreadNotifyRoutine is used to clear the thread monitor function (Clear Process Monitor is pssetCreateProcessNotifyRoutine). I have been strange how IagesWord is in 2000 to make thread monitoring. Later, I discovered that I released a Detport.sys file after running ICESWORD. Then there is no unloading in the system. Just hide it, ^ _ ^. This is not a good news, don't I test it once in order to test a driver, do you try it once? Oh, it is certainly not, so I want to Method gets it.

Let's take a look at how to monitor how the bottom is implemented, and you can find a function of creating a thread first in Win2000 source code:

//

//

// /WIN2K/PRIVATE / NTOS/PS/CREATE.H

//

//

NTSTATUS

PSPCREATTHREAD

...

...

)

{

...

IF (pspcreateprocessNotifyRoutineCount! = 0) {// First call the process monitoring function

Ulong i;

For (i = 0; i

IF (pspcreateprocessNotifyRoutine [i]! = null) {

(* PspcreateprocessNotifyRoutine [i]) (Process-> InheritedFromuniqueProcessID,

Process-> UniqueProcessid,

True

);

}

}

}

}

...

...

IF (pspcreatethreadNotifyRoutineCount! = 0) {

Ulong i;

For (i = 0; i

IF (pspcreatethreadNotifyRoutine [i]! = null) {

(* Pspcreatethreadnotifyroutine [i]) (thread-> Cid.uniqueProcess,

Thread-> Cid.uniquethread,

True

);

}

}

}

...

...

}

As can be seen from the above, the PSPCreateProcessNotifyRoutine [i] address pointed to the PSSetCreatethreadNotifyNeRoutine is the address of the monitoring function when the PSSetCreateThreadNotifyNEROUTINE is set to the PSSetCreateThreadNotifyine [i] array.

NTSTATUS

PSSetcreatethreadNotifyRoutine

In pcreate_thread_notify_routine notifyroutine)

{

Ulong i;

NTSTATUS STATUS;

Status = status_insuffect_resources;

For (i = 0; i

IF (pspcreatethreadnotifyroutine [i] == null) {

PSPCREATTHREADNOTIFYROUTINE [I] = NotifyRoutine;

PSPCREATTHREADNOTIFYROUTINECOUNT = 1;

Status = status_success;

Break;

}

}

Return status;

}

Some of the above structures are as follows:

//

//

// /WIN2K/PRIVATE / NTOS/PS/psp.h

//

//

#define psp_max_create_thread_notify 8 // Maximum number of monitoring

Ulong pspcreatethreadNotifyRoutineCount; // used to record

Pcreate_thread_notify_routine pspcreatethreadNotifyRoutine [PSP_MAX_CREATE_THREAD_NOTIFY]; // Function Address array

Pcreate_thread_notify_routine is defined as follows:

Typedef

Void

(* PCREATE_THREAD_NOTIFY_ROUTINE)

In Handle Processid,

In Handle ThreadID,

In Boolean Create

);

Corresponding, the structure of the process is also the same.

By the above, we can see that as long as we find out the array address, let all of us clearly, clear the size of PSP_MAX_CREATE_THREAD_NOTIFY,

This kind of words will not call this function pointer. Just return the system back to normal, we will verify it through pssetcreateprocessNotifyRoutine:

NTSTATUS

PSsetCreateProcessNotifyRoutine

In pcreate_process_notify_routine notifyroutine,

In Boolean Remove

)

{

Ulong i;

For (i = 0; i

IF (radove) {

IF (pspcreateprocessNotifyRoutine [i] == notifyroutine) {// is simple to set up

PSPCreateProcessNotifyRoutine [i] = null;

PSpCreateProcessNotifyRoutineCount - = 1; // minus the counter

Return status_success;

}

} else {

IF (pspcreateprocessNotifyRoutine [i] == null) {// setting is also a simple assignment operation

PSpCreateProcessNotifyRoutine [i] = notifyroutine;

PSpCreateProcessNotifyRoutineCount = 1; // Pick up the counter

Return status_success;

}

}

}

RETURN Remove? status_procedure_not_found: status_invalid_parameter;}

Ok, the method has already known, as long as you find the address, we can "retreat". Look at the PSRemoveCreatethreadNotifyRETHREADNOTINEROTINE implementation under Windows2003:

LKD> u psremovecreatethreadNotifyRoutine L 20

Nt! psremovecreatethreadnotifyRoutine:

80651D7B 53 Push EBX

80651D7C 56 Push ESI

80651D7D 57 Push EDI

80651D7E 33DB XOR EBX, EBX

80651D80 BF400F5780 MOV EDI, 0x80570F40 // start address

80651D85 57 Push EDI

80651D86 E8A7500100 Call Nt! EXWAITFORRUNDOWNPROTECTIONRELEASE 0X5CF (80666E32)

80651D8B 8BF0 MOV ESI, EAX

80651D8D 85F6 Test ESI, ESI

80651D8F 7420 JZ NT! PSRemovecreatethreadNotifyRoutine 0x36 (80651DB1)

80651D91 56 Push ESI

80651D92 E8BA1BFFFF CALL NT! IOREPORTTARGETDEVICECHANGE 0X7AA0 (80643951)

80651D97 3B442410 CMP EAX, [ESP 0x10]

80651D9B 750D JNZ NT! PSRemovecreatethreadNotifyRoutine 0x2F (80651DAA)

80651D9D 56 Push ESI

80651D9E 6A00 PUSH 0x0

80651DA0 57 Push EDI

80651DA1 E8C54F0100 Call NT! EXWAITFORRUNDOWNPROTECTIONRELEASE 0X508 (80666D6B)

80651DA6 84C0 TEST Al, Al

80651DA8 751B JNZ NT! PSRemoveCreatethreadNotifyRoutine 0x4a (80651DC5)

80651DAA 56 PUSH ESI

80651DAB 57 Push EDI

80651DAC E892510100 Call NT! EXWAITFORRUNDOWNPROTECTIONRELEASE 0x6E0 (80666F43)

80651DB1 43 Inc EBX

80651DB2 83C704 Add EDI, 0x4

80651DB5 83FB08 CMP EBX, 0x8 // See if the maximum number (8)

80651db8 72cb jb nt! PsremovecreatethreadNotifyROUTINE 0XA (80651D85)

80651DBA B87A0000C0 MOV EAX, 0xC000007A80651DBF 5F POP EDI

80651DC0 5E POP ESI

80651DC1 5B POP EBX

80651DC2 C20400 RET 0x4

LKD> DD 0x80570F40 // After the monitor function is set

80570F40 E316E557 000000000000000000000000

.............................

LKD> DD 0x80570F40 // After the monitoring function is cleared

80570F40 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

Haha. Below is the implementation code, the code is implemented in the code, and the high thread monitor is realized:

Drivers.c

/

//

// Made by Zwell

#include "ntddk.h"

#include "windef.h"

#include "define.h"

#define sysname "system"

#define VersionLen 100

Const Wchar Devlink [] = L "// ?? // myevent";

Const wchar devname [] = l "// device // myevent";

Unicode_String DevnameUnic;

Unicode_String Devlinkunicd;

Pvoid ​​gpeventObject = null; // EVENT object communication with the application

Ulong processNameOffset = 0;

PVOID OUTBUF [255];

Bool g_bmainthread;

Ulong g_dwparentId;

Checklist checklist;

Ulong buildnumber; // system version number

Ulong systemID; // system process ID

PWchar Version [VersionLen];

NTSTATUS PSLOOKUPPROCESSBYPROCESSID (IN ULONG ULPROCID, OUT Peprocess * peprocess);

Ulong getProcessNameOffset ()

{

Peprocess curproc;

INT I;

Curproc = psgetcurrentprocess ();

For (i = 0; i <3 * Page_size; i )

{

IF (! Strncmp (sysname, (pchar) Curproc i, Strlen (sysname)))

{

Return I;

}

}

Return 0;

}

NTSTATUS GETREGVALUE (Pcwstr Regpath, PCWSTR VALUENAME, PWCHAR VALUE)

{

Int returnvalue = 0;

NTSTATUS STATUS;

Object_attributes objectattribute;

Handle KeyHandle;

PKEY_VALUE_PARTIAL_INFORMATION VALUEINFOP;

Ulong valueInfolength, returngength;

UNICODE_STRING UNICODEREGPATH;

Unicode_String UnicodeValuename;

RTLinitunicodeString (& UnicodeRegpath, Regpath);

RTLinitunicodeString (& UnicodeValuename, VALUENAME);

InitializeObjectAttributes (& ObjectAttributes,

& UnicodeRegPath,

Obj_case_insensitive, // Flags

Null, // root Directory

NULL); // Security Descriptor

Status = zwopenkey (& KeyHandle,

Key_all_access,

& Objectattributes;

IF (status! = status_success)

{

DBGPrint ("ZwopenKey Wrong / N);

Return 0;

}

ValueInfolength = SIZEOF (key_value_partial_information) VersionLen;

ValueInfop = (PKEY_VALUE_PARTIAL_INFORMATION) EXALLOCATEPOOL

(NonpagedPool, ValueInfolength);

Status = ZwQueryValueKey (KeyHandle,

& Unicodevaluename,

KeyValuePartiaLinformation,

ValueInfop,

ValueInfolength,

& returngength);

IF (! NT_Success (status))

{

DBGPrint ("ZWQueryValueKey Wrong:% 08X / N", Status;

Return status;

}

Else

{

RTLCopyMemory (Pchar) Value, (Pchar) ValueInfop-> Data, ValueInfop-> Datales;

ReturnValue = 1;

}

IF (! valueInfop);

EXFREEPOOL (ValueInfop);

ZWClose (keyhandle);

Return ReturnValue;

}

Void myremovecratethreadNotifyRoutine

In pcreate_thread_notify_routine notifyroutine

)

{

// psremovecreatethreadNotifyRoutine (ThreadCreatemon);

PVOID PTR = NULL;

IF (buildnumber == 2195) // Windows 2000 SP4, 2195

// I have no debugging below SP4

{

PTR = 0x80484520;

}

Else IF (buildnumber == 2600)

{

IF (WCSCMP (Version, L "Service Pack 1") == 0) // Windows XP SP1,2600

PTR = 0x8054EFC0; Else IF (WCSCMP (Verscmp (Version, L "Service Pack 2") == 0) // Windows XP SP2, 2600

PTR = 0x80561d20;

}

Else IF (buildnumber == 3790) // Windows 2003 Server, 3790

{

PTR = 0x80570f40;

}

IF (PTR! = null)

MEMSET (PTR, 0, SIZEOF (ULONG) * 8);

}

Void Threadcreatemon (in Handle Pid, ​​In Handle Tid, in Boolean Bcreate)

{

Peprocess EPROCESS, PEPROCESS;

NTSTATUS STATUS;

Handle dwparentpid;

Status = PslookupprocessByProcessId ((Ulong) PID, & EPROCESS;

IF (! NT_Success (status))

{

DBGPrint ("PslookupprocessByProcessId () / N");

Return;

}

IF (BCREATE)

{

DWParentPid = psgetcurrentprocessid ();

Status = pslookupprocessByProcessId

(Ulong) dwparentpid,

& Proprocess);

IF (! NT_Success (status))

{

DBGPrint ("PslookupprocessByProcessId () / N");

Return;

}

IF (PID == 4) // The SYSTEM process created in Dongdong, we don't care

/ / 0 under 2000, 4 after XP

Return;

IF ((g_bmainthread == true)

&& (g_dwparentID! = dwparentPid)

&& (dwparentPid! = PID)

)

{

g_bmainthread = false;

Sprintf (Outbuf, "==============================="

"Remote Thread:"

"==============================="

"/ NT:% 18S% 9D% 9D% 25S% 9D / N"

====================================== "

"=============================================== / n", (char *) ((char *) *) EPROCESS ProcessNameOffset,

PID, TID,

(char *) ((char *) Peprocess ProcessNameOffset), dwparentPid;

IF (GPEVENTOBJECT! = NULL)

KESEVENT (PRKEVENT) GPEVENTOBJECT, 0, FALSE

}

If (checklist.onlyshowremothread) // only display far thread

Return;

DBGPRINT ("T:% 18S% 9D% 9D% 25S% 9D / N",

(char *) (CHAR *) EPROCESS ProcessNameOffset,

PID, TID,

(char *) ((char *) Peprocess ProcessNameOffset), dwparentPid;

Sprintf (Outbuf, "T:% 18S% 9D% 9D% 25S% 9D / N",

(char *) (CHAR *) EPROCESS ProcessNameOffset,

PID, TID,

(char *) ((char *) Peprocess ProcessNameOffset), dwparentPid;

IF (GPEVENTOBJECT! = NULL)

KESEVENT (PRKEVENT) GPEVENTOBJECT, 0, FALSE

}

Else if (Checklist.ShowterminateTHREAD)

{

DBGPRINT ("Terminated == Thread ID:% D / N", TID);

Sprintf (Outbuf, "Terminated == Thread ID:% D / N", TID);

IF (GPEVENTOBJECT! = NULL)

KESEVENT (PRKEVENT) GPEVENTOBJECT, 0, FALSE

}

}

Void ProcessCreatemon (Handle HparentID, Handle Pid, ​​Boolean Bcreate)

{

Peprocess EPROCESS, PPROCESS

NTSTATUS STATUS;

Handle TID;

g_dwparentid = hparentId;

Status = PslookupprocessByProcessId ((Ulong) PID, & EPROCESS;

IF (! NT_Success (status))

{

DBGPrint ("PslookupprocessByProcessId () / N");

Return;

}

Status = PslookupprocessByProcessId ((Ulong) HParentID, & PPRocess

IF (! NT_Success (status))

{

DBGPrint ("PslookupprocessByProcessId () / N");

Return;

}

IF (BCREATE)

{

g_bmainthread = true;

DBGPRINT ("P:% 18S% 9D% 9D% 25S% 9D / N", (Char *) (CHAR *) EPROCESS ProcessNameOffset,

PID, PsgetCurrentThreadId (),

(char *) ((char *) PPROCESS ProcessNameOffset,

HParentID

);

Sprintf (Outbuf, "P:% 18S% 9D% 9D% 25S% 9D / N",

(char *) (CHAR *) EPROCESS ProcessNameOffset,

PID, PsgetCurrentThreadId (),

(char *) ((char *) PPROCESS ProcessNameOffset,

HParentID

);

IF (GPEVENTOBJECT! = NULL)

KESEVENT (PRKEVENT) GPEVENTOBJECT, 0, FALSE

}

Else if (Checklist.ShowterminateProcess)

{

DBGPRINT ("Terminated == Process ID:% D / N", PID);

Sprintf (Outbuf, "Terminated == Process ID:% D / N", PID);

IF (GPEVENTOBJECT! = NULL)

KESEVENT (PRKEVENT) GPEVENTOBJECT, 0, FALSE

}

}

NTSTATUS ONUNLOAD (in PDRIVER_Object PDRIVEROBJECT)

{

NTSTATUS STATUS;

DBGPRINT ("Onunload Called / N");

IF (GPEVENTOBJECT)

ObdereferenceObject (GPEVENTOBJECT);

PSsetCreateProcessNotifyRoutine (ProcessCreatemon, true);

MyRemovecrateThreadNotifyRoutine (Threadcreatemon);

IF (PDRIVEROBJECT-> DeviceObject! = NULL)

{

Status = IodeesertesymbolicLink (& DevlinkUnicd);

IF (! NT_Success (status))

{

DBGPrint ("IodeleteSymbolicLink () failed / n"));

Return status;

}

IodeleteDevice (PDRIVEROBJECT-> DEVICEOBJECT);

}

Return status_success;

}

NTSTATUS DeviceiocontrolDispatch

In PDEvice_Object DeviceObject,

In Pirp Pirp

)

{

PIO_STACK_LOCATION IRPSTACK;

NTSTATUS STATUS;

PVOID INPUTBUFFER;

Ulong InputLength;

PVOID OUTPUTBUFFER;

Ulong OutputLength;

Object_handle_information objhandleinfo;

Status = status_success; // Remove the IOCTL request code

Irpstack = IOGETCURRENTIRPSTACKLOCATION (PIRP);

Switch (Irpstack-> Majorfunction)

{

Case IRP_MJ_CREATE:

DBGPRINT ("CALL IRP_MJ_CREATE / N");

Break;

Case IRP_MJ_CLOSE:

DBGPRINT ("CALL IRP_MJ_CLOSE / N");

Break;

Case IRP_MJ_DEVICE_CONTROL:

DBGPRINT ("IRP_MJ_DEVICE_CONTROL / N");

INPUTLENGTH = Irpstack-> parameters.deviceioControl.InputBufferLength;

OutputLength = Irpstack-> Parameters.Deviceiocontrol.outputBufferLength;

Switch (irpstack-> parameters.deviceiocontrol.iocontrolcode)

{

Case ioctl_passevent: // Do communicate with events

InputBuffer = PIRP-> Associatedirp.systembuffer;

DBGPRINT ("InputBuffer:% 08x / N", (Handle) InputBuffer;

Status = ObreferenceObjectByHandle (* (Handle *) InputBuffer,

Generic_all,

NULL,

KernelMode,

& gpeventObject,

& objhandleinfo;

IF (status! = status_success)

{

DBGPRINT ("WRONG / N");

Break;

}

Break;

Case ioctl_unpassevent:

IF (GPEVENTOBJECT)

ObdereferenceObject (GPEVENTOBJECT);

DBGPRINT ("Unpassevent Called / N);

Break;

Case IOCTL_PASSBUF:

RTLCopyMemory (PirP-> Userbuffer, Outbuf, OutputLength);

Break;

Case ioctl_passevstruct:

InputBuffer = PIRP-> Associatedirp.systembuffer;

Memset (& Checklist, 0, Sizeof (Checklist));

RTLCopyMemory (& Checklist, InputBuffer, Sizeof (Checklist);

DBGPRINT ("% D:% D / N", checklist.onlyshowremothread, checklist.showthread;

Break;

DEFAULT:

Break;

}

Break;

DEFAULT:

DBGPRINT ("CALL IRP_MJ_UNKNOWN / N");

Break;

}

PIRP-> iostatus.status = status;

PIRP-> iostatus.information = 0;

IOCOMPLETEREQUEST (PIRP, IO_NO_INCREMENT);

Return status;

}

NTSTATUS DRIVERENTRY (in PDRIVER_Object PDRIVEROBJECT, IN PUNICODE_STRING THEREGISTRYPATH) {

NTSTATUS STATUS;

PDEvice_Object PDevice;

DBGPRINT ("DriveREntry Called! / N");

g_bmainthread = false;

IF (1! = getRegvalue (l "// registry // machine // Software // Microsoft // Windows NT // CurrentVersion, L" csdversion ", version))

{

DBGPrint ("GetRegValuedWord WRONG / N);

}

Psgetversion (NULL, NULL, & BuildNumber, NULL);

DBGPrint ("[[[[[% d]]]: [[[[[[% ws]]", buildnumber, version);

RtlinitunicodeString (& devnameunicd, defname);

RTLinitunicodeString (& Devlinkunicd, Devlink);

Status = IOCREATEVICE (PDRIVEROBJECT,

0,

& devnameUnicd,

File_Device_unknown,

0,

True,

& pdevice);

IF (! NT_Success (status))

{

DBGPrint ("CAN Not Create Device./N));

Return status;

}

Status = IOCREATESYMBOLICLICLICLICLINK (& DevlinkunicD);

IF (! NT_Success (status))

{

DBGPRINT ("Cannot Create Link./N"));

Return status;

}

ProcessNameOffset = getProcessNameOffset ();

PDRIVEROBJECT-> Driverunload = onunload;

PDRIVEROBJECT-> Majorfunction [IRP_MJ_CREATE] =

PDRIVEROBJECT-> Majorfunction [IRP_MJ_CLOSE] =

PDRIVEROBJECT-> Majorfunction [IRP_MJ_DEVICE_CONTROL] = DeviceiocontrolDispatch;

Status = pssetcreateProcessNotifyRoutine (ProcessCreatemon, False);

IF (! NT_Success (status))

{

DBGPrint ("PSSetcreateProcessNotifyRoutine () / N");

Return status;

}

Status = pssetcreatethreadNotifyRoutine (ThreadCreatemon);

IF (! NT_Success (status))

{

"" Pssetcreatethreadnotifyroutine () / n ");

Return status;

}

Return status_success;

}

Main.c, here I use an event as a communication driver

// Made by Zwell

#include #include

#include "define.h"

int main ()

{

Handle HDevice;

Bool status;

Handle M_Hcommevent;

Ulong dwreturn;

CHAR OUTBUF [255];

Checklist checklist;

HDevice = NULL;

m_hcommevent = NULL;

HDevice = CREATEFILE (".//myevent",

Generic_read | generic_write,

File_share_read | file_share_write,

NULL,

Open_EXISTING,

FILE_ATTRIBUTE_NORMAL,

NULL);

IF (HDevice == Invalid_Handle_Value)

{

Printf ("CreateFile Wrong / N");

GetChar ();

Return 0;

}

M_Hcommevent = CreateEvent (NULL,

False,

False,

NULL);

Printf ("HEVENT:% 08X / N", M_Hcommmevent);

Status = DeviceioControl (HDEvice,

IOCTL_PASSEVENT,

& m_hcommmevent,

Sizeof (M_Hcommevent),

NULL,

0,

& dwreturn,

NULL);

IF (! status)

{

Printf ("IO WRONG % D / N", getLastError ());

GetChar ();

Return 0;

}

Checklist.onlyShowRemoteThread = true;

Checklist.showthread = true;

Checklist.showterminateThread = false;

Checklist.showterminateProcess = false;

Status = DeviceioControl (HDEvice,

IOCTL_PASSEVSTRUCT,

& Checklist,

Sizeof (Checklist),

NULL,

0,

& dwreturn,

NULL);

IF (! status)

{

Printf ("IO WRONG % D / N", getLastError ());

GetChar ();

Return 0;

}

Printf ("[Process Name] [PID] [PARENT Process Name] [PID] [TID] / N");

While (1)

{

ResetEvent (m_hcommmevent);

WaitforsingleObject (m_hcommmevent, infinite);

Status = DeviceioControl (HDEvice,

IOCTL_PASSBUF,

NULL,

0,

& Outbuf,

SIZEOF (Outbuf),

& dwreturn,

NULL);

IF (! status)

{

Printf ("IO WRONG % D / N", getLastError ());

GetChar ();

Return 0;

}

Printf ("% s", outbuf);

}

Status = Deviceiocontrol (HDevice, IOCTL_UNPASSEVENT,

NULL,

0,

NULL,

0,

& dwreturn,

NULL);

IF (! status)

{

Printf ("Unpassevent Wrong % D / N", getLastError ());

GetChar ();

Return 0;

}

Status = CloseHandle (HDEvice);

Status = closehandle (m_hcommmevent);

GetChar ();

Return 0;

}

/

Define.h

/

#include "stdio.h"

#define file_device_event 0x8000

// define interface reference / dereference routines for

// interfaces exported by IRP_MN_QUERY_INTERFACE

#define Event_iocTl (Index) /

CTL_CODE (File_Device_Event, Index, Method_Buffered, File_Read_Data)

#define ioctl_passevent /

CTL_CODE (file_device_event, 0x801, method_buffered, file_any_access)

#define ioctl_passbuf /

CTL_CODE (File_Device_Event, 0x802, Method_Buffered, File_Ane_access)

#define ioctl_unpassevent /

CTL_CODE (file_device_event, 0x803, method_buffered, file_any_access)

#define ioctl_passevstruct /

CTL_CODE (file_device_event, 0x804, method_buffered, file_any_access)

Typedef struct // This structure is mainly used for debugging

{

Bool showthread;

Bool OnlyShowRemoteThread;

Bool showterminateprocess;

Bool showterminatethem;

Checklist, * pchecklist;

First use drive load tools to load drive, then run the program, you can monitor the operation information of the process line, and you can achieve the creation of the monitoring far thread. Personally think it is perfect.

If you have a better way, please let me know, thank you. ^ _ ^

The following operations:

HEVENT: 00000010

[Process Name] [PID] [TID] [PARENT Process Name] [PID] [TID]

T: svchost.exe 940 3540 svchost.exe 940

T: Explorer.exe 1680 3564 Explorer.exe 1680

P: Notepad.exe 3568 1684 Explorer.exe 1680

T: Notepad.exe 3568 3572 Explorer.exe 1680

T: svchost.exe 1036 3576 SVCHOST.EXE 1036

T: cmd.exe 3580 3084 Explorer.exe 1680p: doskey.exe 3608 3084 cmd.exe 3580

T: Taskmgr.exe 352 3752 Explorer.exe 1680

T: svchost.exe 1036 2492 svchost.exe 1036

T: Remote.exe 3824 3828 cmd.exe 3580

============================== Remote thread: ====================================================================================================================================================================================================== =============

T: hh.exe 3116 3832 Remote.exe 3824

============================================================================================================================================================================================================= ==========================

Reference:

1. Write processes / thread monitors -sinister

http://www.xfocus.net/articles/200303/495.html

2. Monitor the creation of remote threads - a three-cent

Http://www.luocong.com/bbs/dispbbs.asp?boardid=2&id=6895&page=2

3. Windows 2000 Source Code

转载请注明原文地址:https://www.9cbs.com/read-42039.html

New Post(0)