首页
社区
课程
招聘
[讨论]x64中无法通过cr0来关闭内存写保护?!
发表于: 2016-8-29 23:39 10686

[讨论]x64中无法通过cr0来关闭内存写保护?!

2016-8-29 23:39
10686
要修改内核某处,在X86中,往往会通过关闭cr0的WP位来关闭内存写保护,如cli; mov eax, cr0; and eax, 0xfffeffff; mov cr0,eax;

我发现这个方法在x64下无效了, 百度了一下,网上都是一大堆的 WPOFFx64, WPONx64, 都是老样子,先Raise Irql,  cli, 然后清除cr0的WP位。  我不明白,我测试到明明这种方法在x64下是无效的, 为什么网上还煞有其事地讲来讲去,到处是例子代码, 是专坑新手的吗?故意的吗?

不要谈 Patch Guard,  这个不关Patch Guard 的事,因为操作cr0后,试图修改内存时,立即KiPageFault , KiBugCheckDispatch, KeBugCheckEx ...   不要告诉我这是 Patch Guard , 并且当时系统是调试模式。  蓝屏是因为 Page Fault 啊,PageFault ....  明显关闭cr0的WP位根本不起作用。

难道是与目标内存有关?不太可能,因为我换了好几处无关痛痒的地方来测试(比如, 函数尾部的nop),哪怕只动1字节,也是一样的KiPageFault

x64中无法通过cr0来关闭内存写保护?哪要怎么做?重新映射什么的?

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (7)
雪    币: 12848
活跃值: (9142)
能力值: ( LV9,RANK:280 )
在线值:
发帖
回帖
粉丝
2
MDL映射一下
2016-8-29 23:48
0
雪    币: 36
活跃值: (212)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
我又查了一下cr0的WP的定义,来自<软件调试>-张银奎, 第44页,是这样定义 cr0 的WP位的:

为 1 时,禁止 内核级代码 写 用户级 的只读内存页;
为 0 时允许

为什么在 32位中,关闭cr0的WP又是有效的呢。
2016-8-29 23:49
0
雪    币: 8835
活跃值: (2404)
能力值: ( LV12,RANK:760 )
在线值:
发帖
回帖
粉丝
4
正统应该使用MDL
CR0这玩意动它干啥
2016-8-30 00:40
0
雪    币: 333
活跃值: (161)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
5
x64内核不可以用汇编了吧
有专门的函数可以改写cr0
2016-8-30 07:32
0
雪    币: 125
活跃值: (45)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
6
char sz_关闭[15]=
                "\xFA"                     //0
                "\x0F\x20\xC0"             //3
                "\x48\x25\xFF\xFF\xFE\xFF" //9
                "\x0F\x22\xC0"             //12
                "\xC3";                    //13
        char sz_开启[15]=
                "\x0F\x20\xC0"             //2
                "\x48\x0D\x00\x00\x01\x00" //8
                "\x0F\x22\xC0"             //11
                "\xFB"                     //12
                "\xC3";                    //13
你自己分配内存直接调用就用
是你的问题x64是没有问题的
2016-9-4 02:05
0
雪    币: 739
活跃值: (2314)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
7
可以的,我之前写过的

/*cli
cli
mov rax,cr0
mov rcx,rax
and eax,0fffeffffh
mov cr0,rax
mov rax,rcx
ret

*/
UCHAR shellcode[20] =
"\xFA"                 //0
"\x0F\x20\xC0"         //3
"\x48\x8B\xC8"         //6
"\x25\xFF\xFF\xFE\xFF" //11
"\x0F\x22\xC0"         //14
"\x48\x8B\xC1"         //17
"\xC3";                //18
/*
mov cr0,rcx
sti
ret
*/
UCHAR shellcode1[6] =
"\x0F\x22\xC1" //2
"\xFB"         //3
"\xC3";        //4

ULONG closeinterupt()
{
        ULONG old_cr0;
        CLOSEINTERUPT func = ExAllocatePool(NonPagedPool, 20);
        memcpy(func, shellcode, 20);
        old_cr0 = func();
        ExFreePool(func);
        return old_cr0;
}
void startinteript(ULONG old_cr0)
{
        OPENINTERUPT func = ExAllocatePool(NonPagedPool, 6);
        memcpy(func, shellcode1, 6);
        func(old_cr0);
        ExFreePool(func);
}
2016-9-4 10:35
0
雪    币: 1187
活跃值: (410)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
KIRQL  WPOFFx64()
{
       KIRQL  irql=KeRaiseIrqlToDpcLevel();
       UINT64  cr0=__readcr0();
       cr0  &=  0xfffffffffffeffff;
       __writecr0(cr0);
       _disable();
       return  irql;
}

void  WPONx64(KIRQL  irql)
{
       UINT64  cr0=__readcr0();
       cr0  |=  0x10000;
       _enable();
       __writecr0(cr0);
       KeLowerIrql(irql);
}


别人的代码,很好用,_enable  是  sti  指令,  _disable是  cli  指令,不懂为什么要这样
2018-6-26 16:39
0
游客
登录 | 注册 方可回帖
返回
//