What is CMKD?
CMKD.dll is an extension DLL for the Debugging Tools for Windows
package.
It implements the commands !packet, !ptelist, !kvas, !stack and !help.
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]
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.
!packet
The !packet command decodes and displays a network packet stored in memory.
Syntax
!packet [-v] <Address>
Description
!packet decodes the contents of a network packet in memory and displays the Ethernet, ARP, IPv4, IPv6, TCP and UDP headers. !packet requires the packet to start with the Ethernet header and expects the Ethernet, ARP/IPv4/IPv6, TCP/UDP headers to be stored contiguously in memory. !packet only processes the first contiguous part of a fragmented packet (a packet described by multiple MDLs). !packet does not process tunneled packets like IPv4 in IPv6.
The following output shows an ARP packet.
kd> !cmkd.packet fffffa800293400a PKT : 70-1a-04-93-f7-5d -> ff-ff-ff-ff-ff-ff arp-req 192.168.100.118 -> 192.168.100.110 kd> !cmkd.packet -v fffffa800293400a ETH : smac=70-1a-04-93-f7-5d dmac=ff-ff-ff-ff-ff-ff type=0806 ARP : hwtype=Ethernet ptype=IP hwalen=6 palen=4 arp-req shwa=70-1a-04-93-f7-5d thwa=00-00-00-00-00-00 spa=192.168.100.118 tpa=192.168.100.110
The following output shows an IPv4/UDP packet.
kd> !cmkd.packet fffffa8002da6dc6
PKT : 08-00-27-8d-2b-27 -> 00-23-69-ef-4a-28 udp 119.100.168.192:59007 -> 68.105.28.12:53 (71)(51) {85d9}
kd> !cmkd.packet -v fffffa8002da6dc6
ETH : smac=08-00-27-8d-2b-27 dmac=00-23-69-ef-4a-28 type=0800
IP4 : len=71 id=332 -- off=0 UDP src=119.100.168.192 dst=68.105.28.12
UDP : sport=59007 dport=53 len=51 sum=34265
The following output shows an IPv4/TCP packet.
kd> !packet 8508a00a
PKT : 52-54-00-12-35-02 -> 08-00-27-47-c6-cc tcp 70.37.131.41:80 -> 10.0.2.15:49257 (44) --- SYN --- --- ACK --- {68ab}
kd> !packet -v 8508a00a
ETH : smac=52-54-00-12-35-02 dmac=08-00-27-47-c6-cc type=0800
IP4 : len=44 id=42157 -- off=0 TCP src=70.37.131.41 dst=10.0.2.15
TCP : sport=80 dport=49257 seq=4293419521 ack=2884144001 flags= --- SYN --- --- ACK --- win=65535 sum=26795 urp=0
The following output is truncated (does not show the UDP header), since the packet is fragmented.
kd> !cmkd.packet -v 859af816 ETH : smac=08-00-27-47-c6-cc dmac=33-33-00-01-00-03 type=86dd IP6 : trc=6 flw=0 len=30 nxt=UDP hop=1 src=fe80::a5e2:2fe9:fb12:c11f dst=ff02::1:3
Parameters
The following parameters can be passed to the "!packet" command.
| <Address> | <Address> is the virtual address of the packet. |
| -v | Displays the packet headers in verbose format. Each of the layer 2, 3, 4 header information is printed on separate lines. Without the -v option all packet headers are displayed on a single lines, similar to the output generated by tcpdump. |
!ptelist
The !ptelist command displays the page table entry (PTE) information for a given virtual address.
Syntax
!ptelist <StartVa> [<EndVa>] [-l <Count>] [-f Hard|Trns|Prot|PgFl|DmZr] [-c] [-p] [-v]
Description
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 :
- Supports XP, 2003, Vista, 2008 and Windows 7 on x86 and x64 platforms.
- Displays PTEs for VA spans rather than an individual VA. (-l flag).
- Allows display filtering by PTE type i.e. Hardware, Transition, Prototype, PageFile, Demand Zero (-f flag).
- Decodes any arbitrary number as PTE contents (-c flag).
- Displays contents of a list of PTEs using the VA of the PTE (-p flag) . For example this can be used to list and decode all PTEs in a page directory page.
- For PTEs of shared pages, it automatically decodes the contents of the PTE in the Prototype PTE array.
- Displays contents of PXE/PPE/PDE/PTE (as appropriate) in a single line by default allowing for easy filtering. This can be changed to display each level on an individual line (-v flag).
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-.
Parameters
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-V
When 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)
|
!kvas
The !kvas command displays the kernel virtual address space layout on Vista and later versions of Windows.
Syntax
!kvas [<Address>] [-t <VaTypeFilter>]
Description
The debugger extension command "!address" does not work on Vista and later versions of Windows for kernel mode targets. "!kvas" provides functionality similar to the "!address" command on both X86 and X64 targets. !kvas does not work on Windows XP, Windows 2003 or Windows 2000.
When run without any parameters "!kvas" displays the complete layout of the kernel virtual address space (KVAS). Since the layout of the KVAS is significantly different on X86 and X64 systems, the output of this command looks very different on these two CPU architectures.
Due to the static nature of KVAS on x64 the output is as follows:
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) HalReserved
The 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
Parameters
The following optional parameters can be passed to the "!kvas" command to display only specific regions of the KVAS.
| <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
The !stack command displays registers based parameters passed to x64 functions.
Syntax
!stack [-u] [-r] [-p [-t]]
Description
x64 'C/C++' compiler optimization causes the first 4 parameters to functions to be passed via registers as opposed to being passed on the stack. This poses a challenge when debugging as one cannot read the values of these parameters from the call stack as one would on x86. Moreover as parameters are passed in volatile registers (P1=rcx, P2=rdx, P3=r8 and P4=r9) their values get overwritten as the function executes making it hard or sometimes impossible to retrieve the values they contained at the start of a function. It is, however, quite commonplace for these parameter registers (rcx, rdx, r8, r9) to be saved in non-volatile registers and for these non-volatile registers to be saved on the stack across function calls. The "!stack" command leverages this fact and detects the availability of parameters on the stack and accordingly attempts to retrieve them on behalf of the user. This command works both in user and kernel mode but on x64 targets only.
By default this command displays the following information similar to that displayed by debugger's native "kn" command.
| 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 |
Unlike the "kvn" command the "!stack" command displays the names of BBT'd functions correctly, as shown below.
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 . . .
Parameters
The following optional parameters can be passed to the "!stack" command to control the information it displays. Multiple options can be specified together. These parameters affect the display of this command but not the actual execution path.
| -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
.
.
.
|
Comments
This "!stack" command uses the following 4 methods to determine parameter values:
- Find any immediate data or memory contents that were loaded into the parameter registers by examining the caller.
- Find any non-volatile register values that were loaded into the parameter registers by examining the caller and then retrieve the non-volatile register values from the current frame.
- Find any memory locations where the parameter register values have been saved by examining the current frame.
- Find any non-volatile registers that were used to save the values in contained in the parameter registers by examining the current frame and then retrieve the non-volatile register values from the child frames.
For more information on the mechanisms used by this extension please refer the presentation x64 Deep Dive. The implementation of this command comprises of a custom x64 disassembler, function call graph generator, function block parser, register modification tracker, stack frame and unwind information parser. Quite frequently, the x64 compiler optimizations make it hard or even impossible to retrieve parameters passed to functions either because they are not loaded from or saved into non-volatile registers or because the non-volatile registers containing their values are overwritten. In all such cases the individual parameters that cannot be determined are listed as "(unknown)". CodeMachine endeavors to improve the success rate of finding parameters by enhancing the above retrieval techniques.
!help
Displays the various commands and their respective command line parameters currently implemented in CMKD.dll.
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
Source code for all of CodeMachine's tools is available for commercial licensing.