Who opened that file?
Sometimes certain files are opened but not closed when not needed and this prevents other applications and users from using, deleting or replacing them. Sometimes on behalf of certain API calls another process opens them. One of the questions I was asked recently is how to find that process. The answer that I found is very simple: just list all handles from all processes and search for that file name there. This works in kernel and complete memory dumps and also in live kernel debugging session including its local kernel debugging variant. The following WinDbg command lists all objects (we need to open a log because the output is usually of several megabytes):
3: kd> !for_each_process "!handle 0 3 @#Process"
!handle 0 3 @#Process
processor number 3, process 8a392818
PROCESS 8a392818 SessionId: none Cid: 0004 Peb: 00000000 ParentCid: 0000
DirBase: bfc51000 ObjectTable: e1001e00 HandleCount: 2650.
Image: System
Handle table at e16a3000 with 2650 Entries in use
0004: Object: 8a392818 GrantedAccess: 001f0fff Entry: e1004008
Object: 8a392818 Type: (8a392e70) Process
ObjectHeader: 8a392800 (old version)
HandleCount: 3 PointerCount: 235
0008: Object: 8a391db0 GrantedAccess: 00000000 Entry: e1004010
Object: 8a391db0 Type: (8a392ca0) Thread
ObjectHeader: 8a391d98 (old version)
HandleCount: 1 PointerCount: 1
000c: Object: e101bca0 GrantedAccess: 00000000 Entry: e1004018
Object: e101bca0 Type: (8a37db00) Key
ObjectHeader: e101bc88 (old version)
HandleCount: 1 PointerCount: 3
Directory Object: 00000000 Name: \REGISTRY
[...]
1fac: Object: 88ec72b0 GrantedAccess: 00000003 (Protected) Entry: e1ed7f58
Object: 88ec72b0 Type: (8a36f900) File
ObjectHeader: 88ec7298 (old version)
HandleCount: 1 PointerCount: 2
Directory Object: 00000000 Name: \Documents and Settings\MyUserName\NTUSER.DAT {HarddiskVolume1}
[...]
07fc: Object: e1000768 GrantedAccess: 00000003 Entry: e2fefff8
Object: e1000768 Type: (8a387e70) KeyedEvent
ObjectHeader: e1000750 (old version)
HandleCount: 273 PointerCount: 274
Directory Object: e1001a48 Name: CritSecOutOfMemoryEvent
processor number 3, process 8873f3b8
PROCESS 8873f3b8 SessionId: 6 Cid: 4c1c Peb: 7ffdf000 ParentCid: 42bc
DirBase: 49dbb000 ObjectTable: e325f788 HandleCount: 90.
Image: PROFLWIZ.EXE
Handle table at e36c3000 with 90 Entries in use
0004: Object: e1000768 GrantedAccess: 00000003 Entry: e36c3008
Object: e1000768 Type: (8a387e70) KeyedEvent
ObjectHeader: e1000750 (old version)
HandleCount: 273 PointerCount: 274
Directory Object: e1001a48 Name: CritSecOutOfMemoryEvent
[...]
- Dmitry Vostokov @ DumpAnalysis.org -
July 14th, 2008 at 12:03 pm
I usually use ProcExp’s find handle command, but this seems to be great addition to the toolbox.
Thanks Dima
August 18th, 2009 at 2:04 pm
I found another technique via !devhandles WinDbg command, searching for open files (Windows Internals, 5th edition, p. 155)
August 18th, 2009 at 2:09 pm
[…] !devhandles WinDbg command, searching for open files (p. 155) - it looks like it is done through device prefix to a file name; I’ve done simple text search for a file name if known through all handle tables: http://www.dumpanalysis.org/blog/index.php/2008/05/30/who-opened-that-file/ […]