Windbg查看Shadow SSDT

《Linux运维总结:Ubuntu22.04忘记root密码解决方案》 阅读详情

关于SSDT即系统描述符表,《SSDT Hook的妙用-对抗ring0 inline hook》这篇文章描述的已经很清楚了。引用文章中的一段话:

“内核中有两个系统服务描述符表,一个是KeServiceDescriptorTable(由ntoskrnl.exe导出),一个是KeServieDescriptorTableShadow(没有导出)。两者的区别是,KeServiceDescriptorTable仅有ntoskrnel一项,KeServieDescriptorTableShadow包含了ntoskrnel以及win32k。一般的Native API的服务地址由KeServiceDescriptorTable分派,gdi.dll/user.dll的内核API调用服务地址由KeServieDescriptorTableShadow分派。还有要清楚一点的是win32k.sys只有在GUI线程中才加载,一般情况下是不加载的……”

现在我们看看KeServiceDescriptorTable的内容

lkd> dd KeServiceDescriptorTable 
843b0b00  842c5d7c 00000000 00000191 842c63c4 
843b0b10  00000000 00000000 00000000 00000000 
843b0b20  845744f2 843246ab 00000000 01fa8bd2 
843b0b30  00000bb8 00000011 5385d2ba d717548f

可以发现,只有第一项有内容,第二项并没有内容。现在我们要谈的就是以一个可编程实现的思路,用WinDbg获取KeServieDescriptorTableShadow。

在线程的内核对象中即KTHREAD结构里有一个成员是很特殊的,即ServiceTable,在我现在的Win 7 SP1系统下,这个成员的偏移是0x0bc。我们随便在System(4号进程)里找个线程看看这个成员的值,

lkd> dt _kthread 0x863bfd48 
nt!_KTHREAD 
   +0×000 Header           : _DISPATCHER_HEADER 
   +0×010 CycleTime        : 0×23`5c65163e 
   +0×018 HighCycleTime    : 0×23 
   +0×020 QuantumTarget    : 0×23`6050f166 
   +0×028 InitialStack     : 0x80786fd0 Void 
………… 
   +0x0b8 ThreadFlags      : 0n96 
  +0x0bc ServiceTable     : 0x843b0b00 Void 
   +0x0c0 WaitBlock        : [4] _KWAIT_BLOCK 
   +0×120 QueueListEntry   : _LIST_ENTRY [ 0x0 - 0x0 ] 
………… 
lkd> dd 0x843b0b00 
843b0b00  842c5d7c 00000000 00000191 842c63c4 
843b0b10  00000000 00000000 00000000 00000000 
843b0b20  845744f2 843246ab 00000000 01fa8bd2 
843b0b30  00000bb8 00000011 5385d2ba d717548f

会发现恰好这个地址就是KeServieDescriptorTable的地址,KeServieDescriptorTable是被内核导出的,我们并不需要获取。System(4号进程)中0x863bfd48是非GUI线程,然而只有GUI线程的线程内核对象此域才是KeServieDescriptorTableShadow的地址,因此我们如果想要找到获取这个地址,那么必须先从系统中找到一个GUI线程,其实这很简单。

在KTHREAD中,有几个成员是专门负责记录线程的栈的信息的。如StackBase内核态栈的栈基址,StackLimit内核态栈栈边界,LargeStack是否是大内核栈等,其中我们需要关注的是LargeStack。当线程刚被创建时,所有线程都不是GUI线程,只有当线程使用Windows子系统内核服务(win32k.sys)时,Windows才将线程转换为GUI线程。在x86架构的系统中,内核态栈的初始大小是12K(StackBase-StackLimit)。在Windows将一个线程转换成GUI线程时,系统会重新为线程分配一个栈,新的栈是可以改变大小的,称之为大内核栈。同时KTHREAD的LargeStack域由非1变为1,Win32Thread域由0变为非0,这是判断一个线程是不是GUI线程的依据。

