PreviousMode

Ketika aplikasi mode pengguna memanggil versi Nt atau Zw dari rutinitas layanan sistem asli, mekanisme panggilan sistem menjebak utas panggilan ke mode kernel. Untuk menunjukkan bahwa nilai parameter berasal dari mode pengguna, penangan trap untuk panggilan sistem mengatur bidang PreviousMode di objek utas pemanggil ke UserMode. Layanan sistem asli rutin memeriksa bidang PreviousMode dari utas panggilan untuk menentukan apakah parameter berasal dari sumber mode pengguna.

Jika driver mode kernel memanggil rutinitas layanan sistem asli dan meneruskan nilai parameter ke rutinitas yang berasal dari sumber mode kernel, driver harus memastikan bahwa bidang PreviousMode di objek utas saat ini diatur ke KernelMode.

Driver mode kernel dapat berjalan dalam konteks utas arbitrer, dan bidang PreviousMode dari utas ini mungkin diatur ke UserMode. Dalam situasi ini, driver mode kernel dapat memanggil versi Zw dari rutinitas layanan sistem asli untuk menginformasikan rutinitas bahwa nilai parameter berasal dari sumber mode kernel tepercaya. Panggilan Zw masuk ke fungsi pembungkus tipis yang mengambil alih nilai PreviousMode di objek utas saat ini. Fungsi pembungkus mengatur PreviousMode ke KernelMode dan memanggil versi Nt dari rutinitas. Saat dikembalikan dari versi Nt dari rutinitas, fungsi pembungkus memulihkan nilai PreviousMode asli dari objek utas dan mengembalikan.

Driver mode kernel dapat langsung memanggil versi Nt dari rutinitas layanan sistem asli. Ketika driver mode kernel memproses permintaan I/O yang dapat berasal baik dalam mode pengguna atau dalam mode kernel, driver dapat memanggil versi Nt dari rutinitas sehingga nilai PreviousMode dari utas saat ini tetap tidak berubah selama panggilan. Rutinitas NtXxx memeriksa nilai PreviousMode utas panggilan untuk menentukan apakah nilai parameter berasal dari aplikasi mode pengguna atau komponen mode kernel, dan memperlakukannya dengan sesuai.

Kesalahan dapat terjadi jika driver mode kernel memanggil rutinitas NtXxx dan nilai PreviousMode di objek utas saat ini tidak secara akurat menunjukkan apakah nilai parameter berasal dari mode pengguna atau sumber mode kernel.

Misalnya, asumsikan bahwa driver mode kernel berjalan dalam konteks utas arbitrer, dan bahwa nilai PreviousMode untuk utas ini diatur ke UserMode. Jika driver melewati handel file mode kernel ke rutinitas NtClose , rutinitas ini memeriksa nilai PreviousMode dan memutuskan bahwa handel harus handel mode pengguna. Ketika NtClose tidak menemukan handel dalam tabel handel mode pengguna, NtClose mengembalikan kode kesalahan STATUS_INVALID_HANDLE. Sementara itu, driver membocorkan handel mode kernel, yang tidak pernah ditutup.

Misalnya, jika parameter untuk rutinitas NtXxx menyertakan buffer input atau output, dan jika PreviousMode = UserMode, rutin memanggil rutinitas ProbeForRead atau ProbeForWrite untuk memvalidasi buffer. Jika buffer dialokasikan dalam memori sistem alih-alih dalam memori mode pengguna, rutinitas ProbeForXxx menimbulkan pengecualian, dan rutinitas NtXxx mengembalikan kode kesalahan STATUS_ACCESS_VIOLATION.

Jika perlu, driver dapat memanggil rutinitas ExGetPreviousMode untuk mendapatkan nilai PreviousMode dari objek utas saat ini. Atau, driver dapat membaca bidang RequestorMode dari struktur IRP yang menjelaskan operasi I/O yang diminta. Bidang RequestorMode berisi salinan nilai PreviousMode dari utas yang meminta operasi.