NT式驱动,在映射物理内存地址时提示错误,错误代码:0xC00000F1
执行函数:ZwMapViewOfSection
我是想直接访问物理地址0x400处的值,这个位置是写的串口地址
//--------------------------------------------------------------------------
//打开物理内存,并返回Handle
#pragma PAGEDCODE
HANDLE _OpenPhyMem()
{
NTSTATUS status;
HANDLE hMem;
UNICODE_STRING MemDevName;
OBJECT_ATTRIBUTES obj_attr;

RtlInitUnicodeString(&MemDevName,L"\\Device\\PhysicalMemory");
InitializeObjectAttributes(&obj_attr,&MemDevName,OBJ_CASE_INSENSITIVE,NULL,NULL);
status = ZwOpenSection(&hMem,SECTION_ALL_ACCESS,&obj_attr);
if(!NT_SUCCESS(status))
{
KdPrint(("Open memory device error\n"));
return 0;
}
return hMem;
}
//--------------------------------------------------------------------------
//从内存读一个32位值
#pragma PAGEDCODE
ULONG _In_Mem_32(ULONG MemAddr)
{
NTSTATUS status;
ULONG Value = 0xFFFFFFFF;
PHYSICAL_ADDRESS phyAddr;
ULONG *pVirMemAddr;
ULONG memSize = 0x0F;
HANDLE hLocal;
HANDLE hMem; hMem = _OpenPhyMem();
if(!hMem)
{
KdPrint(("Can not open physical memory\n"));
return Value;
} hLocal = NtCurrentProcess();
phyAddr.u.LowPart = MemAddr;
phyAddr.u.HighPart = 0x00;
status = ZwMapViewOfSection(hMem,hLocal,(VOID**)(&pVirMemAddr),0,memSize,&phyAddr,&memSize,ViewShare,0,PAGE_READWRITE | PAGE_NOCACHE); //执行到这里返回错误
if(!NT_SUCCESS(status))
{
ZwClose(hMem);
KdPrint(("Map physical memory eror:%X\n",status));
return Value;
}
Value = pVirMemAddr[0];
KdPrint(("Value=%X,Buf=%X%X\n",Value,pVirMemAddr[0],pVirMemAddr[1]));
ZwUnmapViewOfSection(hLocal,pVirMemAddr);
ZwClose(hMem);
return Value;
}

解决方案 »

  1.   

    #define STATUS_INVALID_PARAMETER_3       ((NTSTATUS)0xC00000F1L)
    看来是楼主的 ZwMapViewOfSection传参出错了! (VOID**)???
      

  2.   

    调用ZwMapViewOfSection前,将pVirMemAddr初始化为0。
      

  3.   

    修改了一下映射程序,调用的时候就蓝屏了,0x0000008E
    NTSTATUS MapPhyMem(PHANDLE phSection,LARGE_INTEGER uPhyAddr,PVOID pVirtualMemAddr)
    {
    UNICODE_STRING unstrDevName;
    OBJECT_ATTRIBUTES obj_attr;
    NTSTATUS status;
    SIZE_T ssize = 0xFF;

    RtlInitUnicodeString(&unstrDevName,L"\\Device\\PhysicalMemory");
    InitializeObjectAttributes(&obj_attr,&unstrDevName,OBJ_KERNEL_HANDLE,NULL,NULL);

    status = ZwOpenSection(phSection,SECTION_ALL_ACCESS,&obj_attr);
    if(!NT_SUCCESS(status))
    {
    KdPrint(("Open section error\r\n"));
    return status;
    } pVirtualMemAddr = NULL;
    status = ZwMapViewOfSection(*phSection, //Section handle
                            NtCurrentProcess(), //要使用的进程
    &pVirtualMemAddr, //映射到的虚拟内存地址
    0, 
    0xFF, 
    &uPhyAddr, //要映射的物理地址
    &ssize,
    ViewShare,
    0,
    PAGE_READWRITE | PAGE_NOCACHE);
    if(!NT_SUCCESS(status))
    {
    KdPrint(("Map physical memory error\r\n"));
    ZwClose(*phSection);
    }

    return status;
    }//--------------------------------------------------------------------------
    //驱动程序内存处理函数-->取消物理内存映射
    #pragma PAGEDCODE
    NTSTATUS UnMapPhyMem(HANDLE hVirMem,PVOID pVirtualMemAddr)
    {
    NTSTATUS status = STATUS_SUCCESS;
    status = ZwUnmapViewOfSection(NtCurrentProcess(),pVirtualMemAddr);
    if(NT_SUCCESS(status))
    {
    ZwClose(hVirMem);
    }
    return status;
    }
    读内存NTSTATUS status = STATUS_SUCCESS;
    ULONG info = 0;

    //获取当前堆栈
    PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(pIrp);
    //获取输入缓冲区大小
    ULONG InBufSize = stack->Parameters.DeviceIoControl.InputBufferLength;
    //获取输出缓冲区大小
    ULONG OutBufSize = stack->Parameters.DeviceIoControl.OutputBufferLength;
    //获取操作码
    ULONG OperCode = stack->Parameters.DeviceIoControl.IoControlCode;
    PVOID pvIOBuf = pIrp->AssociatedIrp.SystemBuffer;
    ULONG Value = 0xFFFFFFFF;
    ULONG *OutBuf = (ULONG*)pIrp->AssociatedIrp.SystemBuffer;
    PVOID pVirBuf = 0;
    LARGE_INTEGER phyAddr;
    HANDLE hVirMem = 0;
    ULONG uPort = *((ULONG*)pvIOBuf);
    ULONG uValue = ((ULONG*)pvIOBuf)[1];
    phyAddr.LowPart = uPort;
    phyAddr.HighPart = 0x00000000;
    switch(OperCode)
    {......
    case IOCTL_MEM_READ_8:
    status = MapPhyMem(&hVirMem,phyAddr,pVirBuf);
    if(NT_SUCCESS(status))
    {
    Value = *((UCHAR*)pVirBuf);
    status = UnMapPhyMem(hVirMem,pVirBuf);
    }
    break;
    }
      

  4.   

    我现在不用zwMapViewofSection了,直接用mmMapIOSpace也可以获取.只是用IRPTrace程序追踪驱动输出值都是正常的,但用deviceiocontrol得到的有时是0,有时又正常.