Jump to content

Help getting drive letter from an Arc Path?


Recommended Posts

  • 2 years later...
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.

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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

 

Saludos

Link to comment
Share on other sites

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

  • 2 years later...

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

 

 

Link to comment
Share on other sites

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
 Share

  • Recently Browsing   0 members

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