Sterowniki jądra to rozszerzenia jądra, które mogą pomóc systemowi w interakcji z wcześniej nieznanymi urządzeniami lub systemami plików, zapewnić interfejs do introspekcji jądra do trybu użytkownika i zmodyfikować sposób działania jądra. To ostatnie jest mocno zniechęcane przez Microsoft, tak bardzo, że firma wprowadziła Kernel Patch Protection (znany również jako PatchGuard), aby uniemożliwić programistom ingerencję w podstawowe procedury systemowe i struktury danych. Sterowniki jądra znane jako sterowniki rozruchowe są ładowane podczas rozruchu przez program ładujący. Inne sterowniki są ładowane przez menedżera usług po uruchomieniu systemu. Tylko administratorzy lub osoby z uprawnieniami SeLoadDriverPrivilege mogą ładować sterowniki w systemie Windows. Microsoft nie uważa granicy między administratorem systemu a jądrem za granicę bezpieczeństwa, ponieważ administratorzy mogą po prostu ładować (prawie) dowolne sterowniki. Jednak sterowniki muszą mieć akceptowalny podpis cyfrowy, aby mogły zostać załadowane, ponieważ podpisywanie kodu w trybie jądra (KMCS) jest wymuszane domyślnie na wszystkich maszynach 64-bitowych. Sterownik może udostępniać procedury wejścia/wyjścia (I/O) w formie głównych funkcji. Windows Driver Kit (WDK) definiuje 28 głównych funkcji, w tym tworzenie, zamykanie, zasilanie, sterowanie we/wy, odczyt, zapis, wyszukiwanie informacji, ustawianie informacji i wyłączanie. Obsługujące funkcje dla każdej głównej funkcji są ustawiane wewnątrz struktury _DRIVER_OBJECT sterownika, gdy sterownik jest inicjowany. Ta struktura zawiera różne informacje o sterowniku, takie jak nazwa sterownika, połączona lista urządzeń skojarzonych ze sterownikiem, opcjonalna procedura rozładowania, która jest wywoływana, gdy żądane jest rozładowanie sterownika, oraz ograniczenia pamięci sterownika (start i rozmiar). Sterownik może tworzyć powiązane struktury _DEVICE_OBJECT, które reprezentują urządzenie, za które odpowiada sterownik. Urządzenia mogą być lub nie być obsługiwane przez rzeczywisty sprzęt. Przykładem sterownika nieobsługiwanego sprzętowo jest sterownik, którego Sysinternal Process Explorer używa do uzyskania dodatkowych informacji o systemie. W przypadku Process Explorera sterownik podpisany przez Microsoft jest ładowany podczas uruchamiania narzędzia, a do komunikacji z nim używane są interfejsy API trybu użytkownika. Sterownik tworzy obiekt urządzenia dostępny w trybie użytkownika i obsługuje żądania z trybu użytkownika za pośrednictwem systemu I/O w jądrze. System I/O jądra wysyła żądania do głównej procedury obsługi funkcji zdefiniowanej w _DRIVER_OBJECT, do którego należy urządzenie. Główne kody funkcji to stałe wartości całkowite zdefiniowane w nagłówkach WDK. Wszystkie ich nazwy symboli zaczynają się od IRP_MJ_ i są indeksami w głównej tablicy funkcji _DRIVER_OBJECT, zaczynając od 0x70. Główne procedury obsługi funkcji są również nazywane procedurami obsługi sterowników i mają następujący prototyp:
Pakiet żądania wejścia/wyjścia (IRP) opisuje żądanie wejścia/wyjścia do urządzenia. Zawiera wiele pól, które staną się ważne, gdy będziesz pracować nad laboratorium w dalszej części rozdziału. Kilka godnych uwagi pól obejmuje pole AssociatedIrp.SystemBuffer, które często obejmuje bufor wejściowy i/lub wyjściowy dla żądania, oraz pole Tail.Overlay.CurrentStackLocation, które zawiera informacje o żądaniu odnoszące się do konkretnego wywoływanego urządzenia. Ważne informacje w CurrentStackLocation (_IO_STACK_LOCATION) obejmują pole MajorFunction, które jest bieżącą żądaną funkcją główną, oraz pole Parameters, które jest masywną unią zawierającą różne informacje w zależności od wywoływanej funkcji głównej. W przypadku sterowania wejściem/wyjściem urządzenia, pole MajorFunction będzie miało wartość IRP_MJ_DEVICE_CONTROL (14), a pole Parameters będzie opisywać wywoływany kod sterowania wejściem/wyjściem (IOCTL) oraz rozmiary buforów wejściowych i wyjściowych. W przypadku większości wywołań IOCTL bufor wejściowy i/lub wyjściowy będzie znajdował się w polu AssociatedIrp.SystemBuffer w _IRP. Aby uzyskać więcej informacji na temat kodów IOCTL, zapoznaj się z dokumentacją systemu Windows. W laboratoriach w tym rozdziale wykonasz inżynierię wsteczną i debuggowanie sterownika jądra, aby zlokalizować urządzenie, które tworzy, określisz główne programy obsługi funkcji, które są zarejestrowane, nauczysz się wywoływać główne programy obsługi funkcji z trybu ser i ostatecznie napiszesz exploit, aby wykonać lokalną eskalację uprawnień (LPE).