mimidrv driver documentation
mimidrv is the optional kernel-mode driver that powers the commands behind Mimikatz's kernel helper module. It exposes kernel information (processes, modules, callbacks, SSDT, file-system filters) and privileged primitives (token duplication, process protection, kernel memory read/write) through a device object that user-mode code can reach via standard DeviceIoControl calls. The driver creates the \\Device\\mimidrv device and a \\DosDevices\\mimidrv symbolic link, and registers a IRP_MJ_DEVICE_CONTROL dispatch routine for all supported IOCTLs when it loads.【F:mimidrv/mimidrv.c†L6-L166】 User-mode code inside Mimikatz routes any command that starts with ! to this driver via kuhl_m_kernel_do, which parses the command name and optional /flag:value arguments before issuing the matching IOCTL.【F:mimikatz/mimikatz.c†L149-L165】【F:mimikatz/modules/kuhl_m_kernel.c†L8-L54】
Safety notice – Loading unsigned kernel drivers requires disabling Secure Boot or using test-signing, and the commands below directly manipulate kernel data structures. Use them only in lab environments where crashing or destabilizing the OS is acceptable.
mimidrv project. The rest of Mimikatz builds without the WDK, but the driver relies on it.【F:README.md†L107-L115】mimikatz.sln inside Visual Studio on a machine that has WDK 7.1 installed.Win32 or x64) and build the solution; Visual Studio invokes the _build_.cmd helper for the driver project. If the WDK is missing you will see MSBuild error MSB3073 referencing _build_.cmd—installing WDK 7.1 resolves it.【F:README.md†L107-L115】The mimidrv/_build_.cmd script automates a WDK build using the legacy build.exe environment.
cd mimidrv
_build_.cmd Win32 ..\bin
Win32 or x64); the script maps it to the WDK architecture directories (x86/i386 or amd64/amd64).【F:mimidrv/build.cmd†L6-L16】%SystemDrive%\WinDDK\7600.16385.1, runs setenv.bat to initialize the environment, calls build, and copies the resulting .sys file into the destination folder you pass as the second argument.【F:mimidrv/build.cmd†L4-L25】obj and architecture folders are removed after the build to keep the tree clean.【F:mimidrv/build.cmd†L26-L27】mimidrv.sys next to mimikatz.exe.!+. The command resolves the absolute path to mimidrv.sys and installs or starts a kernel-service named mimidrv through the Service Control Manager.【F:mimikatz/modules/kuhl_m_kernel.c†L56-L68】!- to uninstall the service entry and unload the driver.【F:mimikatz/modules/kuhl_m_kernel.c†L70-L74】If Mimikatz cannot locate the .sys file or SCM operations fail, the helper prints the relevant Windows error code, allowing you to troubleshoot path or privilege issues.【F:mimikatz/modules/kuhl_m_kernel.c†L62-L66】
! and are parsed by kuhl_m_kernel_do. Unknown commands fall back to IOCTL_MIMIDRV_RAW, which currently just echoes a "not implemented" message.【F:mimikatz/mimikatz.c†L149-L165】【F:mimikatz/modules/kuhl_m_kernel.c†L30-L54】/flag:value. Boolean switches (for example /remove) are present or absent; they do not take values unless specified below.【F:mimikatz/modules/kuhl_m_kernel.c†L82-L206】Each section lists the syntax, supported flags, what the command does, and when to use it.
!+ — install or start mimidrvmimidrv.sys, installs it as a kernel service if necessary, and starts it.【F:mimikatz/modules/kuhl_m_kernel.c†L56-L68】\\.\mimidrv exists so subsequent IOCTLs succeed.【F:modules/kull_m_kernel.c†L44-L75】!- — remove the drivermimidrv service entry, unloading the driver.【F:mimikatz/modules/kuhl_m_kernel.c†L70-L74】!pingIOCTL_MIMIDRV_PING and prints the input string alongside a pong response, verifying the control path between user mode and the driver.【F:mimidrv/mimidrv.c†L79-L158】!bsodKeBugCheck(MANUALLY_INITIATED_CRASH) through IOCTL_MIMIDRV_BSOD.【F:mimidrv/mimidrv.c†L87-L89】!process!processProtect/process:<image> – resolve the process ID by image name.【F:mimikatz/modules/kuhl_m_kernel.c†L84-L89】/pid:<id> – target a specific PID when the image name is ambiguous.【F:mimikatz/modules/kuhl_m_kernel.c†L90-L94】/remove – remove protection instead of applying it.【F:mimikatz/modules/kuhl_m_kernel.c†L82-L124】MIMIDRV_PROCESS_PROTECT_INFORMATION structure with protection levels suited to the current Windows build, then sets or clears the target's protection fields inside EPROCESS.【F:mimikatz/modules/kuhl_m_kernel.c†L95-L124】【F:mimidrv/ioctl.h†L50-L58】【F:mimidrv/kkll_m_process.c†L69-L118】!processToken/from:<pid> – PID to copy the token from (0 defaults to the SYSTEM process).【F:mimikatz/modules/kuhl_m_kernel.c†L134-L143】/to:<pid> – PID to receive the duplicated token (0 applies to every cmd.exe and mimikatz.exe).【F:mimikatz/modules/kuhl_m_kernel.c†L137-L144】/to:0 is used.【F:mimikatz/modules/kuhl_m_kernel.c†L140-L147】【F:mimidrv/kkll_m_process.c†L120-L176】!processPrivilege/pid:<id> – optional; when omitted the command targets all tracked shells and Mimikatz instances.【F:mimikatz/modules/kuhl_m_kernel.c†L152-L160】IOCTL_MIMIDRV_PROCESS_FULLPRIV, which clears privilege restrictions and enables every privilege bit in the target process token.【F:mimikatz/modules/kuhl_m_kernel.c†L151-L160】【F:mimidrv/mimidrv.c†L103-L108】SeDebugPrivilege) without editing the token manually.!modulesAuxKlibQueryModuleInformation.【F:mimidrv/mimidrv.c†L110-L112】【F:mimidrv/kkll_m_modules.c†L8-L33】!ssdt!notifProcess, !notifThread, !notifImage, !notifReg, !notifObject!filtersIoEnumerateRegisteredFiltersList, including driver names.【F:mimidrv/mimidrv.c†L134-L136】【F:mimidrv/kkll_m_filters.c†L50-L70】!minifilters!sysenvset/name:<variable> – EFI variable name (default Kernel_Lsa_Ppl_Config).【F:mimikatz/modules/kuhl_m_kernel.c†L173-L210】/guid:<GUID> – Vendor GUID in braces (default {77fa9abd-0359-4d32-bd60-28f4e78f784b}).【F:mimikatz/modules/kuhl_m_kernel.c†L173-L206】/attributes:<hex> – EFI attribute mask (default 1).【F:mimikatz/modules/kuhl_m_kernel.c†L173-L206】/data:<hexbytes> – Hex-encoded payload (default 00000000).【F:mimikatz/modules/kuhl_m_kernel.c†L173-L207】MIMIDRV_VARIABLE_NAME_AND_VALUE buffer, prints a summary, and sends it to ZwSetSystemEnvironmentValueEx through the driver so the EFI variable is created or updated.【F:mimikatz/modules/kuhl_m_kernel.c†L195-L207】【F:mimidrv/ioctl.h†L68-L75】【F:mimidrv/mimidrv.c†L47-L58】!sysenvdel/name, /guid, /attributes – same defaults as !sysenvset.【F:mimikatz/modules/kuhl_m_kernel.c†L225-L257】IOCTL_MIMIDRV_SYSENVSET, which causes ZwSetSystemEnvironmentValueEx to delete the variable if the attributes match.【F:mimikatz/modules/kuhl_m_kernel.c†L233-L253】【F:mimidrv/mimidrv.c†L93-L95】! commandsAny !something that does not match the table above is forwarded as a raw Unicode string to IOCTL_MIMIDRV_RAW, which currently just echoes that the command is unimplemented. This makes it safe to experiment without triggering undefined behavior.【F:mimikatz/modules/kuhl_m_kernel.c†L40-L52】【F:mimidrv/mimidrv.c†L81-L84】
Developers who want to call the driver from custom tooling can use the IOCTL codes defined in mimidrv/ioctl.h. All codes use METHOD_NEITHER and require administrator access to open \\.\mimidrv.【F:mimidrv/ioctl.h†L6-L75】【F:modules/kull_m_kernel.c†L8-L77】
| Category | IOCTL | Purpose | Why use it |
|---|---|---|---|
| Diagnostics | IOCTL_MIMIDRV_PING, IOCTL_MIMIDRV_DEBUG_BUFFER, IOCTL_MIMIDRV_RAW |
Connectivity test, buffer introspection, or placeholder passthroughs for future expansion.【F:mimidrv/mimidrv.c†L81-L92】 | Validate handle access, inspect driver buffer handling, or prototype new commands without recompiling the driver. |
| Stability testing | IOCTL_MIMIDRV_BSOD |
Invokes KeBugCheck.【F:mimidrv/mimidrv.c†L87-L89】 |
Force crash dumps or test blue-screen monitoring setups. |
| System configuration | IOCTL_MIMIDRV_SYSENVSET |
Set or delete EFI variables.【F:mimidrv/mimidrv.c†L93-L95】 | Persist configuration changes across boots, such as LSA protection flags. |
| Process management | IOCTL_MIMIDRV_PROCESS_LIST, IOCTL_MIMIDRV_PROCESS_PROTECT, IOCTL_MIMIDRV_PROCESS_TOKEN, IOCTL_MIMIDRV_PROCESS_FULLPRIV |
Enumerate processes, toggle protection, duplicate tokens, or grant all privileges.【F:mimidrv/mimidrv.c†L97-L108】【F:mimidrv/ioctl.h†L13-L16】 | Collect intelligence on protected processes or perform privilege escalation primitives. |
| Module and SSDT insight | IOCTL_MIMIDRV_MODULE_LIST, IOCTL_MIMIDRV_SSDT_LIST |
List loaded modules and dump SSDT entries.【F:mimidrv/mimidrv.c†L110-L116】 | Detect hooks and locate driver entry points. |
| Callback inventory | IOCTL_MIMIDRV_NOTIFY_*, IOCTL_MIMIDRV_FILTER_LIST, IOCTL_MIMIDRV_MINIFILTER_LIST |
Enumerate process/thread/image/registry/object callbacks and file-system filters.【F:mimidrv/mimidrv.c†L118-L139】 | Map third-party monitoring components that could hinder red-team activity. |
| Memory primitives | IOCTL_MIMIDRV_VM_READ, IOCTL_MIMIDRV_VM_WRITE, IOCTL_MIMIDRV_VM_ALLOC, IOCTL_MIMIDRV_VM_FREE |
MDL-backed read/write, allocation, and free in kernel memory.【F:mimidrv/mimidrv.c†L141-L151】【F:mimidrv/kkll_m_memory.c†L17-L90】 | Implement direct kernel memory manipulation for advanced implants or diagnostics. |
| Threading | IOCTL_MIMIDRV_CREATEREMOTETHREAD |
Calls a function pointer supplied from user mode in kernel context.【F:mimidrv/mimidrv.c†L153-L155】【F:mimidrv/ioctl.h†L36-L67】 | Experimental primitive for invoking custom kernel payloads after mapping them into the driver's address space. |
Because all IOCTLs use METHOD_NEITHER, callers must supply user-mode pointers directly. The driver uses MDLs (IoAllocateMdl, MmProbeAndLockPages) to safely copy kernel memory for read/write requests and allocates pool memory for kernel outputs where necessary.【F:mimidrv/mimidrv.c†L71-L160】【F:mimidrv/kkll_m_memory.c†L17-L78】 When an IOCTL returns textual data, Mimikatz allocates the output buffer automatically and prints the UTF-16 stream character by character before freeing it.【F:modules/kull_m_kernel.c†L64-L77】 When writing your own tooling, mirror this pattern to avoid leaks and ensure buffers are large enough.
The driver's DriverUnload routine deletes the symbolic link and device object, so unloading through !- or the Service Control Manager removes user-mode access to \\.\mimidrv.【F:mimidrv/mimidrv.c†L16-L20】 Always unload the driver when finished to restore the system to its original state.