首页 > 系统相关 >7.3 Windows驱动开发:内核监视LoadImage映像回调

7.3 Windows驱动开发:内核监视LoadImage映像回调

时间:2023-12-01 16:33:18浏览次数:50  
标签:函数 Windows 映像 7.3 模块 LoadImage 回调 加载

在笔者上一篇文章《内核注册并监控对象回调》介绍了如何运用ObRegisterCallbacks注册进程与线程回调,并通过该回调实现了拦截指定进行运行的效果,本章LyShark将带大家继续探索一个新的回调注册函数,PsSetLoadImageNotifyRoutine常用于注册LoadImage映像监视,当有模块被系统加载时则可以第一时间获取到加载模块信息,需要注意的是该回调函数内无法进行拦截,如需要拦截则需写入返回指令这部分内容将在下一章进行讲解,本章将主要实现对模块的监视功能。

PsSetLoadImageNotifyRoutine和PsRemoveLoadImageNotifyRoutine是Windows操作系统提供的两个内核API函数,用于注册和取消注册LoadImage映像的回调函数。

LoadImage映像回调函数是一种内核回调函数,它可以用于监视和拦截系统中的模块加载事件,例如进程启动时加载的DLL、驱动程序等。当有新的模块被加载时,操作系统会调用注册的LoadImage映像回调函数,并将加载模块的相关信息传递给回调函数。

PsSetLoadImageNotifyRoutine函数用于注册LoadImage映像的回调函数,而PsRemoveLoadImageNotifyRoutine函数则用于取消注册已经注册的回调函数。开发者可以在LoadImage映像回调函数中执行自定义的逻辑,例如记录日志、过滤敏感数据、或者阻止某些操作。

需要注意的是,LoadImage映像回调函数的注册和取消注册必须在内核模式下进行,并且需要开发者有一定的内核开发经验。同时,LoadImage映像回调函数也需要遵守一些约束条件,例如不能阻塞或挂起进程或线程的创建或访问,不能调用一些内核API函数等。

内核监视LoadImage映像回调在安全软件、系统监控和调试工具等领域有着广泛的应用。开发者可以利用这个机制来监视和拦截系统中的模块加载事件,以保护系统安全。

监视模块加载与卸载需要费别使用两个函数,这两个函数的参数传递都是自己的回调地址。

  • PsSetLoadImageNotifyRoutine 设置回调
  • PsRemoveLoadImageNotifyRoutine 移除回调

此处MyLySharkLoadImageNotifyRoutine回调地址必须有三个参数传递组成,其中FullImageName代表完整路径,ModuleStyle代表模块类型,一般来说ModuleStyle=0表示加载SYS驱动,如果ModuleStyle=1则表示加载的是DLL,最后一个参数ImageInfo则是映像的详细参数结构体。

VOID MyLySharkLoadImageNotifyRoutine(PUNICODE_STRING FullImageName, HANDLE ModuleStyle, PIMAGE_INFO ImageInfo)

那么如何实现监视映像加载呢,来看如下完整代码片段,首先PsSetLoadImageNotifyRoutine注册回调,当有模块被加载则自动执行MyLySharkLoadImageNotifyRoutine回调函数,其内部首先判断ModuleStyle得出是什么类型的模块,然后再通过GetDriverEntryByImageBase拿到当前进程详细参数并打印输出。

#include <ntddk.h>
#include <ntimage.h>

// 未导出函数声明
PUCHAR PsGetProcessImageFileName(PEPROCESS pEProcess);

// 获取到镜像装载基地址
PVOID GetDriverEntryByImageBase(PVOID ImageBase)
{
    PIMAGE_DOS_HEADER pDOSHeader;
    PIMAGE_NT_HEADERS64 pNTHeader;
    PVOID pEntryPoint;
    pDOSHeader = (PIMAGE_DOS_HEADER)ImageBase;
    pNTHeader = (PIMAGE_NT_HEADERS64)((ULONG64)ImageBase + pDOSHeader->e_lfanew);
    pEntryPoint = (PVOID)((ULONG64)ImageBase + pNTHeader->OptionalHeader.AddressOfEntryPoint);
    return pEntryPoint;
}

// 获取当前进程名
UCHAR* GetCurrentProcessName()
{
    PEPROCESS pEProcess = PsGetCurrentProcess();
    if (NULL != pEProcess)
    {
        UCHAR *lpszProcessName = PsGetProcessImageFileName(pEProcess);
        if (NULL != lpszProcessName)
        {
            return lpszProcessName;
        }
    }
    return NULL;
}

// 设置自己的回调函数
VOID MyLySharkLoadImageNotifyRoutine(PUNICODE_STRING FullImageName, HANDLE ModuleStyle, PIMAGE_INFO ImageInfo)
{
    PVOID pDrvEntry;

    // MmIsAddress 验证地址可用性
    if (FullImageName != NULL && MmIsAddressValid(FullImageName))
    {
        // ModuleStyle为零表示加载sys
        if (ModuleStyle == 0)
        {
            // 得到装载主进程名
            UCHAR *load_name = GetCurrentProcessName();
            pDrvEntry = GetDriverEntryByImageBase(ImageInfo->ImageBase);
            DbgPrint("[LyShark SYS加载] 模块名称:%wZ --> 装载基址:%p --> 镜像长度: %d --> 装载主进程: %s \n", FullImageName, pDrvEntry, ImageInfo->ImageSize, load_name);
        }
        // ModuleStyle非零表示加载DLL
        else
        {
            // 得到装载主进程名
            UCHAR *load_name = GetCurrentProcessName();
            pDrvEntry = GetDriverEntryByImageBase(ImageInfo->ImageBase);
            DbgPrint("[LyShark DLL加载] 模块名称:%wZ --> 装载基址:%p --> 镜像长度: %d --> 装载主进程: %s \n", FullImageName, pDrvEntry, ImageInfo->ImageSize, load_name);
        }
    }
}

