A forum for reverse engineering, OS internals and malware analysis 

Forum for discussion about kernel-mode development.
 #20656  by takep
 Fri Aug 30, 2013 10:29 pm
Hello

The aim I want to reach - is to close all handles to my process. I use NtQuerySystemInformation with SystemExtendedHandleInformation class. It returns a bunch of structures of type "SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX". Here they are:
Code: Select all
typedef struct _SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX
{
    PVOID Object;
    HANDLE UniqueProcessId;
    HANDLE HandleValue;
    ULONG GrantedAccess;
    USHORT CreatorBackTraceIndex;
    USHORT ObjectTypeIndex;
    ULONG HandleAttributes;
    ULONG Reserved;
} SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX, *PSYSTEM_HANDLE_TABLE_ENTRY_INFO_EX;
there is a member "ObjectTypeIndex". Since I'm closing handles to my process, I need to search for handles of type "Process". ObjectTypeIndex is exactly whan I need to check, but its values differ from windows to windows. How can I obtain its value in the right way without using NtQueryObject every time?

OR are there even better solutions to close all handles to my process?

Thanks in advance for your answers!
 #20658  by EP_X0FF
 Sat Aug 31, 2013 12:33 am
Open handle for your process, remember handle value, query it through enum. As you know exactly it value you can filter by it and obtain right "Process" object index from structure. Same for threads etc.
 #20671  by takep
 Sun Sep 01, 2013 9:08 pm
Thanks, if this is only solution I'll do it that way.
 #20728  by EP_X0FF
 Thu Sep 05, 2013 3:48 pm
There are no other documented workarounds AFAIK for user mode. All the rest - hardcoding.
 #20742  by Vrtule
 Sat Sep 07, 2013 11:20 pm
Hello,

you can also try enumerating all object types via NtQueryObject (information class 3 – ObjectTypesInformation). The routine returns an array of OBJECT_TYPE_INFORMATION structures.

I think the ObjectTypeIndex is related to the order in which object types are created (the first object type has index 0, the second one 1 etc.). The ObjectTypeIndex value should be reflected by position of the correspinding OBJECT_TYPE structure in the object type array returned by NtQueryObject. For example, if the Process object type is listed as the seventh in the type array, its (zero-based) ObjectTypeIndex is 6.

However, I tested this idea long ago and I am not clearly suer of the result. And my approach would be probably slower than one EP_X0FF suggested. I mainly post this information hoping someone finds it interesting.

And here are some definitions in the end.
Code: Select all
typedef struct _OBJECT_TYPE_INFORMATION {
    UNICODE_STRING TypeName;
    ULONG TotalNumberOfObjects;
    ULONG TotalNumberOfHandles;
    ULONG TotalPagedPoolUsage;
    ULONG TotalNonPagedPoolUsage;
    ULONG TotalNamePoolUsage;
    ULONG TotalHandleTableUsage;
    ULONG HighWaterNumberOfObjects;
    ULONG HighWaterNumberOfHandles;
    ULONG HighWaterPagedPoolUsage;
    ULONG HighWaterNonPagedPoolUsage;
    ULONG HighWaterNamePoolUsage;
    ULONG HighWaterHandleTableUsage;
    ULONG InvalidAttributes;
    GENERIC_MAPPING GenericMapping;
    ULONG ValidAccessMask;
    BOOLEAN SecurityRequired;
    BOOLEAN MaintainHandleCount;
    ULONG PoolType;
    ULONG DefaultPagedPoolCharge;
    ULONG DefaultNonPagedPoolCharge;
} OBJECT_TYPE_INFORMATION, *POBJECT_TYPE_INFORMATION;

typedef struct _OBJECT_TYPES_INFORMATION {
    ULONG NumberOfTypes;
    // The array of OBJECT_TYPE_INFORMATION structures
} OBJECT_TYPES_INFORMATION, *POBJECT_TYPES_INFORMATION;
 #20744  by nullptr
 Sat Sep 07, 2013 11:51 pm
I think the ObjectTypeIndex is related to the order in which object types are created (the first object type has index 0, the second one 1 etc.). The ObjectTypeIndex value should be reflected by position of the correspinding OBJECT_TYPE structure in the object type array returned by NtQueryObject. For example, if the Process object type is listed as the seventh in the type array, its (zero-based) ObjectTypeIndex is 6.
This method seemingly held true for XP, though it doesn't work on Win 7 (I assume Vista also).
 #20745  by Brock
 Sun Sep 08, 2013 10:38 am
EP is 100% right. It's the most obvious solution and pure common sense. Let's say for example, you want to determine the ObjectTypeIndex of some object handle, logic says open this object, save the handle and then compare it "locally" through enumerating the handles in your current process via the handle table, if they match then simply return the ObjectTypeIndex value in which you are seeking. I've done this for years and it works fine, no need to enumerate ALL object type indexes and object type names, that's excessive. Not all object types are "named" IIRC so matching handles is a definite way to get the correct ObjectTypeIndex
 #20747  by Vrtule
 Sun Sep 08, 2013 10:50 am
