Windows process leaking handles

Process Handles and Identifiers

When a new process is created by the CreateProcess function, handles of the new process and its primary thread are returned. These handles are created with full access rights, and — subject to security access checking — can be used in any of the functions that accept thread or process handles. These handles can be inherited by child processes, depending on the inheritance flag specified when they are created. The handles are valid until closed, even after the process or thread they represent has been terminated.

The CreateProcess function also returns an identifier that uniquely identifies the process throughout the system. A process can use the GetCurrentProcessId function to get its own process identifier (also known as the process ID or PID). The identifier is valid from the time the process is created until the process has been terminated. A process can use the Process32First function to obtain the process identifier of its parent process.

If you have a process identifier, you can get the process handle by calling the OpenProcess function. OpenProcess enables you to specify the handle’s access rights and whether it can be inherited.

A process can use the GetCurrentProcess function to retrieve a pseudo handle to its own process object. This pseudo handle is valid only for the calling process; it cannot be inherited or duplicated for use by other processes. To get the real handle to the process, call the DuplicateHandle function.

Registry Handles Leaked

1 user registry handles leaked from \Registry\User\S-1-5-21-1202660629-651377827-839522115-500:

Process 1268 (\Device\HarddiskVolume2\Windows\System32\svchost.exe) has opened key \REGISTRY\USER\S-1-5-21-1202660629-651377827-839522115-500\Printers\DevModePerUser

Replies (4) 

Was this reply helpful?

Sorry this didn’t help.

Great! Thanks for your feedback.

How satisfied are you with this reply?

Thanks for your feedback, it helps us improve the site.

How satisfied are you with this reply?

Thanks for your feedback.

1 user registry handles leaked from \Registry\User\S-1-5-21-1202660629-651377827-839522115-500:

Process 1268 (\Device\HarddiskVolume2\Windows\System32\svchost.exe) has opened key \REGISTRY\USER\S-1-5-21-1202660629-651377827-839522115-500\Printers\DevModePerUser

5 user registry handles leaked from \Registry\User\S-1-5-21-3804598342-3278123506-2730381023-1000:
Process 1176 (\Device\HarddiskVolume2\Windows\System32\lsass.exe) has opened key \REGISTRY\USER\S-1-5-21-3804598342-3278123506-2730381023-1000
Process 1176 (\Device\HarddiskVolume2\Windows\System32\lsass.exe) has opened key \REGISTRY\USER\S-1-5-21-3804598342-3278123506-2730381023-1000

It occurs regularly and harddiskVolume2 is a usb card reader on my monitor which is disabled as I prefer not to use it..

I am the user (administrator) whose SID is shown.

The keys referred to are SystemCertificates\CA and SystemCertificates\disallowed

I have not modified the registry

1 person found this reply helpful

Was this reply helpful?

Sorry this didn’t help.

Great! Thanks for your feedback.

How satisfied are you with this reply?

Thanks for your feedback, it helps us improve the site.

How satisfied are you with this reply?

Thanks for your feedback.

I’m getting virtually the same error on shutdown:

event ID 1530
Windows detected your registry file is still in use by other applications or services. The file will be unloaded now. The applications or services that hold your registry file may not function properly afterwards.

DETAIL —
5 user registry handles leaked from \Registry\User\S-1-5-21-3726416164-3775131788-299159259-500:
Process 936 (\Device\HarddiskVolume2\Windows\System32\lsass.exe) has opened key \REGISTRY\USER\S-1-5-21-3726416164-3775131788-299159259-500
Process 936 (\Device\HarddiskVolume2\Windows\System32\lsass.exe) has opened key \REGISTRY\USER\S-1-5-21-3726416164-3775131788-299159259-500
Process 936 (\Device\HarddiskVolume2\Windows\System32\lsass.exe) has opened key \REGISTRY\USER\S-1-5-21-3726416164-3775131788-299159259-500\Software\Microsoft\SystemCertificates\My
Process 936 (\Device\HarddiskVolume2\Windows\System32\lsass.exe) has opened key \REGISTRY\USER\S-1-5-21-3726416164-3775131788-299159259-500\Software\Microsoft\SystemCertificates\CA
Process 936 (\Device\HarddiskVolume2\Windows\System32\lsass.exe) has opened key \REGISTRY\USER\S-1-5-21-3726416164-3775131788-299159259-500\Software\Microsoft\SystemCertificates\Disallowed

1 person found this reply helpful

Was this reply helpful?

Sorry this didn’t help.

Great! Thanks for your feedback.

How satisfied are you with this reply?

Thanks for your feedback, it helps us improve the site.

Windows process leaking handles

I feel like I’m in school; excellent address once again. 5

Sign In· View Thread

How to Avoid Deadlocks

Turion 28-Nov-09 14:16
Hi all,

