nez
nez
驱动牛犊
驱动牛犊
  • 注册日期2006-07-16
  • 最后登录2013-07-14
  • 粉丝0
  • 关注0
  • 积分195分
  • 威望24点
  • 贡献值1点
  • 好评度23点
  • 原创分0分
  • 专家分0分
阅读:3426回复:8

ZwMapViewOfSection 不解

楼主#
更多 发布于:2007-06-24 11:55

NTSTATUS
memshare(
            IN POPEN_CONTEXT          pOpencontext,
            IN PUCHAR               pNameBuffer,
            IN UINT                  BufferLength
            )
{
    NTSTATUS                     NtStatus=STATUS_SUCCESS;
    OBJECT_ATTRIBUTES            objAttrs;
    UNICODE_STRING               usSharedMemoryObjName;
    PVOID                        uBaseAddress = NULL;
    ULONG                        ViewSize = 0;
    PMDL                         Mdl;

    RtlInitUnicodeString(&usSharedMemoryObjName, MY_SHARED_OBJ);
    
    InitializeObjectAttributes(
        &objAttrs,
        &usSharedMemoryObjName,
        OBJ_FORCE_ACCESS_CHECK | OBJ_CASE_INSENSITIVE |OBJ_KERNEL_HANDLE,
        (HANDLE)NULL,
        (PSECURITY_DESCRIPTOR)NULL
        );

    NtStatus = ZwOpenSection(
        & pOpencontext->pAdapt->SendMemHandle,
        SECTION_ALL_ACCESS,//SECTION_QUERY | SECTION_MAP_READ|    SECTION_MAP_WRITE,
        &objAttrs
    );
    
    if(NtStatus != STATUS_SUCCESS)
    {
        DBGPRINT(("ZwOpenSection FAILED %x\n" ,NtStatus));
        return NtStatus;
    }
        
    NtStatus = ZwMapViewOfSection(
        pOpencontext->pAdapt->SendMemHandle, //section handle
        (HANDLE)-1,//NtCurrentProcess(), // current process
        &uBaseAddress, //virtual based address
        0L, //Zerobits
        ViewSize,
        NULL, // optional
        (PSIZE_T)&ViewSize, // How much to map
        ViewShare, // Inherit disposition
        0,//MEM_COMMIT,// ALlocation Type
        PAGE_READWRITE //protection
        );

    if(NtStatus != STATUS_SUCCESS)
    {
        DBGPRINT(("ZwMapViewOfSection FAILED %x\n" ,NtStatus));
        return NtStatus;
    }

    DBGPRINT(("%x %x %x\n", &ViewSize , uBaseAddress ,*(PUCHAR)uBaseAddress));//error

    ZwUnmapViewOfSection(pOpencontext->pAdapt->SendMemHandle,uBaseAddress);
    
    ZwClose(pOpencontext->pAdapt->SendMemHandle);

    return NtStatus;
}

我每次访问由ZwMapViewOfSection 映射的地址中的内容就会蓝屏 不知道为什么
谁帮帮我,我把份全部奉献 我的分也不多了
zhaock
驱动太牛
驱动太牛
  • 注册日期2002-01-26
  • 最后登录2018-06-02
  • 粉丝3
  • 关注2
  • 积分73328分
  • 威望362317点
  • 贡献值1点
  • 好评度226点
  • 原创分0分
  • 专家分0分
  • 社区居民
沙发#
发布于:2007-06-24 23:13
1.你的memshare是在什么irql级别调用的? passive_level?
2.每次访问由ZwMapViewOfSection 映射的地址中的内容就会蓝屏,是在什么情况下访问的?
是在ZwMapViewOfSection 成功后,调用DBGPRINT(("%x %x %x\n", &ViewSize , uBaseAddress ,*(PUCHAR)uBaseAddress));就蓝屏的吗?显然在其他进程环境下,访问肯定会出问题
3.你蓝屏后,生成转储文件,用windbg分析一下,把!analyze -v 的结果贴上来,好帮你分析原因
nez
nez
驱动牛犊
驱动牛犊
  • 注册日期2006-07-16
  • 最后登录2013-07-14
  • 粉丝0
  • 关注0
  • 积分195分
  • 威望24点
  • 贡献值1点
  • 好评度23点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2007-06-25 09:27
引用第1楼zhaock于2007-06-24 23:13发表的  :
1.你的memshare是在什么irql级别调用的? passive_level?
2.每次访问由ZwMapViewOfSection 映射的地址中的内容就会蓝屏,是在什么情况下访问的?
是在ZwMapViewOfSection 成功后,调用DBGPRINT(("%x %x %xn", &ViewSize , uBaseAddress ,*(PUCHAR)uBaseAddress));就蓝屏的吗?显然在其他进程环境下,访问肯定会出问题
3.你蓝屏后,生成转储文件,用windbg分析一下,把!analyze -v 的结果贴上来,好帮你分析原因


