7

I have seen NtQueryObject hang for duplicated handles with these granted access values (handle.GrantedAccess is an ACCESS_MASK type):

1179785 (integer) --> 0b100100000000010001001 (binary)
1180063 (integer) --> 0b100100000000110011111 (binary)
1180041 (integer) --> 0b100100000000110001001 (binary)
2032127 (integer) --> 0b111110000000111111111 (binary)
                             ||||||| |   |
                             ||||||| |   |
                             ||||||| |   |
                             ^^^^^^^ ^   ^
 Possible culprit bits seem to be 3rd and 7th bit, but could also be 9th to 15th bit.

Always, the handle.ObjectTypeNumber is 30. What is this object type number, and how can I get a list of the specific rights of this type? My experiments have kind of shown that it must be bits 0-15 causing the hang on this object type number of 30 (integer). handle is a SYSTEM_HANDLE type defined as:

typedef struct _SYSTEM_HANDLE
{
    ULONG ProcessId;
    BYTE ObjectTypeNumber;
    BYTE Flags;
    USHORT Handle;
    PVOID Object;
    ACCESS_MASK GrantedAccess;
} SYSTEM_HANDLE, *PSYSTEM_HANDLE;

I am writing a forensic tool to enumerate all open file handles using the method described here.

Alexandru
  • 12,264
  • 17
  • 113
  • 208
  • 1
    `NtQueryObject` for the `ObjectTypeInformation` (`OBJECT_TYPE_INFORMATION`), including the type name, generic mapping, and valid access mask. – Eryk Sun Nov 11 '14 at 17:08
  • 1
    @eryksun It didn't turn up much. For these handles, querying for `PUBLIC_OBJECT_TYPE_INFORMATION` returned TypeName = {Length=8 MaximumLength=10 Buffer=0x058bbdc0 "File" }, Reserved = 0x058bbd68. So they are just regular file handles. – Alexandru Nov 11 '14 at 21:27
  • 1
    @eryksun Now, how to get the Specific Rights for a File-type object in Windows? – Alexandru Nov 11 '14 at 21:35
  • 1
    `File` objects don't use use bits 9-15. Bit 3 is `FILE_READ_EA` and bit 7 is `FILE_READ_ATTRIBUTES`. See [File Access Rights Constants](http://msdn.microsoft.com/en-us/library/windows/desktop/gg258116%28v=vs.85%29.aspx). I don't see how this is related to a hanging system call. – Eryk Sun Nov 11 '14 at 21:42
  • 1
    http://msdn.microsoft.com/en-us/magazine/cc982153.aspx#id0100099 is the most I can find on this. 0x80 => 7th bit => reading attributes is allowed, probably can rule it out. 3rd bit is 0x4, Append. Can probably rule this one out too. Leaving...9th to 15th bits...which aren't mapped... – Alexandru Nov 11 '14 at 21:43
  • 1
    @eryksun Yeah, you're on the same page as I am but, it does hang; it's not just me that sees it happen (even the guys from the Sysinternals forum use some sort of filtering for handles that make it stop hanging). More proof (also check the question link, there is source code in that forum): http://stackoverflow.com/questions/3628919/list-all-open-files – Alexandru Nov 11 '14 at 21:47
  • 1
    @eryksun I might be filtering out too many handles in my code; the other Stack Overflow question says that people seem to say that "ObjectNameInformation will hang on handles that are synchronous pipes"...gotta do some more testing; will post back. – Alexandru Nov 11 '14 at 21:51
  • 1
    @eryksun Nope, link is wrong; its always a File for me. – Alexandru Nov 11 '14 at 22:05
  • 1
    @eryksun I think I ought to try using a threaded timeout type of approach here: http://forum.sysinternals.com/discussion-howto-enumerate-handles_topic19403_page2.html The other Stack link says this approach can cause some nasty problems though, but maybe if I just use a single thread for all my calls, it might not be so bad. – Alexandru Nov 11 '14 at 22:18
  • 1
    @eryksun Well, there is no good solution. However, there is a clever workaround to this using threading. You just need to pool one thread for the work involved and use two events to terminate the thread on failure, as described here: http://forum.sysinternals.com/discussion-howto-enumerate-handles_topic19403_page2.html Confirmed, this method works. – Alexandru Nov 12 '14 at 00:00
  • 1
    I see. The access mask is irrelevant. The file object is synchronous, so the thread waits to acquire the file lock. Chances are the file was opened by Win32 with `FILE_SYNCHRONOUS_IO_NONALERT`, so interrupting the wait isn't possible, which means you have to terminate the thread. – Eryk Sun Nov 12 '14 at 06:13
  • Thanks guys for this awesome disucssion, it really helped me figure out that I need to filter some handles out in order to not hang. I also only wanted "files" so the solution presented by Rick below worked for me. – Noitidart Oct 08 '16 at 00:05
  • @Noitidart Awesome, I'm absolutely stoked to hear that. That's exactly why I post these hair splitting questions and why I love this site! – Alexandru Oct 08 '16 at 00:14

1 Answers1

10

I'm a little late, but if you're only interested in disk-based files, you can do this:

if(GetFileType(handle) == FILE_TYPE_DISK) {
    ...
}

The hang generally happens for non-disk files (such as pipes). With this technique, you don't need to worry about handle.GrantedAccess at all.

ReflexiveCode
  • 256
  • 3
  • 7
  • Thanks, I suppose in my case I only needed it for disk files. I went a bit beyond though and made a library to enumerate all handles for all processes, which as you suggested I could make much faster by using this check for FILE_TYPE_DISK: https://www.dima.to/blog/?p=220 – Alexandru Mar 17 '16 at 18:40
  • 2
    A note, if you want to use `GetFileType` make sure you have duplicated the handle with proper permission first, otherwise it will give you file type of `0` which is `FILE_TYPE_UNKNOWN`. After I duplicated handle with `DUPLICATE_SAME_ACCESS` it gave me `FILE_TYPE_DISK`. – Noitidart Oct 07 '16 at 23:47
  • This test fixed this for me - http://stackoverflow.com/q/39910608/1828637 - its weird. Thanks for sharing Rick and thanks for asking @Alexandru – Noitidart Oct 08 '16 at 00:00