I’ve run across this problem so much that I finally found the solution by myself. Nobody seems to know how Process Explorer and other programs avoid deadlocks on pipes, so I thought I’d share what I found out.

Yes, you can use the SYNCHRONIZE access mask and avoid anything that is synchronous, but that is way too broad. And no, using ObQueryNameString in a driver doesn’t change anything. The key is to use the pointer to the object (which you get along with the handle when you retrieve all the handles in the system) and see if ALL of these conditions are satisfied (I assume the pointer is named pObject):

1. *(SHORT*)pObject == 5
> In other words, is this a FILE_OBJECT, which means it can be a pipe? (I assume pObject is of type FILE_OBJECT in the next steps.)

2. CONTAINING_RECORD(pObject, OBJECT_HEADER, NameInfoOffset) == 0
> Gets the object’s header from the object, and sees if there’s no pre-determined name already given to the object (if there is, we won’t deadlock)
> You can find the definition of OBJECT_HEADER in ReactOS, but just as a note, the beginning of object’s header is (sizeof(LONG) + sizeof(PVOID) * 2 + 4 * sizeof(BYTE) + sizeof(PVOID) * 2) bytes behind beginning of the object.

3. (pObject->Flags & FO_SYNCHRONOUS_IO) == 0
> Is this file/pipe opened synchronously?

4. (pObject->Device != NULL) && ((pObject-Device->DeviceType != FILE_DEVICE_DISK) & (pObject-Device->DeviceType != FILE_DEVICE_DISK_FILE_SYSTEM))
> Is there a device behind the object (there should be) and is it something other than a disk or disk file system (they don’t deadlock)?

If TRUE for ALL of these, then deadlock is possible. The solution? Get the object name for the pObject’s device (ObQueryNameString(pObject-Device)) and concatenate it to the object’s file name (pObject->FileName, a UNICODE_STRING value). This last step uses ObQueryNameString, a kernel-mode function; however, if pObject-Device->DeviceType == FILE_DEVICE_NAMED_PIPE, then you can assume it’s \Device\NamedPipe.

How do you actually access the kernel-mode memory to do all this without a driver? NtSystemDebugControl and SysDbgReadVirtual are your friends! (Google them.)

Hope this helps!

Sign In· View Thread
Re: How to Avoid Deadlocks

TheRaven 18-Sep-11 17:39

Sign In· View Thread
Handle.exe

Baroon 1-Sep-08 7:35
Hi Toby, So Many thanks for this article. I have a question about handle.exe’s output. When I use handle -a, it shows all open handles include objects with no name! Would you please tell me what are these objects? There are some Files, Sections, Ports, Mutants, Events and Semaphores that don’t have any name.

Thank you in advance.

Sign In· View Thread
ntCreateFile Handles

Kharfax 22-Jun-06 3:09
Hi mate, first of all, thanks for writing great articles

I’m working in a windows hook, and I need to get a copy of the handles generated by zwCreateFile
I was geting the pointer of the stack, calling the real service, and then copying the value pointed by the PHANDLE I got before.
And in your article I see you are getting the handle from EAX, wich is a LOTTTT simpler than what I’m doing.

So the question is, where did you get that info? It would be really helpfull to me.

Thanks a lot mate

Sign In· View Thread
Re: ntCreateFile Handles

Toby Opferman 22-Jun-06 6:58

The return value from a function is put into EAX/RAX and so the user mode API «CreateFile» will return you the handle in EAX. However, «ZwCreateFile» I believe returns a status code and requires you pass a pointer to recieve the handle as a parameter to the API. So, what you are doing is what you would need to do for that API.

The article in any case does not actually display the location of where it currently is when I dump the handle, so I could be anywhere executing that has just put the handle value into EAX actually. I wrote this article a few years ago, but most likely I was at the return from CreateFile when I copied that text.

8bc7c0ec02c0e404c0cc0680f7018827ebee

Sign In· View Thread
Re: ntCreateFile Handles

Kharfax 22-Jun-06 7:33

damn :S
Thanks a lot for the explanation, and yes, zwCreateFile first parameter is a pointer to the handle.
So, I think the suffering continues

Sign In· View Thread
!process

mtavis 26-May-05 5:00
When I attempt to use !process in WinDbg it complains that no export was found. !handle works fine though. Is there some sort of extension I need to install?

P.S. Great series of articles

Sign In· View Thread
Re: !process

Toby Opferman 27-May-05 20:02

Thanks for the complement. In order to use !process you must be kernel debugging, this will not work with debugging a user mode process. It should be loaded by default when kernel debugging though.

8bc7c0ec02c0e404c0cc0680f7018827ebee

Sign In· View Thread
NtQueryObject and Sync question

Neil 14-Feb-05 3:04

Neil

