Shadow SSDT详解、WinDbg查看Shadow SSDT
一、获取ShadowSSDT
好吧,我们已经在R3获取SSDT的原始地址及SDT、SST、KiServiceTbale的关系里面提到:所有的SST都保存在系统服务描述表(SDT)中。系统中一共有两个SDT,一个是ServiceDescriptorTable,另一个是ServiceDescriptorTableShadow。ServiceDescriptor中只有指向KiServiceTable的SST,而ServiceDescriptorTableShadow则包含了所有的两个SST。SSDT是可以访问的,而SSDTShadow是不公开的。
所以结论是ServiceDescriptorTable是导出的,而ServiceDescriptorTableShadow是未导出的。那我们是不是就获取不了ServiceDescriptorTableShadow的地址呢?未导出未必就不能得到。其实在KeAddSystemServiceTable这个导出函数里面是有ServiceDescriptorTableShadow的地址的。我们来反汇编看一下。
我们看到在这个函数里面ServiceDescriptorTable的地址和ServiceDescriptorTableShadow都是可以找到的。
其实 KeServiceDescriptorTableShadow包含4个子结构,其中第一个就是ntoskrnl.exe ( native api ),和KeServiceDescriptorTable指向一样 我们真正需要获得的是第二个win32k.sys (gdi/user support),第三个和第四个一般不使用。
如何定位ServiceDescriptorTableShadow呢?
①硬编码:
//for xp
if(gKernelVersion==WINXP)
KeServiceDescriptorTableShadow=KeServiceDescriptorTable-0×40;
//for 2k
if(gKernelVersion==WIN2K)
KeServiceDescriptorTableShadow=KeServiceDescriptorTable+0xE0;
//for win7 32
if(gKernelVersion==WIN7X86)
KeServiceDescriptorTableShadow=KeServiceDescriptorTable+0×40;
②根据KeAddSystemServiceTable来搜索
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
ULONG GetAddressOfShadowTable()
{ ULONG i; UCHAR* p; ULONG dwordatbyte; UNICODE_STRING usKeAddSystemServiceTable; RtlInitUnicodeString(&usKeAddSystemServiceTable, L"KeAddSystemServiceTable"); p = (UCHAR*)MmGetSystemRoutineAddress(&usKeAddSystemServiceTable); for (i = 0; i < 4096; i++,p++) if(MmIsAddressValid((PVOID)dwordatbyte)) |
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
PULONG GetAddressOfShadowTable2()
{ PUCHAR Buff; PUCHAR p; UNICODE_STRING usKeAddSystemServiceTable; PULONG ShadowTable = NULL; RtlInitUnicodeString(&usKeAddSystemServiceTable, L"KeAddSystemServiceTable"); |
获取到KeServiceDescriptorTableShadow的地址后,我们用windbg来看一下ShadowSSDT里面保存的函数数组。
我们看到KeServiceDescriptorTableShadow里面既有ntoskrnl.exe 的服务函数表也有win32k.sys 的服务函数表。
然后我们来看看win32k.sys 的服务函数表里面的数组。
一大堆????????是因为访问不到ShadowSSDT的里面的函数地址。
网上很多说法是只有GUI进程才能访问ShadowSSDT。我们切换到explorer.exe进程试试。
这样确实可以得到ShadowSSDT的函数地址。
引用黑月教主文章里面的一段话。
MJ说win32k.sys和Session有关,也就是说,win32k.sys在Session Leader(Csrss.exe)及属于该Session的任何一个进程空间中都可以访问。
WindowsXP下系统服务和第一个登录用户共享同一个Session,即Session 0,Vista/Win7中采用了Session隔离,系统服务使用Session 0,第一个用户使用Session 1,其它依次类推。
在这两种系统中,都是遵守这个规则的。但是有一个特殊的不属于任何Session的进程,就是Session Manager(Smss.exe)。
切换到Smss.exe进程空间看一看:
kd> dt_eprocess 8501d3e8 ImageFileName
nt!_EPROCESS
+0x16c ImageFileName : [15] “smss.exe”
kd> .process 8501d3e8
Implicit process is now 8501d3e8
WARNING: .cache forcedecodeuser is not enabled
kd> dd 8fc25000
bf800000 ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ????????????????
bf800010 ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ????????????????
bf800020 ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ????????????????
bf800030 ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ????????????????
bf800040 ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ????????????????
bf800050 ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ????????????????
bf800060 ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ????????????????
bf800070 ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ????????????????
kd> !pte 8fc25000
VA 8fc25000
PDE at C06023F0 PTE at C047E128
contains 0000000000000000
not valid
在Session Manager的进程空间中,win32k.sys也是无法访问的,因为它不属于任何一个Session.
观察一下进程可以看到了:
也就是说,除了System进程和Smss进程,在其它任何一个属于某个Session进程内都可以访问win32k.sys,并非只有GUI进程才能访问。
二、如何HOOK?
似乎这个问题并不大,shadow ssdt和ssdt本质上都是1个地址表,最为简单的方法是把你的函数替换地址表的对应项,具体hook代码甚至可以完全照抄ssdt的,这里只说下几个遇到的小问题。
1。win32k.sys不是常在内存的,如果不是GUI线程,shadow ssdt地址无效
解决办法:
1。在driverdispatch中hook
driverdispatch是位于执行driveriocontrol的线程上下文的
我们使用1个GUI线程去driveriocontrol
2。attachtoprocess
这里我们使用explorer.exe进程。
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
VOID KeAttachCsrss()
{ NTSTATUS status; PEPROCESS exlorerEproc; PKAPC_STATE ApcState; ULONG i; DbgPrint("GetExplorerIdByEnumProcess ==> %d", GetExplorerIdByEnumProcess()); DbgPrint("KeServiceDescriptorTableShadow=%x \r\n",KeServiceDescriptorTableShadow); status = PsLookupProcessByProcessId((HANDLE)GetExplorerIdByEnumProcess(), &exlorerEproc); if (!NT_SUCCESS( status )) for (i=0;i<KeServiceDescriptorTableShadow->win32k.NumberOfService;i++) KeUnstackDetachProcess(ApcState); |
其中GetExplorerIdByEnumProcess这个方法的实现,只需要简单的遍历进程活动链表即可。
三、获取ShadowSSDT函数名
比较简单的应该算是设计张函数名表和用symbol的方法。
这办法简单的原因是我只需要一个win32k.sys,win32k.pdb,以及调用不到10个的API就能完成工作。
1.调用SymInitialize初始化Dbghelp这系列的函数。
2.调用ImageLoad读取文件win32.sys。
3.调用SymLoadModule来读取pdb文件。
4.调用SymEnumSymbols枚举符号,其中一个参数是回调函数SymEnumSymbolsProc,that’s the key。
SymEnumSymbolsProc中有一个系统会帮忙填充一个为PSYMBOL_INFO结构的参数。在这个结构中我主要用到的是Name和Address。
5.调用ImageUnload和SymCleanup做一些清理工作。
首先是获得W32pServiceTable的地址。熟悉ShadowSSDT都知道,W32pServiceTable是在内核初始化用来填充ShadowSSDT的表。
然后,知道了W32pServiceTable的地址,后面的事情也很容易。用SymEnumSymbolsProc把ShadowSSDT每个函数的地址和函数名保存下来。
但是我并不推荐使用这种方法来获取ShadowSSDT的函数地址。pdb文件也有几M吧,还需要去请求pdb文件,还得看网络环境。
所以还不如使用硬编码吧。。。
本文链接:http://www.blogfshare.com/shadowssdt-explain-in-detail.html
jpg 改 rar
Shadow SSDT详解、WinDbg查看Shadow SSDT的更多相关文章
- /etc/shadow字段详解
1)/etc/shadow 概说: /etc/shadow文件是/etc/passwd 的影子文件,这个文件并不由/etc/passwd 而产生的,这两个文件是应该是对应互补的:shadow内容包括用 ...
- linux /etc/shadow文件详解
struct spwd { char *sp_namp; /* user login name */ char *sp_pwdp; /* encrypted password */ long int ...
- ulimit 命令详解 socket查看linux最大文件打开数
ulimit 命令详解 Linux对于每个用户,系统限制其最大进程数.为提高性能,可以根据设备资源情况,设置各linux 用户的最大进程数 可以用ulimit -a 来显示当前的各种用户进程限 ...
- linux 系统中 /etc/passwd 和 /etc/shadow文件详解
链接地址:http://blog.csdn.net/yaofeino1/article/details/54616440
- du 使用详解 linux查看目录大小 linux统计目录大小并排序 查看目录下所有一级子目录文件夹大小 du -h --max-depth=1 |grep [
常用命令 du -h --max-depth=1 |grep [TG] |sort #查找上G和T的目录并排序 du -sh #统计当前目录的大小,以直观方式展现 du -h --max-d ...
- 详解Linux查看实时网卡流量的几种方式(转)
转自https://www.jb51.net/article/112965.htm 假如Keepalived有10个VIP,怎么查看每个VIP的流量呢? 这里就可以使用sar命令查看网卡流量了.前提是 ...
- sqlserver锁机制详解(sqlserver查看锁)
简介 在SQL Server中,每一个查询都会找到最短路径实现自己的目标.如果数据库只接受一个连接一次只执行一个查询.那么查询当然是要多快好省的完成工作.但对于 大多数数据库来说是需要同时处理多个查询 ...
- TOP命令 详解CPU 查看多个核心的利用率按1
top命令是linux下常用的工具,可以查看各个进程的CPU使用情况.先看一个实例: 这是Ramnode双核VPS的top显示结果: 左上角可以看到CPU的使用率是11.3%,但是看下面的进程,plu ...
- who命令参数及用法详解(linux查看在线用户命令)
功能说明:显示目前登入系统的用户信息. 语 法:who [-Himqsw][--help][--version][am i][记录文件] 补充说明:执行这项指令可得知目前有那些用户登入系统,单独执 ...
随机推荐
- Android webView解析URL参数
2015年6月18日 13:56:21 星期四 又当爹又当娘啊............ public void onPageFinished(WebView view, String url) { s ...
- ACM/ICPC 之 数论-费马大定理(HNUOJ 13371)
好歹我是数学专业的学生,还是要写写训练的时候遇到的数学问题滴~~ 在ACM集训的时候在各高校OJ上也遇见过挺多的数学问题,例如大数的处理,素数的各种算法,几何问题,函数问题(单调,周期等性质),甚至是 ...
- [转载]Linux命令笔记
*以下内容均来自于网络转载,感谢原作者分享 <对Linux新手非常有用的20个命令> 传送门 英文原文为“Switching From Windows to Nix or a Newbie ...
- webpack学习笔记一
主要参考: https://blog.madewithlove.be/post/webpack-your-bags/ 起因: 作为运维狗, 对前端一窍不通但心向往之, 最近做一个Dashboard, ...
- DB2中错误信息说明
DB2错误信息SQLCODE SQLSTATE (按sqlcode排序) .分类: db2数据库 2012-10-19 11:35 2942人阅读 评论(0) 收藏 举报 db2sql存储table数 ...
- IOS - 控件的AutoresizingMask属性
在 UIView 中有一个autoresizingMask的属性,它对应的是一个枚举的值(如下),属性的意思就是自动调整子控件与父控件中间的位置,宽高. enum { UIViewAutoresi ...
- VS2013调试时,IIS Express Worker Process 已停止工作
之前调试都没有报错的,今天突然报错了,然后网上找了下资料,很快解决了问题 这是我报错的提示 解决办法: 用管理员身份运行CMD,输入netsh winsock reset并回车(注意,必须是已管理员身 ...
- mongodb3.x用户角色
用户和角色是多对多的关系,一个用户可以对应多个角色,一个角色可以拥有多个用户.用户角色的不同对应的权限也是不一样的.下面是一些分配给用户的常见的角色. read ...
- Swift - 多行文本输入框(UITextView)
1,多行文本控件的创建 1 2 3 4 let textview = UITextView(frame:CGRect(x:10, y:100, width:200, height:100)) text ...
- UML类图五种关系与代码的对应关系
转: UML类图中的五种关系的耦合强弱比较:依赖<关联<聚合<组合<继承 一.依赖关系: (一)说明 虚线+箭头 可描述为:Uses a 依赖是类的五种关系中耦合最小的一种关系 ...