写在前面

  此系列是本人一个字一个字码出来的,包括示例和实验截图。由于系统内核的复杂性,故可能有错误或者不全面的地方,如有错误,欢迎批评指正,本教程将会长期更新。 如有好的建议,欢迎反馈。码字不易,如果本篇文章有帮助你的,如有闲钱,可以打赏支持我的创作。如想转载,请把我的转载信息附在文章后面,并声明我的个人信息和本人博客地址即可,但必须事先通知我

你如果是从中间插过来看的,请仔细阅读 羽夏看Win系统内核——简述 ,方便学习本教程。

  看此教程之前,问一个问题,你明确学系统调用的目的了吗? 没有的话就不要继续了,请重新学习 羽夏看Win系统内核——系统调用篇 里面的内容。


华丽的分割线


SSDT

  SSDT的全称是System Services Descriptor Table,意为系统服务描述符表。在32位XP中,我们可以通过ETHREAD结构体加偏移的方式进行访问。在内核文件中,有一个变量是导出的:KeServiceDescriptorTable。通过它我们可以访问SSDT

  我们在WinDbg看一看SSDT是什么样子:

  1. kd> dd KeServiceDescriptorTable
  2. 80553fa0 80502b8c 00000000 0000011c 80503000
  3. 80553fb0 00000000 00000000 00000000 00000000
  4. 80553fc0 00000000 00000000 00000000 00000000
  5. 80553fd0 00000000 00000000 00000000 00000000
  6. 80553fe0 00002730 bf80c0b6 00000000 00000000
  7. 80553ff0 bad6da80 ba0deb60 89c3e0f0 ba6bf8e8
  8. 80554000 00000000 00000000 00000000 00000000
  9. 80554010 0ceb6c40 01d7db79 00000000 00000000

  SSDT有四个成员,每个成员都是一张系统服务表。根据系统服务表的结构,它有四个四字节的成员,第一个是函数地址表,第二个是调用次数,第三个是函数个数,最后一个是参数个数表,我们之前用过ReadProcessMemory做的实验,它的服务号是0xBA,我们做一下测试:

  1. kd> dd 80502b8c+ba*4
  2. 80502e74 805aa712 805c99e0 8060ea76 8060c43c
  3. 80502e84 8056f0d2 8063ab56 8061aca8 8061d332
  4. 80502e94 8059b804 8059c7cc 8059c1d4 8059baee
  5. 80502ea4 805bf456 80598d62 8059908e 805bf264
  6. 80502eb4 806064b6 8051ee82 8061cc3e 805cbd40
  7. 80502ec4 805cbc22 8061cd3a 8061ce20 8061cf48
  8. 80502ed4 8059a07c 8060db50 8060db50 805c892a
  9. 80502ee4 8063d80e 8060be28 80607fb8 8060882a
  10. kd> uf 805aa712
  11. 805aa712 6a1c push 1Ch
  12. 805aa714 68d8a44d80 push offset nt!MmClaimParameterAdjustDownTime+0x90 (804da4d8)
  13. 805aa719 e8f2e7f8ff call nt!_SEH_prolog (80538f10)
  14. 805aa71e 64a124010000 mov eax,dword ptr fs:[00000124h]
  15. 805aa724 8bf8 mov edi,eax
  16. 805aa726 8a8740010000 mov al,byte ptr [edi+140h]
  17. 805aa72c 8845e0 mov byte ptr [ebp-20h],al
  18. 805aa72f 8b7514 mov esi,dword ptr [ebp+14h]
  19. 805aa732 84c0 test al,al
  20. 805aa734 7466 je nt!NtReadVirtualMemory+0x8a (805aa79c) Branch
  21. kd> db 80503000+ba
  22. 805030ba 14 04 08 0c 14 08 08 0c-08 10 14 08 04 08 0c 04 ................
  23. 805030ca 08 0c 0c 04 08 08 0c 0c-24 08 08 08 0c 04 08 04 ........$.......
  24. 805030da 10 08 04 04 04 14 14 10-10 10 10 10 10 08 14 18 ................
  25. 805030ea 04 04 10 0c 08 14 0c 0c-08 08 1c 0c 04 18 14 04 ................
  26. 805030fa 10 04 04 04 08 18 08 08-08 00 10 10 04 04 08 14 ................
  27. 8050310a 10 08 08 10 14 0c 04 04-24 24 18 14 00 10 0c 10 ........$$......
  28. 8050311a 10 00 00 00 00 00 cc cc-cc cc cc cc cc cc 0f 57 ...............W
  29. 8050312a c0 b8 40 00 00 00 0f 2b-41 00 0f 2b 41 10 0f 2b ..@....+A..+A..+

  是不是逐个对应起来了?那么我们如何在驱动程序使用呢?我们只需要在驱动程序输入这行代码声明即可。

  1. extern PKSERVICE_TABLE_DESCRIPTOR KeServiceDescriptorTable;

  注意,PKSERVICE_TABLE_DESCRIPTOR是自己构造的系统服务表指针,结构体需要自行编写,我们来测试一下:

  1. #include <ntddk.h>
  2. extern ULONG KeServiceDescriptorTable; //只是为了访问地址,就不写那个结构体了
  3. NTSTATUS UnloadDriver(PDRIVER_OBJECT DriverObject)
  4. {
  5. DbgPrint("卸载成功!!!");
  6. }
  7. NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
  8. {
  9. DriverObject->DriverUnload = UnloadDriver;
  10. DbgPrint("SSDT 的地址:%X", KeServiceDescriptorTable);
  11. return STATUS_SUCCESS;
  12. }

  演示效果如下:

  如果你细心地发现,咱操作系统系统服务表不是用了两个吗?的确,但SSDT并没有导出与GUI相关的服务表。那么如何别的方式找到呢?接下来我们来介绍SSDTShadow