irql级别调用dispetch level.
只要访问 *(PUCHAR)uBaseAddress) 就会蓝屏,你说显然在其他进程环境下,访问肯定会出问题,难道映射后的空间不能通过这种方式访问吗??那我该怎么使用 ZwMapViewOfSection 得到的地址?谢谢zhaock
zhaock
驱动太牛
驱动太牛
  • 注册日期2002-01-26
  • 最后登录2018-06-02
  • 粉丝3
  • 关注2
  • 积分73328分
  • 威望362317点
  • 贡献值1点
  • 好评度226点
  • 原创分0分
  • 专家分0分
  • 社区居民
地板#
发布于:2007-06-25 10:13
你有必要在dispetch level调用吗?*(PUCHAR)uBaseAddress) 可能会引起缺页中断.而在dispetch level,缺页中断就会导致系统蓝屏.
低于dispetch level的情况下调用,就没有问题
nez
nez
驱动牛犊
驱动牛犊
  • 注册日期2006-07-16
  • 最后登录2013-07-14
  • 粉丝0
  • 关注0
  • 积分195分
  • 威望24点
  • 贡献值1点
  • 好评度23点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2007-06-25 11:12
那怎么改 irql 的级别? 我用的passthru 的程序,一运行就在 dispatch level 难道可以动态改变吗,你说是缺页中断 我好像也有同感 ,我看程序里的变量地址在 0xfe57eadc , 用ExAllocatePoolWithTag(NonPagedPool ,.256,.) 得到的地址在 0x80d42240 而 zwmapviewofsection 得到的虚拟地址在 0xb30000 ,你看这是不是不太正常呢??
zhaock
驱动太牛
驱动太牛
  • 注册日期2002-01-26
  • 最后登录2018-06-02
  • 粉丝3
  • 关注2
  • 积分73328分
  • 威望362317点
  • 贡献值1点
  • 好评度226点
  • 原创分0分
  • 专家分0分
  • 社区居民
5楼#
发布于:2007-06-25 11:30
你要实现一个什么功能?这种内存共享的方式,不适合你这种情况,很少见到用这种方法来实现驱动和应用程序共享内存的.有很多其他的方法.先把你的需求说清楚
nez
nez
驱动牛犊
驱动牛犊
  • 注册日期2006-07-16
  • 最后登录2013-07-14
  • 粉丝0
  • 关注0
  • 积分195分
  • 威望24点
  • 贡献值1点
  • 好评度23点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2007-06-25 11:43
我就是要把我收到的感兴趣的包传到上层应用程序,我看winpcap 的确没用这种方法,但是看微软文档写道 : 在下边 ,而且网上也有些说法例如提高效率等等,所以就试试。你看可以做不??



Shared Memory Object Method
A memory-mapped file backed by the paging file is a common technique used for sharing memory among user processes. However, you can use the same technique to share memory between user processes and a device driver. There are two approaches to this technique.

In the first method, a driver can create a named memory object (called a section object) and one or more user applications can open the same object by using OpenFileMapping and then calling the MapViewOfFile function to get a pointer to a section or all of the shared memory. By specifying protection attributes to the section object, you can define the manner in which a process can manipulate the memory.

In the second method, an application can create a named memory object in user mode with CreateFileMapping. A driver can open the same memory object by using ZwOpenSection and calling ZwMapViewOfSection to get a pointer to it. Always access this memory address in kernel mode with an exception handler.

Because the object is always mapped in the user address space (below 0x80000000) of a process (regardless of whether the object is created in kernel mode or user mode) the address is valid only if it is accessed in the context of the process. Every call to MapViewOfFile or to ZwMapViewOfSection on the same memory object returns a different memory address even for the same process. This method is not recommended and is used least by low-level device drivers because, as explained earlier, the scope of the address is limited to the process in which the object is mapped, and it cannot be accessed in a DPC or ISR. Also, the API to create a memory object in kernel mode is not documented in the DDK.

However, to use the address at raised IRQL, such as in DPC or ISR, you have to probe and lock the buffer pages and get a system virtual address (MmGetSystemAddressForMdl) as described in the IOCTL method earliern in this article.

This method is simple and easy only if the memory is going to be shared between two or more user processes and one or more device drivers. Otherwise, it is much easier and more efficient to use the IOCTL technique for sharing memory between a user process and a device driver.
zhaock
驱动太牛
驱动太牛
  • 注册日期2002-01-26
  • 最后登录2018-06-02
  • 粉丝3
  • 关注2
  • 积分73328分
  • 威望362317点
  • 贡献值1点
  • 好评度226点
  • 原创分0分
  • 专家分0分
  • 社区居民
7楼#
发布于:2007-06-25 12:21
However, to use the address at raised IRQL, such as in DPC or ISR, you have to probe and lock the buffer pages and get a system virtual address (MmGetSystemAddressForMdl) as described in the IOCTL method earliern in this article.
照这篇文章前面提到的这个方法做.你现在采用的方法不适合.
nez
nez
驱动牛犊
驱动牛犊
  • 注册日期2006-07-16
  • 最后登录2013-07-14
  • 粉丝0
  • 关注0
  • 积分195分
  • 威望24点
  • 贡献值1点
  • 好评度23点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2007-06-25 15:20
好吧,我放弃这种方法了,谢谢版主,怎么给分??
游客

返回顶部