Kompatibilitas driver dengan integritas memori dan VBS

Integritas memori adalah fitur keamanan berbasis virtualisasi (VBS) yang tersedia di Windows 10, Windows 11, dan Windows Server 2016 dan yang lebih baru. Integritas memori dan VBS meningkatkan model ancaman Windows dan memberikan perlindungan yang lebih kuat terhadap malware yang mencoba mengeksploitasi kernel Windows. VBS menggunakan hypervisor Windows untuk membuat lingkungan virtual terisolasi yang menjadi akar kepercayaan OS yang mengasumsikan kernel dapat disusupi. Integritas memori adalah komponen penting yang melindungi dan mengeraskan Windows dengan menjalankan integritas kode mode kernel dalam lingkungan virtual VBS yang terisolasi. Integritas memori juga membatasi alokasi memori kernel yang dapat digunakan untuk membahayakan sistem, memastikan bahwa halaman memori kernel hanya dibuat dapat dieksekusi setelah melewati pemeriksaan integritas kode di dalam lingkungan runtime aman, dan halaman yang dapat dieksekusi sendiri tidak pernah dapat ditulis.

Catatan

Integritas memori terkadang disebut sebagai integritas kode yang dilindungi hypervisor (HVCI) atau integritas kode yang diberlakukan hypervisor, dan awalnya dirilis sebagai bagian dari Device Guard. Device Guard tidak lagi digunakan kecuali untuk menemukan integritas memori dan pengaturan VBS dalam Kebijakan Grup atau registri Windows.

Integritas memori diaktifkan secara default pada penginstalan bersih Windows 10 dalam mode S dan Windows 11 pada perangkat keras yang kompatibel seperti yang dijelaskan dalam pengaktifan integritas memori. Pada sistem lain yang tidak memenuhi persyaratan pengaktifan otomatis integritas memori, pelanggan dapat memilih menggunakan salah satu metode yang dijelaskan dalam cara mengaktifkan integritas memori.

Kompatibilitas aplikasi

Meskipun kompatibilitas dengan integritas memori telah menjadi persyaratan untuk semua driver sejak Windows 10 Anniversary Update (1607), beberapa aplikasi dan driver perangkat keras mungkin masih tidak kompatibel. Ketidaksesuaian ini dapat menyebabkan perangkat atau perangkat lunak tidak berfungsi dan dalam kasus yang jarang terjadi dapat mengakibatkan kegagalan boot (layar biru). Masalah tersebut dapat terjadi setelah perlindungan integritas memori diaktifkan atau selama proses pengaktifan itu sendiri. Jika Anda adalah pengembang aplikasi dan ingin memvalidasi bahwa driver dan paket perangkat lunak Anda kompatibel dengan integritas memori, ikuti langkah-langkah ini.

Beberapa contoh di mana kita telah mengamati ketidaksesuaian dengan integritas memori meliputi:

  • Solusi anti-cheat dengan game
  • Metode input pihak ke-3
  • Perlindungan kata sandi perbankan pihak ke-3

Kami bekerja keras untuk mengurangi pengalaman yang terkena dampak, jadi jika ada ketidaksesuaian untuk driver boot-critical, perlindungan integritas memori akan dimatikan secara diam-diam jika telah diaktifkan secara otomatis. Jika Anda mengalami ketidaksesuaian dengan aplikasi lain, kami menyarankan agar Anda memeriksa pembaruan untuk aplikasi dan versi tertentu yang mengalami masalah sebelum menonaktifkan perlindungan integritas memori.

Cara membangun driver yang kompatibel

Karena halaman dan bagian memori tidak pernah dapat ditulis dan dapat dieksekusi, langkah pertama adalah memastikan pemisahan data dan kode yang jelas dan tidak mencoba memodifikasi halaman kode secara langsung.

  • Ikut serta ke NX secara default
  • Menggunakan API/bendera NX untuk alokasi memori - NonPagedPoolNx
  • Jangan gunakan bagian yang dapat ditulis dan dapat dieksekusi
  • Jangan mencoba memodifikasi memori sistem yang dapat dieksekusi secara langsung
  • Jangan gunakan kode dinamis dalam kernel
  • Jangan muat file data sebagai dapat dieksekusi
  • Perataan Bagian harus kelipatan 0x1000 (PAGE_SIZE). Misalnya DRIVER_ALIGNMENT=0x1000

Gunakan versi terbaru WDK dan Visual Studio untuk menghasilkan driver yang kompatibel saat menggunakan pengaturan default.

Cara memverifikasi kompatibilitas driver dengan integritas memori

Ada tiga langkah untuk memverifikasi kompatibilitas driver:

  1. Gunakan Pemverifikasi Driver (lihat bagian di bawah) dengan pemeriksaan kompatibilitas Integritas Kode diaktifkan.
  2. Uji driver pada sistem dengan integritas memori diaktifkan.
  3. Jalankan Uji Kesiapan Integritas Kode HyperVisor di Windows HLK.

Pemeriksaan kompatibilitas Pemverifikasi Driver

Driver Verifier memiliki bendera opsi Integritas Kode (0x02000000) untuk mengaktifkan pemeriksaan tambahan yang memvalidasi kepatuhan dengan integritas memori. Untuk mengaktifkan ini dari baris perintah, gunakan perintah berikut:

verifier.exe /flags 0x02000000 /driver <driver.sys>

Untuk memilih opsi ini jika menggunakan GUI pemverifikasi, pilih Buat pengaturan kustom (untuk pengembang kode), pilih Berikutnya , lalu pilih Pemeriksaan integritas kode.

Untuk keberhasilan, tidak ada output. Di bawah ini adalah contoh untuk output kegagalan.

Driver Verifier: Enabled for DvCi.sys, flags 0x2000000, build 16299, key o4Dbg8OVJqaBYlqWQ2QvRH

\*\*\*\*\*\*\*\*\*\*\* Verifier Detected a Code Integrity Issue \*\*\*\*\*\*\*\*\*\*\*\*

\*\* The caller 0xFFFFF8094B9852F0 specified an executable page protection 0x40.

\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*

\*\*\* Verifier assertion failed \*\*\*

(B)reak, (I)gnore, (W)arn only, (R)emove assert? B

Uji driver dengan integritas memori diaktifkan

Meskipun Windows akan mengaktifkan integritas memori secara default untuk sebagian besar sistem, ada beberapa alasan yang dapat mencegah hal itu terjadi. Untuk mengaktifkan integritas memori, lihat Cara mengaktifkan integritas memori. Kemudian, uji fungsionalitas driver Anda. Pastikan untuk menjalankan semua jalur kode di driver Anda untuk memastikan driver Anda tidak melakukan operasi pada runtime yang tidak kompatibel dengan integritas memori.

Pengujian HLK (Desktop dan Server)

Uji HLK Uji Kesiapan Integritas Kode HyperVisor harus lulus agar driver disetujui untuk penandatanganan Microsoft. Driver yang kompatibel dengan integritas memori diperlukan untuk Edisi Desktop dan Server. Pengujian HLK adalah pengujian dasar yang ditulis untuk memastikan bahwa driver yang kompatibel dengan integritas memori dimuat dan dijalankan dengan benar oleh OS.

Meskipun hanya lulus tes HLK cukup untuk tanda tangan Microsoft untuk driver, kami sangat menyarankan pengujian fungsional menyeluruh dengan integritas memori diaktifkan. Misalnya, mungkin ada alokasi memori yang salah dikodekan yang melanggar perlindungan NX yang menyebabkan kegagalan yang tidak akan tertangkap oleh pengujian. Penulis driver harus menguji driver secara menyeluruh sambil menjaga integritas memori tetap diaktifkan.

Selama pengembangan driver dan selama pengujian HLK, integritas memori mungkin perlu dinonaktifkan, karena dapat mencegah driver memuat.

Uji Kesiapan Integritas Kode Hypervisor HLK diperlukan sebagai bagian dari Windows Server Assurance AQ dan bendera untuk mengaktifkan pemeriksaan Integritas Kode juga diatur saat mengaktifkan pemverifikasi driver selama pengujian HLK lainnya.

Tanya Jawab Umum

Bagaimana dengan driver yang ada? Apakah saya perlu membuat ulang driver ini untuk membuatnya berfungsi dengan Windows 10?

Tergantung. Banyak driver yang sudah kompatibel. Jika menggunakan pengaturan standar dengan versi lama WDK dan Visual Studio, masalah yang diketahui adalah bahwa bagian INIT ditandai sebagai RWX. Namun, di Windows 10, W akan secara otomatis dilucuti, jadi jika ini adalah satu-satunya masalah maka driver akan kompatibel.

Bagaimana cara memverifikasi bahwa integritas memori diaktifkan?

