内核第三讲,进入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 = ;
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 = ;
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 = ;
int *p = NULL; //异常代码.会造成C05访问异常.
DbgPrint("HelloWorld, %p\r\n",&i); *p = ;       //代码会产生异常,系统会蓝屏. //注册一下驱动卸载的函数
DriverObject->DriverUnload = Unload; return STATUS_SUCCESS;
}

很简单,就加了一行C05访问异常的代码.

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

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

课堂代码资料:

内核工具下载: 链接:https://pan.baidu.com/s/1o9PjpUU 密码:k5sp

课堂驱动代码资料下载: 链接:https://pan.baidu.com/s/1kXiSluv 密码:jnov

转载请著名出处,谢谢.

内核第三讲,进入ring0,以及编写第一个内核驱动程序.的更多相关文章

  1. 《Linux内核设计与实现》读书笔记 第一、二章

    第一章    Linux内核简介 1.1Unix历史 Unix特点:1.很简洁 2.所有东西都被当成文件对待 3.Unix内核和相关的系统工具软件都是用C语言编写而成 4.进程创建非常迅速 所以Uni ...

  2. 《linux内核设计与实现》读书笔记第一、二章

    第一章 Linux内核简介 1.1 Unix的历史 1971年,Unix被移植到PDP-11型机中. 1973年,Unix操作系统用C语言改写——为Unix系统的广泛移植铺平了道路. 1977年,伯克 ...

  3. 十天学Linux内核之第一天---内核探索工具类

    原文:十天学Linux内核之第一天---内核探索工具类 寒假闲下来了,可以尽情的做自己喜欢的事情,专心待在实验室里燥起来了,因为大二的时候接触过Linux,只是关于内核方面确实是不好懂,所以十天的时间 ...

  4. 《Linux内核设计与实现》读书笔记——第一、 二章

    <Linux内核设计与实现>读书笔记--第一. 二章 标签(空格分隔): 20135321余佳源 第一章 Linux内核简介 1.Unix内核特点 十分简洁:仅提供几百个系统调用并且有明确 ...

  5. 《Linux内核设计与实现》读书笔记 第一章 Linux内核简介

    一.相关历史 1. Unix内核的特点 简洁:仅提供系统调用并有一个非常明确的设计目的 抽象:几乎所有东西都被当做文件 可移植性:使用C语言编写,使得其在各种硬件体系架构面前都具备令人惊异的移植能力 ...

  6. Xamarin iOS编写第一个应用程序创建工程

    Xamarin iOS编写第一个应用程序创建工程 在Xcode以及Xamarin安装好后,就可以在Xamarin Studio中编写程序了.本节将主要讲解在Xamarin Studio中如何进行工程的 ...

  7. C#基础知识-编写第一个程序(二)

    通过上一篇数据类型已经介绍了C#中最基本的15种预定义数据类型,了解每一种类型代表的数据以及每种类型的取值范围,这是很重要也是最基本.下面我们通过实例来了解每个类型如何去使用.编写C#程序时我们需要用 ...

  8. django之创建第3个项目:编写第一个模板文件

    1.django结构 2.在站点blog下创建templates文件夹,专门用于存放模板文件 3.在templates文件夹下创建index.html文件 #index.html <!DOCTY ...

  9. 编写第一个微信小程序界面

    编写第一个微信小程序界面 不忘初心,方得始终:初心易得,始终难守. 传统的 web 结构 小程序文件目录结构 小程序页面层级结构 编写第一个小程序 1. 创建小程序目录结构 2. 编写代码 welco ...

随机推荐

  1. eclipse下Spring环境构建及插件

    首先获取spring tool suite插件 获取地址http://spring.io/tools/sts/ 然后打开eclipse选择菜单栏Help下Install new software添加我 ...

  2. python pandas.DataFrame.append

    1.使用append首先要注意的是,你要合并两个DataFrame的columns即列名是否是相同的,不相同的就会报错. 2.我们会发现DataFrame的列名是不能够重复的,而行名(index)是可 ...

  3. centos 下Python独立虚拟环境创建

    virtualenv Python有着庞大的开源社区的支持,很自然就产生这么一个问题:第三方包参差不齐,如果我们想在服务器测试,或者升级某个包,就会导致生产环境产生杂乱,多余的第三方依赖包. virt ...

  4. spring BeanPostProcessor

    BeanPostProcessor spring使用BeanPostProcessor接口来处理生命周期的回调 BeanPostProcessor接口定义的两个方法,分别在bean的(实例化配置和初始 ...

  5. vim配置文件.vimrc

    20171127备份 syntax on "自动语法高亮 set number "显示行号 set autoindent "回车后自动缩进 set tabstop=4 & ...

  6. 可遇不可求的Question之INSERT … ON DUPLICATE KEY UPDATE 语法篇

    MySQL 自4.1版以后开始支持INSERT … ON DUPLICATE KEY UPDATE语法,使得原本需要执行3条SQL语句(SELECT,INSERT,UPDATE),缩减为1条语句即可完 ...

  7. springboot的拦截器Interceptor的性质

    Interceptor在springboot2.x版本的快速入门 实现HandlerInterceptor的接口,并重载它的三个方法:preHandle.postHandle.afterComplet ...

  8. IOS 模拟器多开集成测试和那些坑

    #### 前言公司一直没有IOS自动化,搞得很尴尬,个人感觉搞自动测试的,不搞IOS自动化,就像金X,少了重要一点啊.也向领导申请过不止一次,总只都各种原因没有分配机器,不了了之.某天线上IOS出bu ...

  9. Javascript高级编程学习笔记(16)—— 引用类型(5) Function类型

    JS中许多有趣的地方都和函数脱不了联系 那么是什么让JS中的函数这么有趣呢? 我们一起来看看吧 Function类型 在JS中函数实际上就是对象,每个函数都是Function类型的实例,和JS的其他引 ...

  10. Pycharm永久激活方式

    1.首先下载pycharm破解包 http://idea.lanyus.com/ 2. 将下载的文件放入PyCharm安装bin目录下: 3.在pycharm.exe.vmoptions ,pycha ...