(转载)编写进程/线程监视器

Java 多线程面试问题 原文:Java Multi-Threading and Concurrency Interview Questions with Answers 翻译:并发编程网 - 郑旭东 校对:方腾飞 多线程和并发问题是 Java 技术面试中面试官比较喜欢问的问题之一。在这里,从面试的角度列出了大部分重要的问题,但是你仍然应该牢固的掌握Java多线程基础知识来对应日后碰到的问题。(校对注:非常赞同这个观点。转... 阅读详情

编写进程/线程监视器


创建时间:2003-03-21
文章属性:原创
文章来源: http://www.whitecell.org
文章提交: sinister (jiasys_at_21cn.com)

编写进程/线程监视器


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

}


关于我们:

WSS(Whitecell Security Systems),一个非营利性民间技术组织,致力于各种系统安全技术的研究。坚持传统的hacker精神,追求技术的精纯。
WSS 主页: http://www.whitecell.org/
精选_枚举并删除系统上PsSetCreateThreadNotifyRoutine回调_源码打包 枚举并删除系统上PsSetCreateThreadNotifyRoutine回调 立即下载

相关推荐

Python 使用Pygame库实现足球游戏:创建一个球员和一个足球,并使玩家能够控制球员的移动。游戏将包括碰撞检测、简单的物理模拟,以及基本的用户输入处理

本文将介绍如何使用Python和Pygame库创建一个简单的足球游戏。我们将搭建一个基本的游戏环境,创建一个球员和一个足球,并使玩家能够控制球员的移动。游戏将包括碰撞检测、简单的物理模拟,以及基本的用户输入处理。这个简单的足球游戏展示了Pygame的一些基本功能。虽然这是一个简单的游戏,但它包含了创建游戏循环、用户输入处理、物理模拟、碰撞检测等重要概念。

程序熊的博客 726

在VS2008中配置WDK7600驱动开发环境

网上这类资料多如牛毛,也许很多人都是转来转去,却很有人去真正的测试,有时候感觉确实对他人也是一种误导。 这里是我自己在VS2008 + WDK7600.16385.0 + DDKWizard配置自己的IDE开发环境的设置过程: 1、首先安装DDKWizard 官方网页:http://ddkwizard.assarbad.net/ 从官方网页下载这三个

Koma的主页 7255

Microsemi Libero使用技巧11——CoreUARTAPB RX管脚分配时不显示

调用串口IP核CoreUARTAPB,并例化到顶层设计,发现UART_RX管脚在进行管脚分配时没有显示出来,最后发现是CoreAPB3总线IP核配置不对导致,改为如下配置后正常。

whik1194的博客 722

64位下使用回调函数实现监控(下)

线程监控使用到的API相对于进程监控简单,使用到,而这个值并不能像进程操作的API一样进行操作,这里我们首先先使用这个API来进行线程的监控指向的结构如下,第一个参数为PID,第二个参数为TID,第三个参数表示是创建线程还是删除线程,创建线程则为TRUE,删除线程则为FALSE那么我们这里就可以写出函数这里如果要将函数摘除,就需要用到函数,定义如下我们如果想让进行线程的保护该如何操作呢?

星星我啊,已经很努力在学习了, 有人一起学习吗?Ziansec-1 1024

[原创]通过PsSetCreateProcessNotifyRoutineEx和PsSetCreateThreadNotifyRoutine实现进程线程监控

