内存地址重建

http://tech.it168.com/a2010/0304/856/000000856396_1.shtml

        当应用程序需要调用驱动程序实现的某些功能时,通常需要向驱动程序传递某些必要的信息。这时,可以通过共享内存向驱动程序传递参数,例如利用共享堆或者内存映像文件等。 在大多数情况下,驱动程序的功能都可以通过API调用来加以访问。

  这可能带来两个问题:首先,API参数位于用户内存进程空间中,而驱动程序则位于内核内存空间(对于内核模式驱动程序)或者另一个用户进程(对于用户模式驱动程序而言)中。其次,调用方必须具备足够的权限才能访问被传递的缓冲区。因此,在驱动程序开发期间,您必须检查对要传递的缓冲区的访问权,并为驱动程序提供访问调用方的缓冲区数据所需权限。下图给出了内存地址重建示例。


图1 Abc.exe内存地址重建示例

  在这个例子中,Abc.exe将通过两个参数来调用一个Driver.dll函数。第一个参数是指针参数,第二个是带有嵌入指针的结构体。如果Driver.dll函数是从调用方的线程中调用的,那么可以在调用期间直接从Driver.dll函数中访问Abc.exe的内存空间。同步调用时,直接访问需要检查访问权限,不过无需进行内存地址重建。

  如果需要异步访问缓冲区的话,有两种选择:第一种是将缓冲区拷贝至驱动程序内存,第二种方法是把要传递的缓冲区设为其物理内存的别名。

  内存地址重建的类型有多种,如下:

  ·直接访问。

  调用进程的缓冲区在调用期间可以直接访问。

  这仅适用于内核模式驱动程序的同步访问。

  ·复制。

  将需要传递的缓冲区复制到驱动程序的工作缓冲区。

  一个驱动程序使用一份副本。 如果需要,还可以反向复制。

  ·使用别名。

  在驱动程序内创建一个新缓冲区,而该驱动程序与需要传递的缓冲区恰好位于同一物理内存区。

  缓冲区的所有改变在调用进程中都是可访问的。

  内核程序能确定最合适的内存地址重建方法,它会根据对缓冲区的同步或者异步访问,来确定出内存地址重建所需的API。

  对于同步访问,内核程序会自动转换指针参数,所以开发人员必须通过调用CeOpenCallerBufer()来手动映射嵌入指针,验证访问权限,并执行内存地址重建,最后调用CeCloseCallerBuffer()。

  对于异步访问,转换过程较之于同步访问还需为调用CeAllocAsynchronousBuffer()函数进行异步访问准备好所有的指针,并且最后要调用CeFreeAsynchronousBuffer()函数。

  用户模式驱动程序的内存地址重建有以下限制:对于异步访问来说,指针参数必须以只读方式访问,而不可以写方式访问。尽管可以手工方式完成内部指针的内存地址重建,但是从内核程序调用一个驱动程序时,有可能收到无法从用户模式驱动程序访问的指针。

  因此,更有效的方式是使用一个平滑的缓冲区存放用户模式驱动程序的所有数据,并且不异步访问。

  下面介绍检查调用方缓冲区的访问权限和内存地址重建所需的系统API。对于同步访问,指针参数不需要额外的API调用;嵌入指针可以使用CeOpenCallerBufer()和CeCloseCallerBuffer () 。对于异步访问,当指针参数使用CeAllocAsynchronousBuffer ()时,嵌入指针可以使用CeOpenCallerBufer()和CeAllocAsynchronousBuffer();当指针参数使用CeFreeAsynchronousBuffer()时,嵌入指针可以使用CeFreeAsynchronousBuffer() 和CeCloseCallerBuffer() 。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值