前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >内核第三讲,进入ring0,以及编写第一个内核驱动程序.

内核第三讲,进入ring0,以及编写第一个内核驱动程序.

作者头像
IBinary
发布2022-05-10 13:15:01
1.2K0
发布2022-05-10 13:15:01
举报
文章被收录于专栏:逆向技术逆向技术

       内核第三讲,进入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即可.

代码语言:javascript
复制
NTSTATUS 
  DriverEntry(         //驱动的入口点
    __in struct _DRIVER_OBJECT  *DriverObject,
    __in PUNICODE_STRING  RegistryPath 
    )
  {...} 

返回值: STATUS_SUCCESS

内核输出的API

代码语言:javascript
复制
ULONG
  DbgPrint(
    IN PCHAR  Format,
    . . . .  [arguments] 
    );

利用入口我们可以简单编写一个内核驱动了.

驱动我们可以用C语言去写.也可以是C++

代码语言:javascript
复制
#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  文件

格式:

代码语言:javascript
复制
TARGETNAME= MyFirstDrive          //指明编译的文件名 
TARGETTYPE=DRIVER                 //指明编译的类型
SOURCES= MyFirstDrive.c            //指明编译的文件

图示:

 编译的时候找我们的开发包.

通过开始程序,找到我们的开发包中的编译XP命令框.点开.

输入编译命令 build 文件名

回车就可以编译我们的驱动程序了.

成功会生成一个sys后缀的文件.那么我们就可使用了.

四丶双机调试,加载我们的驱动.

我们以调试系统启动.然后使用加载驱动的工具,加载我们的驱动,那么就可以在调试器中看到我们的驱动代码了.

当我们启动之后,我们可以查看下调试器,可以调试我们的代码.

请注意我们打印的地址,地址是高2G的空间.所以我们就进入了0环空间了.

五丶编写驱动卸载功能.

我们的驱动现在可以加载.启动.停止.但是不能卸载.原因就是我们没有写卸载的函数.

比如我们的DLL,  DLL来的是否还分为4中情况.

很简单.只需要把我们的驱动代码改变一下即可.

代码语言:javascript
复制
#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行.

看下蓝屏的实现.只要我们的程序异常,那么就会蓝屏.

代码:

代码语言:javascript
复制
#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访问异常的代码.

重新编译一下.并且驱动加载.

因为家里电脑系统原因,蓝屏了会紧接着重启.所以来不及截图.请大家自己尝试.

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-01-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  •        内核第三讲,进入ring0,以及编写第一个内核驱动程序.
    • 一丶进入ring0之前的简介
      • 二丶WDK的安装.
        • 三丶进入0环,编写第一个内核驱动程序
          • 四丶双机调试,加载我们的驱动.
            • 五丶编写驱动卸载功能.
              • 六丶蓝屏的出现.
              相关产品与服务
              对象存储
              对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档