Windows Kernel Development
Most security software on Windows runs in kernel mode. This training provides students a jumpstart into the world of Windows kernel-mode software development through a practical hands-on approach using the latest version of Visual Studio, Windows Driver Kit, and WinDBG.
The topics covered in this course go much deeper than the information available in the WDK documentation or in public forums. Coverage includes use cases of various APIs, their applicability to security, behind-the-scenes working of functions, and common usage pitfalls. The discussions do not shy away from undocumented features and techniques that are essential when building kernel-mode software related to security functionality but considered out of scope by generic driver development training courses.
This training course focuses on security related topics and does NOT cover topics related to hardware drivers such as plug and play, power management, hardware busses (PCI, USB, Bluetooth) or the kernel mode driver framework (KMDF).
In the hands-on lab exercises, students develop drivers in C/C++, build them, deploy them, test them on the latest build of Windows 10 64-bit. Students also learn various techniques to debug these drivers using WinDBG.
Attendees must be proficient in C programming. Attendees must have a good working knowledge of the windows kernel. The CodeMachine Windows Kernel Internals course provides the prerequisite Windows kernel knowledge required to get the maximum value from this course.
Upon completion of this course attendees will be able to:
- Develop Windows kernel-mode software using tools such as Visual Studio and WDK or EWDK.
- Build, deploy, test and debug kernel-mode software.
- Select the appropriate debugger commands to perform specific live debugging tasks.
- Interpret the output of the debugger commands to identify problems in kernel-mode software.
- Diagnose failures in kernel mode software using tools such as Driver Verifier, GFlags, and others.
- Recognize the intricacies of kernel-mode software development.
- Determine the appropriate APIs to use to implement features in kernel-mode software.
- Design and implement reasonably complex security functionality in kernel mode.
- Apply best practices when developing kernel-mode software.
- Evaluate the source code of kernel-mode drivers to assess correctness and performance.
- Kernel Development Environment
- Kernel Development Basics
- Kernel Debugging
- Processes, Threads & Modules
- Memory Management
- I/O Processing
- Kernel Execution & Synchronization
- Common Programming Tasks
Kernel Development Environment
The objective of this section is to learn about the Windows driver development toolchain and how to use the tools effectively to code, build, sign, deploy, test, and debug kernel-mode software. It covers topics such as header files and libraries required to build drivers, various options supported by the build process, test-signing, cross-signing, and attestation-signing, service control manager and native APIs to load and unload drivers, source-level debugging and the associated kernel debugger commands, decorating source code with SAL for code analysis, and the pros and cons of using C vs. C++ in the kernel.
- Windows Driver Kit (WDK)
- Building with EWDK
- MSBuild options
- Customizing .VCXPROJ
- Driver signing
- Driver registration and loading
- Source Annotation Language (SAL)
- Symbols and source code
Kernel Development Basics
The objective of this section is to learn about the unique aspects of Windows kernel-mode software development. It covers topics such as various methods of determining kernel version, header file versioning, binding to kernel APIs statically and dynamically, handling kernel API failures, correctly formatting and displaying debug output, using C run time support functions in NTOSKRNL, pool allocation (including the new pool APIs in Windows 10 2004) and performing various operations on Unicode strings.
- Version APIs
- WDK headers
- NTSTATUS code
- Debug prints
- Driver entry points
- Kernel C run time (CRT) support
- Pool allocation
- Unicode string processing
The objective of this section is to learn about tools and techniques to perform live debugging of kernel-mode software. It covers topics such as optimizing the build-debug-deploy cycle, controlling system debug output, techniques for setting breakpoints that go beyond just WinDBG commands, using various tools to find subtle bugs in kernel drivers, performing fault isolation and root-cause analysis, configuring the system to collect instrumentation data, and programming techniques to capture run-time execution information.
- Driver replacement maps
- Live debugging techniques
- Common debugging tasks
- Driver verifier
- Special pool and pool tracking
- Stack tracing
- Bug-check analysis
- Instrumentation techniques
Processes, Threads, and Modules
The objective of this section is to learn about various APIs related to retrieving run-time information from processes, threads, and kernel modules. It covers topics such as different methods of enumerating processes, threads, and modules, querying various properties of processes and threads, suspending and resuming processes, restricting thread migration across CPUs, parsing PE headers of kernel modules, mapping functions to modules, and identifying functions extents in memory.
- Enumerating processes
- Enumerating threads
- Process and thread access
- Thread affinity control
- Process command line
- Enumerating modules
- PE header parsing
- Mapping functions
The objective of this section is to learn about APIs and related to memory management from kernel mode. It covers topics such as enumerating process virtual address space to locate shellcode, enumerating physical address ranges for memory captures, safely accessing process and system memory, switching process address contexts, measuring kernel-mode stack usage, extended kernel-mode stacks, locking process, and system memory, mapping memory with different permissions, mitigating pool fragmentation using lookaside lists and configuring various system settings that affect kernel memory.
- Enumerating process memory
- Enumerating physical RAM
- Safe memory access
- Accessing process memory
- Switching virtual address spaces
- Locking and mapping memory
- Kernel stacks
- Lookaside lists
The objective of this section is to learn how to interface with user-mode applications and other drivers in the system. It covers topics such as registering driver entry points, creating device objects, establishing symbolic links, using Win32 and native I/O APIs, implementing various dispatch routines, manipulating IRPs and I/O stack locations, pre-processing IRPs in dispatch routines, post-processing IRPs in completion routines, defining IOCTL codes, exchanging data between user mode and kernel mode, building synchronous and asynchronous IRPs and dispatching them to other drivers.
- Driver entry points
- Device and symbolic links
- User-kernel interface
- Handling IRPs
- Device I/O control
- Buffering mechanisms
- Building IRPs
- IRP dispatching
Kernel Execution and Synchronization
The objective of this section is to learn about the different execution contexts available in kernel mode, their use cases, the constraints they are subject to, and the synchronization mechanisms they can use to serialize access to data structures. It covers topics such as modifying IRQLs, various methods of querying time in the kernel, implementing timer triggered and custom DPC routines, selecting different types of spinlocks for synchronization at high IRQLs, methods of deferring execution to lower IRQLs, using work items and worker routines, creating and managing custom driver threads, implementing service queues using linked lists, performing queue rundown operations and considerations for selecting waitable locks.
- IRQL management
- DPC routines
- Kernel timers
- High IRQL synchronization
- Work items and worker routines
- Custom driver threads
- Linked Lists
- Waitable Locks
Common Programming Tasks
The objective of this section is to learn about programming constructs that are frequently required when implementing kernel mode software that provides security related functionality. It covers topics such as walking the object namespace and enumerating objects, specifying absolute and relative paths to objects, creating process-specific and kernel handles, storing driver state information in the registry, considerations when performing file I/O in kernel mode, finding caller's security context, token impersonation, common pitfalls to avoid and best practices when developing kernel-mode software.
- Enumerating object namespace
- Absolute and relative paths
- Path processing
- Registry access
- File access
- Token manipulation
- Common programming mistakes
- Kernel development best practices