千家信息网

驱动DriverEntry的初始化

发表于:2025-02-08 作者:千家信息网编辑
千家信息网最后更新 2025年02月08日,这篇文章将为大家详细讲解有关驱动DriverEntry的初始化,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。一、驱动DriverEntry的初始化从DriverEn
千家信息网最后更新 2025年02月08日驱动DriverEntry的初始化

这篇文章将为大家详细讲解有关驱动DriverEntry的初始化,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

一、驱动DriverEntry的初始化

DriverEntry(PDRIVER_OBJECTDriverObject, UNICODE_STRING *pRegistry)的pRegistry中截取末尾名称去获取并计算出设备名和DosDevices的名字。

pDriverName= pRegistry->Buffer;   Len = pRegistry->Length >> 1;   pFirstName = &pDriverName[Len];   if ( pFirstName == pDriverName )   { LABEL_8:     if ( *pFirstName != '\\' )       goto LABEL_10;   }   else   {     while ( *pFirstName != '\\' )     {       --pFirstName;       if ( pFirstName == pDriverName )         goto LABEL_8; }   }   ++pFirstName;

然后从pRegistry注册表中去获取sysmon的策略规则

使用RtlQueryRegistryValues函数,填入5个RTL_QUERY_REGISTRY_TABLE结构体

RTL_QUERY_REGISTRY_TABLE QueryRegTable[5];RtlInitUnicodeString(&g_ProcessAccessNamesRule,0);  memset(QueryRegTable, 0, 560u);  QueryRegTable[0].Flags = 1;  QueryRegTable[0].Name =L"Parameters";   QueryRegTable[3].EntryContext =&OptionRulesv18;   QueryRegTable[4].EntryContext =&hash_alogrithms;   QueryRegTable[1].Flags = 304;   QueryRegTable[1].Name =g_Name_ProcessAccessNames;   QueryRegTable[1].EntryContext =&g_ProcessAccessNamesRule;   QueryRegTable[1].DefaultType = 0x7000007;   QueryRegTable[1].DefaultData =&unk_10015C34;   QueryRegTable[1].DefaultLength = 4;   QueryRegTable[2].Flags = 304;   QueryRegTable[2].Name = L"ProcessAccessMasks";   QueryRegTable[2].EntryContext =&g_ProcessAccessMasksRule;   QueryRegTable[2].DefaultType = 0x3000000;   QueryRegTable[3].Flags = 304;   QueryRegTable[3].Name =(PWSTR)&g_wOption;   QueryRegTable[3].DefaultType = 0x4000000;   QueryRegTable[4].Flags = 304;   QueryRegTable[4].Name =(PWSTR)&g_wHashingalgorithm;   QueryRegTable[4].DefaultType = 0x4000000;   RtlQueryRegistryValues(0,g_SysmonRegisterPath.Buffer, QueryRegTable, 0, 0);   if ( !g_ProcessAccessNamesRule.Buffer     || g_ProcessAccessNamesRule.Length <= 2u     || g_ProcessAccessNamesRule.MaximumLength<= 4u )   {    RtlFreeUnicodeString(&g_ProcessAccessNamesRule);    RtlInitUnicodeString(&g_ProcessAccessNamesRule, 0);   }  g_OptionRules =(OptionRulesv18 >> 1) & 1;

对应的注册表键分别是L"Parameters"、L"ProcessAccessNames"、L"ProcessAccessMasks" 、L" Option"、L" Hashingalgorithm"

然后再次获取L"Parameters"项下面的对应的L"Rules"的KeyValues信息,这里是驱动设置的规则。

下面展示出部分规则的数组

上面的过程结束后就开始判断操作系统是否支持flt

如果支持只实现IRP_MJ_CREATE、IRP_MJ_CLOSE 、IRP_MJ_DEVICE_CONTROL三个例程,后续会注册miniFlt过滤,如果不支持Flt就使用老的模式Sfilter的模式

DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]= (PDRIVER_DISPATCH)SysmonDispatchIrp;   DriverObject->MajorFunction[IRP_MJ_CLOSE]= (PDRIVER_DISPATCH)SysmonDispatchIrp;   DriverObject->MajorFunction[IRP_MJ_CREATE]= (PDRIVER_DISPATCH)SysmonDispatchIrp;   if ( IsOpenPipeConnect &&!IsSupportFlt )  {   DriverObject->MajorFunction[IRP_MJ_CREATE] =(PDRIVER_DISPATCH)SysmonDispatchIrp;     DriverObject->MajorFunction[1] =(PDRIVER_DISPATCH)SysmonDispatchIrp;    DriverObject->MajorFunction[IRP_MJ_CLOSE] =(PDRIVER_DISPATCH)SysmonDispatchIrp;     DriverObject->MajorFunction[IRP_MJ_READ]= (PDRIVER_DISPATCH)SysmonDispatchIrp;     DriverObject->MajorFunction[IRP_MJ_WRITE]= (PDRIVER_DISPATCH)SysmonDispatchIrp;    DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] =(PDRIVER_DISPATCH)SysmonDispatchIrp;    DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] =(PDRIVER_DISPATCH)SysmonDispatchIrp;    DriverObject->MajorFunction[IRP_MJ_QUERY_EA] =(PDRIVER_DISPATCH)SysmonDispatchIrp;    DriverObject->MajorFunction[IRP_MJ_SET_EA] =(PDRIVER_DISPATCH)SysmonDispatchIrp;    DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] =(PDRIVER_DISPATCH)SysmonDispatchIrp;    DriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION] =(PDRIVER_DISPATCH)SysmonDispatchIrp;    DriverObject->MajorFunction[IRP_MJ_SET_VOLUME_INFORMATION] =(PDRIVER_DISPATCH)SysmonDispatchIrp;     DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL]= (PDRIVER_DISPATCH)SysmonDispatchIrp;    DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] =(PDRIVER_DISPATCH)SysmonDispatchIrp;    DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] =(PDRIVER_DISPATCH)SysmonDispatchIrp;     DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL]= (PDRIVER_DISPATCH)SysmonDispatchIrp;    DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] =(PDRIVER_DISPATCH)SysmonDispatchIrp;    DriverObject->MajorFunction[IRP_MJ_LOCK_CONTROL] = (PDRIVER_DISPATCH)SysmonDispatchIrp;    DriverObject->MajorFunction[IRP_MJ_CLEANUP] =(PDRIVER_DISPATCH)SysmonDispatchIrp;    DriverObject->MajorFunction[IRP_MJ_CREATE_MAILSLOT] =(PDRIVER_DISPATCH)SysmonDispatchIrp;    DriverObject->MajorFunction[IRP_MJ_QUERY_SECURITY] =(PDRIVER_DISPATCH)SysmonDispatchIrp;    DriverObject->MajorFunction[IRP_MJ_SET_SECURITY] =(PDRIVER_DISPATCH)SysmonDispatchIrp;    DriverObject->MajorFunction[IRP_MJ_POWER] =(PDRIVER_DISPATCH)SysmonDispatchIrp;     DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL]= (PDRIVER_DISPATCH)SysmonDispatchIrp;   DriverObject->MajorFunction[IRP_MJ_DEVICE_CHANGE] =(PDRIVER_DISPATCH)SysmonDispatchIrp;    DriverObject->MajorFunction[IRP_MJ_QUERY_QUOTA] =(PDRIVER_DISPATCH)SysmonDispatchIrp;     DriverObject->MajorFunction[IRP_MJ_SET_QUOTA]= (PDRIVER_DISPATCH)SysmonDispatchIrp;  }

然后就是常规过程,IoCreateDevice、IoCreateSymbolicLink。

然后根据操作系统是否支持FltRegisterFilter(Driver, &g_Registration, &g_pFilter);

具体创建了哪些minifilter,接着看结构体

