电脑爱好者,提供IT资讯信息及各类编程知识文章介绍,欢迎大家来本站学习电脑知识。 最近更新 | 联系我们 RSS订阅本站最新文章
电脑爱好者
站内搜索: 
当前位置:首页>> 网络安全>>监视远程线程的创建之回复:

监视远程线程的创建之回复

来源:远方网络 | 2005-5-22 9:16:03 | (有2934人读过)

*有时候我们希望能够动态监视系统中任意进程/线程的创建与销毁。为了达

到此目的我翻阅了 DDK 手册,发现其提供的 PsSetCreateProcessNotifyRoutine(),

PsSetCreateThreadNotifyRoutine(),等函数可以实现此功能。这两个函数可以

通过向系统注册一个 CALLBALCK 函数来监视进程/线程等操作。函数原形如下:


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

);

通过原形可以看出,其 CALLBACK 函数只提供了进程ID/线程ID。并没有提供

进程名。那么我们要进一步通过进程ID来获取进程名。这需要用到一个未公开

的函数 PsLookupProcessByProcessId()。函数原形如下:


NTSTATUS PsLookupProcessByProcessId(

IN ULONG ulProcId,

OUT PEPROCESS * pEProcess

);


函数输出的 EPROCESS 结构也是未公开的内核进程结构,很多人称其为 KPEB。

EPROCESS 结构中的偏移 0x1FC 指向当前进程名的偏移。(这个结构虽然可以在

驱动程序中直接使用。但没有公布其结构,网上有不少高手已将其结构给出。有

兴趣可以自行搜索,或去 IFS DDK 中获取,这里因为结构太长,就不贴出来了)

有了这个结构我们就可以从中得到进程名。NT系统还提供了一个函数可以动态监

视进程装载映像。此函数可以得到进程加栽时所调用的 DLL 名称与全路径,还有

一些映像信息。为我们获得更详细的进程装载信息提供了更好的帮助。


函数原形如下:


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;


利用以上提供的函数与结构,我们便能实现一个进程/线程监视器。下面这段

代码演示了如何实现此功能。
*/

/*****************************************************************

文件名 : WssProcMon.c

描述 : 进程/线程监视器

作者 : sinister

最后修改日期 : 2002-11-02


*****************************************************************/


#include "ntddk.h"
#include "windef.h"
#include "string.h"
#define SYSNAME "System"
//#define ProcessNameOffset 0x1fc


ULONG GetProcessNameOffset();
VOID Unload(IN PDRIVER_OBJECT DriverObject);
static NTSTATUS MydrvDispatch (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
NTSTATUS PsLookupProcessByProcessId(IN ULONG ulProcId, 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 );

// 驱动入口
ULONG ProcessNameOffset =0;
NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath )

{
UNICODE_STRING nameString, linkString;
PDEVICE_OBJECT deviceObject;
NTSTATUS status;
int i;
//建立设备

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;

}
ProcessNameOffset = GetProcessNameOffset();
/*status = PsSetLoadImageNotifyRoutine(ImageCreateMon);

if (!NT_SUCCESS( status ))
{
DbgPrint("PsSetLoadImageNotifyRoutine()\n");
return status;
}*/


status = PsSetCreateThreadNotifyRoutine(ThreadCreateMon);
if (!NT_SUCCESS( status ))
{
DbgPrint("PsSetCreateThreadNotifyRoutine()\n");
return status;
}


status = PsSetCreateProcessNotifyRoutine(ProcessCreateMon, FALSE);
if (!NT_SUCCESS( status ))
{
DbgPrint("PsSetCreateProcessNotifyRoutine()\n");
return status;
}

for ( i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
{
DriverObject->MajorFunction[i] = MydrvDispatch;
}
DriverObject->DriverUnload = Unload;
return STATUS_SUCCESS;
}

VOID Unload(IN PDRIVER_OBJECT DriverObject)
{
UNICODE_STRING linkString;
PsRemoveCreateThreadNotifyRoutine(ThreadCreateMon);
PsSetCreateProcessNotifyRoutine(ProcessCreateMon, TRUE);
RtlInitUnicodeString( &linkString, L"\\DosDevices\\WssProcMon" );
IoDeleteSymbolicLink( &linkString );
IoDeleteDevice( DriverObject->DeviceObject );
}

//处理设备对象操作


static NTSTATUS MydrvDispatch (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)

{
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0L;
IoCompleteRequest( Irp, 0 );
return Irp->IoStatus.Status;
}

