LPC part 2 Kernel Debugger Extensions
Hello my name is Roy, I’m an EE on the Microsoft global escalation services / CPR team. This blog is a follow on to my first LPC blog. We will be discussing debugger extensions that allow you to look at LPC related issues.
Disclaimer: The purpose of this blog is to illustrate debugging techniques with LPC. Please do not rely on this information as documentation for the APIs when writing your own code. As always, this is subject to change in the future.
LPC Kernel Debugger Extensions
Command |
Description |
!lpc |
Display the list and description of all the !lpc commands |
!lpc message [MessageId] |
Display the message with a given ID and all related information by attempting to match the given Message ID to the EHTREAD->LpcReceivedMessageId and to the ETHREAD->LpcReplyMessageId of all threads in the system. If the MessageId parameter is omitted then it attempts to display all the outstanding messages in the system by searching for the tag ‘LpcM’ in the pools. |
!lpc port [PortAddress] |
Displays port information. If a server connection port address is specified then only information about that port is displayed. If either a client or server communication port is specified it prints information about the specified communication port, the peer communication port and the server connection port. If the PortAddress parameter is omitted then it attempts to walk the list of all objects of type “Port” and “WaitablePort” and display them. Note that for this feature to work the GFlags option “+otl” i.e. “Maintain a list of objects for each type” must be enabled. |
!lpc scan PortAddress |
Displays port information. It attempts to walk the list of all objects of type “Port” and “WaitablePort” and display the one matching the specified port address. Note that for this feature to work the GFlags option “+otl” i.e. “Maintain a list of objects for each type” must be enabled. |
!lpc thread [ThreadAddr] |
If ThreadAddr is specified it walks the list of threads in the ETHREAD-> LpcReplyChain to locate the list head i.e. a “Port” or “WaitablePort” object on which the thread is waiting for a reply. If the ThreadAddr parameter is omitted then it attempts to find all LPC server threads by looking for threads with a non-NULL EHTREAD->LpcReceivedMessageId and all client threads by looking for threads with a non-NULL ETHREAD->LpcReplyMessageId and displays them. |
!lpc PoolSearch |
Toggles a setting that controls whether the “lpc message” command will search for LPC message tag (‘LpcM’) in the kernel pools or not. |
LPC Kernel Debugger Extension Usage
LPC Connection Port information from call stack
On the call stack of any client or server threads blocked on LPC data transfer or LPC connection there will be a frame containing either one of the functions NtRequestWaitReplyPort() or NtReplyWaitReceivePortEx() . The first parameter to either one of these functions is the handle to the port they are blocked on.
kd> !thread 810de2a8
THREAD 810de2a8 Cid 01dc.01f4 Teb: 7ffde000 Win32Thread: 00000000 WAIT: (WrLpcReceive) UserMode Non-Alertable
81131188 Semaphore Limit 0x7fffffff
810de398 NotificationTimer
Not impersonating
DeviceMap e196c460
Owning Process 810ddda0 Image: rpclpcs.exe
Wait Start TickCount 64555 Ticks: 402 (0:00:00:04.025)
Context Switch Count 2
UserTime 00:00:00.000
KernelTime 00:00:00.000
Win32 Start Address 0x77e76bf0
Start Address 0x7c810856
Stack Init f8e28000 Current f8e27c4c Base f8e28000 Limit f8e25000 Call 0
Priority 8 BasePriority 8 PriorityDecrement 0 DecrementCount 0
ChildEBP RetAddr Args to Child
f8e27c64 804dc6a6 810de318 810de2a8 804dc6f2 nt!KiSwapContext+0x2e (FPO: [Uses EBP] [0,0,4])
f8e27c70 804dc6f2 e1084108 8055a540 e1084108 nt!KiSwapThread+0x46 (FPO: [0,0,0])
f8e27c98 8056a50a 00000001 00000010 00000001 nt!KeWaitForSingleObject+0x1c2 (FPO: [Non-Fpo])
f8e27d48 804df06b 000007c4 002bff70 00000000 nt!NtReplyWaitReceivePortEx+0x3dc (FPO: [Non-Fpo])
f8e27d48 7c90eb94 000007c4 002bff70 00000000 nt!KiFastCallEntry+0xf8 (FPO: [0,0] TrapFrame @ f8e27d64)
002bff80 00000000 00000000 00000000 00000000 ntdll!KiFastSystemCallRet (FPO: [0,0,0])
kd> !handle 7c4 3 810ddda0
processor number 0, process 810ddda0
PROCESS 810ddda0 SessionId: 0 Cid: 01dc Peb: 7ffd9000 ParentCid: 01b4
DirBase: 058cd000 ObjectTable: e1a13278 HandleCount: 18.
Image: rpclpcs.exe
Handle table at e107d000 with 18 Entries in use
07c4: Object: e1084108 GrantedAccess: 001f0001 Entry: e107df88
Object: e1084108 Type: (812b5c80) Port
ObjectHeader: e10840f0 (old version)
HandleCount: 1 PointerCount: 4
Directory Object: e14c72c8 Name: rpclpc
kd> !lpc port e1084108
Server connection port e1084108 Name: rpclpc
Handles: 1 References: 4
Server process : 810ddda0 (rpclpcs.exe)
Queue semaphore : 81131188
Semaphore state 0 (0x0)
The message queue is empty
The LpcDataInfoChainHead queue is empty
LPC Messages that are waiting to be picked up by the server thread
When a message is queued to the server connection port and the server thread has not yet not been signaled to pull out the message the ‘!lpc port <Port>” displays the following output that includes the message.
kd> !lpc port e10d8388
Client communication port 0xe10d8388
Handles: 1 References: 2
The LpcDataInfoChainHead queue is empty
Connected port: 0xe106dc00 Server connection port: 0xe15512e0
Server communication port 0xe106dc00
Handles: 1 References: 1
The LpcDataInfoChainHead queue is empty
Server connection port e15512e0 Name: rpclpc
Handles: 1 References: 9
Server process : ffbbebe8 (rpclpcs.exe)
Queue semaphore : 81250848
Semaphore state 0 (0x0)
Messages in queue:
0000 e10513f8 - Busy Id=000048d8 From: 05f4.0108 Context=80020000 [e15512f0 . e15512f0]
Length=0054003c Type=00000001 (LPC_REQUEST)
Data: 00000001 00000241 00000000 00000000 f877bc04 804ec10e
The message queue contains 1 messages
The LpcDataInfoChainHead queue is empty
LPC Messages being processed by the server
When an LPC message has been queued by the client, dequeued by the sever and being worked upon by the server both the client and the server thread have the message ID associated with them
kd> !lpc message 16fa
Searching message 16fa in threads ...
Server thread 810de2a8 is working on message 16fa
Client thread 810dc930 waiting a reply from 16fa
Searching thread 810dc930 in port rundown queues ...
Server connection port e1084108 Name: rpclpc
Handles: 1 References: 3
Server process : 810ddda0 (rpclpcs.exe)
Queue semaphore : 81131188
Semaphore state 0 (0x0)
The message queue is empty
The LpcDataInfoChainHead queue is empty
Done.
kd> !thread 810de2a8
THREAD 810de2a8 Cid 01dc.01f4 Teb: 7ffde000 Win32Thread: 00000000 RUNNING on processor 0
Not impersonating
DeviceMap e196c460
Owning Process 810ddda0 Image: rpclpcs.exe
Wait Start TickCount 65732 Ticks: 10 (0:00:00:00.100)
Context Switch Count 4
UserTime 00:00:00.000
KernelTime 00:00:00.010
Win32 Start Address 0x000016fa
LPC Server thread working on message Id 16fa
Start Address kernel32!BaseThreadStartThunk (0x7c810856)
Stack Init f8e28000 Current f8e27728 Base f8e28000 Limit f8e25000 Call 0
Priority 9 BasePriority 8 PriorityDecrement 0 DecrementCount 0
ChildEBP RetAddr Args to Child
f8e27d64 7c90eb94 badb0d00 002bfe24 00000000 nt!KiFastCallEntry+0xf8 (FPO: [0,0] TrapFrame @ f8e27d64)
002bfe18 7c90e399 77e76703 000007c4 002bff70 ntdll!KiFastSystemCallRet (FPO: [0,0,0])
002bfe1c 77e76703 000007c4 002bff70 00000000 ntdll!NtReplyWaitReceivePortEx+0xc (FPO: [5,0,0])
002bff80 77e76c22 002bffa8 77e76a3b 00084540 RPCRT4!LRPC_ADDRESS::ReceiveLotsaCalls+0xf4 (FPO: [Non-Fpo])
002bff88 77e76a3b 00084540 7c90ee18 0006fb10 RPCRT4!RecvLotsaCallsWrapper+0xd (FPO: [Non-Fpo])
002bffa8 77e76c0a 00083f20 002bffec 7c80b50b RPCRT4!BaseCachedThreadRoutine+0x79 (FPO: [Non-Fpo])
002bffb4 7c80b50b 00084718 7c90ee18 0006fb10 RPCRT4!ThreadStartRoutine+0x1a (FPO: [Non-Fpo])
002bffec 00000000 77e76bf0 00084718 00000000 kernel32!BaseThreadStart+0x37 (FPO: [Non-Fpo])
kd> !thread 810dc930
THREAD 810dc930 Cid 01e4.01ec Teb: 7ffde000 Win32Thread: 00000000 READY
Waiting for reply to LPC MessageId 000016fa:
Pending LPC Reply Message:
e16b8538: [e16b8538,e16b8538]
Not impersonating
DeviceMap e196c460
Owning Process 810e9860 Image: rpclpcc.exe
Wait Start TickCount 65731 Ticks: 11 (0:00:00:00.110)
Context Switch Count 26
UserTime 00:00:00.000
KernelTime 00:00:00.020
Win32 Start Address rpclpcs!pre_c_init (0x01001a91)
Start Address kernel32!BaseProcessStartThunk (0x7c810867)
Stack Init fbe0e000 Current fbe0dc28 Base fbe0e000 Limit fbe0b000 Call 0
Priority 8 BasePriority 8 PriorityDecrement 0 DecrementCount 16
ChildEBP RetAddr Args to Child
fbe0dc40 804ea3a4 00000000 810dc930 e107f388 nt!KiUnlockDispatcherDatabase+0x77 (FPO: [Uses EBP] [0,0,4])
fbe0dc58 80586255 81131188 00000001 00000001 nt!KeReleaseSemaphore+0x70 (FPO: [Non-Fpo])
fbe0dd10 80598c58 000847b0 0006f8c0 0006f8c8 nt!NtSecureConnectPort+0x635 (FPO: [Non-Fpo])
fbe0dd3c 804df06b 000847b0 0006f8c0 0006f8c8 nt!NtConnectPort+0x24 (FPO: [Non-Fpo])
fbe0dd3c 7c90eb94 000847b0 0006f8c0 0006f8c8 nt!KiFastCallEntry+0xf8 (FPO: [0,0] TrapFrame @ fbe0dd64)
0006f8d0 7c93040b ffffffff 00000000 7c859e48 ntdll!KiFastSystemCallRet (FPO: [0,0,0])
0006f9b0 7c8107fd 00000000 00084718 7c90e642 ntdll!DbgPrint+0x1b (FPO: [Non-Fpo])
0006fe68 77ea11a8 00000022 00084540 00000000 kernel32!CreateRemoteThread+0x284 (FPO: [Non-Fpo])
000847a8 00000000 00000001 00000000 00000000 RPCRT4!LRPC_ADDRESS::CompleteListen+0x84 (FPO: [Non-Fpo])
Finding all threads in the system involved in LPC communication
To get a consolidated list of all client threads in the system waiting on LPC replies and a list of server threads working on received LPC requests use the “!lpc threads” command without any parameters
0: kd> !lpc thread
Searching message 0 in threads ...
Client thread 89a4cdb0 waiting a reply from 15f6
Server thread 898c6a50 is working on message 63f09
Server thread 89671020 is working on message 63f75
Server thread 89904a48 is working on message 63f10
Server thread 88d6bdb0 is working on message 3d6b1
Server thread 89973db0 is working on message 63f32
Server thread 896d32b8 is working on message 3454
Server thread 8995d020 is working on message 63f76
Server thread 8960f020 is working on message 63f77
Server thread 898cd350 is working on message 61bd9
Server thread 8900edb0 is working on message 3832f
Server thread 8900fbf0 is working on message 33c2e
Server thread 88d539a8 is working on message 3343f
Client thread 89be4020 waiting a reply from 6077e
Client thread 89012990 waiting a reply from 39239
Server thread 89012990 is working on message 39232
Client thread 89531020 waiting a reply from 3923d
Server thread 89531020 is working on message 39236
Client thread 88d13b40 waiting a reply from 3c96e
Quick Tips
8 No thread in the system is doing a NtListenPort( ) does that mean no LPC connection port is open for connections?
!stacks 2 NtListenPort does not return any thread because NtListenPort( ) calls NtRequestWaitReplyPort( ) to wait for an incoming LPC_CONNECTION_REQUEST message. Instead of calling NtListenPort( ) for listening for incoming connections most LPC connection threads directly call NtRequestWaitReplyPort( ).
8 !lpc message does not show any message?
!poolfind LpcM 1 should do the trick.
0: kd> !lpc message
Scanning large pool allocation table for Tag: LpcM (8974e000 : 8976e000)
Searching Paged pool (e1000000 : f7000000) for Tag: LpcM
0: kd> !poolfind LpcM 1
Scanning large pool allocation table for Tag: LpcM (8974e000 : 8976e000)
Searching Paged pool (e1000000 : f7000000) for Tag: LpcM
e1061000 size: 168 previous size: 0 (Allocated) LpcM
e1090758 size: 168 previous size: 8 (Allocated) LpcM
e10a7a40 size: 168 previous size: 8 (Allocated) LpcM
e1188468 size: 8 previous size: 20 (Free) LpcM
e1261000 size: 168 previous size: 0 (Allocated) LpcM
e1297428 size: 168 previous size: 8 (Allocated) LpcM
Once you have the pool blocks listed with the “LpcM” tag dump the ones that are “Allocated”. On a 32-bit machine add 8bytes to the pool address listed on the left most column. On a 64-bit machine add 16bytes i.e. 0x10. Dump the message as below to retrieve the message id.
0: kd> dt nt!_LPCP_MESSAGE e1061000+8
+0x000 Entry : _LIST_ENTRY [ 0xe295fa80 - 0xe29279e8 ]
+0x000 FreeEntry : _SINGLE_LIST_ENTRY
+0x004 Reserved0 : 0xe29279e8
+0x008 SenderPort : 0xe2327020
+0x00c RepliedToThread : (null)
+0x010 PortContext : 0x8021000d
+0x018 Request : _PORT_MESSAGE
0: kd> dt nt!_LPCP_MESSAGE e1061000+8 Request.
+0x018 Request :
+0x000 u1 : __unnamed
+0x004 u2 : __unnamed
+0x008 ClientId : _CLIENT_ID
+0x008 DoNotUseThisField : 9.8460604703041575e-311
+0x010 MessageId : 0x4617f
+0x014 ClientViewSize : 0
+0x014 CallbackId : 0
0: kd> !lpc message 0x4617f
Searching message 4617f in threads ...
Server thread 88f91c08 is working on message 4617f
Client thread 88f0f5f8 waiting a reply from 4617f
Searching thread 88f0f5f8 in port rundown queues ...
Server communication port 0xe2300a38
Handles: 1 References: 1
The LpcDataInfoChainHead queue is empty
Connected port: 0xe2327020 Server connection port: 0xe13734b0
Client communication port 0xe2327020
Handles: 1 References: 9
The LpcDataInfoChainHead queue is empty
Server connection port e13734b0 Name: epmapper
Handles: 1 References: 93
Server process : 896e1450 (svchost1.exe)
Queue semaphore : 8995ac10
Semaphore state 0 (0x0)
The message queue is empty
8 The number of server threads shown by !lpc thread processing requests is much more than the number of client threads waiting for reply.
!lpc thread interprets stale data in ETHREAD structure as valid LPC information. An indication of the stale data is the ETHREAD.LpcExitThreadCalled will be set. This field is only set when the thread is exiting.
0: kd> !lpc thread
Searching message 0 in threads ...
Client thread 89a4cdb0 waiting a reply from 15f6
Server thread 898c6a50 is working on message 63f09
Server thread 89671020 is working on message 63f75
Server thread 89904a48 is working on message 63f10
Server thread 88d6bdb0 is working on message 3d6b1
Server thread 89973db0 is working on message 63f32
Server thread 896d32b8 is working on message 3454
Server thread 8995d020 is working on message 63f76
Server thread 8960f020 is working on message 63f77
Server thread 898cd350 is working on message 61bd9
Server thread 8900edb0 is working on message 3832f
Server thread 8900fbf0 is working on message 33c2e
Server thread 88d539a8 is working on message 3343f
0: kd> !lpc message 3454
Searching message 3454 in threads ...
Server thread 896d32b8 is working on message 3454
Done.
0: kd> dt nt!_ETHREAD 896d32b8 Lpc.
+0x1c0 LpcReplyChain : [ 0x896d3478 - 0x896d3478 ]
+0x000 Flink : 0x896d3478 _LIST_ENTRY [ 0x896d3478 - 0x896d3478 ]
+0x004 Blink : 0x896d3478 _LIST_ENTRY [ 0x896d3478 - 0x896d3478 ]
+0x1ec LpcReplySemaphore :
+0x000 Header : _DISPATCHER_HEADER
+0x010 Limit : 1
+0x200 LpcReplyMessage :
+0x200 LpcWaitingOnPort :
+0x220 LpcReceivedMessageId : 0x3454
+0x234 LpcReplyMessageId : 0
+0x248 LpcReceivedMsgIdValid : 0x1 ''
+0x248 LpcExitThreadCalled : 0x1 ''
8 Finding all client threads in the system waiting for LPC reply.
!lpc thread
Comments
- Anonymous
June 13, 2009
PingBack from http://quickdietsite.info/story.php?id=4700