PsSetCreateProcessNotifyRoutineEx是Windows提供得一个可以通过设置回调函数实现进程监控的内核API。其在文档的定义如下: 1 2 3 4 5 NTSTATUS PsSetCreateProcessNotifyRoutineEx( INPCREATE_PROCESS_NOTIFY_ROUTINE_EXNotifyRoutine, INBOOLEAN...

追逐光芒,追随内心 2349

驱动开发:内核监控进程线程创建

监控进程的启动与退出可以使用 `PsSetCreateProcessNotifyRoutineEx` 来创建回调,当新进程产生时,回调函数会被率先执行,然后执行我们自己的`MyCreateProcessNotifyEx`函数,并在内部进行打印输出。而检测线程操作与检测进程差不多,检测线程需要调用`PsSetCreateThreadNotifyRoutine` 创建回调函数,然后就可以检测线程的创建了。

微软技术分享 1万+

线程任务监视器

本文介绍了Java线程池任务超时控制的几种实现方案。首先分析了线程池中任务阻塞导致线程无法释放的问题,提出通过设置最大执行时长来强制终止超时任务。然后详细比较了三种实现方式:1)在子线程中再创建线程并利用join()方法监控;2)使用ScheduledExecutorService定时检查任务状态;3)结合CompletableFuture和ScheduledExecutorService实现更精确的监控。重点阐述了第三种方案的工作原理:通过CompletableFuture作为监控器,当任务正常完成或异常

纯洁的小魔鬼 1464

java 监视锁_【转载】Java锁与监视器

锁的相关基本概念。了解底层的Object 监视器~在Java中,与线程通信相关的几个方法,是定义在Object中的,大家都知道Object是Java中所有类的超类在Java中,所有的类都是Object,借助于一个统一的形式Object,显然在有些处理过程中可以更好地完成转换,传递,省去了一些不必要的麻烦另外有些东西,比如toString,的确是所有的类的特征但是,为何线程通信相关的方法会被设计在O...

weixin_42128393的博客 199

[转载] Python开发系列课程(16) - 进程线程

参考链接: Python | 使用Tkinter进行消息编码-解码 进程线程 今天我们使用的计算机早已进入多CPU或多核时代,而我们使用的操作系统都是支持“多任务”的操作系统,这使得我们可以同时运行多个程序,也可以将一个程序分解为若干个相对独立的子任务,让多个子任务并发的执行,从而缩短程序的执行时间,同时也让用户获得更好的体验。因此在当下不管是用什么编程语言进行开发,实现让程序同时执行多个任务也就是常说的“并发编程”,应该是程序员必备技能之一。为此,我们需要先讨论两个概念,一个叫进程,一个叫线程。..

u013946150的博客 142

Python 多线程进程 实现并行 和并发

此文转载自 知乎问题评论:https://www.zhihu.com/question/315908877/answer/975306735 GIL 全局解释器锁: GIL(全局解释器锁,GIL 只有cpython有): 在同一个时刻,只能有一个线程在一个 CPU 上执行字节码,没法像 c 和 Java 一样将多个线程映射到多个 CPU上执行,但是GIL会根据执行的字节码行数(为了让各个线程能够平均利用CPU时间,python会计算当前已执行的微代码数量,达到一定阈值后就强制释放GIL)和时间片以及遇到IO

H_sen's Blog 1922

Linux htop命令,进程监视器

htop 是一个 Linux 下的交互式的进程浏览器,可以用来替换Linux下的top命令。与Linux传统的top相比,htop更加人性化。它可让用户交互式操作,支持颜色主题,可横向或纵向滚动浏览进程列表,并支持鼠标操作。

不忘初心~ 6669

libev源码解析——监视器(watcher)结构和组织形式

在《libev源码解析——总览》中,我们介绍了libev的一些重要变量在不同编译参数下的定义位置。由于这些变量在多线程下没有同步问题,所以我们将问题简化,所提到的变量都是线程内部独有的,不用考虑任何多线程问题。(转载请指明出于breaksoftware的csdn博客) 之前提到过,libev支持多种功能,比如文件状态监控、定时器等。这些功能都是有其相对应的一个“监...

方亮的专栏 2949

程序.线程.进程

程序进程线程的概念: 程序:是为完成特定任务,用某种语言编写的一组指令的集合.即指一段静态的代码.静态对象 进程:是程序的一次执行的过程,或正在运行的一个程序.动态的过程.她有自身的产生.存在.和消亡的过程,是动态的 线程:进程可进一步细化为线程,是一个程序内部的一条执行路径   若一个进程可同时执行多个线程,就是正吃多线程的 thre...

