zoukankan      html  css  js  c++  java
  • Windows 64位驱动编程基础与win64 ssdt

    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.

    https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/bug-check-0x109---critical-structure-corruption

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

      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中 反汇编即可:

    编写代码如下 :

    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
    ", addr));
    
                      return addr;
    
                 }
    
             }
    
        }
    
        KdPrint(("find ssdt error
    "));
    
        return 0;
    
    }
    

      

    测试结果:

     

  • 相关阅读:
    构建之法(一)
    大二下周总结十四
    寒假学习报告03
    寒假学习报告02
    2019春季学期个人总结
    2019春学习进度报告(第十六周)
    计算英语最长单词连
    2019春学习进度报告(第十五周)
    用户体验评价
    2019春学习进度报告(第十四周)
  • 原文地址:https://www.cnblogs.com/freesec/p/7571454.html
Copyright © 2011-2022 走看看