Enumerate Windows objects

Share your advanced PureBasic knowledge/code with the community.
User avatar
Keya
Addict
Addict
Posts: 1890
Joined: Thu Jun 04, 2015 7:10 am

Enumerate Windows objects

Post by Keya »

hello i was interested to see how Sysinternals WinObj works, from what i could see it's mainly just calling NtOpenDirectoryObject and NtQueryDirectoryObject
this demo is for Unicode compile, 32bit Windows only as it still needs a couple tweaks to work under 64bit

Code: Select all

CompilerIf #PB_Compiler_Unicode = 0
  CompilerError "Unicode compile required for this demo"
CompilerEndIf

EnableExplicit

Structure LSA_UNICODE_STRING Align SizeOf(Word)
  Length.w
  MaximumLength.w
  Buffer.i
EndStructure

Structure LSA_STRING Align SizeOf(Word)
  Length.w
  MaximumLength.w
  Buffer.i
EndStructure

Structure LSA_OBJECT_ATTRIBUTES Align SizeOf(Long)
  Length.l
  RootDirectory.i
  *ObjectName.LSA_UNICODE_STRING
  Attributes.l
  SecurityDescriptor.l
  SecurityQualityOfService.l
EndStructure

Structure OBJECT_DIRECTORY_INFORMATION
  RealName.LSA_UNICODE_STRING
  TypeName.LSA_UNICODE_STRING
EndStructure

#DIRECTORY_QUERY = $0001
#DIRECTORY_TRAVERSE = $0002
#DIRECTORY_CREATE_OBJECT = $0004
#DIRECTORY_CREATE_SUBDIRECTORY = $0008
#DIRECTORY_ALL_ACCESS = #STANDARD_RIGHTS_REQUIRED | $F


Procedure EnumDirectoryObject(szObject.s)
  Define pObj.LSA_OBJECT_ATTRIBUTES, DesiredAccess.l, lRet.l, hDir.l, UniStr.LSA_UNICODE_STRING, Context.l, BytesReturned.l, arrObjSize.l, i.i
  PrintN("Enumerating " + szObject)
  DesiredAccess = #DIRECTORY_QUERY | #DIRECTORY_TRAVERSE
  UniStr\Length = (Len(szObject) * 2)
  UniStr\MaximumLength = (Len(szObject) * 2) + 2
  UniStr\Buffer = @szObject
  pObj\Length = SizeOf(LSA_OBJECT_ATTRIBUTES)
  pObj\Attributes = $40
  pObj\ObjectName = @UniStr  
  lRet = NtOpenDirectoryObject_(@hDir, DesiredAccess, @pObj)
  If lRet = 0 And hDir <> 0
    arrObjSize = 4096
    Dim arrObjDir.OBJECT_DIRECTORY_INFORMATION(arrObjSize)
    Repeat
      ReDim arrObjDir.OBJECT_DIRECTORY_INFORMATION(arrObjSize)
      lRet = NtQueryDirectoryObject_(hDir, @arrObjDir(0), arrObjSize * 8, 0, 1, @Context, @BytesReturned)
      If lRet < 0
        Break
      ElseIf lRet = 0
        Repeat
          If arrObjDir(i)\RealName\Buffer = 0 And arrObjDir(i)\TypeName\Buffer = 0: Break: EndIf
          PrintN(" [" + PeekS(arrObjDir(i)\TypeName\Buffer) + "] " + PeekS(arrObjDir(i)\RealName\Buffer) )
          i = i + 1
        ForEver
        Break
      Else 
        arrObjSize = arrObjSize + 4096
      EndIf
    ForEver
    NtClose_(hDir)
  Else
    PrintN("NtOpenDirectoryObject failed")
  EndIf
EndProcedure  


OpenConsole()
Define old.i
RtlAdjustPrivilege_ (20, 1, 0, @old)

EnumDirectoryObject ("\BaseNamedObjects\Restricted")
EnumDirectoryObject ("\ArcName")
EnumDirectoryObject ("\NLS")
EnumDirectoryObject ("\Driver")
EnumDirectoryObject ("\Device")
EnumDirectoryObject ("\Device\DmControl")
EnumDirectoryObject ("\Device\DmControl\RawDmVolumes")
EnumDirectoryObject ("\Device\HarddiskDmVolumes")
EnumDirectoryObject ("\Device\HarddiskDmVolumes\PhysicalDmVolumes")
EnumDirectoryObject ("\Device\Http")
EnumDirectoryObject ("\Device\Ide")
EnumDirectoryObject ("\Device\Harddisk0")
EnumDirectoryObject ("\Device\Harddisk1")
EnumDirectoryObject ("\Device\Harddisk2")
EnumDirectoryObject ("\Device\WinDfs")
EnumDirectoryObject ("\Windows")
EnumDirectoryObject ("\Windows\WindowStations")
EnumDirectoryObject ("\Sessions")
EnumDirectoryObject ("\Sessions\BNOLINKS")
EnumDirectoryObject ("\Sessions\0")
EnumDirectoryObject ("\Sessions\0\DosDevices")
EnumDirectoryObject ("\RPC Control")
EnumDirectoryObject ("\BaseNamedObjects")
EnumDirectoryObject ("\KernelObjects")
EnumDirectoryObject ("\FileSystem")
EnumDirectoryObject ("\FileSystem\Filters")
EnumDirectoryObject ("\GLOBAL??")
EnumDirectoryObject ("\ObjectTypes")
EnumDirectoryObject ("\Security")
EnumDirectoryObject ("\Callback")
EnumDirectoryObject ("\KnownDlls")

Input()
CloseConsole()
; IDE Options = PureBasic 5.41 LTS Beta 1 (Windows - x86)
; ExecutableFormat = Console
; EnableUnicode