Jump to content

Recommended Posts

  • 2 years later...
Posted
On 9/6/2015 at 6:56 PM, Danyfirex said:

it took me more about 1200000 milisegundos :'(

;Danyfirex 06/09/2015
#include <Array.au3>
#include <WinAPI.au3>
Opt("MustDeclareVars", 1)


Global Const $DIRECTORY_QUERY = 0x0001
Global Const $DIRECTORY_TRAVERSE = 0x0002
Global Const $sTagUNICODESTRING = "USHORT Length;USHORT MaximumLength;PTR Buffer;"
Global Const $sTagOBJECT_ATTRIBUTES = "ULONG Length;HANDLE RootDirectory;PTR ObjectName;ULONG Attributes;PTR SecurityDescriptor;PTR SecurityQualityOfService"

Local $aSubObject = 0
Local $aObjects = _GetObjects()
_ArrayDisplay($aObjects, "\", Default, Default, Default, "Name|Type|SymLink")

If IsArray($aObjects) Then
    For $i = 0 To UBound($aObjects) - 1
        If $aObjects[$i][1] = "Directory" Then
            $aSubObject = _GetObjects($aObjects[$i][0])
            If IsArray($aSubObject) Then
                _ArrayDisplay($aSubObject, $aObjects[$i][0], Default, Default, Default, "Name|Type|SymLink")
            EndIf
        EndIf
    Next

EndIf


Func _GetObjects($sSource = "\")
    If $sSource <> "\" Then $sSource = "\" & $sSource
    Local $tNameSource = _tName($sSource)
    Local $tUnicodeString = _RtlInitUnicodeString($tNameSource)
    Local $pUnicodeString = DllStructGetPtr($tUnicodeString)

    Local $tObject_Attributes = _InitializeObjectAttributes($pUnicodeString)
    Local $pObject_Attributes = DllStructGetPtr($tObject_Attributes)

    Local $hDirectory = _NtOpenDirectoryObject($pObject_Attributes, BitOR($DIRECTORY_TRAVERSE, $DIRECTORY_QUERY))


    Local $tData = 0
    Local $tName = 0
    Local $tType = 0
    Local $index = 0
    Local $bytes = 0
    Local $tBuffer = 0
    Local $aArcName[0]
    Local $taName = 0
    Local $tStr = 0
    Local $tAttr = 0
    Local $hLink = 0
    Local $taTarget = 0
    Local $tTarget = 0
    Local $tSTarget = 0
    $tBuffer = DllStructCreate("byte Data[32767]")

    Local $aRet = DllCall("Ntdll.dll", "LONG", "NtQueryDirectoryObject", "HANDLE", $hDirectory, "ptr", DllStructGetPtr($tBuffer), "ULONG", 32767, "BOOL", False, "BOOL", True, "ULONG*", 0, "ULONG*", 0)

    If @error Or $aRet[0] < 0 Then Return

    $index = $aRet[6]
    $bytes = $aRet[7]

    ConsoleWrite("!index: " & $index & " $bytes: " & $bytes & @CRLF)

    For $i = 0 To $index - 1
        $tData = DllStructCreate($sTagUNICODESTRING & $sTagUNICODESTRING, DllStructGetPtr($tBuffer) + ($i * 16))
        $tName = DllStructCreate("wchar wNameString[" & DllStructGetData($tData, 1) & "]", DllStructGetData($tData, 3))
        $tType = DllStructCreate("wChar wTypeString[" & DllStructGetData($tData, 4) & "]", DllStructGetData($tData, 6))
        $taName = _tName($tName.wNameString)
        $tStr = _RtlInitUnicodeString($taName)
        $tAttr = _InitializeObjectAttributes(DllStructGetPtr($tStr), 0, $hDirectory)
        $hLink = _NtOpenSymbolicLinkObject(DllStructGetPtr($tAttr), $GENERIC_READ)
        ConsoleWrite("+$hLink: " & $hLink & @CRLF)
        $taTarget = _tName("")
        $tTarget = _RtlInitUnicodeString($taTarget)
        $tTarget.MaximumLength = 512
        _NtQuerySymbolicLinkObject($hLink, $tTarget)
        $tSTarget = DllStructCreate("wchar wString[" & DllStructGetData($tTarget, 1) & "]", DllStructGetData($tTarget, 3))
        ReDim $aArcName[UBound($aArcName) + 1][3]
        $aArcName[UBound($aArcName) - 1][0] = $tName.wNameString
        $aArcName[UBound($aArcName) - 1][1] = $tType.wTypeString
        $aArcName[UBound($aArcName) - 1][2] = (IsDllStruct($tSTarget) = 1) ? $tSTarget.wString : ""
;~  ConsoleWrite(">" & $i + 1 & @TAB & $tName.wNameString & @TAB & $tType.wTypeString & @TAB & $tSTarget.wString & @CRLF)
        $tType = 0
        $tName = 0
        $tData = 0
        $tSTarget = 0
        _WinAPI_CloseHandle($hLink)
    Next

    Return $aArcName

EndFunc   ;==>_GetObjects


Func _RtlInitUnicodeString($tSourceString)
    Local $tUnicodeString = DllStructCreate($sTagUNICODESTRING)
    DllCall("Ntdll.dll", "NONE", "RtlInitUnicodeString", "struct*", $tUnicodeString, "struct*", $tSourceString)
    If @error Then SetError(@error, 0, 0)
    Return $tUnicodeString
EndFunc   ;==>_RtlInitUnicodeString

Func _tName($String)
    Local $t = DllStructCreate("wchar String[512]")
    DllStructSetData($t, 1, $String)
    Return $t
EndFunc   ;==>_tName


Func _InitializeObjectAttributes($pObjectName, $ulAttributes = 0, $hRootDirectory = Null, $pSecurityDescriptor = Null)
    Local $tObject_Attributes = DllStructCreate($sTagOBJECT_ATTRIBUTES)
    DllStructSetData($tObject_Attributes, 1, DllStructGetSize($tObject_Attributes))
    DllStructSetData($tObject_Attributes, 2, $hRootDirectory)
    DllStructSetData($tObject_Attributes, 3, $pObjectName)
    Return $tObject_Attributes
EndFunc   ;==>_InitializeObjectAttributes


Func _NtQuerySymbolicLinkObject($hLinkHandle, $tLinkTarget)
    Local $aRet = DllCall("Ntdll.dll", "LONG", "NtQuerySymbolicLinkObject", "HANDLE", $hLinkHandle, "struct*", $tLinkTarget, "ULONG*", 0)
    If @error Then SetError(@error, 0, 0)
    If $aRet[0] <> 0 Then SetError(1, 0, 0)
EndFunc   ;==>_NtQuerySymbolicLinkObject

Func _NtOpenDirectoryObject($pObjectAttr, $AccessMask)
    Local $aRet = DllCall("Ntdll.dll", "LONG", "NtOpenDirectoryObject", "HANDLE*", 0, "ULONG", $AccessMask, "PTR", $pObjectAttr)
    If @error Then SetError(@error, 0, 0)
    If $aRet[0] < 0 Or $aRet[1] = 0 Then SetError(1, 0, 0)
    Return $aRet[1]

EndFunc   ;==>_NtOpenDirectoryObject

;~ Retur hLink
Func _NtOpenSymbolicLinkObject($pObjectAttr, $AccessMask)
    Local $aRet = DllCall("Ntdll.dll", "LONG", "NtOpenSymbolicLinkObject", "HANDLE*", 0, "ULONG", $AccessMask, "PTR", $pObjectAttr)
    If @error Then Return SetError(@error, 0, 0)
    If $aRet[0] < 0 Or $aRet[1] = 0 Then Return SetError(1, 0, 0)
    Return $aRet[1]
EndFunc   ;==>_NtOpenSymbolicLinkObject

Saludos

For some reason I cannot get the local drives under \GLOBAL??\X: or C: under WinPE
 

What is what? What is what.

Posted
Just now, Danyfirex said:

Google It.

 

Saludos

Have been, and still looking, tried setting same tokens as WinOBJ, tried setting GENERIC_ALL to  _NtOpenSymbolicLinkObject and BitOR($STANDARD_RIGHTS_REQUIRED,0xF) for _NtOpenDirectoryObject and no luck yet

What is what? What is what.

Posted

It does not make sence to me. long time has passed since I did this. maybe I'll check later. 

 

Saludos

Posted

Yep, and im currently tracing API calls to try to reverse it. WinOBJ seems to be calling the initial NtOpenDirectoryObject with a handle, but can't see where it's getting that handle. And NtQueryDirectory obj is making use of RestartScan=TRUE, and context. Now, on the first Query, Context resolves to 51, then RestartScan is set false in next call and Context is set to 1 then increments with each call

What is what? What is what.

Posted
On 8/15/2015 at 9:03 PM, Danyfirex said:

A wrote a simple AutoIt example based on this. http://blogs.microsoft.co.il/pavely/2014/02/05/creating-a-winobj-like-tool/

 

#include <Array.au3>

Opt("MustDeclareVars", 1)


Global Const $DIRECTORY_QUERY = 0x0001
Global Const $DIRECTORY_TRAVERSE = 0x0002
Global Const $sTagUNICODESTRING = "USHORT Length;USHORT MaximumLength;PTR Buffer;"
Global Const $sTagOBJECT_ATTRIBUTES="ULONG Length;HANDLE RootDirectory;PTR ObjectName;ULONG Attributes;PTR SecurityDescriptor;PTR SecurityQualityOfService"

Local $tUnicodeString = DllStructCreate($sTagUNICODESTRING)
Local $pUnicodeString = DllStructGetPtr($tUnicodeString)

ConsoleWrite("!$pUnicodeString: " & $pUnicodeString & @CRLF)


Local $tSourceString = DllStructCreate("wchar[256]")
DllStructSetData($tSourceString, 1, "\ArcName")

Local $aRet = DllCall("Ntdll.dll", "NONE", "RtlInitUnicodeString", "ptr", $pUnicodeString, "ptr", DllStructGetPtr($tSourceString))

ConsoleWrite("!$tUnicodeString.Length: " & $tUnicodeString.Length & @CRLF)

Local $tObject_Attributes = DllStructCreate($sTagOBJECT_ATTRIBUTES)
Local $pObject_Attributes = DllStructGetPtr($tObject_Attributes)

ConsoleWrite("!$pObject_Attributes: " & $pObject_Attributes & @CRLF)

DllStructSetData($tObject_Attributes, 1, DllStructGetSize($tObject_Attributes))
DllStructSetData($tObject_Attributes, 3, $pUnicodeString)


$aRet = DllCall("Ntdll.dll", "LONG", "NtOpenDirectoryObject", "HANDLE*", 0, "ULONG", BitOR($DIRECTORY_TRAVERSE, $DIRECTORY_QUERY), "PTR", $pObject_Attributes)

Local $hDirectory = $aRet[1]
ConsoleWrite("!$hDirectory: " & $hDirectory & @CRLF)

Local $tData = 0
Local $tName = 0
Local $tType = 0
Local $index = 0
Local $bytes = 0
Local $tBuffer = 0
Local $aArcName[0]

    $tBuffer = DllStructCreate("byte Data[32767]")

    $aRet = DllCall("Ntdll.dll", "LONG", "NtQueryDirectoryObject", "HANDLE", $hDirectory, "ptr", DllStructGetPtr($tBuffer), "ULONG", 32767, "BOOL", False, "BOOL", True, "ULONG*", 0, "ULONG*", 0)

    If @error or $aRet[0]<0 then Exit

    $index = $aRet[6]
    $bytes = $aRet[7]

    ConsoleWrite("!index: " & $index & " $bytes: " & $bytes & @CRLF)

       For $i = 0 To $index - 1
        $tData = DllStructCreate($sTagUNICODESTRING  & $sTagUNICODESTRING , DllStructGetPtr($tBuffer) + ($i * 16))
        $tName = DllStructCreate("wchar wNameString[" & DllStructGetData($tData,1) & "]", DllStructGetData($tData,3))
        $tType = DllStructCreate("wChar wTypeString[" & DllStructGetData($tData,4) & "]", DllStructGetData($tData,6))
       ConsoleWrite(">" & $i + 1 & @TAB & $tName.wNameString & @TAB & $tType.wTypeString & @CRLF)
       ReDim $aArcName[UBound($aArcName)+1][2]
       $aArcName[UBound($aArcName)-1][0]=$tName.wNameString
       $aArcName[UBound($aArcName)-1][1]=$tType.wTypeString
       $tType = 0
        $tName = 0
        $tData = 0
    Next

_ArrayDisplay($aArcName)

I did not implement SimbolicLink. I'm lazy.

 

Saludos

This one works as expected, ill try to rework symlink resolution into this

What is what? What is what.

  • 2 years later...
Posted

Hello Biatu. time without knowing about you.

Here is the fix.

#AutoIt3Wrapper_UseX64=y
#include <Array.au3>
Opt("MustDeclareVars", 1)


Global Const $DIRECTORY_QUERY = 0x0001
Global Const $DIRECTORY_TRAVERSE = 0x0002
Global Const $sTagUNICODESTRING = "USHORT Length;USHORT MaximumLength;PTR Buffer;"
Global Const $sTagOBJECT_ATTRIBUTES = "ULONG Length;HANDLE RootDirectory;PTR ObjectName;ULONG Attributes;PTR SecurityDescriptor;PTR SecurityQualityOfService"

Local $tUnicodeString = DllStructCreate($sTagUNICODESTRING)
Local $pUnicodeString = DllStructGetPtr($tUnicodeString)

ConsoleWrite("!$pUnicodeString: " & $pUnicodeString & @CRLF)


Local $tSourceString = DllStructCreate("wchar[256]")
DllStructSetData($tSourceString, 1, "\ArcName")

Local $aRet = DllCall("Ntdll.dll", "NONE", "RtlInitUnicodeString", "ptr", $pUnicodeString, "ptr", DllStructGetPtr($tSourceString))

ConsoleWrite("!$tUnicodeString.Length: " & $tUnicodeString.Length & @CRLF)

Local $tObject_Attributes = DllStructCreate($sTagOBJECT_ATTRIBUTES)
Local $pObject_Attributes = DllStructGetPtr($tObject_Attributes)

ConsoleWrite("!$pObject_Attributes: " & $pObject_Attributes & @CRLF)

DllStructSetData($tObject_Attributes, 1, DllStructGetSize($tObject_Attributes))
DllStructSetData($tObject_Attributes, 3, $pUnicodeString)


$aRet = DllCall("Ntdll.dll", "LONG", "NtOpenDirectoryObject", "HANDLE*", 0, "ULONG", BitOR($DIRECTORY_TRAVERSE, $DIRECTORY_QUERY), "PTR", $pObject_Attributes)

Local $hDirectory = $aRet[1]
ConsoleWrite("!$hDirectory: " & $hDirectory & @CRLF)

Local $tData = 0
Local $tName = 0
Local $tType = 0
Local $index = 0
Local $bytes = 0
Local $tBuffer = 0
Local $aArcName[0]

$tBuffer = DllStructCreate("byte Data[32767]")

$aRet = DllCall("Ntdll.dll", "LONG", "NtQueryDirectoryObject", "HANDLE", $hDirectory, "ptr", DllStructGetPtr($tBuffer), "ULONG", 32767, "BOOL", False, "BOOL", True, "ULONG*", 0, "ULONG*", 0)

If @error Or $aRet[0] < 0 Then Exit

$index = $aRet[6]
$bytes = $aRet[7]

ConsoleWrite("!index: " & $index & " $bytes: " & $bytes & @CRLF)

For $i = 0 To $index - 1
    $tData = DllStructCreate($sTagUNICODESTRING & $sTagUNICODESTRING, DllStructGetPtr($tBuffer) + ($i * (@AutoItX64 ? 32 : 16)))
    $tName = DllStructCreate("wchar wNameString[" & DllStructGetData($tData, 1) & "]", DllStructGetData($tData, 3))
    $tType = DllStructCreate("wChar wTypeString[" & DllStructGetData($tData, 4) & "]", DllStructGetData($tData, 6))
    ConsoleWrite(">" & $i + 1 & @TAB & $tName.wNameString & @TAB & $tType.wTypeString & @CRLF)
    ReDim $aArcName[UBound($aArcName) + 1][2]
    $aArcName[UBound($aArcName) - 1][0] = $tName.wNameString
    $aArcName[UBound($aArcName) - 1][1] = $tType.wTypeString
    $tType = 0
    $tName = 0
    $tData = 0
Next

_ArrayDisplay($aArcName)

Saludos

 

 

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...