CMKD.dll is an extension DLL for the "Debugging Tools for Windows Package. CodeMachine plans to add commands useful to developers and support engineers to CMKD.dll over time. CMKD.dll automatically checks for updates and informs the user when updates are available. The user is responsible for downloading and installing the updates.
This document lists all the commands currently implemented in CMKD.dll.
Download CMKD.dll for X86 Debugger [90 KB]
Download CMKD.dll for X64 Debugger [104 KB]
The !ptelist command displays the page table entry (PTE) information for a given virtual address.
!ptelist <StartVa> [<EndVa>] [-l <Count>] [-f Hard|Trns|Prot|PgFl|DmZr] [-c] [-p] [-v]
The debugger extension command "!pte" (in kdexts.dll) does display page table entry information for a virtual address but has a few shortcomings. It does not allow changing the display format and it works on an individual virtual address instead of a range of virtual addresses. The "!ptelist" provides functionality similar to "!pte" but addresses some of the shortcomings of the !pte command.
Following is the output of the "!pte" command on the X86.
kd> !pte 478F7000
VA 478f7000
PDE at C06011E0 PTE at C023C7B8
contains 0000000026FFA867 contains 000000002F6A5005
pfn 26ffa ---DA--UWEV pfn 2f6a5 -------UREV
Following is the output of the "!ptelist" command on X86
kd> !ptelist 478F7000 ptelist : Using 478f7000 as VA VA |PPE |PDE |PTE 478F7000 |Hard Pfn=24A49 Attr=-------KREV |Hard Pfn=26FFA Attr=---DA--UWEV |Hard Pfn=2F6A5 Attr=-------UREV
Here are some of the features provided by the "!ptelist" command :
The !ptelist command uses abbreviations to display the states of the PTEs. Hardware PTEs are shown as Hard, Page File PTEs are displayed as PgFl, Demand Zero PTEs are displayed as DmZr, Transition PTEs are displayed as Trns and Invalid PTEs for shared pages are displayed as Prot. For such PTES the contents of the prototype PTEs are decoded and displayed automatically. When the PTE for a page has its contents zeroed out, it is displayed as Invl. If the entry at a certain translation level is invalid then all subsequent level entries are displayed as -NA-.
The following parameters can be passed to the "!ptelist" command.
| <StartVa> | <StartVa> is the Virtual Address (VA) for which the !ptelist command will display PTE information. A range of VAs can be specified using <StartVa> along with the <EndVa> as well as <StartVa> along with the -l <Count> options. When used with the -c option <StartVa> is interpreted as the contents of the PTE. |
| <EndVa> |
<EndVa> is an optional parameter. When used along with <StartVa> it specifies the Virtual Address range for which "!ptelist will display PTE information. When used with the -p option <StartVa> along with the <EndVa> are interpreted as <StartPTEVa> and <EndPTEVa> respectively and is used to specify the address range from which PTE contents will be displayed. <EndVa> cannot be used with the -l flag.
kd> !ptelist 478F7000 478FD000 ptelist : Using 478f7000 as VA VA |PPE |PDE |PTE 478F7000 |Hard Pfn=24A49 Attr=-------KREV |Hard Pfn=26FFA Attr=---DA--UWEV |Hard Pfn=2F6A5 Attr=-------UREV 478F8000 |Hard Pfn=24A49 Attr=-------KREV |Hard Pfn=26FFA Attr=---DA--UWEV |Hard Pfn=1D97E Attr=-------UREV 478F9000 |Hard Pfn=24A49 Attr=-------KREV |Hard Pfn=26FFA Attr=---DA--UWEV |Hard Pfn=1E5BF Attr=-------UREV 478FA000 |Hard Pfn=24A49 Attr=-------KREV |Hard Pfn=26FFA Attr=---DA--UWEV |Hard Pfn=05400 Attr=-------UREV 478FB000 |Hard Pfn=24A49 Attr=-------KREV |Hard Pfn=26FFA Attr=---DA--UWEV |Hard Pfn=3BA81 Attr=----A--UREV 478FC000 |Hard Pfn=24A49 Attr=-------KREV |Hard Pfn=26FFA Attr=---DA--UWEV |Hard Pfn=28BC2 Attr=----A--UREV 478FD000 |Hard Pfn=24A49 Attr=-------KREV |Hard Pfn=26FFA Attr=---DA--UWEV |Hard Pfn=335C3 Attr=----A--UREV |
| -v |
Causes !ptelist to display verbose PTE information. Index, PTE VA, PTE contents and decoded PTE contents are displayed.
kd> !ptelist -v 478F7000 ptelist : Using 478f7000 as VA VA=478F7000 PPE Idx=001 Va=84CBC028 Contents=0000000024A49801 Hard Pfn=24A49 Attr=-------KREV PDE Idx=03C Va=C06011E0 Contents=0000000026FFA867 Hard Pfn=26FFA Attr=---DA--UWEV PTE Idx=0F7 Va=C023C7B8 Contents=000000002F6A5005 Hard Pfn=2F6A5 Attr=-------UREV |
| -l <Count> |
!ptelist displays PTE information for <Count> pages starting at <StartVa>. When used with the -p option, !ptelist reads <Count> PTE contents starting at the PTE address in <StartVa>. <Count> must be a hexadecimal number.
kd> !ptelist 0028D000 -l 3 ptelist : Using 28d000 as VA VA |PPE |PDE |PTE 0028D000 |Hard Pfn=24AC8 Attr=-------KREV |Hard Pfn=24A85 Attr=---DA--UWEV |DmZr Protect=4(--W--) 0028E000 |Hard Pfn=24AC8 Attr=-------KREV |Hard Pfn=24A85 Attr=---DA--UWEV |PgFl PageFile=0 Offset=624A 0028F000 |Hard Pfn=24AC8 Attr=-------KREV |Hard Pfn=24A85 Attr=---DA--UWEV |Hard Pfn=00769 Attr=---DA--UWEV |
| -c |
Interpret <StartVa> as content of PTE, instead of a virtual address. Note that the -v, -l, -p, -f options cannot be used with the -c.
kd> !ptelist -c 8000000024A85867 ptelist : Using 8000000024a85867 as Contents of PTE Hard Pfn=24A85 Attr=---DA--UW-V |
| -p |
Interpret <StartVa> as pointer to list PTEs. If Use -l option to specify count. Note that the -v, -c, -f options cannot be used with the -p.
kd> !ptelist -p C0001468 -l 3 ptelist : Using c0001468 as Address of PTE PteAddr=00000000C0001468 PteContents=0000000000000080 DmZr Protect=4(--W--) PteAddr=00000000C0001470 PteContents=0000624A00000080 PgFl PageFile=0 Offset=624A PteAddr=00000000C0001478 PteContents=8000000000769867 Hard Pfn=00769 Attr=---DA--UW-VWhen used along with <EndVa>, the range <StartVa> to <EndVa> is interpreted as an address range containing PTEs. kd> !ptelist -p C0001468 C0001478 ptelist : Using c0001468 as Address of PTE PteAddr=00000000C0001468 PteContents=0000000000000080 DmZr Protect=4(--W--) PteAddr=00000000C0001470 PteContents=0000624A00000080 PgFl PageFile=0 Offset=624A PteAddr=00000000C0001478 PteContents=8000000000769867 Hard Pfn=00769 Attr=---DA--UW-V |
| -f <Filter> |
Allows display filtering by PTE type i.e. Hardware, Transition, Prototype, PageFile, Demand Zero.
kd> !ptelist 48340000 48352fff -f Prot ptelist : Using 48340000 as VA, filter as Prot VA |PPE |PDE |PTE 48344000 |Hard Pfn=278D7 Attr=-------KREV |Hard Pfn=277D2 Attr=---DA--UWEV |Prot Pte=879FB458 Trns Pfn=27754 Protect=3(--REC) 48346000 |Hard Pfn=278D7 Attr=-------KREV |Hard Pfn=277D2 Attr=---DA--UWEV |Prot Pte=879FB468 Trns Pfn=27896 Protect=3(--REC) 48351000 |Hard Pfn=278D7 Attr=-------KREV |Hard Pfn=277D2 Attr=---DA--UWEV |Prot Pte=879FB4C0 Trns Pfn=0AEF6 Protect=1(--R-C) 48352000 |Hard Pfn=278D7 Attr=-------KREV |Hard Pfn=277D2 Attr=---DA--UWEV |Prot Pte=879FB4C8 Trns Pfn=276FA Protect=1(--R-C) |
0: kd> !cmkd.kvas ### Start End Length Type 000 ffff080000000000 fffff67fffffffff ee8000000000 ( 238 TB) SystemSpace 001 fffff68000000000 fffff6ffffffffff 8000000000 ( 512 GB) PageTables 002 fffff70000000000 fffff77fffffffff 8000000000 ( 512 GB) HyperSpace 003 fffff78000000000 fffff78000000fff 1000 ( 4 KB) SharedSystemPage 004 fffff78000001000 fffff7ffffffffff 7ffffff000 ( 511 GB) CacheWorkingSet 005 fffff80000000000 fffff87fffffffff 8000000000 ( 512 GB) LoaderMappings 006 fffff88000000000 fffff89fffffffff 2000000000 ( 128 GB) SystemPTEs 007 fffff8a000000000 fffff8bfffffffff 2000000000 ( 128 GB) PagedPool 008 fffff90000000000 fffff97fffffffff 8000000000 ( 512 GB) SessionSpace 009 fffff98000000000 fffffa7fffffffff 10000000000 ( 1 TB) DynamicKernelVa 010 fffffa8000000000 fffffa80035fffff 3600000 ( 54 MB) PfnDatabase 011 fffffa8003600000 fffffa80c03fffff bce00000 ( 2 GB) NonPagedPool 012 ffffffffffc00000 ffffffffffffffff 400000 ( 4 MB) HalReservedThe memory manager on Windows Vista and later versions of Windows on the X86 uses dynamic memory allocation in the kernel virtual address space. The address space is divided into fixed sized regions (4MB/2MB in size) and each region is used for a certain type of allocation. The following output shows regions of the kernel virtual address space being allocated for various uses:
kd> !cmkd.kvas ### Start End Length ( MB) Count Type 000 80000000 803fffff 400000 ( 4) 2 BootLoaded 001 80400000 807fffff 600000 ( 6) 2 SystemPtes 002 80800000 81dfffff 1800000 ( 24) 11 BootLoaded 003 81e00000 821fffff 600000 ( 6) 2 PagedPool 004 82200000 823fffff 400000 ( 4) 1 SystemCache 005 82400000 82ffffff e00000 ( 14) 6 BootLoaded 006 83000000 833fffff 600000 ( 6) 2 DriverImages 007 83400000 839fffff 800000 ( 8) 3 BootLoaded 008 83a00000 845fffff e00000 ( 14) 6 PfnDatabase 009 84600000 885fffff 4200000 ( 66) 32 NonPagedPool . . . 077 9be00000 bfffffff 24400000 ( 580) 289 Unused 078 c0000000 c0ffffff 1200000 ( 18) 8 ProcessSpace 079 c1000000 fcdfffff 3c000000 ( 960) 479 Unused 080 fce00000 fd1fffff 600000 ( 6) 2 SessionSpace 081 fd200000 fd5fffff 600000 ( 6) 2 Unused 082 fd600000 fddfffff a00000 ( 10) 4 SessionSpace 083 fde00000 fdffffff 400000 ( 4) 1 Unused 084 fe000000 ffbfffff 1e00000 ( 30) 14 SessionSpace
| <Address> |
"!kvas <Address>" only displays the kernel virtual address region that contains <Address>. If <Address> points within an executable image, the name of the executable file is displayed. If <Address> points to the kernel mode stack of a thread, the details of the thread are displayed. Following are some example of the "!kvas <Address>" command. kd> !cmkd.kvas 9b053bfc kvas : Show region containing 9b053bfc ### Start End Length ( MB) Count Type 000 9b000000 9b1fffff 400000 ( 4) 1 SystemPtes Thread 84EEB6F0 [09a8.09bc] Stack 9b054000 - 9b051000 kd> !cmkd.kvas 8285ed11 kvas : Show region containing 8285ed11 ### Start End Length ( MB) Count Type 000 82400000 82ffffff e00000 ( 14) 6 BootLoaded Module \SystemRoot\system32\ntkrnlpa.exe 0x82604000 - 0x82a14000 0: kd> !cmkd.kvas fffff960`002c3b40 kvas : Show region containing fffff960002c3b40 ### Start End Length Type 008 fffff90000000000 fffff97fffffffff 8000000000 ( 512 GB) SessionSpace Module \SystemRoot\System32\win32k.sys 0xfffff96000070000 - 0xfffff9600037f000 0: kd> !cmkd.kvas fffff880`00f412a7 kvas : Show region containing fffff88000f412a7 ### Start End Length Type 006 fffff88000000000 fffff89fffffffff 2000000000 ( 128 GB) SystemPTEs Module \SystemRoot\system32\drivers\Wdf01000.sys 0xfffff88000f09000 - 0xfffff88000fad000 |
| -t |
The "-t" option displays only those regions of KVAS that contain the VA type identified by Following are some example of the "!kvas <Address>" command. kd> !cmkd.kvas -t SessionSpace kvas : Show regions containing SessionSpace ### Start End Length ( MB) Count Type 000 fce00000 fd1fffff 600000 ( 6) 2 SessionSpace 001 fd600000 fddfffff a00000 ( 10) 4 SessionSpace 002 fe000000 ffbfffff 1e00000 ( 30) 14 SessionSpace kd> !cmkd.kvas -t PfnDatabase kvas : Show regions containing PfnDatabase ### Start End Length ( MB) Count Type 000 83a00000 845fffff e00000 ( 14) 6 PfnDatabase |
| Stack-Pointer | Value of the RSP register right after the function's prolog has finished execution. |
| Return-Address | Address, the function will return to, after it completes execution. |
| Call Site | Function Name and Instruction Offset. The marker (perf) indicates that function body has been subject to Basic Block Tools (BBT) optimization. For such functions the offset would be often negative (-) if the call site happens to be located at an address that is numerically lower than the start of the function |
kd> !stack . . 1b fffffa60017181f0 fffffa6000826825 NDIS!ndisMDispatchReceiveNetBufferLists+395 (perf) 1c fffffa6001718670 fffffa60009b0fd8 NDIS!ndisMTopReceiveNetBufferLists+a085 (perf) 1d fffffa60017186b0 fffffa600084bb8d NDIS!ndisDoLoopbackNetBufferList+2b8 1e fffffa6001718720 fffffa60009adc92 NDIS!ndisMLoopbackNetBufferLists+ed 1f fffffa60017187a0 fffffa60009ac27a NDIS!ndisMSendNBLToMiniport-5ee (perf) 20 fffffa60017187f0 fffffa6003409fba NDIS!NdisSendNetBufferLists+9a . . . kd> kn . . . 1b fffffa60`017181f0 fffffa60`00826825 NDIS!ndisMDispatchReceiveNetBufferLists+0x395 1c fffffa60`01718670 fffffa60`009b0fd8 NDIS! ?? ::FNODOBFM::`string'+0xc057 1d fffffa60`017186b0 fffffa60`0084bb8d NDIS!ndisDoLoopbackNetBufferList+0x2b8 1e fffffa60`01718720 fffffa60`009adc92 NDIS!ndisMLoopbackNetBufferLists+0xed 1f fffffa60`017187a0 fffffa60`009ac27a NDIS! ?? ::FJGMBFAB::`string'+0x585 20 fffffa60`017187f0 fffffa60`03409fba NDIS!NdisSendNetBufferLists+0x9a . . .
| -u |
The "-u" option displays function unwind information. The contents displayed above are retrieved from the RUNTIME_FUNCTION, UNWIND_INFO and UNWIND_CODE structures that correspond to functions inside x64 executables. This option additionally parses the UNWIND_CODEs, locates values of the non-volatile registers saved on the stack, retrieves them and displays them.
kd> !stack -u . . . 48 fffffa600171b5c0 fffffa60009751e8 NDIS!ndisMIndicateNetBufferListsToOpen+ac (perf) UnwindInfo : ver=1 flag=0x0 prolog=25 codes=10 freg=none foff=0x0 UnwindCodes : [ 0] @ 19: UWOP_SAVE_NONVOL rdi @ 0x68 (0xfffffa600171b628) = 0xfffffa8007877680 [ 1] @ 19: UWOP_SAVE_NONVOL rsi @ 0x60 (0xfffffa600171b620) = 0x0000000000000001 [ 2] @ 19: UWOP_SAVE_NONVOL rbp @ 0x58 (0xfffffa600171b618) = 0xfffffa600171b730 [ 3] @ 19: UWOP_ALLOC_SMALL 0x30 [ 4] @ 15: UWOP_PUSH_NONVOL r14 @ (0xfffffa600171b5f0) = 0x0000000000000000 [ 5] @ 13: UWOP_PUSH_NONVOL r13 @ (0xfffffa600171b5f8) = 0x0000000000000001 [ 6] @ 11: UWOP_PUSH_NONVOL r12 @ (0xfffffa600171b600) = 0x0000000000000000 . . . |
| -r |
The "-r" option displays saved non-volatile registers for each stack frame. The values of only those non-volatile registers that are saved in a particular frame are displayed. Note that debuggers ".frame /r" command also attempts to display this information but sometimes the non-volatile register information displayed by this command is incorrect. kd> !stack -r . . . 48 fffffa600171b5c0 fffffa60009751e8 NDIS!ndisMIndicateNetBufferListsToOpen+ac (perf) NvRegs: rdi=0xfffffa8007877680 rsi=0x0000000000000001 rbp=0xfffffa600171b730 r14=0x0000000000000000 r13=0x0000000000000001 r12=0x0000000000000000 . . . |
| -p |
The "-p" option displays function parameters. In many situations specific parameters cannot be located, in such cases the parameter is displayed as "(unknown)".
kd> !stack -p . . . 48 fffffa600171b5c0 fffffa60009751e8 NDIS!ndisMIndicateNetBufferListsToOpen+ac (perf) Parameter[0] = fffffa8007877680 Parameter[1] = fffffa8007877c00 Parameter[2] = 0000000000000000 Parameter[3] = 0000000000000000 . . . |
| -t |
Adding the "-t" option to "-p" displays parameter tracking information. It displays how the parameters are retrieved and the source of the parameter values. This information is useful when CMKD heuristics incorrectly determine the parameter values. The user can use this information to validate the parameter values displayed by CMKD and retrieve the correct values manually.
kd> !stack -p -t . . . 48 fffffa600171b5c0 fffffa60009751e8 NDIS!ndisMIndicateNetBufferListsToOpen+ac (perf) Parameter[0] = fffffa8007877680 : rcx setup in parent frame by mov instruction @ fffffa60009751db from NvReg rdi which is saved by current frame Parameter[1] = fffffa8007877c00 : rdx saved in current frame into NvReg rsi which is saved by child frames Parameter[2] = 0000000000000000 : r8 saved in current frame into NvReg r13 which is saved by child frames Parameter[3] = 0000000000000000 : r9 saved in current frame into NvReg r12 which is saved by child frames . . . |
kd> !cmkd.help CodeMachine Debugger Extension v1.2.0.0 (c) 1999-2010 CodeMachine Inc. http://www.codemachine.com help : Prints this help stack [-u] [-r] [-p [-t]] : Display Stack Trace -u : Display function unwind information -r : Display saved non-volatile register for each frame -p : Display function parameters -t : Display function parameters tracking information kvas [<Address>] [-t <Filter>] : Display Kernel Virtual Address Space <Address> : Displays only the KVA region that contains <Address> -t <Filter> : Displays only the KVA regions that match <Filter> (X86 only) ptelist <StartVa> [<EndVa>] [-l <Count>] [-f <Filter>] [-c] [-p] [-v] : Display PTEs <StartVa> : Display PTE for virtual address in <StartVa> <EndVa> : Display PTEs for virtual addresses from <StartVa> to <EndVa> -l <Count> : Display PTEs for <Count> virtual address starting at <StartVa> -f <Filter> : Display PTEs that match <Filter>. Where <Filter> is Hard, Trns, PgFl, DmZr, Prot or Invl -c : Interpret <StartVa> as PTE content, instead of virtual address -p : Interpret <StartVa> as pointer to list PTEs. Use -l option to specify count -v : Display verbose PTE contents i.e. PTE Index, PTE VA, PTE contents and PTE decode