Metode paling sederhana adalah menjalankan aplikasi Informasi Sistem (msinfo32). Cari baris berikut: "Layanan keamanan berbasis virtualisasi Berjalan". Ini harus melaporkan: "Hypervisor memberlakukan Integritas Kode". Ada juga antarmuka WMI untuk memeriksa menggunakan alat manajemen, lihat Memvalidasi fitur integritas VBS dan memori yang diaktifkan.

Integritas memori juga dapat diperiksa di aplikasi Keamanan Windows di Pengaturan> Update & Security> Keamanan Windows> Device security>Inti integritas> memori. Untuk informasi selengkapnya, lihat KB4096339.

Dapatkah saya memverifikasi bahwa integritas memori diaktifkan secara terprogram dari kernel untuk mengubah perilaku driver?

Ya, Anda dapat menggunakan NtQuerySystemInformation: https://msdn.microsoft.com/library/windows/desktop/ms724509(v=vs.85).aspx

Struktur SYSTEM_CODEINTEGRITY_INFORMATION memiliki nilai 0x400 terekspos, menunjukkan bahwa integritas memori aktif.

Bagaimana cara memperbaiki masalah kompatibilitas?

Selain pemeriksaan ganda bahwa tidak ada halaman W+X dan bagian driver selaras dengan benar seperti yang disebutkan di atas, masalah yang paling mungkin adalah alokasi memori yang tidak tepat. Informasi tentang peringatan Analisis Kode yang terkait dengan alokasi memori yang dikeluarkan tersedia di MSDN di halaman berikut:

Analisis Kode untuk Peringatan Driver

Tautan MSDN berikut menunjukkan beberapa contoh API yang umum digunakan yang menyebabkan memori yang dapat dieksekusi dialokasikan, bersama dengan beberapa contoh perbaikan:

Gunakan tabel berikut untuk menginterpretasikan output untuk menentukan perubahan kode driver apa yang diperlukan untuk menyelesaikan berbagai jenis ketidaksesuaian HVCI.

Peringatan Resolusi
Tipe Kumpulan Eksekusi Pemanggil menentukan jenis kumpulan yang dapat dieksekusi. Memanggil fungsi alokasi memori yang meminta memori yang dapat dieksekusi. Pastikan bahwa semua jenis kumpulan berisi bendera NX yang tidak dapat dieksekusi.
Eksekusi Perlindungan Halaman Pemanggil menentukan perlindungan halaman yang dapat dieksekusi. Tentukan masker perlindungan halaman "tanpa eksekusi".
Jalankan Pemetaan Halaman Pemanggil menentukan pemetaan daftar deskriptor memori (MDL) yang dapat dieksekusi. Pastikan bahwa masker yang digunakan berisi MdlMappingNoExecute. Untuk informasi selengkapnya, lihat MmGetSystemAddressForMdl Brankas
Bagian Jalankan-Tulis Gambar berisi bagian yang dapat dieksekusi dan dapat ditulis.
Kegagalan Perataan Bagian Gambar berisi bagian yang tidak sejajar dengan halaman. Perataan Bagian harus kelipatan 0x1000 (PAGE_SIZE). Misalnya DRIVER_ALIGNMENT=0x1000
Relokasi yang Tidak Didukung Di Windows 10 versi 1507 hingga versi 1607, karena penggunaan Address Space Layout Randomization (ASLR) masalah dapat muncul dengan penyelarasan alamat dan relokasi memori. Sistem operasi perlu merelokasi alamat dari tempat linker mengatur alamat dasar defaultnya ke lokasi aktual yang ditetapkan ASLR. Relokasi ini tidak dapat mengalihkan batas halaman. Misalnya, pertimbangkan nilai alamat 64-bit yang dimulai pada 0x3FFC offset di halaman. Nilai alamat tumpang tindih ke halaman berikutnya pada 0x0003 offset. Jenis relokasi yang tumpang tindih ini tidak didukung sebelum Windows 10 versi 1703.

Situasi ini dapat terjadi ketika penginisialisasi variabel jenis struct global memiliki penunjuk yang tidak selaras ke global lain, yang ditata sedih sehingga linker tidak dapat memindahkan variabel untuk menghindari relokasi straddling. Linker akan mencoba memindahkan variabel, tetapi ada situasi di mana mungkin tidak dapat melakukannya, misalnya dengan struct besar yang tidak sejajar atau array besar dari struct yang tidak sejajar. Jika sesuai, modul harus dirakit menggunakan opsi /Gy (COMDAT) untuk memungkinkan linker menyelaraskan kode modul sebanyak mungkin.

