内核第三讲,进入ring0,以及编写第一个内核驱动程序.
内核第三讲,进入ring0,以及编写第一个内核驱动程序.
PS: 请下配置双机调试,下方有可能用到.如果不配置,则你可以不用调试, 博客连接: http://www.cnblogs.com/iBinary/p/8260969.html
一丶进入ring0之前的简介
进入0环之前,我们要明白操作系统的设计,操作系统允许驱动程序使用In out等等特权指令来操作高2G的内存.那么必然会有接口.
图示如下.
那么我们可以模拟一个驱动程序来进入0环.
而操作系统提供的接口的,有专门的名称. 叫做DDK, 现在改名为WDK了.
DDK: Driver Development Kit 驱动程序开发包,例如我们写的3环系统下,用到的SDK,也可以成为是API.只不过现在叫做内核方法(内核函数)了.
WDK:Windows Driver Kit
WDK是DDK升级而来的.操作系统为了支持热插拔,所以对DDK升级了.热插拔就是U盘插入系统.不用安装驱动了.和U盘绑定在一起了.
WDK官方下载连接: https://developer.microsoft.com/zh-cn/windows/hardware/windows-driver-kit
我自己用的是WDK7.1.7600,会上传到课堂资料中.有兴趣的可以下载.
注意: 如果编写驱动程序,请下载对应系统的WDK,因为驱动程序不兼容.只会跟着系统走.
二丶WDK的安装.
下载之后直接下一步,下一步即可. 如果不会建议百度.
三丶进入0环,编写第一个内核驱动程序
在进入ring0之前,我们要知道,不管是驱动程序,或者是应用程序,都会有一个入口点.
比如控制台的入口点是 main,窗口的是winmain.那么看下驱动程序的入口点是什么.
PS:安装好WDK之后,会有帮助文档.可以参考帮助文档.
如果我们要编写内核驱动,则要看内核驱动的入口点,也就是kerner mode,内核模型.
如果是编写硬件驱动,则寻找WDM即可.
NTSTATUS DriverEntry( //驱动的入口点 __in struct _DRIVER_OBJECT *DriverObject, __in PUNICODE_STRING RegistryPath ) {...}
返回值: STATUS_SUCCESS
内核输出的API
ULONG
DbgPrint(
IN PCHAR Format,
. . . . [arguments]
);
利用入口我们可以简单编写一个内核驱动了.
驱动我们可以用C语言去写.也可以是C++
#include <Ntddk.h> //编写内核驱动需要包含NTddk头文件. NTSTATUS DriverEntry(__in struct _DRIVER_OBJECT *DriverObject, __in PUNICODE_STRING RegistryPath) { int i = 0; DbgPrint("HelloWorld, %p\r\n",&i); return STATUS_SUCCESS; }
在编译驱动程序的是否,我们需要一个sources 文件
格式:
TARGETNAME= MyFirstDrive //指明编译的文件名 TARGETTYPE=DRIVER //指明编译的类型 SOURCES= MyFirstDrive.c //指明编译的文件
图示:
编译的时候找我们的开发包.
通过开始程序,找到我们的开发包中的编译XP命令框.点开.
输入编译命令 build 文件名
回车就可以编译我们的驱动程序了.
成功会生成一个sys后缀的文件.那么我们就可使用了.
四丶双机调试,加载我们的驱动.
我们以调试系统启动.然后使用加载驱动的工具,加载我们的驱动,那么就可以在调试器中看到我们的驱动代码了.
当我们启动之后,我们可以查看下调试器,可以调试我们的代码.
请注意我们打印的地址,地址是高2G的空间.所以我们就进入了0环空间了.
五丶编写驱动卸载功能.
我们的驱动现在可以加载.启动.停止.但是不能卸载.原因就是我们没有写卸载的函数.
比如我们的DLL, DLL来的是否还分为4中情况.
很简单.只需要把我们的驱动代码改变一下即可.
#include <Ntddk.h> //编写内核驱动需要包含NTddk头文件. //卸载回调函数 VOID Unload(__in struct _DRIVER_OBJECT *DriverObject) { DbgPrint("Unload MyDrive\n"); } NTSTATUS DriverEntry(__in struct _DRIVER_OBJECT *DriverObject, __in PUNICODE_STRING RegistryPath) { int i = 0; DbgPrint("HelloWorld, %p\r\n",&i); //注册一下驱动卸载的函数 DriverObject->DriverUnload = Unload; return STATUS_SUCCESS; }
给个卸载的函数指针即可.注意启动入口点的参数是一个结构体.启动你想要支持卸载驱动.那么就写上卸载驱动的函数指针即可.
六丶蓝屏的出现.
编写驱动代码,不像我们编写ring3下的应用程序,崩溃了就是崩溃了. 我们写驱动程序恨不得写一行,检查500行.
看下蓝屏的实现.只要我们的程序异常,那么就会蓝屏.
代码:
#include <Ntddk.h> //编写内核驱动需要包含NTddk头文件. //卸载回调函数 VOID Unload(__in struct _DRIVER_OBJECT *DriverObject) { DbgPrint("Unload MyDrive\n"); } NTSTATUS DriverEntry(__in struct _DRIVER_OBJECT *DriverObject, __in PUNICODE_STRING RegistryPath) { int i = 0; int *p = NULL; //异常代码.会造成C05访问异常. DbgPrint("HelloWorld, %p\r\n",&i); *p = 1; //代码会产生异常,系统会蓝屏. //注册一下驱动卸载的函数 DriverObject->DriverUnload = Unload; return STATUS_SUCCESS; }
很简单,就加了一行C05访问异常的代码.
重新编译一下.并且驱动加载.
因为家里电脑系统原因,蓝屏了会紧接着重启.所以来不及截图.请大家自己尝试.
课堂代码资料:
内核工具下载: 链接:https://pan.baidu.com/s/1o9PjpUU 密码:k5sp
课堂驱动代码资料下载: 链接:https://pan.baidu.com/s/1kXiSluv 密码:jnov
转载请著名出处,谢谢.
坚持两字,简单,轻便,但是真正的执行起来确实需要很长很长时间.当你把坚持两字当做你要走的路,那么你总会成功. 想学习,有问题请加群.群号:725864912(收费)群名称: 逆向学习小分队 群里有大量学习资源. 以及定期直播答疑.有一个良好的学习氛围. 涉及到外挂反外挂病毒 司法取证加解密 驱动过保护 VT 等技术,期待你的进入。
详情请点击链接查看置顶博客 https://www.cnblogs.com/iBinary/p/7572603.html
本文来自博客园,作者:iBinary,未经允许禁止转载 转载前可联系本人.对于爬虫人员来说如果发现保留起诉权力.https://www.cnblogs.com/iBinary/p/8264251.html
欢迎大家关注我的微信公众号.不定期的更新文章.更新技术. 关注公众号后请大家养成 不白嫖的习惯.欢迎大家赞赏. 也希望在看完公众号文章之后 不忘 点击 收藏 转发 以及点击在看功能. QQ群: