千赢娱乐手机登录_ qy8com千赢手机版_千赢网页手机版
做最好的网站

千赢娱乐手机登录

当前位置:千赢娱乐手机登录 > 千赢娱乐手机登录 > 核心技术之绕过,操作系统基本原理

核心技术之绕过,操作系统基本原理

来源:http://www.modeLspro.net 作者:千赢娱乐手机登录 时间:2019-11-09 06:41

图片 1

————————————————————————————————————————————————————————————————

     欢迎来到windows编程的世界,先给我们的windows打个招呼吧:

 

在上一篇文章中,我们已经看到 IopParseDevice() 如何对传入的 OPEN_PACKET 结构进行验证。假设 ObReferenceObjectByName() 的调用者没有分配并初始化第七个参数 ParseContext,而仅是简单地传入 “NULL” ,那么当调用链深入到 IopParseDevice() 内部时,就会因验证失败返回 C0000024(STATUS_OBJECT_TYPE_MISMATCH)。

#include <Windows.h>

操作系统用于管理系统的硬件、软件和数据资源,控制程序的运行,是应用软件与硬件之间的接口,也是人机之间的接口。操作系统的职能包括进程管理、存储管理、文件管理、设备管理、作业管理等。

我们根据源码中的暗示来追踪 OPEN_PACKET 结构究竟在哪分配的,如前所述,调用链 NtCreateFile->IoCreateFile()->IopCreateFile() 的结尾,也就是在 IopCreateFile() 内部,实际负责 OPEN_PACKET 的初始化。下面贴出的代码片段以 NT 5.2 版内核源码为样例:

#include <iostream>

 

 

using namespace  std;

在进程管理中,PV操作在处理进程的同步与互斥问题方面非常重要,当多个进程需要同时访问共享资源时会用到。PV是用荷兰语表示的简写,P表示通过,V表示释放,据说这是计算机领域为数不多的非英语简写。

图片 2

int  main()

图片 3

也就是说,我们直接复制 IopCreateFile() 中的 OPEN_PACKET 结构初始化部分逻辑就行了?

{

 

这里还有一个问题,负责分配该结构体内核内存的例程 IopAllocateOpenPacket() 是一个宏,Visual C 2015 中给出它是用 ExAllocatePoolWithTag() 定义的。这就好办了,在我们自己的驱动源码中,添加相应定义即可,如下图:

       int iSelect=MessageBox(NULL,TEXT("你好,windows世界,我来了!"),TEXT("你好,世界"),MB_OKCANCEL);

PV操作由P操作原语和V操作原语组成,原语也叫原子操作,表示不可中断的过程,这两个原语要操作信号量S。

 

       if(iSelect==IDOK)

P操作将S的值减1,如果S<0,则将该进程置为等待状态并加入进程队列中,否则继续执行。

图片 4

       {

V操作将S的值加1,如果S<=0则唤醒等待队列中的第一个进程,否则继续执行。

 

              *cout<<"you select ok "<<endl*;

接下来使用单缓存区生产者、消费者问题来描述PV操作的运用,由于只有一个单缓存区,生产速度过快会使缓存区溢出,而消费速度过快会从缓存区拿到空值,如图所示,在加入PV操作后就能解决这些问题

————————————————————————————————————————————————————————————

       }else

图片 5

因为 OPEN_PACKET 结构同样没有公开的文档来描述,所以要么在我们的驱动源码中用  “#include” 包含定义它的头文件,要么直接复制定义的那一部分黏贴进来。很显然,后者比较轻松——OPEN_PACKET 在内核源码的 “iomgr.h” 中定义,而该头文件又嵌套包含了一堆杂七杂八的内核头文件,要理清这些嵌套包含关系很麻烦,而且最重要的是,其中一些头文件定义的数据类型会与驱动开发中用的 “ntddk.h” 和“wdm.h”重复,引起编译器的抱怨。所以直接在 “iomgr.h” 中搜索字串 “typedef struct _OPEN_PACKET”,把找到的定义块拷贝进来即可。

       {

 

然而,OPEN_PACKET 结构中唯有一个字段不是 “原生” 定义的——这就是 “PDUMMY_FILE_OBJECT” 类型,需要包含其它头文件才不致使编译器报错。

              *cout<<"you select cancel"<<endl*;

有生产者、消费者两个进程,使用两个PV操作,S1的初值为1,S2的初值为0。生产者第一次执行,S1=0,送产品到缓存区,S2=1;第二次执行时S1=-1,生产者进程转为等待状态并加入进程队列。对于消费者进程,第一次执行过程中S2=0,从缓存区取产品,S1=0,消费产品,由于S1=0,生产者进程便被唤醒了,此时正好缓存区的产品被消费完。同理,如果消费者进程先执行,也照样能保证两个进程的配合无间。

我的解决方案是,直接把该字段的声明所在行注释掉,下图展示了该字段具体的位置(在 “iomgr.h” 中的行号),方便各位快速查找:

       }

PV操作便是通过这样的过程来协调几个需要同步的进程的。

 

       *system*("pause");

 

图片 6

       return  0;

 

——————————————————————————————————————————————————————————————————

}

注意,NT 6.1 版内核在编译时刻的 OPEN_PACKET 结构显然是未经 “恶意” 修改的,所以编译器为其 “sizeof(OPEN_PACKET)” 表达式计算 0x70 的值,而我们在自己的驱动中拿掉了 OPEN_PACKET 其中一个字段使得编译器为表达式 “sizeof(OPEN_PACKET)” 预计算 0x58 的值(后面的调试阶段会验证),这会造成 “Size” 字段不是 IopParseDevice() 内部逻辑预期的 0x70,从而导致返回 C0000024(STATUS_OBJECT_TYPE_MISMATCH)。

   所谓windows编程就是指通过调用Windows API来和操作系统交互的编程方式。API就是与操作系统交互的各种功能函数,MessageBox就是一个API,调用它就可以弹出一个对话框。

解决办法也很简单,我们的驱动中,不要依赖编译时刻的计算,直接把 “Size” 字段的值硬编码为 0x70 不就好了?

如下图所示,你还会注意到,我把 “Type” 字段的常量 “IO_TYPE_OPEN_PACKET” 改成了对应的数值,以确保万一。

 

图片 7

 

本文由千赢娱乐手机登录发布于千赢娱乐手机登录,转载请注明出处:核心技术之绕过,操作系统基本原理

关键词:

上一篇:格式化对话框的设计,命令学习

下一篇:没有了