卸载内核_安全内核初探

内核相关基础知识

1. CPU模式:实模式、保护魔术、8086虚拟模式

实模式:操作系统和软件权限一样,可以随便访问内存的每一个地方

保护模式:32位开始、开启了段页的保护,分为了用户模式和特权模式,这样可以保护关键内存不被访问修改。用户权限的应用程序,是不能访问特效模式的。

8086虚拟模式:CPU提供这种模式,使得可以跑16位程序

2. 内核:就是操作系统的一部分,这部分在0环运行

3. 驱动:可以看做是操作系统的一个dll,在0环运行操控硬件,但是我们肯定不是用来操控硬件。硬件不是微软产的,所有他肯定得让厂家能够编写,驱动代码控制硬件。所有我们就有机会能够访问内核。到了win7 64位后编写驱动需要增加签名才能够,被系统加载进去。

4. 用户模式和内核模式通信图

effb42cbdad66d1a54c9f1fac62facf6.png

用户模式和内核模式对内核驱动程序进行证明签名以便公开发布

安装开发驱动包(WDK)

我们现在学习的是XP系统,所有我们要开发XP的驱动,所以选择这个。

518551038e587bcfaeefd06e206a848a.png

自己随便安装到一个目录、我安装的是D:\WinDDK

7f0b1217e35690e0988d2d18f5f93618.png

介绍WDK

第一个重要的是WDK的帮助文档

1138353807034559332dd66ee0f625bb.png
这个部分就是我们关于内核的帮助,驱动还有开发硬件的相关的,这些我们不需要了解。

2e694ccb36792658cce7a4485fb2e81e.png

这些就是内核函数

1. ob开头的API: 一般是对象使用,操作系统是C和汇编写的,但是用的却是面向对象设计,比如进程.还有引用计数等等.所以需要调用这种API.

2. Mm开头的API: Mm开头的API,都是内存管理的API,比如锁定一块内存,不让其与磁盘交换数据等等.

3. Ps开头的API: ps开头的API,一般都是管理进程和线程的API,比如psGetCurrentProcessId,获得当前进程ID.

4. Io开头的API: Io开头的API一般就是负责IO操作的.如果写硬件驱动则不用管这些.直接使用in 或者out进行操作.

5. Po开头的API: Po开头的API一般就是管理电源的API.对于写内核驱动的我们,不关心这些.写硬件驱动的则要关心,比如通电了.硬件驱动需要做些初始化什么的.

6. Cm开头的API: Cm开头的API一般是注册表常用的API.

7. Zw开头的API: Zw开头的API,一般是内核版本的API,比如三环有CreateFile,那么在内核API中则是ZwCreateFile.

8. Ke开头API: ke开头的API,一般是内核层的API.在内核中,分为内核层还有执行层.

9. Ex开头的API: Ex开头的API,则是执行层的API.

10. Rtl开头的API :  Rtl开头的Api和C库函数很像,在驱动中可以使用C库函数,但是 微软不建议使用.所以提供了Rtl开头的API,甚至比C库函数还多.

11. DMA开头的API: 一般是写硬件驱动用的,我们不用.

12. HAL开头的API: 操作硬件抽象层的API.

13. Dbg开头的是调试函数

a2d1b29cc813f1c8fbf40f9858331c57.png

编译环境

我们现在看的是编译XP内核的环境
free编译的就是Release版
Checked编译的就是debug版

9aba0d751d7f492247ce6e85c68d878a.png

编写第一个内核程序

dll编写时候有一个dllmain
驱动有DriverEntry

0ca152581ef340e8dda3a17dac08b366.png

编写代码

92312dd6cc64eae449f3c4c21b198c06.png

然后在DKK目录下找到src

51d88b82e4bde88ac3e0b0f4cd2da215.png

找到这两个文件夹,然后拷贝到我们源码那里

2fa4813c58917ee64e0caaeaef994a6f.png

把不需要的删除并且改名字就可以了

15bcc29498a0c61b4979f061d890b3bb.png

然后打开编译环境

181e90b1c665a3a3dbfb24d88bae1342.png

进入源码路径,然后编译(build),发现这个错误就时路径有空格

8100be536734a481af32b6867d27a111.png
得到sys的程序

f609607ef239ffb145333a6fa866c04b.png

#include VOID DriverUnload(__in struct _DRIVER_OBJECT *DriverObject){DbgPrint("DriverUnload\n");}int g_num = 100;NTSTATUS DriverEntry(PDRIVER_OBJECT     DriverObject,PUNICODE_STRING    RegistryPath){//注册卸载函数DriverObject->DriverUnload = DriverUnload;DbgPrint("Hello WDK!:%p\n", &g_num);return  STATUS_SUCCESS;}

