How to Find the Owner of a Named Pipe

How to Find the Owner of a Named Pipe

  • Comments 1

This is a follow-up on the LPC hang blog. The same hang troubleshooting techniques apply to this, but when a named pipe is involved you’ll have to use a slightly different method to following the chain from a client application to the server application. For the purpose of this exercise I’ll use the named pipe server ( and client ( given by MSDN.



Here is a diagram of our scenario.



Here we have the client application that is waiting on a read operation to a named pipe. We need to determine what process will be putting data into the named pipe which will let the client application move forward.

Here is the thread in the client application.



THREAD 81e70858  Cid 06bc.06c0  Teb: 7ffdf000 Win32Thread: 00000000 WAIT: (Executive) UserMode Non-Alertable

    81baaf7c  NotificationEvent

Not impersonating

DeviceMap                 e25176b8

Owning Process            81b3a020       Image:         client.exe

Attached Process          N/A            Image:         N/A

Wait Start TickCount      73194          Ticks: 1599 (0:00:00:24.984)

Context Switch Count      21            

UserTime                  00:00:00.000

KernelTime                00:00:00.000

Win32 Start Address client (0x00401376)

Start Address kernel32!BaseProcessStartThunk (0x77e617f8)

Stack Init f7450000 Current f744fc04 Base f7450000 Limit f744d000 Call 0

Priority 10 BasePriority 8 PriorityDecrement 2

ChildEBP RetAddr  Args to Child             

f744fc1c 808202b6 81e70858 81e70900 00000700 nt!KiSwapContext+0x25 (FPO: [Uses EBP] [0,0,4])

f744fc34 8081fb6e 8207dac0 00000000 81baaf20 nt!KiSwapThread+0x83 (FPO: [Non-Fpo])

f744fc78 8092deb3 81baaf7c 00000000 81f93601 nt!KeWaitForSingleObject+0x2e0 (FPO: [Non-Fpo])

f744fca0 80924ca9 81f936e0 00000103 81baaf20 nt!IopSynchronousServiceTail+0x180 (FPO: [Non-Fpo])

f744fd38 8082350b 00000024 00000000 00000000 nt!NtReadFile+0x5d5 (FPO: [Non-Fpo])

f744fd38 7c8285ec 00000024 00000000 00000000 nt!KiFastCallEntry+0xf8 (FPO: [0,0] TrapFrame @ f744fd64)

0012eed4 7c82776b 77e418b2 00000024 00000000 ntdll!KiFastSystemCallRet (FPO: [0,0,0])

0012eed8 77e418b2 00000024 00000000 00000000 ntdll!NtReadFile+0xc (FPO: [9,0,0])

0012ef40 004010ab 00000024 0012ef60 00001000 kernel32!ReadFile+0x16c (FPO: [Non-Fpo])

0012ff78 0040131f 00000001 00323038 00323078 client+0x10ab

0012ffc0 77e6f23b 00000000 00000000 7ffd8000 client+0x131f

0012fff0 00000000 00401376 00000000 78746341 kernel32!BaseProcessStart+0x23 (FPO: [Non-Fpo])


We have highlighted the first parameter to the ReadFile function. This parameter is the handle to the file we are trying to read.

Knowing this we can use the !handle extension to display details on this handle. The !handle extension takes three parameters: 1. The handle to get details on, 2: a flag controlling the level of verbosity the extension will display (f being the most verbose level), and 3: the process address.


kd> !handle 00000024 f 81b3a020

processor number 0, process 81b3a020

PROCESS 81b3a020  SessionId: 0  Cid: 06bc    Peb: 7ffd8000  ParentCid: 0f2c

    DirBase: 1d486000  ObjectTable: e252bbc8  HandleCount:  10.

    Image: client.exe

Handle table at e2845000 with 10 Entries in use

0024: Object: 81baaf20  GrantedAccess: 0012019f Entry: e2845048

Object: 81baaf20  Type: (823ceca0) File

    ObjectHeader: 81baaf08 (old version)

        HandleCount: 1  PointerCount: 3

        Directory Object: 00000000  Name: \mynamedpipe {NamedPipe}

We have highlighted the object address (yellow) and the type of the object (green) above. The object is of type file which is defined by the FILE_OBJECT structure. So we can examine that using the dt (Display Type) command. The dt command can take 3 parameters: 1. The structure you want to cast the data as, 2: the address of the object, and 3: the field in the structure to be displayed.


kd> dt nt!_FILE_OBJECT 81baaf20 FsContext2

   +0x010 FsContext2       : 0x81b5cc90


The FsContext2 field points to an NPFS CCB structure. The importance of this structure is that it is charged to the server process which created it. The !pool extension can be used to display information about the ownership of the memory the file object is stored in.


kd> !pool 0x81b5cc90  2

Pool page 81b5cc90 region is Nonpaged pool

*81b5cc88 size:   50 previous size:  140  (Allocated) *NpFc Process: 81be0d88

              Pooltag NpFc : CCB, client control block, Binary : npfs.sys

PROCESS 81be0d88  SessionId: 0  Cid: 07b4    Peb: 7ffd4000  ParentCid: 0160

    DirBase: 02b6f000  ObjectTable: e234a530  HandleCount:  10.

    Image: server.exe



Now you have the established the link from the client application and the server application. Now you will be able to move forward in your debugging and figure out why the server process isn’t writing data back to the client.


- Bryan

Leave a Comment
  • Please add 2 and 5 and type the answer here:
  • Post