HANDLE g_dwProcessId;
BOOL g_bMainThread;
VOID ProcessCreateMon ( IN HANDLE hParentId, IN HANDLE PId,IN BOOLEAN bCreate )
{
PEPROCESS EProcess;
ULONG ulCurrentProcessId;
LPTSTR lpCurProc;
NTSTATUS status;
#ifdef _AMD64_
ULONG ProcessId = HandleToUlong(PId);
status = PsLookupProcessByProcessId( ProcessId, &EProcess);
#else
HANDLE ProcessId =PId;
status = PsLookupProcessByProcessId( (ULONG)PId, &EProcess);
#endif

if (!NT_SUCCESS( status ))
{
DbgPrint("PsLookupProcessByProcessId()\n");
return ;
}

if ( bCreate )
{
//g_dwProcessId = ProcessId;
g_bMainThread = TRUE;
lpCurProc = (LPTSTR)EProcess;
lpCurProc = lpCurProc + ProcessNameOffset;
DbgPrint( "CREATE PROCESS = PROCESS NAME: %s , PROCESS PARENTID: %d, PROCESS ID: %d, PROCESS ADDRESS %x:\n",
lpCurProc,
hParentId,
PId,
EProcess );
}
else
{
DbgPrint( "TERMINATED == PROCESS ID: %d\n", PId);
}
}


VOID ThreadCreateMon (IN HANDLE PId, IN HANDLE TId, IN BOOLEAN bCreate)

{
PEPROCESS EProcess,ParentEProcess;
LPTSTR lpCurProc,lpParnentProc;
NTSTATUS status;

#ifdef _AMD64_
ULONG System=4;
ULONG dwParentPID=HandleToUlong(PsGetCurrentProcessId());//创建该线程的进程
ULONG ProcessId = HandleToUlong(PId);
status = PsLookupProcessByProcessId( ProcessId, &EProcess);
status = PsLookupProcessByProcessId( dwParentPID, &ParentEProcess);
#else
HANDLE System=(HANDLE)4;//under xp, in win2k is 8
HANDLE dwParentPID=PsGetCurrentProcessId();//创建该线程的进程
HANDLE ProcessId =PId;//ProcessId 是进程号,这里的进程号是指向包括该线程的进程,而不是创建该线程的进程
status = PsLookupProcessByProcessId( (ULONG)ProcessId, &EProcess);
status = PsLookupProcessByProcessId( (ULONG)dwParentPID, &ParentEProcess);
#endif

if (!NT_SUCCESS( status ))
{
DbgPrint("PsLookupProcessByProcessId()\n");
return ;
}

if ( bCreate )
{
if((g_bMainThread==TRUE)&&(ProcessId!=System)&&(ProcessId!=dwParentPID))
{
HANDLE dwParentTID=PsGetCurrentThreadId();
lpCurProc = (LPTSTR)EProcess;
lpParnentProc= (LPTSTR)ParentEProcess;
lpCurProc += ProcessNameOffset;
lpParnentProc +=ProcessNameOffset;
DbgPrint("caller: Name=%s PID=%d TID=%d\t\tcalled: Name=%s PID=%d TID=%d\n", \
lpParnentProc, dwParentPID, dwParentTID, lpCurProc, ProcessId, TId);
g_bMainThread=FALSE;
}

lpCurProc = (LPTSTR)EProcess;
lpCurProc = lpCurProc + ProcessNameOffset;
DbgPrint( "CREATE THREAD = PROCESS NAME: %s PROCESS ID: %d, THREAD ID: %d\n", lpCurProc, PId, TId );
}
else
{
DbgPrint( "TERMINATED == THREAD ID: %d\n", TId);
}
}


//VOID ImageCreateMon (IN PUNICODE_STRING FullImageName, IN HANDLE ProcessId, IN PIMAGE_INFO ImageInfo )
//
//{
// DbgPrint("FullImageName: %S,Process ID: %d\n",FullImageName->Buffer,ProcessId);
// DbgPrint("ImageBase: %x,ImageSize: %d\n",ImageInfo->ImageBase,ImageInfo->ImageSize);
//}

ULONG GetProcessNameOffset()
{
PEPROCESS curproc;
int i;

curproc = PsGetCurrentProcess();

//
// Scan for 12KB, hopping the KPEB never grows that big!
//
for( i = 0; i < 3*PAGE_SIZE; i++ ) {

if( !strncmp( SYSNAME, (PCHAR) curproc + i, strlen(SYSNAME) )) {

return i;
}
}

//
// Name not found - oh, well
//
return 0;
}

根据你的改为C代码,并支持WINXP -64.......

网络安全热门文章排行
网站赞助商
购买此位置

 

关于我们 | 网站地图 | 文档一览 | 友情链接| 联系我们

Copyright © 2003-2024 电脑爱好者 版权所有 备案号:鲁ICP备09059398号