内核第三讲,进入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 = ;
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,以及编写第一个内核驱动程序.的更多相关文章
- 《Linux内核设计与实现》读书笔记 第一、二章
第一章 Linux内核简介 1.1Unix历史 Unix特点:1.很简洁 2.所有东西都被当成文件对待 3.Unix内核和相关的系统工具软件都是用C语言编写而成 4.进程创建非常迅速 所以Uni ...
- 《linux内核设计与实现》读书笔记第一、二章
第一章 Linux内核简介 1.1 Unix的历史 1971年,Unix被移植到PDP-11型机中. 1973年,Unix操作系统用C语言改写——为Unix系统的广泛移植铺平了道路. 1977年,伯克 ...
- 十天学Linux内核之第一天---内核探索工具类
原文:十天学Linux内核之第一天---内核探索工具类 寒假闲下来了,可以尽情的做自己喜欢的事情,专心待在实验室里燥起来了,因为大二的时候接触过Linux,只是关于内核方面确实是不好懂,所以十天的时间 ...
- 《Linux内核设计与实现》读书笔记——第一、 二章
<Linux内核设计与实现>读书笔记--第一. 二章 标签(空格分隔): 20135321余佳源 第一章 Linux内核简介 1.Unix内核特点 十分简洁:仅提供几百个系统调用并且有明确 ...
- 《Linux内核设计与实现》读书笔记 第一章 Linux内核简介
一.相关历史 1. Unix内核的特点 简洁:仅提供系统调用并有一个非常明确的设计目的 抽象:几乎所有东西都被当做文件 可移植性:使用C语言编写,使得其在各种硬件体系架构面前都具备令人惊异的移植能力 ...
- Xamarin iOS编写第一个应用程序创建工程
Xamarin iOS编写第一个应用程序创建工程 在Xcode以及Xamarin安装好后,就可以在Xamarin Studio中编写程序了.本节将主要讲解在Xamarin Studio中如何进行工程的 ...
- C#基础知识-编写第一个程序(二)
通过上一篇数据类型已经介绍了C#中最基本的15种预定义数据类型,了解每一种类型代表的数据以及每种类型的取值范围,这是很重要也是最基本.下面我们通过实例来了解每个类型如何去使用.编写C#程序时我们需要用 ...
- django之创建第3个项目:编写第一个模板文件
1.django结构 2.在站点blog下创建templates文件夹,专门用于存放模板文件 3.在templates文件夹下创建index.html文件 #index.html <!DOCTY ...
- 编写第一个微信小程序界面
编写第一个微信小程序界面 不忘初心,方得始终:初心易得,始终难守. 传统的 web 结构 小程序文件目录结构 小程序页面层级结构 编写第一个小程序 1. 创建小程序目录结构 2. 编写代码 welco ...
随机推荐
- excel支持正则表达式提取字符函数(支持RegExp捕获分组)
一.要让excel脚本支持Microsoft VBScript Regular Expressions 5.5 ,按快捷键alt+F11,出现下图界面,操作如图示: 二.添加VBA代码: 代码添加完毕 ...
- linux (ubuntu) 命令学习笔记
1, md5sum 输出字符串的MD5值 echo -n 123456 | md5sum //-n表示不打印回车符 2, ubuntu设置dock任务栏鼠标点击效果 16.04: 调整位置:gsett ...
- Django之路
备注:本套笔记内容来源于互联网,只做学习使用,如有侵权请联系本笔记作者. 资料内容 Django之路(一)——什么是Web开发 Django之路(二)——Django初识 Django之路(三)——U ...
- android-基础编程-Notification
Notification 的创建主要涉及到 Notification.Builder . Notification . NotificationManager . Notification.Buile ...
- python+unittest 控制用例的执行顺序
unittest的main()方法执行用例的顺序是按照测试类.测试方法的名字的ASCII顺序来执行测试方法.所以可能执行的顺序和你想要的顺序不一样,可能通过下面两种方法修改执行顺序 1. 通过Test ...
- Java中的NIO基础知识
上一篇介绍了五种NIO模型,本篇将介绍Java中的NIO类库,为学习netty做好铺垫 Java NIO 由3个核心组成,分别是Channels,Buffers,Selectors.本文主要介绍着三个 ...
- 「ZJOI2016」解题报告
「ZJOI2016」解题报告 我大浙的省选题真是超级神仙--这套已经算是比较可做的了. 「ZJOI2016」旅行者 神仙分治题. 对于一个矩形,每次我们从最长边切开,最短边不会超过 \(\sqrt{n ...
- C++ Opencv 傅里叶变换的代码实现及关键函数详解
一.前言 最近几天接触了图像的傅里叶变换,数学原理依旧不是很懂,因此不敢在这里妄言.下午用Opencv代码实现了这一变换,有一些经验心得,愿与大家分享. 二.关键函数解析 2.1copyMakeBor ...
- 小程序开发基础-swiper 滑块视图容器
小编 / 达叔小生 参考官方文档:https://developers.weixin.qq.com/miniprogram/dev/component/ 小程序开发基础-swiper 滑块视图容器 根 ...
- canvas转图片中的文字自动换行
概述 最近项目用到了canvas转图片,但是由于canvas对文字排版的支持非常弱,一般我们在canvas上画不同排版的文字(比如竖排文字)都是利用js计算横纵坐标,然后一个字一个字地画出来,今天无意 ...