首页
社区
课程
招聘
[求助]请教一段驱动代码
发表于: 2013-11-25 23:13 5561

[求助]请教一段驱动代码

2013-11-25 23:13
5561
ProbeForWrite 这个函数
判断指针是否可写
我申请了一段内存,执行起来的时候怎么还会抛出异常?
哪里出错了?

VOID MyTryAndExcept()
{
        __try
        {
                KdPrint(("Entry __try\r\n"));
                PVOID p = ExAllocatePool(PagedPool, 900);

                //判断指针是否可写,显然会导致异常
                ProbeForWrite(p, 100, 4);
               

                //如果不发生异常 就会执行到这里  并且不会知道到__except里面

                KdPrint(("Leaving __try __except\r\n"));
                if ( p )
                {
                        ExFreePool(p);
                }

        }
        __except(EXCEPTION_EXECUTE_HANDLER)
        {
                //发生异常了 执行到这里
                KdPrint(("catch the exception!...\r\n"));
        }
}

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

收藏
免费 0
支持
分享
最新回复 (6)
雪    币: 4817
活跃值: (23)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
你看下文档啊,WDK文档里写着“The ProbeForWrite routine checks that a user-mode buffer actually resides in the user-mode portion of the address space, is writable, and is correctly aligned.”

在看看WRK里ProbeForWrite的代码部分:
if (Length != 0) {

        //
        // If the structure is not properly aligned, then raise a data
        // misalignment exception.
        //

        ASSERT((Alignment == 1) || (Alignment == 2) ||
               (Alignment == 4) || (Alignment == 8) ||
               (Alignment == 16));

        StartAddress = (ULONG_PTR)Address;
        if ((StartAddress & (Alignment - 1)) == 0) {

            //
            // Compute the ending address of the structure and probe for
            // write accessibility.
            //

            EndAddress = StartAddress + Length - 1;
            if ((StartAddress <= EndAddress) &&
             [B]   (EndAddress < MM_USER_PROBE_ADDRESS))[/B] {

                //
                // N.B. Only the contents of the buffer may be probed.
                //      Therefore the starting byte is probed for the
                //      first page, and then the first byte in the page
                //      for each succeeding page.
                //
                // If this is a Wow64 process, then the native page is 4K, which
                // could be smaller than the native page size/
                //

                EndAddress = (EndAddress & ~(PageSize - 1)) + PageSize;
                do {
                    *(volatile CHAR *)StartAddress = *(volatile CHAR *)StartAddress;
                    StartAddress = (StartAddress & ~(PageSize - 1)) + PageSize;
                } while (StartAddress != EndAddress);

                return;

            } else {
                [B]ExRaiseAccessViolation();[/B]
            }

        } else {
            ExRaiseDatatypeMisalignment();
        }
    }


这两段说明,这个函数不判断内核地址,只用来检查R3内存。如果碰到R0地址,直接抛异常
2013-11-25 23:23
0
雪    币: 19
活跃值: (1086)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
thks,明白了 非常感谢  还是要认真看看文档
2013-11-25 23:25
0
雪    币: 19
活跃值: (1086)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
那请问一下 内核下的函数是什么呢
2013-11-25 23:34
0
雪    币: 4817
活跃值: (23)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
你没发现这个函数其实就是把数据读出来再写一遍么?你完全可以自己写一个的啊。
内核一般情况下不使用函数来检查R0地址,而是使用try execpt宏包含可能导致访问异常的代码。
2013-11-25 23:46
0
雪    币: 110
活跃值: (34)
能力值: (RANK:50 )
在线值:
发帖
回帖
粉丝
6
内核下:
MmIsAddressValid:

BOOLEAN MmIsAddressValid(
  _In_  PVOID VirtualAddress
);

http://msdn.microsoft.com/en-us/library/windows/hardware/ff554572(v=vs.85).aspx
这个函数能测试访问该地址是否会产生缺页错误,有时候用来实现类似ProbeForWrite的的功能。
但是:
1.在执行MmIsAddressValid时指定的内存的情况并不一定和你访问该位置时相同。
2.有时候有效的内核地址也会缺页。
所以用该函数实现对内核地址的访问检查不一定可靠。
//==================================
不过如果只想检测一下 ExAllocatePool申请内存是否成功的话,直接判断其返回值是否为0即可(具体请参考 ExAllocatePool的说明)
在Windows NT 6.2(Windows 8/Server 2012)之前的内核中,默认情况下PagedPool是可读写但不可执行的,NonPagedPool是可读写可执行的。要修改内核内存保护属性请使用MDL
2013-11-26 00:13
0
雪    币: 19
活跃值: (1086)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
thank you very much!
2013-11-26 18:23
0
游客
登录 | 注册 方可回帖
返回
//