使用pywintrace监控Windows进程变动


写在前面

最近突发奇想,想监控某个进程的启动和退出事件,搜了一下,有个专门的名词来描述这类事件,叫做Event Trance For Windows,简称ETW,跟Windows的事件管理器有比较大的关系。
为了快速实现这个想法,决定使用python来完成,上github搜索,发现一个名为pywintrace的项目,只要稍作修改就能实现我们的需求。

安装依赖

需要用到pywintracepsutil两个模块。

pip install pywintrace
pip install psutil

示例代码

直接拿项目中的示例,稍作修改即可(需要管理员权限执行示例代码),这里以微信作为示例:

import time
import etw
import psutil

def on_trace_event(event):
    event_descriptor_id, info = event
    if event_descriptor_id == 1:
        # parent_process_id = int(info["ParentProcessID"])
        process_id = int(info["ProcessID"])
        # image_name = info["ImageName"]
        # timestamp = int(info["TimeDateStamp"][2:], 16)
        try:
            p = psutil.Process(process_id)
            if p.name() == "WeChat.exe":
                print(" [process] 微信启动: {}".format(process_id))
        except:
            pass
    elif event_descriptor_id == 2:
        process_id = int(info["ProcessID"])
        image_name = info["ImageName"]
        try:
            if image_name == "WeChat.exe":
                print(" [process] 微信退出: {}".format(process_id))
        except:
            pass


class MyETW(etw.ETW):

    def __init__(self, event_callback):
        # define capture provider info, use `logman query providers`
        providers = [etw.ProviderInfo('Microsoft-Windows-Kernel-Process', etw.GUID("{22FB2CD6-0E7B-422B-A0C7-2FAD1FD0E716}"))]
        super().__init__(providers=providers, event_callback=event_callback)

    def start(self):
        # do pre-capture setup
        self.do_capture_setup()
        super().start()

    def stop(self):
        super().stop()
        # do post-capture teardown
        self.do_capture_teardown()

    def do_capture_setup(self):
        # do whatever setup for capture here
        pass

    def do_capture_teardown(self):
        # do whatever for capture teardown here
        pass


def my_capture():
    # instantiate class
    capture = MyETW(on_trace_event)
    # start capture
    capture.start()
    # wait some time to capture data
    while True:
        try:
            time.sleep(0.5)
        except KeyboardInterrupt:
            break
    # stop capture
    capture.stop()


if __name__ == '__main__':
    my_capture()

写在后面

这个具体能做什么呢,或许可以监控到指定的进程启动,就注入自己的模块,或者在进程启动的时候关掉互斥锁,实现多开之类的操作。
顺便,ETW能做的事情还有很多,有兴趣可以研究一下。