编写加载驱动软件

我们知道dll加载进入程序需要loadlibrary。而安装驱动等于创建服务,CreateSever把驱动信息记录注册表。

CreateServiceA

SC_HANDLE hService=CreateServiceA(hSCM,       // handle to SCM database"CR33",      // name of service to start"CR33Display",      // display nameSERVICE_ALL_ACCESS,      // type of access to serviceSERVICE_KERNEL_DRIVER,        // type of serviceSERVICE_DEMAND_START,          // when to start serviceSERVICE_ERROR_NORMAL,       // severity of service failurestrPath.toStdString().c_str(),   // name of binary file sys路径NULL,   // name of load ordering groupNULL,          // tag identifierNULL,     // array of dependency namesNULL, // account nameNULL        // account password);

就这几个参数比较重要

1b1733b72c0d58eddc32066cf3eb4665.png

dwServiceType

选这个就表示写内核程序

0b524d9703cc081dd6f4fa3503c60c84.png

dwStartType
这个是驱动方式
第一个是系统启动后就会启动
第二个会开机就启动
第三个只有调用startSever才会启动
第四个不能启动
第五个系统初始化之前启动

d964c0e537bcd793d5b5b462b739d0dc.png

lpBinaryPathName

sys路径

StartService(开启驱动)

ControlService(停止)

DeleteService(卸载)

SERVICE_STATUS status;SC_HANDLE hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);//check//1.安装 CreateServiceSC_HANDLE  hService = CreateService(hSCM,"cr33Hello","cr33Hello",SERVICE_ALL_ACCESS,SERVICE_KERNEL_DRIVER, //内核驱动SERVICE_DEMAND_START,  /*启动方式*/SERVICE_ERROR_NORMAL,"C:\\Documents and Settings\\Administrator\\桌面\\Hello.sys",  //驱动路径NULL, NULL, NULL, NULL, NULL);if (hService == NULL){printf("CreateService Error:%d\n", GetLastError());CloseServiceHandle(hSCM);system("pause");return 0;}else{printf("CreateService OK\n");}//2.启动 StartServiceif (StartService(hService, NULL, NULL) == 0){printf("StartService Error:%d\n", GetLastError());DeleteService(hService);CloseServiceHandle(hService);CloseServiceHandle(hSCM);system("pause");return 0;}else{printf("StartService OK\n");}//3.停止 ControlServiceControlService(hService, SERVICE_CONTROL_STOP, &status);//4.卸载 DeleteService//OpenService();DeleteService(hService);CloseServiceHandle(hService);CloseServiceHandle(hSCM);system("pause");return 0;

调试驱动程序

蓝屏保存DUM
当系统出错后会dump内存保存下来e35948036c7c5459178be80a8e840237.png

为了看到蓝屏把这个取消

f6cf88078d7d20a8cfbfb7bafe134c8f.png

现在编写一个有问题的驱动程序

f323a58ace273efb842f3348c47fb69a.png

启动运行后出错了,可以看到里面有错误驱动名,错误类型还有代码位置
如果真的蓝屏,上面也写了,可以进入安全模式,然后把驱动删除,因为安全模式,只会加载基础的驱动,第三方的都不会加载。

a8172d8553a44994ebfe6c218207582a.png

这个就是我们DUM的文件

6851171484c980f1548418a677e8981f.png

拷贝出来用windbg打开

81a0e46bbb4bb2acdbffe967ef533ef9.png

点击自动分析

42f8824aed4328eba4318d4145a7ff77.png

能分析错误位置,和错误类型,还能调试,有源码的话还能判断哪行出错

11cce3f32c54fe942c613d268b529f3f.png

5bf6b9b746a0e88775ea6cb3e563bb9f.png

双机调式

我系统64位的所以打开这个

d8f1067b7777a6633b351cd2a30b7c83.png

然后重启虚拟机里面的xp系统

d0a1392276b3b29f9a88c1e9ed048a3f.png

最后打开windbg

57441079d05a1ec1f34ac8f3512d16ed.png

20988f20846ad693647e4aa029e19325.png

然后输入g,系统就能正常跑起来

bd6971e90e0e0efb275562e41886ffc3.png

现在可以编写驱动的调试代码了,用代码给下断点,我们一般不用int 3
用DbgBreakPoint()
DbgBreakPoint()
_asm int 3
编译好,用加载器启动

89bb43bdd55edcb81efefb7d72f79078.png

触发断点就能调试了

ee8564d73abb0f08492247db62581bcd.png

end

13a1645c1b20285cec89469da63f8fc3.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值