Win64编程
32位系统逐渐淘汰,转到64位编程相当重要. 但苦于64位驱动编程网上的资料比较杂乱
这里打算写写关于64位驱动编程的内容,当然大部分内容都是从网上搜集过来的,然后汇集到一起好用来学习.
- 准备
双机调试, 加载驱动工具,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; } |
测试结果:
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET制作智能桌面机器人:结合BotSharp智能体框架开发语音交互
· 软件产品开发中常见的10个问题及处理方法
· .NET 原生驾驭 AI 新基建实战系列:向量数据库的应用与畅想
· 从问题排查到源码分析:ActiveMQ消费端频繁日志刷屏的秘密
· 一次Java后端服务间歇性响应慢的问题排查记录
· 互联网不景气了那就玩玩嵌入式吧,用纯.NET开发并制作一个智能桌面机器人(四):结合BotSharp
· Vite CVE-2025-30208 安全漏洞
· 《HelloGitHub》第 108 期
· MQ 如何保证数据一致性?
· 一个基于 .NET 开源免费的异地组网和内网穿透工具