登录社区:用户名: 密码: 忘记密码 网页功能:加入收藏 设为首页 网站搜索  

文档

下载

图书

论坛

安全

源码

硬件

游戏
首页 信息 空间 VB VC Delphi Java Flash 补丁 控件 安全 黑客 电子书 笔记本 手机 MP3 杀毒 QQ群 产品库 分类信息 编程网站
 内容搜索 网页 下载 源代码
热点文章
  利用鼠标键盘钩子截获密码
  利用鼠标键盘钩子截获密码
  如何将多个文件捆绑成一个可..
  如何将多个文件捆绑成一个可..
  内核级HOOK的几种实现与应用
  内核级HOOK的几种实现与应用
  书写基于内核的linux键盘纪录..
  书写基于内核的linux键盘纪录..
  CIH病毒原码
  CIH病毒原码
  编写进程/线程监视器
  编写进程/线程监视器
本站原创
  利用鼠标键盘钩子截获密码
  利用鼠标键盘钩子截获密码
最新招聘信息

您现在的位置:立华软件园->安全防线->黑客编程
编写进程/线程监视器
发表日期:2003-10-14作者:[] 出处:  

原始文档:http://www.xfocus.net/articles/200303/495.html

创建时间:2003-03-21

浏览次数:74

原创:sinister (jiasys_at_21cn.com)

来源:http://www.whitecell.org

编写进程/线程监视器

Author : sinister

Email  : sinister@whitecell.org

HomePage: http://www.whitecell.org

(首先说明一下。有不少朋友来信问一些进程/线程监视工具是如何实现的。

我写出来是为了让那些朋友有进一步的了解,也省的我一封封的回MAIL。如果您

是 NT DRIVER熟手,那么此文提到的方法您可能早已掌握,完全可以略过不看。)

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

到此目的我翻阅了 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 "string.h"

#define ProcessNameOffset 0x1fc

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 );

// 驱动入口

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;

  }  

  

  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;

  }

  

 return STATUS_SUCCESS;

}

//处理设备对象操作

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;

  

}

VOID ProcessCreateMon ( IN HANDLE hParentId, IN HANDLE PId,IN BOOLEAN bCreate )

{

  PEPROCESS EProcess;

  ULONG   ulCurrentProcessId;

  LPTSTR    lpCurProc;

  NTSTATUS  status;

  status = PsLookupProcessByProcessId( (ULONG)PId, &EProcess);

  if (!NT_SUCCESS( status ))

  {

    DbgPrint("PsLookupProcessByProcessId()\n");

    return ;

  }

  

  if ( bCreate )

  {

     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;

  ULONG    ulCurrentProcessId;

  LPTSTR    lpCurProc;

  NTSTATUS  status;

  status = PsLookupProcessByProcessId( (ULONG)PId, &EProcess);

  if (!NT_SUCCESS( status ))

  {

    DbgPrint("PsLookupProcessByProcessId()\n");

    return ;

  }  

  if ( bCreate )

  {

     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);

}

我来说两句】 【发送给朋友】 【加入收藏】 【返加顶部】 【打印本页】 【关闭窗口
中搜索 编写进程/线程监视器
关于我们 / 合作推广 / 给我留言 / 版权举报 / 意见建议 / 广告投放 / 友情链接

Copyright ©2001-2003 Allrights reserved
e_mail:站长:webmaster(at)lihuasoft.net
网站编程QQ群  
京ICP备05001064号

页面生成时间:0.00489