内核知识第六讲,内核编写规范,以及获取GDT表
2018-01-16 00:51
375 查看
内核知识第六讲,内核编写规范,以及获取GDT表
一丶内核驱动编写规范
我们都知道,在ring3下,如果我们的程序出错了.那么就崩溃了.但是在ring0下,只要我们的程序崩溃了.那么直接就蓝屏了.那么有那些规范?
1.最基本的检查要有. 比如检查指针是否为NULL,基本的校验错误必须有
2.对内存进行操作的时候,要进行内存判断.下面提供内存判断的API
BOOLEAN MmIsAddressValid( IN PVOID VirtualAddress );
给定一个缓冲区,然后检查其内存是否有效
VOID ProbeForWrite( IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment );
给定一个缓冲区.然后检查是否可以写. 但是注意,检测的是ring3下的内存地址.
3.尽量不要使用太大变量,因为在内核中.内存地址都是共享的.如果你使用了很大.那么相应的内核空间就会变少.
比如不能这样写 char szBuf[0x1000];这样是使用栈内存了.但是编译是不通过了.操作系统不让你这样使用.
但是你可以写成 char szBuf1[0x500], char szBuf2[0x500]; 但是没有任何意义.
4.ring0下不能直接访问ring3的内存
这个是有原因的.因为ring0知道一块物理内存.但是不知道是那个进程的.所以不能直接访问.
二丶分页内存与非分页内存管理
我们在内核下申请空间的API:PVOID ExAllocatePool( IN POOL_TYPE PoolType, //指定内存的类型 IN SIZE_T NumberOfBytes //申请的字节数 );
但是第一个参数是我们制定内存的内容是一个结构体
typedef enum _POOL_TYPE { NonPagedPool, //非分页管理 PagedPool, //分页管理 NonPagedPoolMustSucceed, DontUseThisType, NonPagedPoolCacheAligned, PagedPoolCacheAligned, NonPagedPoolCacheAlignedMustS } POOL_TYPE;
然后类型中有个非分页管理以及分页管理,什么意思?
意思就是在内核中申请一块内存,这块内存可否与磁盘交互.
非分页内存: 不可以进行交互.申请了这块内存就不能动了.
分页内存: 可以进行交互.当内存资源紧张的是否,而这块内存很少是否.可以暂时放到磁盘.
操作系统的代码都是放到非分页内存中的.
三丶设置分页内存
了解了分页内存和非分页内存.那么此时就产生了一个新的问题.我们的代码.有的只调用一次,不该占着这个空间不放.那么我们就要设置为分页内存中.
关键字:
总共两种方式:
1.#pragma code_seg("PAGE") //每个函数都加上,设置到PAGE节中
例如:
但是这种方式,很麻烦,且每写一个函数都要设置.那么此时就有第二种方式
2.#pragma Alloc_text("PAGE",函数名,.....) //类似于一个数组一样,可以设置多个.
但是此时就要注意了.我们就需要一个头文件了.把我们的函数声明都放到头文件中.
然后下方设置.
Page节,和INIT节. 内核中,我们编写的sys驱动程序,其实也是一个PE文件. 类似于我们的ring3下的DLL, ring3的DLL是给应用程序使用的.而sys则是给操作系统使用的. 只不过一个是3环一个是0环
Page节: 这个节则是我们说的分页内存节. 我们给了函数指针.那么就代表这块内存很自由了.操作系统可以在资源紧张的时候使用.
INIT节: 这个节则是初始化的节.例如我们的入口函数,只用一次初始化而已,不用占着内存.所以给INIT节中.那么操作系统会初始化之后释放这块内存.这样可以留给其它驱动使用.
四丶设置内核代码运行的CPU在那个核心上跑.并获取出来每个核心的GDT表.
代码:int shift = 1; char szGDT[6]; nCount = KeQueryActiveProcessors();//获取CUP核心个数,按位来算. while(shift != 0x80000000) { if (nCount & shift) { KeSetSystemAffinityThread(nCount & shift);//设置在那个线程跑 __asm { sgdt szGDT } KdPrint(("limit:%p GDT:%p\n", *(short*)szGDT, *(int*)(szGDT + 2))); } shift <<= 1; }
相关文章推荐
- 内核知识第七讲,内核中设备常用的三种通信方式,以及控制回调的编写
- 内核知识第五讲.驱动框架编写,以及3环和0环通信.
- 内核知识第十讲,内核结构体简介.以及自己实现内存读写功能.
- c语言知识回顾以及编码规范 gcc的简单使用
- printk的实现以及内核日志的相关知识
- C、C++的Makefile的编写以及动、静态库的制作调用(包括MAC地址的获取及MD5加密)
- JAR包中的MANIFEST.MF文件详解以及编写规范
- 可重入函数与不可重入函数概念以及编写规范
- 初步使用AOP编写一个helloword的步骤以及相关知识的解析
- CodeSmith部署安装以及编写MySQL模板的时候无法获取description
- 五子棋源代码 以及 对战DLL编写规范
- 可重入函数与不可重入函数概念以及编写规范
- linux下的shell命令的编写,以及java怎样调用linux的shell命令(java怎样获取linux上的网卡的ip信息)
- C、C++的Makefile的编写以及动、静态库的制作调用(包括MAC地址的获取及MD5加密)
- android点滴(16)--ubuntu下android源代码以及内核的获取
- spring jdbcTemplate queryForList 预编译 order by ?失效 带来的思考以及查阅资料 获取到的知识
- XML文档学习以及规范编写
- 内核开发知识第二讲,编写Kerner 程序中注意的问题.
- 【Shell脚本编程系列】知识储备以及建立规范的脚本
- windows程序设计的一些基础知识点——内核对象以及它们的句柄