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;
}
执行函数: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;
}
解决方案 »
- VC++头文件定义
- 关与doc与多个view的问题
- 请问按钮类的WM_CTLCOLOR_REFLEFT的消息有什么作用?
- 如何在Dialog based的程序窗体上加上状态栏
- 一个简单的问题??
- 谁有《COM技术内幕》的第13章的例子的源码,送100分,谢谢先!
- 关于OCX的一个看似简单的问题求助?
- 问VC+MAKEFILE高手,有一些问题弄不清楚,敬请帮忙UP+指正,分以倾我所有,再加再补。
- CDialogEx,裁减子窗口的属性在资源对话框里设定和在代码里设定有不同?
- 窗口标题栏的一个怪问题
- MFC 迷茫,大家推荐几本好书吧,谢谢
- 公司是通过代理来上网的。只有浏览器可以访问网络。有什么办法可以让电脑上的其他程序上网?
看来是楼主的 ZwMapViewOfSection传参出错了! (VOID**)???
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;
}