下面我们用Windbg来看看这一过程。现在的一个关键问题是如何找一个GUI线程,仔细想想便可知道explorer.exe是一个再好不过的切入点了。explorer.exe是Windows的图形壳,负责管理开始菜单、任务栏等资源,里面必然充斥着大量GUI线程。

首先我们在Windbg里输入!process 0 0,列出当前的所有进程,找出当前的explorer.exe的信息

PROCESS 865d2538  SessionId: 1  Cid: 0f28    Peb: 7ffd3000  ParentCid: 0f00 
    DirBase: 7a0f15a0  ObjectTable: a19f1458  HandleCount: 959. 
    Image: explorer.exe

可知EPROCESS的地址是865d2538,KPROCESS作为EPROCESS的第一个成员,因此地址也是865d2538。在KPROCESS中有一个双链表ThreadListHead将当前进程中的所有线程连接起来

lkd> dt _KPROCESS 865d2538  
nt!_KPROCESS 
   +0×000 Header           : _DISPATCHER_HEADER 
   +0×010 ProfileListHead  : _LIST_ENTRY [ 0x865d2548 - 0x865d2548 ] 
   +0×018 DirectoryTableBase : 0x7a0f15a0 
   +0x01c LdtDescriptor    : _KGDTENTRY 
   +0×024 Int21Descriptor  : _KIDTENTRY 
  +0x02c ThreadListHead   : _LIST_ENTRY [ 0x8655b210 - 0xc2b0f210 ] 
   +0×034 ProcessLock      : 0 
   +0×038 Affinity         : _KAFFINITY_EX 
   +0×044 ReadyListHead    : _LIST_ENTRY [ 0x865d257c - 0x865d257c ] 
   +0x04c SwapListEntry    : _SINGLE_LIST_ENTRY 
   +0×050 ActiveProcessors : _KAFFINITY_EX 
………………

同时在KTHREAD中,这个链表体现在ThreadListEntry

lkd> dt _kthread 
nt!_KTHREAD

………… 
   +0x1bc LegoData         : Ptr32 Void 
   +0×194 SuspendApcFill5  : [47] UChar 
   +0x1c3 LargeStack       : UChar 
   +0x1c4 UserTime         : Uint4B 
   +0x1c8 SuspendSemaphore : _KSEMAPHORE 
   +0x1c8 SuspendSemaphorefill : [20] UChar 
   +0x1dc SListFaultCount  : Uint4B 
   +0x1e0 ThreadListEntry  : _LIST_ENTRY 
   +0x1e8 MutantListHead   : _LIST_ENTRY 
   +0x1f0 SListFaultAddress : Ptr32 Void 
   +0x1f4 ThreadCounters   : Ptr32 _KTHREAD_COUNTERS 
   +0x1f8 XStateSave       : Ptr32 _XSTATE_SAVE

因此,我们查找一个线程的KTHREAD地址就可以是KPROCESS中链表中的一项(0x8655b210)减去KTHREAD中ThreadListEntry的便宜(0x1e0),我们来瞅下:

lkd> dt _kthread 0x8655b210-0x1e0 
nt!_KTHREAD 
   +0×000 Header           : _DISPATCHER_HEADER 
   +0×010 CycleTime        : 0xe`e8408198 
   +0×018 HighCycleTime    : 0xe 
   +0×020 QuantumTarget    : 0xe`ead812a6 
  +0×028 InitialStack     : 0x9ba53fd0 Void 
   +0x02c StackLimit       : 0x9ba51000 Void 
   +0×030 KernelStack      : 0x9ba53ba0 Void 
   +0×034 ThreadLock       : 0 
   …………

   +0x0b8 UmsDispatched    : 0y0 
   +0x0b8 ReservedFlags    : 0y000000000000000000000 (0) 
   +0x0b8 ThreadFlags      : 0n96 
  +0x0bc ServiceTable     : 0x843b0b40 Void 
   +0x0c0 WaitBlock        : [4] _KWAIT_BLOCK 
   +0×120 QueueListEntry   : _LIST_ENTRY [ 0x0 - 0x0 ] 