OperationRegistrationdd IRP_MJ_CREATE  ; DATA XREF:.data:10015014↓o.rdata:10013454                 dd 0.rdata:10013458                 dd offset PreOperation.rdata:1001345C                 dd offset PostOperation.rdata:10013460                 dd 0.rdata:10013464                 dd IRP_MJ_CLEANUP.rdata:10013468                 dd 0.rdata:1001346C                 dd offset PreOperation.rdata:10013470                 dd offset PostOperation.rdata:10013474                 dd 0.rdata:10013478                 dd IRP_MJ_SET_INFORMATION.rdata:1001347C                 dd 0.rdata:10013480                 dd offset PreOperation.rdata:10013484                 dd offset PostOperation.rdata:10013488                 dd 0.rdata:1001348C                 dd IRP_MJ_CLOSE.rdata:10013490                 dd 0.rdata:10013494                 dd offset PreOperation.rdata:10013498                 dd offset PostOperation.rdata:1001349C                 dd 0.rdata:100134A0                 dd IRP_MJ_CREATE_NAMED_PIPE.rdata:100134A4                 dd 0.rdata:100134A8                 dd offset PreOperation.rdata:100134AC                 dd offset PostOperation.rdata:100134B0                 dd 0.rdata:100134B4                 dd IRP_MJ_OPERATION_END.rdata:100134B8                 dd 0.rdata:100134BC                 dd 0.rdata:100134C0                 dd 0.rdata:100134C4                 dd 0

从上可以看到minifilter过滤了IRP_MJ_CREATEIRP_MJ_CLEANUPIRP_MJ_SET_INFORMATIONIRP_MJ_CLOSEIRP_MJ_CREATE_NAMED_PIPE

文件系统相关的注册完毕,然后就是设置一些进程、线程相关的回调函数例程

PsSetLoadImageNotifyRoutine(SysmonLoadImageNotifyRoutine); PsSetCreateThreadNotifyRoutine(PsCreateThreadNotifyRoutine); PsSetCreateProcessNotifyRoutine(PsCreateProcessNotifyRoutine, 0);

为了记录注册表sysmon还注册表注册表CmRegisterCallback(RegisterCallback, 0, &Cookie);回调,

为了记录进程open对象的事件注册了ob事件

g_bIsRegisterCallback= 1;  g_OperationRegistration.ObjectType =(POBJECT_TYPE *)PsProcessType;  g_OperationRegistration.Operations = 1;  g_OperationRegistration.PreOperation =PreProcessOperation;  g_OperationRegistration.PostOperation =PostProcessOperation;  g_CallbackRegistration.OperationRegistration= &g_OperationRegistration;  *(_DWORD*)&g_CallbackRegistration.Version = 0x10100;  g_CallbackRegistration.RegistrationContext =0;  RtlInitUnicodeString(&g_CallbackRegistration.Altitude,L"1000");  Status =g_ObRegisterCallbacks(&g_CallbackRegistration, &RegistrationHandle);

为了获取管道的事件,它挂接了设备L\\Device\\NamedPipe,创建了L\\Device\\SysmonPipeFilter的过滤设备

至此sysmon的DriverEntry的初始化动作基本结束了。

二、IRP_MJ_DEVICE_CONTROL例程

Case 0x83400000:

打开驱动开启标志,并且获取且保存当前UI进程的句柄

Case 0x83400004

Ring3请求事件信息,并返回到ring3的缓冲区

Case 0x83400008

加载策略规则

Case 0x8340000C

获取传入进程的相关信息(包括TokenUser、pTokenStatics、TokenGroup、TokenSeesion)

还会获取进程pImagePathName、pCommandLine、CurrentDirectory

获取进程的CreateTime

该事件类型为4或者1

三、文件信息的记录

Minifilter的PreOperation(PFLT_CALLBACK_DATA pData, PFLT_RELATED_OBJECTSFltObjects, PVOID *CompletionContext)例程为主要的判断逻辑例程,先判断当前FileObject的路径是否为管道路径,管道事件直接记录上报事件

