内核驱动中改写寄存器值
来源:互联网 发布:中国进口粮食数据 编辑:程序博客网 时间:2024/06/13 02:22
在Kernel Model的驱动程序中向给定的寄存器地址、内存地址或IO端口地址等16进制的地址写入指定的值。
主要依靠的是MSDN中提供的MmMapIoSpace函数进行的。该函数将一个十六进制的物理地址映射到一个指针,然后针对该指针进行操作即可改变对应的物理单元内的数据。该函数的具体描述可参看微软的MSDN:
https://msdn.microsoft.com/zh-cn/office/ff554618(v=msdn.10).aspx
以下是使用该方法操作物理地址的代码示例:
LARGE_INTEGER memAddress;
PULONG pMemAddress;
memAddress.QuadPart= 0xFED0D048;
pMemAddress = (PULONG) MmMapIoSpace(memAddress,
sizeof(ULONG), MmNonCached);
*pMemAddress= 0x00000000;
KeStallExecutionProcessor(300* 1000);
*pMemAddress= 0x00000003;
KeStallExecutionProcessor(50 * 1000);
目前在驱动中,我们可以通过系统函数MmMapIoSpace,将指定的内存地址映射为一个指针,然后通过该指针即可实现对内存的读写;
但由于驱动中操作的内存地址很可能是直接与某个物理端口直接对应,它所指向的值是一个volatile的,所以在使用指针所指向的值时,必须先将其赋值给一个局部变量,以防数据访问错误。
我们在反汇编对比两个版本的程序后,发现由于Release版本对代码进行了优化而导致的问题。
一、如下代码,使用Debug模式进行编译时
*deviceContext->pMemAddress,是个ULONG型的指针,此时该指针所指向的对象的值为:0x02或0x03,当有外接键盘时该址为0x02,否则该值为0x03。此时该指针的值与0x00000001按位与时,可以正确地反馈出键盘状态的变化;
二、在Release模式下进行编译时
编译器对代码进行了优化,当使用指针所指向的值与0x00000001进行按位与操作时,由于0x00000001前3个字节都为0,按位与的结果永远为0,编译器认为没必要再进行计算,只使用最低位的01进行计算即可。所以编译器在编译时,把*deviceContext->pMemAddress_homekeyWanlida这个指针优化成了一个BYTE型的指针。但当使用BYTE型指针去访问0xFED0E258这个地址时取到的值永远都是0xFF,这就导致了在Release版本的驱动中,第一个if判断永远都是生效的。
if (((*deviceContext->pMemAddress)& 0x00000001) == 1)
{
deviceContext->homekeyInvalid = FALSE;//Homekey有效
WriteLogFormat(device, "***homekeyInvalid_Wanlida status:%d\r\n",deviceContext->homekeyInvalid);
}
else
{
deviceContext->homekeyInvalid = TRUE;//Homekey失效
WriteLogFormat(device, "***homekeyInvalid_Wanlida status:%d\r\n",deviceContext->homekeyInvalid);
}
三、最根本的原因
根本原因还是0xFED0E258这个地址的访问,当使用BYTE型指针和WORD型指针访问时,取到的值永远都是0xFF跟0xFFFF,只有当使用DWORD/ULONG型的指针访问该地址时才可以取到正确的值。
- 内核驱动中改写寄存器值
- linux 内核中 查看寄存器的值
- 内核中访问物理寄存器
- Linux内核驱动之网络驱动(3)PHY寄存器分析
- ARM内核中寄存器的浅见
- 内核中操作寄存器的方法
- ARM内核中寄存器的浅见
- 驱动中如何访问CPU中的寄存器?
- 驱动中如何访问CPU中的寄存器
- 驱动中读写硬件寄存器的方式
- 触摸屏驱动的改写
- 向内核中添加驱动
- Linux0.11内核中处理器的寄存器关系
- Android内核驱动(linux内核驱动)中使用Completion
- 【内核驱动】 内核驱动中添加系统调用
- (zz)linux - 驱动中如何访问CPU中的寄存器?
- Linux驱动中建立动态映射来实现操作寄存器
- 【从零开始,从内核驱动驱动到用户空间调用】编写第一个linux驱动,通过端口访问I/O寄存器。
- 学习设计模式原则之依赖倒置原则,代码笔记
- jdk 1.7 安装 centos6.4-64位
- Boost源码学习十一[并发编程](3)
- mysql中的数据同步到elasticsearch
- Java六种排序算法
- 内核驱动中改写寄存器值
- apk打包中程序包R不存在的问题
- makefile编写
- ES6--Generator
- Ceph学习----Ceph性能测试
- myBatis 操作 mysql时,使用 like 关键进行模糊查询的方法
- 理财指南
- SSH免登陆
- 浅谈js的对象