紫水晶编程技术论坛 - 努力打造成全国最好的编程论坛

 找回密码
 加入我们

QQ登录

只需一步,快速开始

搜索
查看: 3542|回复: 3

CR3读写内存,会有PAGE_FAULT_IN_NONPAGED_AREA 问题

[复制链接]

2

主题

11

帖子

0

精华

初来乍到

Rank: 1

积分
23
发表于 2019-5-25 00:13:31 | 显示全部楼层 |阅读模式
论坛的代码,好像有问题,很多控件按钮点击不了。

今天我在使用CR3读写内存时发现,会出现以下错误。
检查了下调用代码没问题,是不是在切换CR3后出现的问题呢?速度慢时不会蓝屏,所以我没有调试到异常。
如果是用keattchprocess来读写没问题。
刚入门的小白,希望大神们不要介意。
蓝屏代码
PAGE_FAULT_IN_NONPAGED_AREA (50)
Invalid system memory was referenced.  This cannot be protected by try-except.
Typically the address is just plain bad or it is pointing at freed memory.
Arguments:
Arg1: fffff5010f5c9a98, memory referenced.
Arg2: 0000000000000000, value 0 = read operation, 1 = write operation.
Arg3: fffff803c6d3d730, If non-zero, the instruction address which referenced the bad memory
        address.
Arg4: 0000000000000002, (reserved)



NTSTATUS KReadWriteProcessMemoryCR3(_In_ PEPROCESS Process, _In_ PVOID Address, _In_ UINT32 Length, _Inout_ PVOID Buffer, _In_ BOOLEAN IsWrite)
{

        NTSTATUS ntStatus = STATUS_UNSUCCESSFUL;

        ULONG64 pDTB = 0, OldCr3 = 0;

        PVOID pDTBBaseAddr = (PVOID)((UCHAR*)Process + DIRECTORY_TABLE_BASE_OFFSET);

        if (!MmIsAddressValid(pDTBBaseAddr))
        {
                return ntStatus;
        }


        pDTB = Get64bitValue(pDTBBaseAddr);

        if (pDTB == 0)
        {
                return ntStatus;
        }


        //Record old cr3 and set new cr3
        _disable();//禁止中断
        OldCr3 = __readcr3();
        __writecr3(pDTB);
        _enable();


        if (MmIsAddressValid(Address) && MmIsAddressValid(Buffer)) {//检查page fault

                __try {

                        if (IsWrite)
                        {
                               
                                RtlCopyMemory(Address, Buffer, Length);

                        }
                        else
                        {
                               
                                RtlCopyMemory(Buffer, Address, Length);
                        }

                        ntStatus = STATUS_SUCCESS;

                }

                __except (1) {

                        if (IsWrite)
                        {
                                KdPrint(("windbg>>>write error %p\n", Address));
                        }
                        else
                        {
                                KdPrint(("windbg>>>read error %p\n", Address));
                        }

                }
        }
        else
        {
                KdPrint(("windbg>>>MmIsAddressValid error %p\n", Address));

        }

        ////Restore old cr3
        _disable();
        __writecr3(OldCr3);
        _enable();

        return ntStatus;

}

2

主题

11

帖子

0

精华

初来乍到

Rank: 1

积分
23
 楼主| 发表于 2019-5-29 22:52:57 | 显示全部楼层
问题已找到是 MmIsAddressValid 判断内存属性造成的,不过这函数没有处理异常,不太懂

0

主题

16

帖子

0

精华

铜牌会员

Rank: 2Rank: 2

积分
36
发表于 2019-5-30 08:33:49 | 显示全部楼层
        __try
        {
                ProbeForRead(Address, sizeof(Buffer), 1);

                RtlCopyMemory(Buffer, Address, Length);

                DbgPrint("[x64Drv] Date read: %ld", *(PULONG)Buffer);
        }
        __except (1)
        {
                DbgPrint("[x64Drv] Memory Is Error \n");
        }

0

主题

16

帖子

0

精华

铜牌会员

Rank: 2Rank: 2

积分
36
发表于 2019-5-30 08:34:52 | 显示全部楼层
这样测试一个地址是否有效,   没坑
您需要登录后才可以回帖 登录 | 加入我们

本版积分规则

手机版|Archiver|紫水晶工作室 ( 粤ICP备05020336号 )

GMT+8, 2024-4-29 11:24 , Processed in 0.023166 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表