特别判断下IRP_MJ_SET_INFORMATION、IRP_MJ_CLEANUP,并且分别上报_,注意在判断IRP_MJ_SET_INFORMATION的时候只记录了RequestorMode是1即USER_MODE,并且是设置FileBasicInformation的请求。

PreOperation处理完毕,则PostOperation(PFLT_CALLBACK_DATA pData, PFLT_RELATED_OBJECTSpFltFileObj, PVOID CompletionContext, int Flags)对前者处理的上下文CompletionContext进行记录日志或者释放的处理,以IRP_MJ_SET_INFORMATION为例,PostOPerate则对PreOperate的CompletionContext的数据进行上报。

四、注册表信息的记录

Sysmon初始化的时候注册了一个注册表过滤,CmRegisterCallback(RegisterCallback, 0, &Cookie);回调函数是NTSTATUS__stdcall RegisterCallback(PVOID CallbackContext, PVOID Argument1, PVOIDArgument2),参数Argument1是过滤的注册表操作类型,sysmon过滤了0(RegNtDeleteKey / RegNtPreDeleteKey) 、4( RegNtRenameKey\RegNtPreRenameKey)、11(RegNtPostCreateKey)、15(RegNtPostDeleteKey)、16(RegNtPostSetValueKey)、17(RegNtPostDeleteValueKey)、19(RegNtPostRenameKey)27(RegNtPostCreateKeyEx)的注册表操作

五、进程操作过滤

Sysmon注册了进程操作过滤,g_ObRegisterCallbacks(&g_CallbackRegistration, &RegistrationHandle);,

他只记录操作类型为OB_OPERATION_HANDLE_CREATE,并且只记录A进程操作B进程,A和B不是同一个进程,注意RtlWalkFrameChain这个函数是获取当前操作线程的线程栈,KeQuerySystemTime(&pOpenInfo.CreateTime);是获取当前系统时间,并且会把这些信息上报。

六、其他重点技术细节

1. 进程模块的枚举

ZwQueryInformationProcess(ProcessHandle, ProcessBasicInformation,&ProcessInformation, 0x18u, 0)获取ProcessInformation的信息,从PebBaseAddress= ProcessInformation.PebBaseAddress;取得进程PEB的地址,在PEB结构中得到LDR的地址,LDR是进程加载模块的结构体,

struct _PEB{UCHAR InheritedAddressSpace;UCHAR ReadImageFileExecOptions;UCHAR BeingDebugged;UCHAR BitField;PVOID Mutant;PVOID ImageBaseAddress;PPEB_LDR_DATA Ldr;PRTL_USER_PROCESS_PARAMETERS ProcessParameters;PVOID SubSystemData;PVOID ProcessHeap;PRTL_CRITICAL_SECTION FastPebLock;PVOID AtlThunkSListPtr;PVOID IFEOKey;ULONG CrossProcessFlags;unsigned __int32 ProcessInJob : 1;unsigned __int32 ProcessInitializing : 1;unsigned __int32 ReservedBits0 : 30;union{PVOID KernelCallbackTable;PVOID UserSharedInfoPtr;};ULONG SystemReserved[1];。。。。。。}

PPEB_LDR_DATA Ldr;这个就是加载模块的结构,有三种加载表内存加载表,加载顺序表,初始化加载表从中可以枚举出模块信息。


struct _PEB_LDR_DATA

{

ULONG Length;

UCHAR Initialized;

PVOID SsHandle;

LIST_ENTRY InLoadOrderModuleList;

LIST_ENTRY InMemoryOrderModuleList;

LIST_ENTRY InInitializationOrderModuleList;

};

2. 进程参数的获取

大致可以看到如下,首先要KeStackAttachProcess进程的空间,然后获取PEB地址,从PEB中的到ProcessParameters的结构

ProcessParameters结构如下:

struct _RTL_USER_PROCESS_PARAMETERS{ULONG MaximumLength;ULONG Length;ULONG Flags;ULONG DebugFlags;PVOID ConsoleHandle;ULONG ConsoleFlags;PVOID StandardInput;PVOID StandardOutput;PVOID StandardError;CURDIR CurrentDirectory;UNICODE_STRING DllPath;UNICODE_STRINGImagePathName;UNICODE_STRING CommandLine;PVOID Environment;ULONG StartingX;ULONG StartingY;ULONG CountX;ULONG CountY;ULONG CountCharsX;ULONG CountCharsY;ULONG FillAttribute;ULONG WindowFlags;ULONG ShowWindowFlags;UNICODE_STRING WindowTitle;UNICODE_STRING DesktopInfo;UNICODE_STRING ShellInfo;UNICODE_STRING RuntimeData;RTL_DRIVE_LETTER_CURDIRCurrentDirectores[32];ULONG EnvironmentSize;};

可以看到该结构中进程参数相关的各种信息。

3. 进程Token相关信息的获取

都是通过ZwQueryInformationToken函数去获取,只是是使用不同的ClassInformation类去获取,定义如下

typedef enum _TOKEN_INFORMATION_CLASS {  TokenUser                             ,  TokenGroups                           ,  TokenPrivileges                       ,  TokenOwner                            ,  TokenPrimaryGroup                     ,  TokenDefaultDacl                      ,  TokenSource                           ,  TokenType                             ,  TokenImpersonationLevel               ,  TokenStatistics                       ,  TokenRestrictedSids                   ,  TokenSessionId                        ,  TokenGroupsAndPrivileges              ,  TokenSessionReference                 ,  TokenSandBoxInert                     ,  TokenAuditPolicy                      ,  TokenOrigin                           ,  TokenElevationType                    ,  TokenLinkedToken                      ,  TokenElevation                        ,  TokenHasRestrictions                  ,  TokenAccessInformation                ,  TokenVirtualizationAllowed            ,  TokenVirtualizationEnabled            ,  TokenIntegrityLevel                   ,  TokenUIAccess                         ,  TokenMandatoryPolicy                  ,  TokenLogonSid                         ,  TokenIsAppContainer                   ,  TokenCapabilities                     ,  TokenAppContainerSid                  ,  TokenAppContainerNumber               ,  TokenUserClaimAttributes              ,  TokenDeviceClaimAttributes            , TokenRestrictedUserClaimAttributes   , TokenRestrictedDeviceClaimAttributes ,  TokenDeviceGroups                     ,  TokenRestrictedDeviceGroups           ,  TokenSecurityAttributes               ,  TokenIsRestricted                     ,  TokenProcessTrustLevel                ,  TokenPrivateNameSpace                 ,  TokenSingletonAttributes              ,  TokenBnoIsolation                     ,  TokenChildProcessFlags                ,  MaxTokenInfoClass} TOKEN_INFORMATION_CLASS, *PTOKEN_INFORMATION_CLASS;

需要获取那个就可以选择那一个。

关于"驱动DriverEntry的初始化"这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。

进程 信息 注册表 结构 事件 驱动 函数 模块 系统 规则 支持 参数 地址 就是 管道 篇文章 类型 线程 设备 处理 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 直接登录服务器能绕过堡垒机么 网络安全科技馆明天起重新开放 河南开封网络安全普察 杭州健康码服务器怎么样了 桌面云和服务器一起管理吗 请求超时 是服务器还是app 网络安全证书查询网 网络用语网络安全手抄报 重庆铜梁金达软件开发有限公司 软件开发最好的工作 传奇4挖矿服务器 广州网络安全工程师薪资 世界最大数据库位于哪 三清三服务器离江西有多远 法院开展国家网络安全周 金蝶显示无法登录到数据库 黑莓服务器+为什么安全 打印服务器支持的操作系统 软件开发公司常见组织结构 仪征新百网络技术 河南开封网络安全普察 春节期间网络安全保障方案 2021计算机网络技术考试 博朗软件开发 中国电信企业网络技术部 软件开发甲方不结尾款 网络安全十大金句图片 软件开发公司代挂 网络安全定义的五大特性 红河长期上门回收服务器
0