Brock wrote:EP is 100% right. It's the most obvious solution and pure common sense. Let's say for example, you want to determine the ObjectTypeIndex of some object handle, logic says open this object, save the handle and then compare it "locally" through enumerating the handles in your current process via the handle table, if they match then simply return the ObjectTypeIndex value in which you are seeking. I've done this for years and it works fine, no need to enumerate ALL object type indexes and object type names, that's excessive
I know it is a quite expensive approach. I wrote in my previous post that I presented the "solution" mostly because someone ,may find interesting that NtQueryObject can also be used to enumerate all object types. EP's solution is OK and I would prefer it when running in problem of ObjectTypeIndex identification.

@nullptr: thank you for the information about ObjectTypeIndex relationship on Vista+.
 #20751  by EP_X0FF
 Mon Sep 09, 2013 1:39 am
Well NtQueryObject with ObjectAllTypesInformation is working too, however it has one specialty and I never used it. Index of object will be exact as they are defined in OBJECT_HEADER for WinXP (out-dated system that should not be considered as platform anymore) and will be Index + 1 for more modern systems like win7.

E.g.

Win7, thread type
img1.png
win7 NtQueryObject
img1.png (8.22 KiB) Viewed 429 times
Code: Select all
lkd> dq PsThreadType l1
fffff800`032ff050  fffffa80`06cf3080
lkd> dt nt!_OBJECT_TYPE fffffa8006cf3080
   +0x000 TypeList         : _LIST_ENTRY [ 0xfffffa80`06cf3080 - 0xfffffa80`06cf3080 ]
   +0x010 Name             : _UNICODE_STRING "Thread"
   +0x020 DefaultObject    : (null) 
   +0x028 Index            : 0x8 ''
   +0x02c TotalNumberOfObjects : 0x42b
   +0x030 TotalNumberOfHandles : 0x792
   +0x034 HighWaterNumberOfObjects : 0x4ca
   +0x038 HighWaterNumberOfHandles : 0x8fa
   +0x040 TypeInfo         : _OBJECT_TYPE_INITIALIZER
   +0x0b0 TypeLock         : _EX_PUSH_LOCK
   +0x0b8 Key              : 0x65726854
   +0x0c0 CallbackList     : _LIST_ENTRY [ 0xfffffa80`06cf3140 - 0xfffffa80`06cf3140 ]
And take a look at object header of some Process object.
Code: Select all
lkd> !object fffffa8006cf3840
Object: fffffa8006cf3840  Type: (fffffa8006c91800) Process
    ObjectHeader: fffffa8006cf3810 (new version)
    HandleCount: 4  PointerCount: 194
lkd> dt nt!_OBJECT_HEADER fffffa8006cf3810
   +0x000 PointerCount     : 0n194
   +0x008 HandleCount      : 0n4
   +0x008 NextToFree       : 0x00000000`00000004 Void
   +0x010 Lock             : _EX_PUSH_LOCK
   +0x018 TypeIndex        : 0x7 ''
   +0x019 TraceFlags       : 0 ''
   +0x01a InfoMask         : 0 ''
   +0x01b Flags            : 0x2 ''
   +0x020 ObjectCreateInfo : 0xfffff800`03255940 _OBJECT_CREATE_INFORMATION
   +0x020 QuotaBlockCharged : 0xfffff800`03255940 Void
   +0x028 SecurityDescriptor : 0xfffff8a0`000046d1 Void
   +0x030 Body             : _QUAD
Same with TypeIndex. Due to new version of Object Manager in Win7 which introduced new OBJECT_HEADER structure the same field "TypeIndex" is absent on more old Windows versions.

winXP, thread type
img2.png
winxp NtQueryObject
img2.png (8.11 KiB) Viewed 429 times
Code: Select all
lkd> dd PsThreadType l1
8056145c  81fc8e70
lkd> dt nt!_OBJECT_TYPE 81fc8e70
   +0x000 Mutex            : _ERESOURCE
   +0x038 TypeList         : _LIST_ENTRY [ 0x81fc8ea8 - 0x81fc8ea8 ]
   +0x040 Name             : _UNICODE_STRING "Thread"
   +0x048 DefaultObject    : (null) 
   +0x04c Index            : 6
   +0x050 TotalNumberOfObjects : 0x127
   +0x054 TotalNumberOfHandles : 0x1f8
   +0x058 HighWaterNumberOfObjects : 0x178
   +0x05c HighWaterNumberOfHandles : 0x290
   +0x060 TypeInfo         : _OBJECT_TYPE_INITIALIZER
   +0x0ac Key              : 0x65726854
   +0x0b0 ObjectLocks      : [4] _ERESOURCE
doesn't digged in to find out why it is happening as it was not needed. However if you are interested you can start from ObCreateObjectType as all magic should be there.