正文
沒有用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;
}