博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Windows 64位驱动编程基础与win64 ssdt
阅读量:6091 次
发布时间:2019-06-20

本文共 2221 字,大约阅读时间需要 7 分钟。

hot3.png

Win64编程

32位系统逐渐淘汰,转到64位编程相当重要. 但苦于64位驱动编程网上的资料比较杂乱

这里打算写写关于64位驱动编程的内容,当然大部分内容都是从网上搜集过来的,然后汇集到一起好用来学习.

 

  1. 准备

 

双机调试, 加载驱动工具,debgview工具, win10重启后禁用驱动签名. 重启后加载驱动

双机调试:

在win7虚拟机关机状态添加一个基于命名管道的串口,然后设置另一端时应用程序,然后

执行下面命令

64系统开始有个驱动签名机制,没有通过微软签名的驱动无法加载, 我们调试时需要禁用它.

开机按f8后有个禁用驱动签名启动选项, 选择它启动即可.

bcdedit /dbgsettings serial baudrate:115200 debugport:1    (最后的1表示虚拟机中设置的com1)

     bcdedit /copy {current} /d debug     (记住这里返回的id号,下面用到)

            bcdedit /displayorder {current} {ID}    这里的ID设置为第2条命令返回的id

            bcdedit /debug {ID} ON              这里的ID设置为第2条命令返回的id

重启即可.

 

2.代码

对于ULONG 在64编译时自动转为ULONG64

如果是ULONG_PTR 则编译器自动帮我们转换

无类型指针使用PVOID64.

通过KdPrint打印时, %x不用而用%p .

从xp到windows7 64位      像EPROCESS等结构体也有变化,通过windbg可以查看比较.

 

对于驱动代码来说, 因为那些数据类型都有2个版本:以32结尾和以64结尾,它通过在不同环境编译时自动转到目标类型

 

3.Patchguard

说白了,就是微软为了让系统更安全, 不能随随便便就能hook和inline,不能随随便便就能通过修改EPROCESS来隐藏进程.  

这家伙每隔一段时间对系统关键文件,内存区域进行CRC校验,发现不对立刻进行0x109蓝屏.

而且它自己藏在内存中不好通过解决它来绕过patchguard.

上面的网站有列出的被其保护的内容.

 

  4. 64位ssdt表的查找

在32位系统中我们可以通过已导出的结构体名直接操作, 或者搜素函数KeAddSystemServiceTable, 或者通过windbg查看.

但是在64位系统中并没有导出这个结构. 所以需要通过其他方式找到他.

思路1  (这个思路参考黑客防线2011合订本下半年第7页)

通过读取C0000082寄存器 获得KiSystemCall64函数的地址, 因为这个函数没有导出,故通过这种方式.. (相当佩服作者底层知识功底)

在往下搜索0x500个字节左右就能得到KeServiceDescriptorTable地址

在windbg中查看:

而且KeServiceDescriptorTable的特征码是4c8d15

    KeServiceDescriptorTableShadow的特征码是4c8d1d

 

 

 

查找思路是, 将ntoskrnl.exe拖到ida,随便找到一个内核函数,比如ZwCreateFile: 

 

 

所以在KiSystemServiceRepeat 里面就能看到 在加载好符号的windbg中 反汇编即可:

 

编写代码如下 :

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

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

ULONGLONG GetKeSeviceDescriptorTable64()

 

{

 

    PUCHAR startSearchAddress = (PUCHAR)__readmsr(0xC0000082);

 

    PUCHAR endSearchAddress = startSearchAddress + 0x500;

 

    PUCHAR i = 0;

 

    UCHAR b1 = 0, b2 = 0, b3 = 0;

 

    ULONG temp = 0;

 

    ULONGLONG addr = 0;

 

    for ( i = startSearchAddress; i < endSearchAddress; i++)

 

    {

 

         if (MmIsAddressValid(i) && MmIsAddressValid(i + 1) && MmIsAddressValid(i + 2))

 

         {

 

             b1 = *i;

 

             b2 = *(i + 1);

 

             b3 = *(i + 2);

 

             if (b1 == 0x4c && b2 == 0x8d && b3 == 0x15)

 

             {

 

                  memcpy(&temp, i + 3, 4);

 

                  addr = (ULONGLONG)temp + (ULONGLONG)i + 7;//加上指令长度

 

                  KdPrint(("find ssdt is %p\n", addr));

 

                  return addr;

 

             }

 

         }

 

    }

 

    KdPrint(("find ssdt error\n"));

 

    return 0;

 

}

  

 

测试结果:

 

 

转载于:https://my.oschina.net/u/1777508/blog/1936747

你可能感兴趣的文章
js删除数组元素
查看>>
带空格文件名的处理(find xargs grep ..etc)
查看>>
centos使用docker下安装mysql并配置、nginx
查看>>
需要学的东西
查看>>
Linux 获取文件夹下的所有文件
查看>>
对 Sea.js 进行配置(一) seajs.config
查看>>
第六周
查看>>
解释一下 P/NP/NP-Complete/NP-Hard 等问题
查看>>
javafx for android or ios ?
查看>>
微软职位内部推荐-Senior Software Engineer II-Sharepoint
查看>>
sql 字符串操作
查看>>
【转】Android布局优化之ViewStub
查看>>
网络安全管理技术作业-SNMP实验报告
查看>>
根据Uri获取文件的绝对路径
查看>>
Flutter 插件开发:以微信SDK为例
查看>>
.NET[C#]中NullReferenceException(未将对象引用到实例)是什么问题?如何修复处理?...
查看>>
边缘控制平面Ambassador全解读
查看>>
Windows Phone 7 利用计时器DispatcherTimer创建时钟
查看>>
程序员最喜爱的12个Android应用开发框架二(转)
查看>>
vim学习与理解
查看>>