为了安全起见,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-; 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");
}

原创文章,转载请注明出处:http://www.cnblogs.com/hongfei/

通过修改CR0寄存器绕过SSDT驱动保护的更多相关文章

  1. x86CPU 实模式 保护模式 傻傻分不清楚? 基于Xv6-OS 分析CR0 寄存器

    基于Xv6-OS 分析CR0 寄存器 之前一直认为晕乎乎的...啥?什么时候切换real model,怎么切换,为什么要切换? ------------------------------------ ...

  2. INLINE HOOK过简单驱动保护的理论知识和大概思路

    这里的简单驱动保护就是简单的HOOK掉内核API的现象 找到被HOOK的函数的当前地址在此地址处先修改页面保护属性然后写入5个字节.5个字节就是一个简单的JMP指令.这里说一下JMP指令,如下: 00 ...

  3. 驱动保护中的ObjectType_Callback探索

    最近学习驱动保护,有点小小心德与大家分享下. 当前环境:VM中的win7 32 保护程序是某游戏的驱动保护. 具体现象是:在用PCHunter工具查看object钩子时发现如下的信息: 疑问点1:在H ...

  4. 过 DNF TP 驱动保护(二)

    过 DNF TP 驱动保护(二)   文章目录:                   01. 博文简介: 02. 环境及工具准备: 03. 分析 TP 所做的保护: 04. 干掉 NtOpenProc ...

  5. 过 DNF TP 驱动保护(一)

    过 DNF TP 驱动保护(一)   文章目录:                   01. 博文简介: 02. 环境及工具准备: 03. 分析 TP 所做的保护: 04. 干掉 NtOpenProc ...

  6. Android5.1.1 - APK签名校验分析和修改源码绕过签名校验

    Android5.1.1 - APK签名校验分析和修改源码绕过签名校验 作者:寻禹@阿里聚安全 APK签名校验分析 找到PackageParser类,该类在文件“frameworks/base/cor ...

  7. c/c++ 多线程 绕过mutex的保护

    多线程 绕过mutex的保护 mutex,能够解决线程安全的问题,但它不是万能的.下面的例子虽然使用了mutex,但是恶意注入了一个外部函数,导致把被mutex保护的双向链表,让一个外部的指针指向了, ...

  8. 通过修改EIP寄存器实现远程注入

    功能:通过修改EIP寄存器实现32位程序的DLL注入(如果是64位,记得自己对应修改汇编代码部分) 原理: 挂起目标进程,停止目标进程EIP的变换,在目标进程开启空间,然后把相关的指令机器码和数据拷贝 ...

  9. 通过修改EIP寄存器实现32位程序的DLL注入

    功能:通过修改EIP寄存器实现32位程序的DLL注入 <如果是64位 记得自己对应修改汇编代码部分> 原理:挂起目标进程,停止目标进程EIP的变换,在目标进程开启空间,然后把相关的指令机器 ...

随机推荐

  1. BZOJ 1444 [Jsoi2009]有趣的游戏 (AC自动机 + 概率DP + Gauss)

    1444: [Jsoi2009]有趣的游戏 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 1382  Solved: 498[Submit][Statu ...

  2. mybatis 时间区间比较

    直接上代码,此时数据库使用的Date类型: <if test="minCreateTime != null and minCreateTime != ''"> < ...

  3. TensorFlow 实现 RNN 入门教程

    转子:https://www.leiphone.com/news/201705/zW49Eo8YfYu9K03J.html 最近在看RNN模型,为简单起见,本篇就以简单的二进制序列作为训练数据,而不实 ...

  4. C#-VS发布网站-摘

    在vs生成发布文件 现在已经有了网站,可以发布了.可以将网站发布到您可以使用 Visual Studio 支持的任何连接协议访问的任何位置.复制网站有下面几种方式可选: 复制到本地计算机上的文件夹. ...

  5. (线段树 区间运算求点)Flowers -- hdu -- 4325

    http://acm.hdu.edu.cn/showproblem.php?pid=4325 Flowers Time Limit: 4000/2000 MS (Java/Others)    Mem ...

  6. Java的String类

    String类 String是引用数据类型:字符串是String类的对象 String类的构造方法 共有13种重载方式,这里只示例常用的几个 String():创建一个空字符串 String(Stri ...

  7. AngularJS AOP 实例

    AngularJS有种机制叫做拦截器(interceptor),它是$http扩展点,类似ASP.NET MVC的过滤器filter机制,对每个$http请求的发送和接收过程进行过滤. $httpPr ...

  8. 雪花算法(snowflake)delphi版

    雪花算法简单描述: + 最高位是符号位,始终为0,不可用. + 41位的时间序列,精确到毫秒级,41位的长度可以使用69年.时间位还有一个很重要的作用是可以根据时间进行排序. + 10位的机器标识,1 ...

  9. cudnn 安装步骤

    上官网下载对应的cudnn https://developer.nvidia.com/cudnn 下载完cudnn后,命令行输入文件所在的文件夹 (ubuntu为本机用户名) cd home/ubun ...

  10. What makes for effective detection proposals? 论文解析

    1 介绍(INTRODUCTION) 本文主要对最近的 proposal 检测方法做一个总结和评价.主要是下面这些方法.  2 Detection Proposal 方法(DETECTION PROP ...