首页
社区
课程
招聘
[求助]MmMapIoSpace部分physicaladdress不能map
发表于: 2008-12-20 14:23 13869

[求助]MmMapIoSpace部分physicaladdress不能map

2008-12-20 14:23
13869
发现有些物理地址MmMapIoSpace API并不能成功map,比如说0x01000000的物理地址,居然返回我NULL,而按照MSDN的说法,只有If space for mapping the range is insufficient, it returns NULL
真的觉得有点奇怪,0x10000000就可以成功被map,不知道有没有高手可以指教,而不能被此API map的物理地址我又应该通过何种方式去获取其linear address来访问(或者请高手指点全部4G memory的访问方式)

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (14)
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
诸位大牛们行行好,为小弟指点迷津吧
2008-12-20 16:06
0
雪    币: 364
活跃值: (152)
能力值: ( LV12,RANK:450 )
在线值:
发帖
回帖
粉丝
3
0x01000000 这个虚拟地址本来就没有对应的物理地址吧?
2008-12-20 17:45
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
没有物理地址?0x01000000不过才16M而已,我可是install了1G的内存哦!而且我可以用SE读到里面的数值,可恨就是用MmMapIoSpace就会reurn NULL,猜想应该是windows kernel驻留内存吧,哪位有办法做到穿透内核读写这段内存呢?
2008-12-20 18:07
0
雪    币: 231
活跃值: (45)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
qdk
5
lz说了这个是物理地址。
2008-12-20 22:01
0
雪    币: 231
活跃值: (45)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
qdk
6
#define		MEMORY_DEVICE_NAME	L"\\Device\\PhysicalMemory"
NTSTATUS MapMemoryToUser(ULONG PhysicalOffset,ULONG CommitSize,PVOID* MapAddress)
{
	OBJECT_ATTRIBUTES	ObjectAttributes,ob2;
	UNICODE_STRING		DestinationString;
	HANDLE				SectionHandle=NULL;
	NTSTATUS			status;

	RtlInitUnicodeString(&DestinationString,MEMORY_DEVICE_NAME);
	
	ObjectAttributes.ObjectName		=&DestinationString;
	ObjectAttributes.Length			=sizeof(OBJECT_ATTRIBUTES);
	ObjectAttributes.RootDirectory	=NULL;
	ObjectAttributes.Attributes		=OBJ_KERNEL_HANDLE;
	ObjectAttributes.SecurityDescriptor			=NULL;
	ObjectAttributes.SecurityQualityOfService	=NULL;

	status=ZwOpenSection(&SectionHandle,					//OUT PHANDLE  SectionHandle
		SECTION_QUERY|SECTION_MAP_READ|SECTION_MAP_WRITE,	//IN ACCESS_MASK  DesiredAccess
		&ObjectAttributes									//IN POBJECT_ATTRIBUTES  ObjectAttributes
		);

	PVOID			BaseAddress=NULL;
	SIZE_T			ViewSize=CommitSize;
	LARGE_INTEGER	PhysicalAddress = {PhysicalOffset, 0};

	if(NT_SUCCESS(status))
	{
		DebugPrint("ZwOpenSection成功");					
				status=ObReferenceObjectByHandle(SectionHandle,			//IN HANDLE  Handle
			SECTION_QUERY|SECTION_MAP_READ|SECTION_MAP_WRITE,	//IN ACCESS_MASK  DesiredAccess
			NULL,												//IN POBJECT_TYPE  ObjectType  OPTIONAL
			KernelMode,											//IN KPROCESSOR_MODE  AccessMode
			(PVOID*)&ob2,												//OUT PVOID  *Object
			NULL												//OUT POBJECT_HANDLE_INFORMATION  HandleInformation  OPTIONAL
			);
		if(NT_SUCCESS(status))
		{
			DebugPrint("ObReferenceObjectByHandle成功");
			status=ZwMapViewOfSection(SectionHandle,	//IN HANDLE  SectionHandle
				NtCurrentProcess(),					//IN HANDLE  ProcessHandle
				&BaseAddress,							//IN OUT PVOID  *BaseAddress
				0,										//IN ULONG  ZeroBits
				CommitSize,								//IN ULONG  CommitSize
				&PhysicalAddress,						//IN OUT PLARGE_INTEGER  SectionOffset  OPTIONAL
				&ViewSize,								//IN OUT PSIZE_T  ViewSize
				ViewShare,								//IN SECTION_INHERIT  InheritDisposition
				NULL,									//IN ULONG  AllocationType
				PAGE_READWRITE							//IN ULONG  Protect
				);
			if(NT_SUCCESS(status))
				DebugPrint("ZwMapViewOfSection成功");
			else
				DebugPrint("ZwMapViewOfSection失败");
			ZwClose(SectionHandle);
			*MapAddress=BaseAddress;
			return status;
		}
		else
		{
			DebugPrint("ObReferenceObjectByHandle失败");
			ZwClose(SectionHandle);
			*MapAddress=NULL;
			return status;
		}
	}
	else
	{
		DebugPrint("ZwOpenSection失败");
		*MapAddress=NULL;
		return status;
	}
}
2008-12-20 22:04
0
雪    币: 231
活跃值: (45)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
qdk
7
你怎么调用的,贴代码出来吧
2008-12-20 22:08
0
雪    币: 231
活跃值: (45)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
qdk
8
SE使用的是很奇怪的方式去做的,没有去细究它。