didui0897的博客 125

创建一个守护进程来监听服务进程的异常状态_深入理解Node.js 进程线程(一文彻底搞懂)...

个人这篇文章写的确实很好,而且很详细,图文结合,也比较好理解,所以分享给大伙。文章转载自:https://mp.weixin.qq.com/s/fkrHHMwx75NLhvv4P3rk-w前言进程线程是一个程序员的必知概念,面试经常被问及,但是一些文章内容只是讲讲理论知识,可能一些小伙伴并没有真的理解,在实际开发中应用也比较少。本篇文章除了介绍概念,通过Node.js 的角度讲解 进程线程,...

weixin_40004502的博客 664

关于 java线程的 锁池、等待池(二)

围绕着:「等待池中被 "唤醒"notifyAll()线程一定会进入锁池吗?」 接着上篇转载的博客:https://blog.csdn.net/ScorpC/article/details/90296146 自己又继续深入研究了这个问题,查阅了java虚拟机经典书籍《Inside the Java Virtual Machine(第2版)》,瞬间懂! 不仅感叹,经典就是经典,能成为经典一定...

ScorpC的博客 437

进程线程——学习随笔

什么是线程,什么是进程? 所谓的线程——Thread,是计算机执行计划任务的最小单元,计算机执行的每一次任务,我们称之为作业(JOB)。 进程process:很多线程的集合,操作系统对于应用程序的管理工具,也就是说一个进程里有很多线程线程名可以自己给出,但是进程必须由操作系统给一个独有的进程号,这个有进程号的进程就是一系列线程任务的容器。 线程不能独立存在,有线程一定有进程,有进程至少有一个线程...

qq_40875544的博客 176

监视器(Monitor)内部,是如何做线程同步的?程序应该做哪种级别的同步?

监视器(Monitor)内部,是如何做线程同步的?程序应该做哪种级别的同步? 参考答案 监视器和锁在Java虚拟机中是一块使用的。监视器监视一块同步代码块,确保一次只有一个线程执行同步代码块。每一个监视器都和一个对象引用相关联。线程在获取锁之前不允许执行同步代码。 在java虚拟机中,每个对象(Object和class)通过某种逻辑关联监视器,每个...

weixin_30642267的博客 286

线程进程是怎样使用多核的

最近由于有抢票的需求,对于一个用户而言,用一个死循环,一个刷票就好了,刷到了就break退出。但是现在我要考虑同时给很多人抢,那么必须要考虑并发。但是这是一个耗时的任务,很可能几天都不能结束这个任务,所以这个和普通的java web并发不同。我在思考如何设置这个线程模型时引出了一个问题,之前还一直都没思考过这个。多核时,一个线程是始终由一个cpu核运行还是每个cpu核都会运行该线程呢?...

weixin_30535565的博客 157

转载】性能监视器(SSAS)

使用性能监视器,您可以通过性能计数器监视 Microsoft SQL Server Analysis Services (SSAS) 实例的性能。 性能监视器是用于跟踪资源使用情况的 Microsoft 管理控制 (MMC) 管理单元。您可以通过以下方式启动此 MMC 管理单元:在命令提示符下键入PerfMon,或从“控制面板”依次单击“管理工具”和“性能监视器”。性能监视器使您可...

weixin_30896763的博客 261

性能监视器的简单使用

性能监视器,是Windows NT提供的一种系统功能。Windows NT一直以来总是集成了性能监视工具,它提供有关操作系统当前运行状况的信息,针对各种对象提供了数百个性能计数器。 性能监视器的使用 比如需要监控应用程序NetThreading中每秒中的线程的个数。 1) 清除显示 2) 冻结显示 已经得到了需要的数据,如果不冻结绘图,性能监视器会把不需要的数据绘制出来。 冻结...

weixin_30376509的博客 157
上一篇: Visual Studio 2005 Team System 试用有感
下一篇: (转载)安全稳定的实现进线程监控
Kendiv
博客等级 码龄25年 179粉丝 156原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值