物理地址讀寫驅動

正文

沒有用MmMapIoSpace,用了映射的方式對物理地址數據進行讀寫,之前測試MmMapIoSpace在win10較高版本用不了,貌似是不支持了。然後利用映射的方式測試的時候可以在win10下運行。用法和效果如下,加載驅動後,Read.exe用來讀取物理地址的數據,限制爲0x100字節大小,當然可以通過修改驅動代碼來讀取任意字節,我這裏只是給了個demo;Write.exe則是對指定的物理地址進行寫操作,限制了寫入的大小爲DWORD32,這裏也可以通過修改驅動代碼進行調整。

編譯好的程序在bin目錄下

這裏編譯的是用於64位系統的,32位的話改一下代碼就可以,以後有需求的話再更新。

 

編譯環境

VS2015+WDK10

代碼

QKSword/Physical_RWgithub.com圖標

不是驅動大佬,可能驅動代碼寫的並不是很好,如果有什麼意見或者驅動存在了藍屏的問題,歡迎指出和指導

 

/*
function
	讀取物理地址,大小爲FF
argv
	MapAddress:物理地址映射出來的地址
	Physicaladdress:指定讀取的物理地址
return
	返回狀態
*/
NTSTATUS ReadPhysicalAddress(PVOID MapAddress, DWORD64 Physicaladdress)
{
	NTSTATUS status;
	PVOID BaseAddress = NULL; // 映射的虛地址
	DWORD32 offset;
	LARGE_INTEGER SectionOffset; //存放物理地址
	SIZE_T size = 0x2000; //映射大小

	//打開內核對象
	status = GetPhysicalHandle();
	if (status < 0)
	{
		status = FALSE;
		goto Leave;
	}

	//讀取出來的地址是4K對齊,所以偏移自己處理一下即可
	offset = Physicaladdress & 0xFFF;	//取低12位作爲偏移使用
	SectionOffset.QuadPart = (ULONGLONG)(Physicaladdress);

	// 映射物理內存地址到當前進程的虛地址空間
	status = ZwMapViewOfSection(
		hPhysicalhandle,
		NtCurrentProcess(),
		(PVOID *)&BaseAddress,
		0,
		size,
		&SectionOffset,
		&size,
		ViewShare,
		MEM_TOP_DOWN,
		PAGE_READWRITE);

	if (status < 0)
	{
		status = FALSE;
		goto Leave;
	}

	//獲取映射出來的數據
	memmove_s(MapAddress, 0x100, (PVOID)((DWORD64)BaseAddress + offset), 0x100);

	// 完成操作,取消地址映射
	status = ZwUnmapViewOfSection(NtCurrentProcess(), BaseAddress);

	if (status < 0)
	{
		status = FALSE;
		goto Leave;
	}

Leave:
	if (hPhysicalhandle != NULL)
	{
		ZwClose(hPhysicalhandle);
	}

	return status;
}

/*
function
	寫物理地址,大小爲DWORD
argv
	PhysicalAddress:物理地址
	WriteData:寫入數據
return
	返回狀態
*/
NTSTATUS WritePhysicalMemory(DWORD64 PhysicalAddress, DWORD32 WriteData)
{
	NTSTATUS status;
	PVOID BaseAddress = NULL; // 映射的虛地址
	DWORD32 offset;
	LARGE_INTEGER SectionOffset; //存放物理地址
	SIZE_T size = 0x2000; //映射大小

	//打開內核對象
	status = GetPhysicalHandle();
	if (status < 0)
	{
		status = FALSE;
		goto Leave;
	}

	offset = PhysicalAddress & 0xFFF;		//取低12位作爲偏移使用

	SectionOffset.QuadPart = (ULONGLONG)(PhysicalAddress);

	// 映射物理內存地址到當前進程的虛地址空間
	status = ZwMapViewOfSection(
		hPhysicalhandle,
		NtCurrentProcess(),
		(PVOID *)&BaseAddress,
		0,
		size,
		&SectionOffset,
		&size,
		ViewShare,
		MEM_TOP_DOWN,
		PAGE_READWRITE);

	if (status < 0)
	{
		status = FALSE;
		goto Leave;
	}

	memmove_s((PVOID)((DWORD64)BaseAddress + offset), sizeof(DWORD32), &WriteData, sizeof(DWORD32));

	status = ZwUnmapViewOfSection(NtCurrentProcess(), BaseAddress);

	if (status < 0)
	{
		status = FALSE;
	}

Leave:
	if (hPhysicalhandle != NULL)
	{
		ZwClose(hPhysicalhandle);
	}

	return status;
}

/*
function
	打開內核對象
argv
	NULL
return
	返回調用狀態
*/
NTSTATUS GetPhysicalHandle()
{
	NTSTATUS status;
	UNICODE_STRING PhysicalMemoryString;
	OBJECT_ATTRIBUTES attributes;

	WCHAR PhysicalMemoryName[] = L"\\Device\\PhysicalMemory";
	RtlInitUnicodeString(&PhysicalMemoryString, PhysicalMemoryName);
	InitializeObjectAttributes(&attributes, &PhysicalMemoryString, 0, NULL, NULL);
	status = ZwOpenSection(&hPhysicalhandle, SECTION_MAP_READ | SECTION_MAP_WRITE, &attributes);

	return status;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章