r/w  every thing就是使用我上面贴出来的那段代码做的。

winio也是用同样的代码,不过有一个小小的地方不一样,导致winio有时候不能成功的映射物理内存到虚拟内存。
2008-12-20 22:11
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
楼上的大哥,两个问题,第一,你上面那种做法有能力读到0x01000000的物理地址内容吗(或者换句话说,有能力访问4G以内包括windows kernel程序驻留内存的内容吗?)
其次,贴代码:
#pragma        PAGEDCODE
NTSTATUS KeMapPhysicalMemoryToLinearSpace(PVOID pPhysAddress,ULONG PhysMemSizeInBytes,
                                                                                PVOID *PhysMemLin){
        KdPrint(("Enter MapPhysicalMemoryToLinearSpace entry\n"));
        pTagPhyicalAddressStruct pTagphystruct = (pTagPhyicalAddressStruct)MmAllocateNonCachedMemory(sizeof(TagPhyicalAddressStruct));
        if(!pTagphystruct){
    KdPrint(("Not enough memory to create target allocation list"));
    return STATUS_INSUFFICIENT_RESOURCES;
  }
       
        pTagphystruct->Mdl = NULL;
        pTagphystruct->SystemVirtualAddress = NULL;
        pTagphystruct->UserVirtualAddress = NULL;
        PHYSICAL_ADDRESS   pStartPhysAddress;
        pStartPhysAddress.QuadPart = (ULONGLONG)pPhysAddress;
        __try{
        pTagphystruct->SystemVirtualAddress = MmMapIoSpace(pStartPhysAddress,PhysMemSizeInBytes,MmNonCached);

        if(!pTagphystruct->SystemVirtualAddress){                                                                                        //MmMapIoSpace return NULL indicate function failed.
      KdPrint(("MmMapIoSpace failed\n"));
      return STATUS_INVALID_PARAMETER;
    }
.
.
.
省略尚未执行代码若干...
        KdPrint(("Leave MapPhysicalMemoryToLinearSpace with successful return\n"));
        return STATUS_SUCCESS;
}
很让人愤怒的..输入0x01000000地址的时候(其实4G以内大多数地址好使的),返回"MmMapIoSpace failed;大爷这啥都还米做呢!求楼上大哥指教
2008-12-21 02:55
0
雪    币: 231
活跃值: (45)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
qdk
10


为什么我的就是ok的呢?

PHYSICAL_ADDRESS kk={0x01000000,0};
                        PVOID mm=MmMapIoSpace(kk,0x1000,MmNonCached);
                        if(mm)
                        {
                                DebugPrint("mm ok");
                        }
                        else
                        {
                                DebugPrint("mm failed");
                        }
2008-12-21 10:43
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
等等,我忽然发现一个不同,就是貌似你一个性map了0x1000个bytes,而我只是map了4个bytes,那么与这个问题有没有关系?
2008-12-21 16:16
0
雪    币: 231
活跃值: (45)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
qdk
12
没错啊,页式管理一般每个页4k
页是最小单位了
2008-12-21 16:20
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
可是奇怪的是其他地址也无所谓4k啊,还有就是我上次的问题,这种方法可以访问全部4G无障碍吗,在windows下每次都map 4k会不会很卡呢,这样说好麻烦,楼上大哥能qq不?
2008-12-21 16:24
0
雪    币: 231
活跃值: (45)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
qdk
14
就是在进程的页目录加一个项。

我是这么理解的。

所以不会有卡这种问题。

我没有用MmMapIoSpace试过

我用另一种方法,可以访问所有4G物理地址,只有有设备译码到这些地址,并不一定要是内存

这两种方法应该是差不多的吧
2008-12-21 16:58
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
可以再请教楼上一句您的reference code与winio的source code究竟有哪里不一样呢?winio又是为什么不能map有些地址呢?
2008-12-23 23:41
0
游客
登录 | 注册 方可回帖
返回
//