修改cr0进入实模式
来源:互联网 发布:linux 发包工具 编辑:程序博客网 时间:2024/06/06 19:16
转自:http://www.cnblogs.com/hongfei/archive/2013/06/18/3142162.html
为了安全起见,Windows XP及其以后的系统将一些重要的内存页设置为只读属性,这样就算有权力访问该表也不能随意对其修改,例如SSDT、IDT等。但这种方法很容易被绕过,我们只要将这些部分修改为可写属性就可以了,不过当我们的事情做完后记得把它们恢复为只读属性,不然会造成一些很难预料到的后果。
cr0是系统内的控制寄存器之一。控制寄存器是一些特殊的寄存器,它们可以控制CPU的一些重要特性。
控制寄存器最初出现于低级的286处理器中,以前称之为机器状态字(machine status word),在386以后它们被重命名为控制寄存器(control register)。
cr0寄存器直到486的处理器版本才被加入了“写保护”(Write Protect,WP)位,WP位控制是否允许处理器向标记为只读属性的内存页写入数据。
WP位0:禁用写保护的功能 实模式
WP位1:开启写保护的功能 保护模式
cr0的第16位是WP位,只要将这一位置0就可以禁用写保护,置1则可将其恢复。
禁用写保护的操作步骤:
1 shl 16(1左移16位)//结果:10000000000000000
对结果取反 not (1 shl 16)//结果:FFFEFFFF=01111111111111111
对cr0的值进行“逻辑与”运算:and cr0, 01111111111111111 //即将第17位置0,其余位不变
启用写保护的操作步骤:
直接对CR0的值进行“逻辑或”运算:or cr0,10000000000000000//即将第17位置1,其余位不变
禁用和启用写保护的内联汇编代码如下所示:
// 关闭写保护
__asm
{
cli ;//将处理器标志寄存器的中断标志位清0,不允许中断
mov eax, cr0
and eax, ~0x10000
mov cr0, eax
}
// 恢复写保护
__asm
{
mov eax, cr0
or eax, 0x10000
mov cr0, eax
sti ;//将处理器标志寄存器的中断标志置1,允许中断
}
注意:cli和sti都是特权指令,必须在ring0才能使用的。
核心代码如下:
PJMPCODE pCurAddr;//指向SSDT表中"当前地址"的指针JMPCODE oleCode;//用来保存前5字节,以便恢复//驱动程序的入口函数#pragma INITCODE//将DriverEntry设在分页内存中,当驱动加载成功,此函数在内存中移除。extern "C" NTSTATUS DriverEntry (IN PDRIVER_OBJECT pDriverObject,IN PUNICODE_STRING pRegistryPath){ ULONG curAddr,oldAddr; JMPCODE jmpCode; // __asm int 3;//断点 DbgPrint("驱动加载成功……\n"); curAddr = Get_NTCurAddr(); oldAddr = Get_NTOldAddr(); if (curAddr!=oldAddr) { //保存前5字节 pCurAddr=(PJMPCODE)curAddr;//初始化指针 oleCode.jmpStyle=pCurAddr->jmpStyle;//跳转方式的机器码(1字节) oleCode.jmpAddr=pCurAddr->jmpAddr;//跳转的目的地址机器码(4字节) jmpCode.jmpStyle = 0xE9;//近跳转 jmpCode.jmpAddr = oldAddr-curAddr-5; DbgPrint("要写入的地址:%X",jmpCode.jmpAddr); //写入JMP指令 //关闭写保护 _asm { cli ;//将处理器标志寄存器的中断标志位清0,不允许中断 mov eax, cr0 and eax, ~0x10000 mov cr0, eax } pCurAddr->jmpStyle=0xE9;//近跳转 pCurAddr->jmpAddr=jmpCode.jmpAddr;//要跳转到的地址 // 恢复写保护 _asm { mov eax, cr0 or eax, 0x10000 mov cr0, eax sti ;//将处理器标志寄存器的中断标志置1,允许中断 } DbgPrint("NtOpenProcess被Hook了"); } CreateMyDevice(pDriverObject);//创建设备 pDriverObject->DriverUnload = DDK_UnLoad; return STATUS_SUCCESS;}
//卸载例程void DDK_UnLoad(IN PDRIVER_OBJECT pDriverObject){ //关闭写保护 _asm { cli ;//将处理器标志寄存器的中断标志位清0,不允许中断 mov eax, cr0 and eax, ~0x10000 mov cr0, eax } pCurAddr->jmpStyle=oleCode.jmpStyle;//近跳转 pCurAddr->jmpAddr=oleCode.jmpAddr;//要跳转到的地址 // 恢复写保护 _asm { mov eax, cr0 or eax,0x10000 mov cr0, eax sti ;//将处理器标志寄存器的中断标志置1,允许中断 } DbgPrint("驱动卸载成功……\n");}
- 修改cr0进入实模式
- cr0
- x86CPU 实模式 保护模式 傻傻分不清楚? 基于Xv6-OS 分析CR0 寄存器
- linux进入单用户模式修改root密码
- 修改 redhat 启动默认进入的模式
- Linux进入单用户模式修改root密码
- centos进入单用户模式修改fstab文件
- linux进入单用户模式修改root密码
- centos7进入单用户模式修改root用户密码
- Linux 进入单用户模式 修改root密码
- centos7进入单用户模式修改密码教程
- ubuntu 进入单用户模式,修改sudoers权限,修改root密码
- 通过修改CR0寄存器绕过SSDT驱动保护
- 通过修改CR0寄存器绕过SSDT驱动保护
- 通过修改CR0寄存器绕过SSDT驱动保护
- linux忘记root密码,进入单用户模式修改密码
- linux忘记root密码,进入单用户模式修改密码
- linux忘记root密码,可以进入单用户模式修改密码
- Concurrency之Block的定义和Block中对象变量的访问
- 生成Excel的Sheet目录
- 创建并部署自签名的 SSL 证书到 Nginx
- 数据挖掘技术(五)——离群点检测
- Spark学习之RDD编程(2)
- 修改cr0进入实模式
- java中list的add与addall方法区别
- Gradle:Resolve dependecies 'app_XXAPk'很长时间
- Java访问权限修饰符的区别
- 功率MOSFET保护电路设计
- 很经典的GDB调试命令,包括查看变量,查看内存
- call 和 apply 方法
- Mybatis分页插件
- AWS EC2上传文件到S3(python boto)