#include <pshpack1.h>

typedef struct _BAD_STRUCT {
      USHORT Value;
      CONST CHAR *String;
} BAD_STRUCT, * PBAD_STRUCT;

#include <poppack.h>

#define BAD_INITIALIZER0 { 0, "BAD_STRING" },
#define BAD_INITIALIZER1 \
      BAD_INITIALIZER0      \
      BAD_INITIALIZER0      \
      BAD_INITIALIZER0      \
      BAD_INITIALIZER0      \
      BAD_INITIALIZER0      \
      BAD_INITIALIZER0      \
      BAD_INITIALIZER0      \
      BAD_INITIALIZER0

#define BAD_INITIALIZER2 \
      BAD_INITIALIZER1      \
      BAD_INITIALIZER1      \
      BAD_INITIALIZER1      \
      BAD_INITIALIZER1      \
      BAD_INITIALIZER1      \
      BAD_INITIALIZER1      \
      BAD_INITIALIZER1      \
      BAD_INITIALIZER1

#define BAD_INITIALIZER3 \
      BAD_INITIALIZER2      \
      BAD_INITIALIZER2      \
      BAD_INITIALIZER2      \
      BAD_INITIALIZER2      \
      BAD_INITIALIZER2      \
      BAD_INITIALIZER2      \
      BAD_INITIALIZER2      \
      BAD_INITIALIZER2

#define BAD_INITIALIZER4 \
      BAD_INITIALIZER3      \
      BAD_INITIALIZER3      \
      BAD_INITIALIZER3      \
      BAD_INITIALIZER3      \
      BAD_INITIALIZER3      \
      BAD_INITIALIZER3      \
      BAD_INITIALIZER3      \
      BAD_INITIALIZER3

BAD_STRUCT MayHaveStraddleRelocations[4096] = { // as a global variable
      BAD_INITIALIZER4
};

Ada situasi lain yang melibatkan penggunaan kode perakitan, di mana masalah ini juga dapat terjadi.

IAT di Bagian yang Dapat Dieksekusi Tabel alamat impor (IAT), seharusnya bukan bagian memori yang dapat dieksekusi.

Masalah ini terjadi ketika IAT, terletak di bagian memori baca dan jalankan (RX) saja. Ini berarti bahwa OS tidak akan dapat menulis ke IAT untuk mengatur alamat yang benar tempat DLL yang direferensikan.

Salah satu cara yang dapat terjadi adalah ketika menggunakan opsi /MERGE (Gabungkan Bagian) dalam penautan kode. Misalnya jika .rdata (Data inisialisasi baca-saja) digabungkan dengan data .text (Kode yang dapat dieksekusi), ada kemungkinan bahwa IAT mungkin berakhir di bagian memori yang dapat dieksekusi.

API mana yang berpotensi terpengaruh?