SSDTShadow

  SSDTShadowSSDT不一样的是它并没有从内核文件导出。不过我们还是可以从WinDbg找到它:

  1. kd> dd KeServiceDescriptorTableShadow
  2. 80553f60 80502b8c 00000000 0000011c 80503000
  3. 80553f70 bf999b80 00000000 0000029b bf99a890
  4. 80553f80 00000000 00000000 00000000 00000000
  5. 80553f90 00000000 00000000 00000000 00000000
  6. 80553fa0 80502b8c 00000000 0000011c 80503000
  7. 80553fb0 00000000 00000000 00000000 00000000
  8. 80553fc0 00000000 00000000 00000000 00000000
  9. 80553fd0 00000000 00000000 00000000 00000000

  它的结构和SSDT是一模一样的,只不过它多了一张表,就是少的那个与GUI相关的服务表。那么我们能不能直接用驱动访问这张表呢?答案是不行,我们用WinDbg测试一下。

  1. kd> dd bf999b80
  2. ReadVirtual: bf999b80 not properly sign extended
  3. bf999b80 ???????? ???????? ???????? ????????
  4. bf999b90 ???????? ???????? ???????? ????????
  5. bf999ba0 ???????? ???????? ???????? ????????
  6. bf999bb0 ???????? ???????? ???????? ????????
  7. bf999bc0 ???????? ???????? ???????? ????????
  8. bf999bd0 ???????? ???????? ???????? ????????
  9. bf999be0 ???????? ???????? ???????? ????????
  10. bf999bf0 ???????? ???????? ???????? ????????

  嘿嘿,是不是人傻了?根本看不到,是为什么呢?根据我们学过的段页的知识很容易地判断出没有挂物理页。并不是每一个应用程序都是有GUI,有的是后台没界面的。我们绑定一个GUI进程看一看:

  1. kd> !process 0 0
  2. **** NT ACTIVE PROCESS DUMP ****
  3. (***省略无关进程***)
  4. Failed to get VadRoot
  5. PROCESS 89b28768 SessionId: 0 Cid: 06cc Peb: 7ffd9000 ParentCid: 05d8
  6. DirBase: 157001a0 ObjectTable: e1d763f8 HandleCount: 44.
  7. Image: notepad.exe
  8. kd> .process 89b28768
  9. ReadVirtual: 89b28780 not properly sign extended
  10. Implicit process is now 89b28768
  11. WARNING: .cache forcedecodeuser is not enabled
  12. kd> dd bf999b80
  13. ReadVirtual: bf999b80 not properly sign extended
  14. bf999b80 bf935f7e bf947b29 bf88ca52 bf93f6f0
  15. bf999b90 bf949140 bf936212 bf9362b7 bf83b4cd
  16. bf999ba0 bf948a67 bf934a17 bf94905f bf90f2f4
  17. bf999bb0 bf902318 bf809fdf bf948f31 bf94a72d
  18. bf999bc0 bf900c15 bf893b44 bf94900f bf94a860
  19. bf999bd0 bf820f34 bf8dcb55 bf87a2e4 bf8c29a0
  20. bf999be0 bf91052f bf80e2c5 bf8dc7fd bf94a525
  21. bf999bf0 bf94b430 bf813a71 bf80cf90 bf8d14e4

  是不是可以正常访问了?我们随便u一个试试:

  1. kd> u bf935f7e
  2. ReadVirtual: bf935f7e not properly sign extended
  3. bf935f7e ?? ???
  4. ^ Memory access error in 'u bf935f7e'

  发现不成功,并不代表每一个函数不行,我们再随便u一个试试:

  1. kd> u bf949140
  2. ReadVirtual: bf949140 not properly sign extended
  3. bf949140 6a5c push 5Ch
  4. ReadVirtual: bf949150 not properly sign extended
  5. bf949142 68804599bf push offset win32k!`string'+0x4dc (bf994580)
  6. ReadVirtual: bf949152 not properly sign extended
  7. bf949147 e8bc7aebff call win32k!_SEH_prolog (bf800c08)
  8. bf94914c 33db xor ebx,ebx
  9. bf94914e 43 inc ebx
  10. bf94914f 33f6 xor esi,esi
  11. bf949151 8975e4 mov dword ptr [ebp-1Ch],esi
  12. bf949154 39750c cmp dword ptr [ebp+0Ch],esi

  SSDTShadow就介绍到这里了,感兴趣地自行继续研究。

本节练习

本节的答案将会在下一节的正文给出,务必把本节练习做完后看下一个讲解内容。不要偷懒,实验是学习本教程的捷径。

  俗话说得好,光说不练假把式,如下是本节相关的练习。如果练习没做好,就不要看下一节教程了,越到后面,不做练习的话容易夹生了,开始还明白,后来就真的一点都不明白了。本节练习只有一个,请保质保量的完成。

1️⃣ 写代码保护指定进程(比如记事本),防止别人关闭它,而自己关闭正常退出。

下一篇

  系统调用篇——总结与提升

系统调用篇——SSDT的更多相关文章

  1. 羽夏看Win系统内核——系统调用篇

    写在前面   此系列是本人一个字一个字码出来的,包括示例和实验截图.由于系统内核的复杂性,故可能有错误或者不全面的地方,如有错误,欢迎批评指正,本教程将会长期更新. 如有好的建议,欢迎反馈.码字不易, ...

  2. 鸿蒙内核源码分析(系统调用篇) | 开发者永远的口头禅 | 百篇博客分析OpenHarmony源码 | v37.03

    百篇博客系列篇.本篇为: v37.xx 鸿蒙内核源码分析(系统调用篇) | 开发者永远的口头禅 | 51.c.h .o 任务管理相关篇为: v03.xx 鸿蒙内核源码分析(时钟任务篇) | 触发调度谁 ...

  3. 鸿蒙内核源码分析(信号消费篇) | 谁让CPU连续四次换栈运行 | 百篇博客分析OpenHarmony源码 | v49.04

    百篇博客系列篇.本篇为: v49.xx 鸿蒙内核源码分析(信号消费篇) | 谁让CPU连续四次换栈运行 | 51.c.h .o 进程管理相关篇为: v02.xx 鸿蒙内核源码分析(进程管理篇) | 谁 ...

  4. 鸿蒙内核源码分析(fork篇) | 一次调用,两次返回 | 百篇博客分析OpenHarmony源码 | v45.03

    百篇博客系列篇.本篇为: v45.xx 鸿蒙内核源码分析(Fork篇) | 一次调用,两次返回 | 51.c.h .o 进程管理相关篇为: v02.xx 鸿蒙内核源码分析(进程管理篇) | 谁在管理内 ...

  5. 鸿蒙内核源码分析(任务切换篇) | 看汇编如何切换任务 | 百篇博客分析OpenHarmony源码 | v41.03

    百篇博客系列篇.本篇为: v41.xx 鸿蒙内核源码分析(任务切换篇) | 看汇编如何切换任务 | 51.c.h .o 任务管理相关篇为: v03.xx 鸿蒙内核源码分析(时钟任务篇) | 触发调度谁 ...

  6. 鸿蒙内核源码分析(寄存器篇) | 小强乃宇宙最忙存储器 | 百篇博客分析OpenHarmony源码 | v38.02

    百篇博客系列篇.本篇为: v38.xx 鸿蒙内核源码分析(寄存器篇) | 小强乃宇宙最忙存储器 | 51.c.h .o 硬件架构相关篇为: v22.xx 鸿蒙内核源码分析(汇编基础篇) | CPU在哪 ...

  7. 鸿蒙内核源码分析(CPU篇) | 整个内核就是一个死循环 | 祝新的一年牛气冲天 ! | v32.02

    百篇博客系列篇.本篇为: v32.xx 鸿蒙内核源码分析(CPU篇) | 整个内核就是一个死循环 | 51.c.h .o 任务管理相关篇为: v03.xx 鸿蒙内核源码分析(时钟任务篇) | 触发调度 ...

  8. 鸿蒙内核源码分析(并发并行篇) | 听过无数遍的两个概念 | 百篇博客分析OpenHarmony源码 | v25.01

    百篇博客系列篇.本篇为: v25.xx 鸿蒙内核源码分析(并发并行篇) | 听过无数遍的两个概念 | 51.c.h .o 任务管理相关篇为: v03.xx 鸿蒙内核源码分析(时钟任务篇) | 触发调度 ...

  9. 鸿蒙内核源码分析(线程概念篇) | 是谁在不停的折腾CPU? | 百篇博客分析OpenHarmony源码 | v21.06

    百篇博客系列篇.本篇为: v21.xx 鸿蒙内核源码分析(线程概念篇) | 是谁在不断的折腾CPU | 51.c.h .o 任务管理相关篇为: v03.xx 鸿蒙内核源码分析(时钟任务篇) | 触发调 ...

随机推荐

  1. 关于国密HTTPS 的那些事(一)

    关于国密HTTPS 的那些事(一) 随着<密码法>密码法的颁布与实施,国密的应用及推广终于有法可依.而对于应用国密其中的一个重要组成部分----国密HTTPS通信也应运而生.为了大家更好的 ...

  2. Zookeeper原理系列-Paxos协议的原理和Zookeeper中的应用分析

    Paxo算法介绍 Paxos算法是莱斯利·兰伯特(Leslie Lamport)1990年提出的一种基于消息传递的一致性算法. Paxos产生背景 Paxos算法是基于消息传递且具有高度容错特性的一致 ...

  3. Windows 11 正式版 Build 22000.194 官方简体中文版、英文版(消费者版、商业版)下载

    昨天阿三正式发布了 Windows 11,版本号竟然是 22000.194,也就是 9 月 16 日的 测试版 22000.194,仅仅是文件改了个名,特别是消费者版本 hash 校验都是一致的. W ...

  4. 把之前CompletableFuture留下的坑给填上。

    你好呀,我是歪歪. 填个坑吧,把之前一直欠着的 CompletableFuture 给写了,因为后台已经收到过好几次催更的留言了. 这玩意我在之前写的这篇文章中提到过:<面试官问我知不知道异步编 ...

  5. 浅析InnoDB引擎的索引和索引原理

    浅析InnoDB引擎的索引和索引原理 什么是InnoDB的索引 InnoDB的索引就是一颗B+树.页是InnoDB引擎在内存和磁盘之间交换数据的基本单位,页的大小一般是16KB,页的大小可以在启动My ...

  6. Frida高级逆向-Hook Native(Java So)2

    Frida Hook So 一些操作说明 Native方法第一个参数是 JNIEnv *env 如何在Frida中获取 JNIEnv 对象呢? Java.vm.getEnv(); 如何将string类 ...

  7. scala基础篇 源码中 :_*的作用

    在scala源码中有大量的:_*,其作用是把Array.list转换为参数列表,作为变长参数传入参数列表 例子: def sumx(a:Int*)={ a.sum } val a=Range(1,9) ...

  8. BUAA软件工程个人项目作业

    BUAA软件工程个人项目作业 项目 内容 这个作业属于哪个课程 2020春季计算机学院软件工程(罗杰 任健) 这个作业的要求在哪里 个人项目作业 我在这个课程的目标是 学习软件开发的流程 这个作业在哪 ...

  9. 2020年OO助教工作总结

    随着这学期课程的落幕,我一学期的OO助教工作也宣告结束.这学期我的工作主要在系统组,和OO后台的数据库打交道. 作业查重 我几乎每周都会做的例行工作,是对每周的homework进行查重管理.由于使用了 ...

  10. Spring Authorization Server的使用

    Spring Authorization Server的使用 一.背景 二.前置知识 三.需求 四.核心代码编写 1.引入授权服务器依赖 2.创建授权服务器用户 3.创建授权服务器和客户端 五.测试 ...