Quantcast
Channel: 看雪安全论坛
Viewing all articles
Browse latest Browse all 9556

【求助】MmIsAddressValid 和 ProbeForRead

$
0
0
请看一段在驱动中判断PE文件格式的代码(代码很乱,勿喷):


pBaseADDR 是文件映射到内存之后的地址.

代码:

                __try
                {
                        ProbeForRead((PVOID)(dosheader->e_lfanew+(LONG)pBaseADDR),sizeof(IMAGE_NT_SIGNATURE),1);

                        if(MmIsAddressValid((PVOID)(dosheader->e_lfanew+(LONG)pBaseADDR)))

                        {
                                if( *(DWORD*)(dosheader->e_lfanew+(LONG)pBaseADDR) != IMAGE_NT_SIGNATURE )
                                {
                                        KdPrint(("不是PE文件(NT_SIGNATURE) %wZ\n",&nameInfo->Name));
                               
                                }
                        }else{
                                KdPrint(("MmIsAddressValid error(IMAGE_NT_SIGNATURE):%wZ\n",&nameInfo->Name));

                        }

                }__except(EXCEPTION_EXECUTE_HANDLER)
                {
                        KdPrint(("ProbeForRead error(IMAGE_NT_SIGNATURE)\n"));

                }


这段代码是为了检测PE文件NT头开始的4字节是不是"PE00", 如果是正常的32位PE文件,没有什么问题.但是如果是16位的PE文件,DOS头的e_lfanew字段,很可能是一个极大的数值(比文件尺寸还大),这个时候如果不加判断,直接读取这个位置的数据,直接蓝屏.

所以我加了一句ProbeForRead, 但是,加了这一句并不能避免因为e_lfanew过大而导致的蓝屏,即使e_lfanew比整个文件尺寸还大,他都没有抛出异常.但是如果访问的话,会蓝屏.

所以又加了一句MmIsAddressValid,加了这句之后,可以避免蓝屏.
但是有时候,虽然e_lfanew的数值很大,但是pBaseADDR加上e_lfanew,还处于我们映射的文件范围之内,实际上是可以读取的,但是MmIsAddressValid返回了"假".


XPSP3系统中windows目录下winhelp.exe,这是个16位的程序,如果按照32位PE文件的结构来看,它的e_lfanew值为1E00, 而这个文件的大小是0x3FDF0, 1E00是在文件映射内存的范围之内的,是可以读取的,但是mmisvalidaddress返回假.

从MSDN上看到的说明是:

mmisvalidaddress 仅检测内核地址是否会发生缺页,同时不推荐使用这个函数.
ProbeForRead 会确保内存地址是有效的且在用户空间中.

这样看的话, mmisvalidaddress 返回假 可以理解,可能是因为会发生缺页.

system32文件夹下,有一个dosx.exe,也是个16位的程序,按照32位PE格式来解析,e_lfanew为0x1A688F07,但是实际上这个文件的大小才0XD260, 这样读取会出错,但是ProbeForRead却没有抛出异常.


这种情况下,有什么办法能准确检测指定内存是否可读呢?

Viewing all articles
Browse latest Browse all 9556

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>