14-Feb-05 3:04
Thank you, first of all. Excellent article. As somebody thrust into C++ at the moment, it is extremely helpful.

The article mentions deadlocking NTQueryObject calls, and mentions avoiding this by use of checking masks.

I am encountering exactly this symptom on an in-house written application I am trying to wade through, but have been able to suss out more information on it. By mask, I assume we’re talking about the SystemHandleInfo->HandleInfo.AccessMask property (this code is using a duplicated handle to look for things).

Could anybody point me to further information on checking for SYNC access, or the use of masks to avoid this deadlock?

P.S. Although I am not (yet) an experienced C++ programmer, I have a good bit of experience with APIs and programming in general — it doesn’t have to be a totally newbie source.

Neil

Sign In· View Thread
Re: NtQueryObject and Sync question

Toby Opferman 14-Feb-05 9:53

The code I wrote is in assembly. I think I have some C code somewhere else but not with me here.

The code I used in quick view to attempt to avoid deadlock:

@HandView_NoPortInfo:
LEA EAX, [dwTempLong]
PUSH EAX
PUSH 512
PUSH EBX ; Unicode String is appened to the END of the structure.
PUSH ObjectTypeInformation
PUSH [hObject]
CALL [ZwQueryObject]

CMP EAX, 0
JL @HandView_SkipWithCloseAndCloseObject

CMP DWORD PTR [EBX + 4] , 0
JZ @HandView_SkipWithCloseAndCloseObject

MOV EAX, [EBX + 4]
PUSH EAX
PUSH 2
PUSH [dwCount]
PUSH [hWnd]
CALL ListView_SetItemTextW

MOV WORD PTR [EBX], 500
MOV WORD PTR [EBX + 2], 500
LEA EAX, [EBX + 8]
MOV [EBX + 4], EAX

MOV EAX, [pModInfo]

MOV EAX, [pModInfo]

TEST DWORD PTR [EAX + 12], SYNCHRONIZE_ACCESS ; *SOME* Sync Objects can cause deadlock! Unfortunately, this is the only way to
JZ @HandView_Good ; tell right now, excluding all sync objects.

CMP DWORD PTR [EAX + 12], 01f01ffh ; This seems to be OK access.
JNE @HandView_SkipWithCloseAndCloseObject

; TODO: See if you can remove Sync Access or another way to get the
; object name from user-mode without having to acquire the lock.
; could be bad though and bluescreen? Also, irrelevant if I
; change this to use a driver. The driver would be able to
; directly read the object’s memory location in the kernel
; and read the name directly from there without the need to lock.

LEA EAX, [dwTempLong]
MOV DWORD PTR [EAX], 0
PUSH EAX
PUSH 500
PUSH EBX ; Unicode String is appened to the END of the UNICODE_STRING structure.
PUSH ObjectNameInformation
PUSH [hObject]
CALL [ZwQueryObject]

; TODO: Try ZwQueryInformationFile with «name».

; Sysinternals uses their own driver to do this and does not deadlock.
; If we aren’t getting all the information, I may need to write a driver.
; TODO: Write a driver for this application, we need one anyway for
; a force bluescreen option when Ctrl ScrollLock ScrollLock is not set.

CMP EAX, 0
JL @HandView_SkipWithCloseAndCloseObject

TEST EAX, EAX
JZ @HandView_SkipWithCloseAndCloseObject

PUSH EAX
PUSH 1
PUSH [dwCount]
PUSH [hWnd]
CALL ListView_SetItemTextW

MOV EAX, [pModInfo]

TEST BYTE PTR [EAX + 5], 1 ; We need to fix this in order to close the handle.
JZ @HandView_CloseIt

PUSH 0
PUSH 0FFFFFFFEh
PUSH [hObject]
CALL SetHandleInformation ; Clear the «protect from close» bit so we can close the handle.

@HandView_CloseIt:
PUSH [hObject]
CALL CloseHandle

@HandView_SkipWithClose:
@HandView_SkipHandleInfo:
ADD ESP, 512
POP EBX
LEA EAX, [dwShortToLong]

Sign In· View Thread
Re: NtQueryObject and Sync question

Toby Opferman 14-Feb-05 10:31

The definition of:

SYNCHRONIZE_ACCESS EQU 0100000h

This is actually the granted access mask of the handle.
Excerpt from CDB. Notice «Synch» and the bits set.

0:000> !handle 0 ff
Handle c
Type File
Attributes 0
GrantedAccess 0x100020:
Synch
Execute/Traverse
HandleCount 3
PointerCount 4
No Object Specific Information available
Handle 7ec
Type Port
Attributes 0
GrantedAccess 0x1f0001:
Delete,ReadControl,WriteDac,WriteOwner,Synch
Connect
HandleCount 2
PointerCount 4
Name
No Object Specific Information available

Sign In· View Thread
Re: NtQueryObject and Sync question