VOID UnDriver(PDRIVER_OBJECT driver)
{
    PsRemoveLoadImageNotifyRoutine((PLOAD_IMAGE_NOTIFY_ROUTINE)MyLySharkLoadImageNotifyRoutine);
    DbgPrint("[lyshark] 驱动卸载完成...");
}

NTSTATUS DriverEntry(IN PDRIVER_OBJECT Driver, PUNICODE_STRING RegistryPath)
{
    DbgPrint("hello lyshark \n");

    PsSetLoadImageNotifyRoutine((PLOAD_IMAGE_NOTIFY_ROUTINE)MyLySharkLoadImageNotifyRoutine);
    DbgPrint("[lyshark] 驱动加载完成...");
    Driver->DriverUnload = UnDriver;
    return STATUS_SUCCESS;
}

运行这个驱动程序,则会输出被加载的驱动详细参数。

标签:函数,Windows,映像,7.3,模块,LoadImage,回调,加载
From: https://www.cnblogs.com/LyShark/p/17870104.html

相关文章

  • Windows下Nginx的重用命令及如何配置后台启动
    Windows下Nginx的常用命令在Windows下使用Nginx,我们需要掌握一些基本的操作命令,比如:启动、停止Nginx服务,重新载入Nginx等,下面我就进行一些简单的介绍。1、启动注意:使用后台启动必须配置daemonon;startnginx【后台启动】nginx.exe【临时启动】2、停止nginx.exe-sstop或......
  • 7.6 Windows驱动开发:内核监控FileObject文件回调
    本篇文章与上一篇文章《内核注册并监控对象回调》所使用的方式是一样的都是使用ObRegisterCallbacks注册回调事件,只不过上一篇博文中LyShark将回调结构体OB_OPERATION_REGISTRATION中的ObjectType填充为了PsProcessType和PsThreadType格式从而实现监控进程与线程,本章我们需要将该......
  • 6.8 Windows驱动开发:内核枚举Registry注册表回调
    在笔者上一篇文章《内核枚举LoadImage映像回调》中LyShark教大家实现了枚举系统回调中的LoadImage通知消息,本章将实现对Registry注册表通知消息的枚举,与LoadImage消息不同Registry消息不需要解密只要找到CallbackListHead消息回调链表头并解析为_CM_NOTIFY_ENTRY结构即可实现枚举......
  • 6.5 Windows驱动开发:内核枚举PspCidTable句柄表
    在Windows操作系统内核中,PspCidTable通常是与进程(Process)管理相关的数据结构之一。它与进程的标识和管理有关,每个进程都有一个唯一的标识符,称为进程ID(PID)。与之相关的是客户端ID,它是一个结构,其中包含唯一标识进程的信息。这样的标识符在进程管理、线程管理和内核对象的创建等......
  • 6.6 Windows驱动开发:内核枚举Minifilter微过滤驱动
    Minifilter是一种文件过滤驱动,该驱动简称为微过滤驱动,相对于传统的sfilter文件过滤驱动来说,微过滤驱动编写时更简单,其不需要考虑底层RIP如何派发且无需要考虑兼容性问题,微过滤驱动使用过滤管理器FilterManager提供接口,由于提供了管理结构以及一系列管理API函数,所以枚举过滤驱动将......
  • Windows使用命令行方法,实现docker默认安装目录修改及更改docker镜像默认保存路径
    一、使用软连接方法,修改Docker默认安装目录查看Windows上安装DockerDesktop官方安装指南:https://docs.docker.com/desktop/install/windows-install/  1、提前在D盘新建Program\Docker,使用这行代码安装:"DockerDesktopInstaller.exe"install--installation-dir......
  • 电脑CentOS 7.6与Windows系统对比:使用方式、优缺点概述
    在多操作系统环境中,CentOS7.6和Windows系统各自独占鳌头,它们在功能、稳定性、兼容性以及安全性等方面都有着各自的优点。这篇文章将对比分析这两个操作系统,以便用户能更好地了解它们的特点和使用方式。一、使用方式1. CentOS7.6CentOS7.6是一种成熟的Linux发行版,它的使用方式主......
  • Windows环境单独安装PLSQL访问ORACLE数据库
        PLSQL(ProceduralLanguage/SQL),由allroundautomations开发,针对ORACLE数据库的扩展开发集成工具。本地未安装ORACLE数据库前提下,安装PLSQL后,还需要同时安装oracleclient或者更轻量级的instantclient客户端程序来访问和控制ORACLE数据库。本文主要介绍两者安装完......
  • Windows安装Powershell7.x
    事件起因:由于需要运行一个脚本,但是该脚本是广大网友群众使用Powershell7写的,我自带的是Powershell5,运行过程中总是出现莫名其妙的问题,于是决定将Powershell升级到Powershell7.4.0解决办法:1、首先确认当前系统自带的Powershell的版本:$PsVersionTable.PSVersion......
  • Windows提权2
    本次学习Windows信任服务路径漏洞,劫持服务启动来进行提权实验原理Windows服务运行时,如果服务路径和快捷方式路径具有一个或多个空格并且没有用引号括起来,Windows会对每一个空格尝试寻找名字与空格前的名字相匹配的程序执行,这样会很容易受到路径拦载,然后造成TrustedServiceP......