Windows DTrace及实现原理(三) ——ntos初始化Dtrace
前面两篇介绍了windows Dtrace的set以及efi引导启动,这一章讲解windows引导进入系统内核ntos后,ntos是如何初始化DtraceWindows DTrace及实现原理(一) 2025-11-24 03:12:33 Author: www.freebuf.com(查看原文) 阅读量:1 收藏

前面两篇介绍了windows Dtrace的set以及efi引导启动,这一章讲解windows引导进入系统内核ntos后,ntos是如何初始化Dtrace

Windows DTrace及实现原理(一) ——bcdedit.exe的set实现

Windows DTrace及实现原理(二) ——winload.efi启动加载dtrace

KeInitSystem

众所周知,Windows启动初始化分为‌Phase0(阶段0)‌和‌Phase1(阶段1)‌两个阶段,而Dtrace是在操作系统初始化的Phase1KeInitSystem的时候来初始化的,可以看下该函数的逻辑

在KeInitSystem的过程当中,其中有一个步骤是KiInitDynamicTraceSupport()

KiInitDynamicTraceSupport

该函数的大致逻辑是给KiDynamicTraceEnnable默认值是0,当调用TraceInitSystem成功后,KiDynamicTraceEnnable的值就被赋予了 1 | 2 , KiDynamicTraceEnnable= 3, 当判断KdDebuggerNotPresent值不为0时,就是存在内核调试状态,KiDynamicTraceEnnable= 2 | 5,KiDynamicTraceEnnable= 7,主要的功能就在TraceInitSystem是外部驱动的一个导出函数,如果开启了Dtrace功能,这个函数就会被调用成功。

TraceInitSystem

该函数的实现逻辑实在Dtrace.sys中实现,因为KiInitDynamicTraceSupport 会调用这个函数来初始化Dtrace   

系统build号要> 1900,这个版是win10,下面可以在TaceInitSystem函数看到他支持几种信息的callback和probe(探查)

DtEtwpEventCallback : ETW事件信息探查

StpCallbackEntry: Syscall Entry 探查

StpCallbackReturn: SysCall Return 探查

FbtpCallback: 函数边界探查

FtpPidCallback: 进程pid相关的函数探查

调试展示

dtrace.sysTraceInitSystem函数下断点,然后g

在调用进入该函数前可以看到这个汇编代码如下:

可以看到这里指令是 call dtrace!TraceInitSystem (fffff801`40fdd010),说明这个TraceInitSystem实在Dtrace里实现的

可以看到一会停在了该函数的入口点,以及当前调用堆栈       

同时看kb命令看堆栈如下:

# RetAddr               : Args to Child                                                           : Call Site
00 fffff803`cc9e8941     : 00000000`00000000 00000000`00000000  : dtrace!TraceInitSystem
01 fffff803`cca2067b     : 00000000`00000000 00000000`00000000  : nt!KiInitDynamicTraceSupport+0x51
02 fffff803`cc9cba4f     : 00000000`00000001 ffffd401`30e06b10  : nt!KeInitSystem+0x153
03 fffff803`cc4ca713     : fffff803`cc4ca6f0 fffff803`5a63e530  : nt!Phase1InitializationDiscard+0xaf7
04 fffff803`cc25904a     : ffffa585`1f702080 fffff803`cc4ca6f0  : nt!Phase1Initialization+0x23
05 fffff803`cc4741c4     : fffff803`5b87c180 ffffa585`1f702080  : nt!PspSystemThreadStartup+0x5a
06 00000000`00000000     : ffffd401`30e07000 ffffd401`30e01000  : nt!KiStartSystemThread+0x34

dtrace!TraceInitSystem的第一个参数ecx,会返回dtrace内部的dtrace!TraceSystemApi表所在的地址,最后ntoskrnl会对该地址赋值为KiDynamicTraceContext,也就是说dtrace!TraceSystemApi最后会指向KiDynamicTraceContext

dtrace!TraceInitSystem的第二个参数edx会传入KiDynamicTraceCallouts结构体,是个全局的结构体

dtrace!TraceInitSystem的第三个参数edx会传入KiDynamicTraceCallouts结构体,是个全局的地址qword_140D1F2A8,将会被该函数赋值为dtarce!TraceAccessMemory函数

dtrace!TraceInitSystem调用结束后,可以看到eax返回值为0,表示成功

由上可以看到ntos初始化系统内核的Phase1的时候会调用Dtrace.sysTraceInitSystem来初始化Dtrace的一些结构体,其调用图如下:          


文章来源: https://www.freebuf.com/articles/endpoint/458681.html
如有侵权请联系:admin#unsafe.sh