Anonymous 15-Feb-05 2:25

Thank you very much =]

This will take some muddling through and processing, but it looks like exactly what I need. I’m sure I’ll be back to thank you again

Neil

Sign In· View Thread
Re: NtQueryObject and Sync question

Neil 16-Feb-05 10:07

Neil

16-Feb-05 10:07

Thanks. That worked just fine. (And I learned a *lot* more about C ). Interesting thing is that most of the system had SYNCHRONIZE_ACCESS set, and the app wouldn’t hang at the same location (or on the same object type/access mask). It works well with a very restricted mask (like you used, except h160001).

I’m mostly just thrilled that I can still follow the assembly code, after all these years

Neil

Sign In· View Thread
Re: NtQueryObject and Sync question

Neil 3-Mar-05 6:45

Neil

3-Mar-05 6:45

I received an anonymous request for details on how I got around this in C (CodeProject doesn’t necessarily include your email if you mail thorugh the forums).

Here is the boiled-down code that I used. Please don’t accept this as a good example of code — it’s kludged together from various sources, and probably not well. It does almost exactly what

If it doesn’t copy-and-paste, I apologize. My system at work and codeproject can’t seem to get together . . .

Sign In· View Thread
Re: NtQueryObject and Sync question

Neil 3-Mar-05 7:00

Neil

3-Mar-05 7:00

Please note, this is almost exactly the same as what Toby does (all credit to him, code errors are my fault) with the exception of the actual value; Toby’s code assumes it won’t block if the AccessMask does not have h100000 set or if it equals h01f01ff. In my case, everything I was looking for *did* have the bit set, and objects with a mask of h160001 locked up (other object masks did, too, but inconsistently, and this fixed it for my specific circumstances).

Toby’s version would be more along these lines (except better-written):
if (!(pSystemHandleInfo->HandleInfo[i].AccessMask && 0x100000) || (pSystemHandleInfo->HandleInfo[i].AccessMask == 0x01f01ff))

Chances are that you will have to figure out what mask you need independantly — mine isn’t as safe as Toby’s, it’s just all that worked.

The code included is from where I got it to work — the printfs showed me the masks on the fly, and I ran it a number of times, until I could figure out which masks I needed or didn’t need.

Neil

Sign In· View Thread
Re: NtQueryObject and Sync question

Rajkumar-Kannan 4-Mar-05 4:23

Hi,
Thank you very much for taking the time out for replying. I have found some combination of access masks that are specific to my environment and seem to work well.

Thanks again!
Raj.

Sign In· View Thread
oh.exe — tool for tracking handle leaks

mattiash 27-May-04 10:50
Great article.

In addition I’d like to recommend OH.EXE, which is a handy and free tool from Microsoft really useful for tracking down handle leaks. Basically you let the OS keep track of callstacks when handles are opened and closed. Then you can take snapshots and compare, so you see the allocated handles that haven’t been closed so you can identify leaks.

Sign In· View Thread
!htrace Pavel Lebedinsky 12-May-04 21:32
!htrace is a very useful command for debugging handle leaks because it gives you the stack traces of recent operations on a handle.

To use it you need to enable handle checks in the appverifer first:

c:\debuggers> gflags -v image /enable notepad.exe HANDLE_CHECKS
c:\debuggers> cdb notepad

0:004> !htrace 4dc
—————————————
Handle = 0x000004DC — OPEN
Thread Process/>
0x77D06D25: ntdll!RtlpInitializeTimerThreadPool+0x0000009E
0x77D06DFD: ntdll!RtlpInitializeWorkerThreadPool+0x0000001C
0x77D082FB: ntdll!RtlQueueWorkItem+0x00000055
0x77E6EC01: kernel32!QueueUserWorkItem+0x00000014
0x772DB369: SHLWAPI!SHQueueUserWorkItem+0x00000076
0x75F845C2: +0x000045C2
0x763B48C3: comdlg32!AutoComplete+0x0000008C
0x763BD372: comdlg32!InitLocation+0x00000520
0x763B3D70: comdlg32!OpenDlgProc+0x000003AF
0x77D8857A: USER32!InternalCallWinProc+0x00000028
0x77D96422: USER32!UserCallDlgProcCheckWow+0x000000F0

Sign In· View Thread
Re: !htrace

Toby Opferman 13-May-04 3:30

Yea, I remember seeing that in the help a while back and getting excited.

One thing to note though is that it’s for Windows 2003/XP only. As I stated above, there’s a lot of new cool features in 2003/XP that aren’t in 2000

Sign In· View Thread
Last Visit: 31-Dec-99 18:00 Last Update: 18-Apr-21 1:59 Refresh 1

General News Suggestion Question Bug Answer Joke Praise Rant Admin

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Читайте также:  Посмотреть последние логины linux
Оцените статью