………… 
   +0x18a OtherPlatformFill : 0 ” 
   +0x18c Win32Thread      : 0xff3bc710 Void 
   +0×190 StackBase        : 0x9ba54000 Void 
   +0×194 SuspendApc       : _KAPC 
   +0×194 SuspendApcFill0  : [1]  "??????" 
   +0×195 ResourceIndex    : 0×1 ” 
   +0×194 SuspendApcFill1  : [3]  "???" 
   +0×197 QuantumReset     : 0×6 ” 
   +0×194 SuspendApcFill2  : [4]  "???" 
   +0×198 KernelTime       : 0x37b 
   +0×194 SuspendApcFill3  : [36]  "???" 
   +0x1b8 WaitPrcb         : 0x84371d20 _KPRCB 
   +0×194 SuspendApcFill4  : [40]  "???" 
   +0x1bc LegoData         : (null) 
   +0×194 SuspendApcFill5  : [47]  "???" 
   +0x1c3 LargeStack       : 0 ” 
…………

此时ServiceTable的值是0x843b0b40,看看里面的内容。 
lkd> dd 0x843b0b40 
843b0b40  842c5d7c 00000000 00000191 842c63c4 
843b0b50  9982a000 00000000 00000339 9982b02c 
843b0b60  00000100 00000000 00000000 843b0b68 
843b0b70  00000210 00000200 00000000 00000000

上述思路如果用编程实现的话,要做的只是PsGetCurrentProcess获取当前线程的所属进程,然后遍历进程链表找到explorer.exe,然后遍历explorer的线程链表,定位到某个线程的KTHREAD,然后比较LargeStack和Win32Thread偏移,判断是不是GUI线程,一遍获取Shadow SSDT。因为要做的只是计算便宜,因此效率也是很高的。

华为OD机试2025C卷-双十一最大花费金额[100分](Java_Python3_C++_C语言_JsNode_Go)实现100%通过率 双十一最大花费金额 - 动态规划解法 摘要:本文介绍了华为OD机试中"双十一最大花费金额"问题的动态规划解法。该问题要求在给定N件商品价格和优惠券面额X的情况下,选择若干商品使总花费不超过X且尽可能大。核心解法采用布尔型动态规划数组,记录每个金额是否可被拼出。算法时间复杂度为O(N*X),空间复杂度为O(X)。通过倒序遍历避免重复选择同一商品,最后从X向下查找第一个可达金额作为答案。文中提供了C++和Java的实现代码,并解释了与经典0-1背包问题的关系。 关键点: 问题本质是0-1背包/子集和问题的变体 阅读详情

相关推荐

F5 GTM DNS 实战指南:智能DNS的监控与健康检查机制

本文深入解析F5 BIG-IP GTM智能DNS的核心机制,重点阐述其监控与探针两大功能如何协同工作。监控器负责深度检查服务器应用健康,确保服务可用性;探针则实时测量网络路径质量,实现基于延迟的智能流量调度。文章通过实战配置步骤,指导如何构建逻辑架构、建立iQuery通信、配置业务级健康检查及探针,从而构建高可用、高性能的全局负载均衡解决方案。

weixin_29240711的博客 469

WINDOWS内核学习笔记1—Shadow SSDT表

近期学习内核的

rosykee的专栏 1086

实战指南:基于Windows Server构建企业级AAA认证体系

本文详细介绍了如何在Windows Server环境下构建企业级AAA认证体系,涵盖AD域服务部署、NPS服务器配置及华为设备对接实战。通过整合Radius协议与AD域账号管理,实现网络设备的统一认证与权限控制,提升企业IT安全管理效率。特别适用于需要零成本实现AAA认证的中大型企业。

weixin_28304023的博客 421

shadow ssdt

假设.有一个目标进程A.. 在驱动中首先获取其EPROCESS.. 然后用这个PsGetNextProcessThread取出其线程.. 然后取出ETHREAD...也等同于KTHREAD..(是第一个字段). 然后关键就是这个ServiceTable..字段.. 关于这个指针..ShadowSSDT Hook系列的文章会说.如果其不是GUI进程则此字段不会指向Sha

