x64vista2003 sp1下使用ZwOpenSection直接读写物理内存

    技术2022-05-20  31

    习惯于在应用程序用ZwOpenSection打开"Device"PhysicalMemory访问物理内存的朋友可能要郁闷了,微软出于安全考 虑的原因,在x64/vista/2003 sp1系统中所有用户模式的程序将不能访问"Device"PhysicalMemory对象。

       经过测试,原来应用程序在2k/xp中使用ZwOpenSection,ZwMapViewOfSection可以正常访问物理内存,而同样的代码在 x64上却在ZwOpenSection时返回"拒绝访问"(C0000022 STATUS_ACCESS_DENIED)。

       幸运的是在驱动中,仍然能通过这个方法访问物理内存。所以在x64/vista/2003 sp1下使用ZwOpenSection直接读写物理内存,必须在驱动中进行。

     相关代码如下:

    NTSTATUS MapPhysicalMemoryToLinearSpace(PVOID pPhysAddress,                                         ULONG PhysMemSizeInBytes,                                         PVOID *ppPhysMemLin,                                         HANDLE *pPhysicalMemoryHandle) {   UNICODE_STRING     PhysicalMemoryUnicodeString;   PVOID              PhysicalMemorySection = NULL;   OBJECT_ATTRIBUTES  ObjectAttributes;   PHYSICAL_ADDRESS   ViewBase;   NTSTATUS           ntStatus;   PHYSICAL_ADDRESS   pStartPhysAddress;   PHYSICAL_ADDRESS   pEndPhysAddress;   PHYSICAL_ADDRESS   MappingLength;   BOOLEAN            Result1, Result2;   ULONG              IsIOSpace;   unsigned char     *pbPhysMemLin = NULL;

      OutputDebugString ("Entering MapPhysicalMemoryToLinearSpace");

      RtlInitUnicodeString (&PhysicalMemoryUnicodeString,                         L"""Device""PhysicalMemory ");

      InitializeObjectAttributes (&ObjectAttributes,                               &PhysicalMemoryUnicodeString,                               OBJ_CASE_INSENSITIVE,                               (HANDLE) NULL,                               (PSECURITY_DESCRIPTOR) NULL);

      *pPhysicalMemoryHandle = NULL;

      ntStatus = ZwOpenSection (pPhysicalMemoryHandle,                             SECTION_ALL_ACCESS,                             &ObjectAttributes);

      if (NT_SUCCESS(ntStatus))   {

        ntStatus = ObReferenceObjectByHandle (*pPhysicalMemoryHandle,                                           SECTION_ALL_ACCESS,                                           (POBJECT_TYPE) NULL,                                           KernelMode,                                           &PhysicalMemorySection,                                           (POBJECT_HANDLE_INFORMATION) NULL);

        if (NT_SUCCESS(ntStatus))     {

          pStartPhysAddress.QuadPart = (ULONGLONG)pPhysAddress;

          pEndPhysAddress = RtlLargeIntegerAdd (pStartPhysAddress,                                             RtlConvertUlongToLargeInteger(PhysMemSizeInBytes));

          IsIOSpace = 0;

          Result1 = HalTranslateBusAddress (1, 0, pStartPhysAddress, &IsIOSpace, &pStartPhysAddress);

          IsIOSpace = 0;

          Result2 = HalTranslateBusAddress (1, 0, pEndPhysAddress, &IsIOSpace, &pEndPhysAddress);

          if (Result1 && Result2)       {

            MappingLength = RtlLargeIntegerSubtract (pEndPhysAddress, pStartPhysAddress);

            if (MappingLength.LowPart)         {                   // Let ZwMapViewOfSection pick a linear address

              PhysMemSizeInBytes = MappingLength.LowPart;

              ViewBase = pStartPhysAddress;

              ntStatus = ZwMapViewOfSection (*pPhysicalMemoryHandle,                                          (HANDLE) -1,                                          &pbPhysMemLin,                                          0L,                                          PhysMemSizeInBytes,                                          &ViewBase,                                          (PSIZE_T)&PhysMemSizeInBytes,                                          ViewShare,                                          0,                                          PAGE_READWRITE | PAGE_NOCACHE);

              if (!NT_SUCCESS(ntStatus))             OutputDebugString ("ERROR: ZwMapViewOfSection failed");           else           {             pbPhysMemLin += (ULONG)pStartPhysAddress.LowPart - (ULONG)ViewBase.LowPart;             *ppPhysMemLin = pbPhysMemLin;           }          }         else           OutputDebugString ("ERROR: RtlLargeIntegerSubtract failed");       }       else         OutputDebugString ("ERROR: MappingLength = 0");     }     else       OutputDebugString ("ERROR: ObReferenceObjectByHandle failed");   }   else     OutputDebugString ("ERROR: ZwOpenSection failed");       if (!NT_SUCCESS(ntStatus))     ZwClose(*pPhysicalMemoryHandle);     OutputDebugString ("Leaving MapPhysicalMemoryToLinearSpace");

     

    return ntStatus; }


    最新回复(0)