Daftar API berikut yang tidak dicadangkan untuk penggunaan sistem dapat terpengaruh:

   
Nama API Deskripsi
ExAllocatePool https://msdn.microsoft.com/library/windows/hardware/ff544501(v=vs.85).aspx
ExAllocatePoolWithQuota https://msdn.microsoft.com/library/windows/hardware/ff544506(v=vs.85).aspx
ExAllocatePoolWithQuotaTag https://msdn.microsoft.com/library/windows/hardware/ff544513(v=vs.85).aspx
ExAllocatePoolWithTag https://msdn.microsoft.com/library/windows/hardware/ff544520(v=vs.85).aspx
ExAllocatePoolWithTagPriority https://msdn.microsoft.com/library/windows/hardware/ff544523(v=vs.85).aspx
ExInitializeNPagedLookasideList https://msdn.microsoft.com/library/windows/hardware/ff545301(v=vs.85).aspx
ExInitializeLookasideListEx https://msdn.microsoft.com/library/windows/hardware/ff545298(v=vs.85).aspx
MmAllocateContiguousMemory https://msdn.microsoft.com/library/windows/hardware/ff554460(v=vs.85).aspx
MmAllocateContiguousMemorySpecifyCache https://msdn.microsoft.com/library/windows/hardware/ff554464(v=vs.85).aspx
MmAllocateContiguousMemorySpecifyCacheNode https://msdn.microsoft.com/library/windows/hardware/ff554464(v=vs.85).aspx
MmAllocateContiguousNodeMemory https://msdn.microsoft.com/library/windows/hardware/jj602795(v=vs.85).aspx
MmCopyMemory https://msdn.microsoft.com/library/windows/hardware/dn342884(v=vs.85).aspx
MmMapIoSpace https://msdn.microsoft.com/library/windows/hardware/ff554618(v=vs.85).aspx
MmMapLockedPages https://msdn.microsoft.com/library/windows/hardware/ff554622(v=vs.85).aspx
MmMapLockedPagesSpecifyCache https://msdn.microsoft.com/library/windows/hardware/ff554629(v=vs.85).aspx
MmProtectMdlSystemAddress https://msdn.microsoft.com/library/windows/hardware/ff554670(v=vs.85).aspx
ZwAllocateVirtualMemory https://msdn.microsoft.com/library/windows/hardware/ff566416(v=vs.85).aspx
ZwCreateSection https://msdn.microsoft.com/library/windows/hardware/ff566428(v=vs.85).aspx
ZwMapViewOfSection https://msdn.microsoft.com/library/windows/hardware/ff566481(v=vs.85).aspx
NtCreateSection https://msdn.microsoft.com/library/windows/hardware/ff556473(v=vs.85).aspx
NtMapViewOfSection https://msdn.microsoft.com/library/windows/hardware/ff556551(v=vs.85).aspx
StorPortGetDataInBufferSystemAddress https://msdn.microsoft.com/library/windows/hardware/jj553720(v=vs.85).aspx
StorPortGetSystemAddress https://msdn.microsoft.com/library/windows/hardware/ff567100(v=vs.85).aspx
DxgkCbMapMemory https://msdn.microsoft.com/library/windows/hardware/ff559533(v=vs.85).aspx
IMiniportDMus::NewStream https://msdn.microsoft.com/library/windows/hardware/ff536701(v=vs.85).aspx
FltAllocatePoolAlignedWithTag https://msdn.microsoft.com/library/windows/hardware/ff541762(v=vs.85).aspx
FltAllocateContext https://msdn.microsoft.com/library/windows/hardware/ff541710(v=vs.85).aspx
ChangerClassAllocatePool https://msdn.microsoft.com/library/windows/hardware/ff551402(v=vs.85).aspx
IMiniportMidi::NewStream https://msdn.microsoft.com/library/windows/hardware/ff536710(v=vs.85).aspx
IMiniportWaveCyclic::NewStream https://msdn.microsoft.com/library/windows/hardware/ff536723(v=vs.85).aspx
IPortWavepci::NewMasterDmaChannel https://msdn.microsoft.com/library/windows/hardware/ff536916(v=vs.85).aspx
IMiniportWavePci::NewStream https://msdn.microsoft.com/library/windows/hardware/ff536735(v=vs.85).aspx
PcNewDmaChannel https://msdn.microsoft.com/library/windows/hardware/ff537712(v=vs.85).aspx
PcNewResourceList https://msdn.microsoft.com/library/windows/hardware/ff537717(v=vs.85).aspx
PcNewResourceSublist https://msdn.microsoft.com/library/windows/hardware/ff537718(v=vs.85).aspx
VideoPortAllocatePool https://msdn.microsoft.com/library/windows/hardware/ff570180(v=vs.85).aspx
ClfsCreateMarshallingArea https://msdn.microsoft.com/library/windows/hardware/ff541520(v=vs.85).aspx
WdfLookasideListBuat https://msdn.microsoft.com/library/windows/hardware/ff548694(v=vs.85).aspx
WdfMemoryBuat https://msdn.microsoft.com/library/windows/hardware/ff548706(v=vs.85).aspx
WdfDeviceAllocAndQueryProperty https://msdn.microsoft.com/library/windows/hardware/ff545882(v=vs.85).aspx
WdfDeviceAllocAndQueryPropertyEx https://msdn.microsoft.com/library/windows/hardware/dn265599(v=vs.85).aspx
WdfFdoInitAllocAndQueryProperty https://msdn.microsoft.com/library/windows/hardware/ff547239(v=vs.85).aspx
WdfFdoInitAllocAndQueryPropertyEx https://msdn.microsoft.com/library/windows/hardware/dn265612(v=vs.85).aspx
WdfIoTargetAllocAndQueryTargetProperty https://msdn.microsoft.com/library/windows/hardware/ff548585(v=vs.85).aspx
WdfRegistryQueryMemory https://msdn.microsoft.com/library/windows/hardware/ff549920(v=vs.85).aspx
NdisAllocateMemory https://msdn.microsoft.com/library/windows/hardware/ff550762(v=vs.85).aspx