lionzl的专栏 1228

ABP多租户实现

abp会调用ITenantStore.Find(Guid)方法去查tenant是否存在。要骗过abp就得自己实现ITenantStore并替换原来的实现。abp会自动解jwt里的tenant id,并且尝试验证它。这时候我们之前实现的ITenantStore就可以骗过abp。你要不想骗它也成,反正这个类是可以依赖注入的,你爱咋验证就咋验证。不用open id dict,只用jwt,让abp轻起来。在原来生成jwt的地方加入tenantId。module上也要加DependsOn。

m0_46704355的博客 471

Superpowers与 OpenSpec、Spec Kit 对比

按照官方仓库定义,Superpowers 是一套构建在 composable skills 之上的完整软件开发工作流。它不是单纯的 prompt 集合,而是把一系列工程动作做成默认流程。一个需要明确的点:Superpowers 并不只偏 Claude Code,根据。

人不风流枉少年 1813

shadow ssdt学习笔记

1。取得shadow ssdt真实地址系统只提供了KeServiceDescriptorTable导出KeServiceDescriptorTableShadow是个未导出结构定义Copy code    typedef struct _SYSTEM_SERVICE_TABLE    {          PNTPROC  ServiceTable;  // array of entry

sea 2336

OData V2 消息在 SAP UI5 中的生成、传播与治理全解

SAP UI5 的 OData V2 消息机制通过自动解析服务端响应头(sap-message)或错误体,将消息推送到全局 MessageModel,实现数据质量保障。关键点包括:1)消息通过目标路径与控件绑定联动,触发高亮等反馈;2)生命周期管理需注意避免自动刷新导致消息丢失;3)常见陷阱如批处理错误重复、内外层消息冲突等可通过精准目标路径或自定义处理器解决。代码示例展示了如何配置模型、消息模型及 MessagePopover 实现端到端消息展示,同时支持控件通过 refreshDataState 自定义

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 231

win 64 Shadow ssdt hook

以下参考黑客防线2012合订本 339页 //下午调代码 搞了这个一天,总是蓝屏,不断检查代码,后来发现了很怪的现象. 自己写的代码不能读取shadow ssdt的偏移内容,但是通过和调试作者的代码输出发现地址确实是一模一样的,但是自己的读不出来,而作者的能 读出来,当直接使用windbg调试时也读不出来. 后来将作者的代码完全复制过来,发现能读取了, ,但是又找不到原因, 只能等以后再...

weixin_30709929的博客 567

B3640 T3 句子反转

要求将这些单词倒序输出。而且对于每个单词,如果是小写词,应当转为大写;如果是大写词,应当转为小写;如果是自然数,应该倒转输出。给定一行句子,每个词之间用空格隔开,要么是全小写英文单词,要么是全大写英文单词,要么是自然数。第一次做的时候0分,两个小时没做出来。仅一行,表示程序对句子的处理结果。仅一行,即需要反转的句子。

小前日记 366

基于深度学习YOLOv10的人脸表情识别系统(附完整资源+PySide6界面+训练代码)

本文介绍了如何基于YOLOv10实现一个人脸表情识别系统。我们从数据集准备、模型训练到PySide6界面实现进行了详细的讲解。通过该系统,用户可以实时检测和分类人脸表情,为情感分析、智能交互等应用场景提供支持。

YOLO 1053

两种方法获取shadow ssdt

