Example #1
0
// Initializes GuardMon components
_Use_decl_annotations_ NTSTATUS GMonInitialization() {
  PAGED_CODE();

  GMonpDemoStl();

  g_gmonp_ExAcquireResourceSharedLite =
      UtilGetSystemProcAddress(L"ExAcquireResourceSharedLite");
  if (!g_gmonp_ExAcquireResourceSharedLite) {
    return STATUS_PROCEDURE_NOT_FOUND;
  }

  RTL_OSVERSIONINFOW os_version = {};
  auto status = RtlGetVersion(&os_version);
  if (!NT_SUCCESS(status)) {
    return status;
  }
  if (os_version.dwMajorVersion == 10 && os_version.dwMinorVersion == 0) {
    g_pgmon_IsWindows10 = true;
  }
  return STATUS_SUCCESS;
}
Example #2
0
// Locates RtlPcToFileHeader
_Use_decl_annotations_ static NTSTATUS
MmonpInitializeRtlPcToFileHeader(PDRIVER_OBJECT driver_object) {
  PAGED_CODE();

  if (kMmonpUseRtlPcToFileHeader) {
    const auto p_RtlPcToFileHeader =
        UtilGetSystemProcAddress(L"RtlPcToFileHeader");
    if (p_RtlPcToFileHeader) {
      g_mmonp_RtlPcToFileHeader =
          reinterpret_cast<RtlPcToFileHeaderType *>(p_RtlPcToFileHeader);
      return STATUS_SUCCESS;
    }
  }

#pragma warning(push)
#pragma warning(disable : 28175)
  auto module =
      reinterpret_cast<LdrDataTableEntry *>(driver_object->DriverSection);
#pragma warning(pop)

  g_mmonp_PsLoadedModuleList = module->in_load_order_links.Flink;
  g_mmonp_RtlPcToFileHeader = MmonpUnsafePcToFileHeader;
  return STATUS_SUCCESS;
}
Example #3
0
// Locate MmPfnDatabase
_Use_decl_annotations_ static NTSTATUS MmonpInitializeMmPfnDatabase() {
  PAGED_CODE();

  RTL_OSVERSIONINFOW os_version = {};
  auto status = RtlGetVersion(&os_version);
  if (!NT_SUCCESS(status)) {
    return status;
  }

  // Set appropriate patterns and based on an OS version
  struct MmPfnDatabaseSearchPattern {
    const UCHAR *bytes;
    SIZE_T bytes_size;
    bool hard_coded;
  };
  MmPfnDatabaseSearchPattern patterns[2] = {};

  if (IsX64()) {
    // Win 10 build 14316 is the first version implements randomized page tables
    if (os_version.dwMajorVersion < 10 || os_version.dwBuildNumber < 14316) {
      // PFN database is at the constant location on older x64 Windows
      g_mmonp_MmPfnDatabase = reinterpret_cast<void *>(0xfffffa8000000000);
      return STATUS_SUCCESS;
    }

    // Windows 10 x64 Build 14332+
    static const UCHAR kPatternWin10x64[] = {
        0x48, 0x8B, 0xC1,        // mov     rax, rcx
        0x48, 0xC1, 0xE8, 0x0C,  // shr     rax, 0Ch
        0x48, 0x8D, 0x14, 0x40,  // lea     rdx, [rax + rax * 2]
        0x48, 0x03, 0xD2,        // add     rdx, rdx
        0x48, 0xB8,              // mov     rax, 0FFFFFA8000000008h
    };
    patterns[0].bytes = kPatternWin10x64;
    patterns[0].bytes_size = sizeof(kPatternWin10x64);
    patterns[0].hard_coded = true;

  } else {
    // x86
    if (os_version.dwMajorVersion == 6 && os_version.dwMinorVersion == 1) {
      // Windows 7 (No PAE)
      static const UCHAR kPatternWin7[] = {
          0x6B, 0xC0, 0x18,  // imul    eax, 18h
          0x8B, 0x0D,        // mov     ecx, ds:_MmPfnDatabase
      };
      // Windows 7 (PAE)
      static const UCHAR kPatternWin7Pae[] = {
          0x6B, 0xC0, 0x1C,  // imul    eax, 1Ch
          0x8B, 0x0D,        // mov     ecx, ds:_MmPfnDatabase
      };

      if (UtilIsX86Pae()) {
        patterns[0].bytes = kPatternWin7Pae;
        patterns[0].bytes_size = sizeof(kPatternWin7Pae);
        patterns[0].hard_coded = false;
      } else {
        patterns[0].bytes = kPatternWin7;
        patterns[0].bytes_size = sizeof(kPatternWin7);
        patterns[0].hard_coded = false;
      }

    } else if ((os_version.dwMajorVersion == 6 &&
                os_version.dwMinorVersion == 3) ||
               (os_version.dwMajorVersion == 10 &&
                os_version.dwMinorVersion == 0)) {
      // Windows 8.1 and 10
      static const UCHAR kPatternWin81And10_0[] = {
          0xC1, 0xF8, 0x0C,  // sar     eax, 0Ch
          0xA1,              // mov     eax, ds:_MmPfnDatabase
      };
      static const UCHAR kPatternWin81And10_1[] = {
          0xC1, 0xE8, 0x0C,  // shr     eax, 0Ch
          0xA1,              // mov     eax, ds:_MmPfnDatabase
      };
      patterns[0].bytes = kPatternWin81And10_0;
      patterns[0].bytes_size = sizeof(kPatternWin81And10_0);
      patterns[0].hard_coded = false;
      patterns[1].bytes = kPatternWin81And10_1;
      patterns[1].bytes_size = sizeof(kPatternWin81And10_1);
      patterns[1].hard_coded = false;

    } else {
      // Unknown x86 OS version
      return STATUS_UNSUCCESSFUL;
    }
  }

  // Search the patterns from MmGetVirtualForPhysical
  const auto p_MmGetVirtualForPhysical = reinterpret_cast<UCHAR *>(
      UtilGetSystemProcAddress(L"MmGetVirtualForPhysical"));
  if (!p_MmGetVirtualForPhysical) {
    return STATUS_PROCEDURE_NOT_FOUND;
  }

  for (const auto &pattern : patterns) {
    if (!pattern.bytes) {
      break;  // no more patterns
    }

    auto found = reinterpret_cast<UCHAR *>(UtilMemMem(
        p_MmGetVirtualForPhysical, 0x20, pattern.bytes, pattern.bytes_size));
    if (!found) {
      continue;
    }

    // Get an address of PFN database
    found += pattern.bytes_size;
    if (pattern.hard_coded) {
      HYPERPLATFORM_LOG_DEBUG("Found a hard coded PFN database address at %p",
                              found);
      g_mmonp_MmPfnDatabase = *reinterpret_cast<void **>(found);
    } else {
      HYPERPLATFORM_LOG_DEBUG("Found a reference to MmPfnDatabase at %p",
                              found);
      const auto mmpfn_address = *reinterpret_cast<ULONG_PTR *>(found);
      g_mmonp_MmPfnDatabase = *reinterpret_cast<void **>(mmpfn_address);
    }

    // On Windows 10 RS, a value has 0x8. Delete it.
    g_mmonp_MmPfnDatabase = PAGE_ALIGN(g_mmonp_MmPfnDatabase);
    break;
  }

  HYPERPLATFORM_LOG_DEBUG("MmPfnDatabase = %p", g_mmonp_MmPfnDatabase);
  if (!g_mmonp_MmPfnDatabase) {
    return STATUS_UNSUCCESSFUL;
  }

  return STATUS_SUCCESS;
}
Example #4
0
// Locate MmPfnDatabase
_Use_decl_annotations_ static NTSTATUS MmonpInitializeMmPfnDatabase() {
  PAGED_CODE();

  if (IsX64()) {
    g_mmonp_MmPfnDatabase = reinterpret_cast<void *>(0xfffffa8000000000);
  } else {
    const auto p_MmGetVirtualForPhysical = reinterpret_cast<UCHAR *>(
        UtilGetSystemProcAddress(L"MmGetVirtualForPhysical"));
    if (!p_MmGetVirtualForPhysical) {
      return STATUS_PROCEDURE_NOT_FOUND;
    }

    RTL_OSVERSIONINFOW os_version = {};
    auto status = RtlGetVersion(&os_version);
    if (!NT_SUCCESS(status)) {
      return status;
    }
    if (os_version.dwMajorVersion == 6 && os_version.dwMinorVersion == 1) {
      // Windows 7 (No PAE)
      // 6B C0 18                          imul    eax, 18h
      // 8B 0D 14 28 56 00                 mov     ecx, ds:_MmPfnDatabase
      static const UCHAR kPatternWin7[] = {
          0x6B, 0xC0, 0x18, 0x8B, 0x0D,
      };
      // Windows 7 (PAE)
      // 6B C0 1C                          imul    eax, 1Ch
      // 8B 0D 14 28 56 00                 mov     ecx, ds:_MmPfnDatabase
      static const UCHAR kPatternWin7Pae[] = {
          0x6B, 0xC0, 0x1C, 0x8B, 0x0D,
      };
      const auto is_pae_enabled = Cr4{__readcr4()}.fields.pae;
      const auto pattern = (is_pae_enabled) ? kPatternWin7Pae : kPatternWin7;
      const auto size =
          (is_pae_enabled) ? sizeof(kPatternWin7Pae) : sizeof(kPatternWin7);
      auto found = reinterpret_cast<UCHAR *>(
          UtilMemMem(p_MmGetVirtualForPhysical, 0x20, pattern, size));
      if (found) {
        found += size;
        const auto address = *reinterpret_cast<ULONG_PTR *>(found);
        g_mmonp_MmPfnDatabase = *reinterpret_cast<void **>(address);
      }
    } else if ((os_version.dwMajorVersion == 6 &&
                os_version.dwMinorVersion == 3) ||
               (os_version.dwMajorVersion == 10 &&
                os_version.dwMinorVersion == 0)) {
      // Windows 8.1 and 10
      // C1 F8 0C                          sar     eax, 0Ch
      // A1 08 B7 62 00                    mov     eax, ds:_MmPfnDatabase
      static const UCHAR kPatternWin81And10[] = {
          0xC1, 0xF8, 0x0C, 0xA1,
      };
      auto found = reinterpret_cast<UCHAR *>(
          UtilMemMem(p_MmGetVirtualForPhysical, 0x20, kPatternWin81And10,
                     sizeof(kPatternWin81And10)));
      if (found) {
        found += sizeof(kPatternWin81And10);
        const auto address = *reinterpret_cast<ULONG_PTR *>(found);
        g_mmonp_MmPfnDatabase = *reinterpret_cast<void **>(address);
      }
    }
  }
  return (g_mmonp_MmPfnDatabase) ? STATUS_SUCCESS : STATUS_PROCEDURE_NOT_FOUND;
}