<br />ULONG GetShadowSsdtCurrentAddresses( PSSDT_ADDRESS AddressInfo, PULONG Length ) { PSYSTEM_SERVICE_TABLE KeServiceDescriptorTableShadow = NULL; ULONG NumberOfService = 0; ULONG ServiceId = 0; PKAPC_STA

kedebug 2018

大模型安全-生成检测-事实核查-攻击-防御-思考-记忆-融合-语音相关研究 2025年版

本文整理了关于大模型安全领域的综合性资源,包括7篇综述论文、9个安全数据集以及5篇强化学习相关的安全研究论文。主要涉及大模型的对抗攻击、隐私保护、安全评估等方向,涵盖TruthfulQA、ToxiGen等知名数据集和TrustLLM、HarmBench等关键研究。资源包括知乎博主分享、arXiv预印本和顶会论文,并附有详细的中文讲解链接,为研究者提供了系统性的安全研究参考。

CSPhD-winston的博客 3583

Windbg里查看Shadow SSDT

内核当中已经导出了KeServiceDescriptorTable,可以直接在Windbg当中使用dd命令查看,对于Shadow SSDT的地址,在WinXP当中,地址是KeServiceDescriptorTable-0x40.为了查看win32k的SYSTEM_SERVICE_TABLE,记得要切换到具有图形界面的进程上下文当中才能正确查看.KeServiceDescriptorTableSh

GaA.Ra的自留地 in Csdn 4613

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

Shadow SSDT详解、WinDbg查看Shadow SSDT

一、获取ShadowSSDT 好吧,我们已经在R3获取SSDT的原始地址及SDT、SST、KiServiceTbale的关系里面提到:所有的SST都保存在系统服务描述表(SDT)中。系统中一共有两个SDT,一个是ServiceDescriptorTable,另一个是ServiceDescriptorTableShadow。ServiceDescriptor中只有指向KiServic...

515

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

(转)WINDBG查看SHADOW SSDT(方法一)

http://blog.youkuaiyun.com/gaa_ra/article/details/6277657 内核当中已经导出了KeServiceDescriptorTable,可以直接在Windbg当中使用dd命令查看,对于Shadow SSDT的地址,在WinXP当中,地址是KeServiceDescriptorTable-0x40.为了查看win32k的SYSTEM_SERVICE_T...

weixin_38168590的博客 202

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

(转)WINDBG查看SHADOW SSDT(方法二)

http://blog.youkuaiyun.com/debugge/article/details/7626698 关于SSDT即系统描述符表,《SSDT Hook的妙用-对抗ring0 inline hook》这篇文章描述的已经很清楚了。引用文章中的一段话: “内核中有两个系统服务描述符表,一个是KeServiceDescriptorTable(由ntoskrnl.exe导出),一个是KeS...

weixin_30247781的博客 121

使用Windbg查看系统SSDT表与ShadowSSDT表

x86操作系统 1. 查看当前系统是否已经载入win2k.sys的相关符号信息: kd> lm start end module name 80586000 8058f000 kdcom (deferred) 80e03000 81391000 nt (pdb symbols) d:\symb

baggiowangyu的专栏 7116

在windbg中测试shadow ssdt , win32k!NtUserGetForegroundWindow , hook shadow ssdt

在windbg中查看shadow ssdt: 0: kd> lm start end module name 804d8000 806e3000 nt (pdb symbols) I:\Symbols\ntkrpamp.pdb\966DF78E558F483199141B029DF5A9D51\ntkrpamp.p...

a65783305的博客 634

WinDbg x86下查看SSDT SSSDT

前提:设置好操作系统的符号表 SSDT表的查看: kd> x nt!kes*des*table* 80553fe0 nt!KeServiceDescriptorTableShadow =  80554020 nt!KeServiceDescriptorTable =  kd> dd 80554020 80554020 80502b9c 00000000 0000011c 8050301

zhuhuibeishadiao 1567

windbg命令

.hh -> 帮助文档 .prefer_dml 1 -> 启用DML .hh .prefer_dml -> 获取.prefer_dml帮助文档 vertarget

qq726232111的博客 406

SSDT and Shadow SSDT table

参考:http://x86.renejeschke.de/html/file_module_x86_id_313.html http://msdn.microsoft.com/en-us/library/windows/hardware/ff553516(v=vs.85).aspx http://en.wikipedia.org/wiki/Model-specific_register ...

weixin_34362875的博客 1489
上一篇: 巧用Q盘搭建SVN服务器
下一篇: Bug一词的由来
Debug哥
博客等级 码龄14年 9粉丝 5原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值