Jump to content

Recommended Posts

Posted (edited)

Hi -

Currently I'm playing around with Windows Credential Manager. I'm trying to access it with DllCall("advapi32.dll", ...) using the functions 'CredWriteW', 'CredReadW' and 'CredDeleteW'. All well. Another function I have to deal with is 'CredEnumerateW': https://docs.microsoft.com/en-us/windows/desktop/api/wincred/nf-wincred-credenumeratew/ .

That's the test code I have so far:

#include <Array.au3>
#include <String.au3>


Local $tCredentialsCount = DllStructCreate("DWORD;")
Local $tPointerToArrayOfPointers = DllStructCreate("PTR;")
; Local $tPointerToArrayOfPointers = DllStructCreate(_StringRepeat("PTR;", 200)) ; ???
Local $aResult = DllCall("advapi32.dll", "BOOL", "CredEnumerateW", _
        "WSTR", Null, "DWORD", 1, "DWORD", DllStructGetPtr($tCredentialsCount), "PTR", DllStructGetPtr($tPointerToArrayOfPointers))
If (Not @error) Then


    Local $iCredentialsCount = DllStructGetData($tCredentialsCount, 1)
    _ArrayDisplay($aResult, $iCredentialsCount)


    Local $hPointerToArrayOfPointers = DllStructGetData($tPointerToArrayOfPointers, 1)
    MsgBox(0, "$hPointerToArrayOfPointers", $hPointerToArrayOfPointers)


    ; Fails...
    For $i = 1 To 10 ; $iCredentialsCount
        MsgBox(0, $i & "___" & (($i * 2) - 1), DllStructGetData($tPointerToArrayOfPointers, ($i * 2) - 1))
    Next


    $tCredentialsCount = 0
    $tPointerToArrayOfPointers = 0
    DllCall("advapi32.dll", "NONE", "CredFreeW", "PTR", $hPointerToArrayOfPointers)
EndIf

The DllCall seems to function properly - I get a valid count of credentials (on my computer ~ 133) and a pointer "to array of pointers".

What is meant by "array of pointers"? :blink:

Microsoft says: Pointer to an array of pointers to credentials. The returned credential is a single allocated block. Any pointers contained within the buffer are pointers to locations within this single allocated block.

How to access these pointers... Contained within the buffer???

Any information you can provide me would be greatly appreciated.

Edited by supersonic
Posted

hello. you need to do something like this:

#include <Array.au3>
#include <String.au3>


Local $tCredentialsCount = DllStructCreate("DWORD;")
Local $tPointerToArrayOfPointers = DllStructCreate("PTR;")
; Local $tPointerToArrayOfPointers = DllStructCreate(_StringRepeat("PTR;", 200)) ; ???
Local $aResult = DllCall("advapi32.dll", "BOOL", "CredEnumerateW", _
        "WSTR", Null, "DWORD", 1, "DWORD*", 0, "PTR*", 0)
If (Not @error) Then


    Local $iCredentialsCount = $aResult[3]
    Local $pArrayCredentials = $aResult[4]
;~     _ArrayDisplay($aResult, $iCredentialsCount)

    Local $taPointer = DllStructCreate("ptr[" & $iCredentialsCount & "]", $pArrayCredentials)

    ;show each pointer to credential
    For $i = 1 To $iCredentialsCount
        MsgBox(0, $i, DllStructGetData($taPointer, 1, $i))
    Next

    ;free
    For $i = 1 To $iCredentialsCount
        MsgBox(0, $i,)
        DllCall("advapi32.dll", "NONE", "CredFreeW", "PTR", DllStructGetData($taPointer, 1, $i))
    Next
    $taPointer = 0
EndIf
 

 

 

PD: sorry for syntax highlighting not working in my slow connection

 

Saludos

Posted (edited)

Oh dear - an error occurs if running AutoIt in 64 bit :(

The code to reproduce:

;~ #AutoIt3Wrapper_UseX64 = Y


#include <Array.au3>
#include <String.au3>


Local $aResult = DllCall("advapi32.dll", "BOOL", "CredEnumerateW", "WSTR", Null, "DWORD", 1, "DWORD*", 0, "PTR*", 0)
If (Not @error) Then


    Local $iCredentialsCount = $aResult[3]
    Local $pArrayCredentials = $aResult[4]
    ; _ArrayDisplay($aResult, $iCredentialsCount)


    Local $taPointer = DllStructCreate("ptr[" & $iCredentialsCount & "]", $pArrayCredentials)
    For $i = 1 To $iCredentialsCount
        ; MsgBox(0, $i, DllStructGetData($taPointer, 1, $i))


        DllCall("advapi32.dll", "NONE", "CredFree", "PTR", DllStructGetData($taPointer, 1, $i))
        ConsoleWrite("___" & @error & @CRLF)
    Next
    $taPointer = 0


EndIf

In 32 bit everything works fine. In 64 bit the first 10-12 pointers are read. Then AutoIt crashes.

Any idea to resolve that issue?

P.S.: There is no function 'CredFreeA' or 'CredFreeW'... Only 'CredFree'.

Edited by supersonic
Posted

sorry my fault. I read wrong in msdn. the correct way is free the pointer to the array.

#AutoIt3Wrapper_UseX64 = Y


#include <Array.au3>
#include <String.au3>


Local $aResult = DllCall("advapi32.dll", "BOOL", "CredEnumerateW", "WSTR", Null, "DWORD", 1, "DWORD*", 0, "PTR*", 0)
If (Not @error) Then


    Local $iCredentialsCount = $aResult[3]
    Local $pArrayCredentials = $aResult[4]
    ; _ArrayDisplay($aResult, $iCredentialsCount)


    Local $taPointer = DllStructCreate("ptr[" & $iCredentialsCount & "]", $pArrayCredentials)
    For $i = 1 To $iCredentialsCount
        MsgBox(0, $i, DllStructGetData($taPointer, 1, $i))
    Next
    DllCall("advapi32.dll", "NONE", "CredFree", "PTR", $pArrayCredentials)
    $taPointer = 0


EndIf

Saludos

Posted (edited)

Thank you - I tried this before, too. And it worked. But 'pArrayCredentials' is a structure not a pointer!? Or am I wrong? :blink:

Furthermore... Running in 32 bit works for all entries. Do you know why?

Edited by supersonic
Posted

1.- pArrayCredentials Its Pointer to an array of pointers to credentials

2.- just luck I think. But it's wrong. MSDN says.

Credential

Pointer to an array of pointers to credentials. The returned credential is a single allocated block. Any pointers contained within the buffer are pointers to locations within this single allocated block. The single returned buffer must be freed by calling CredFree.

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
×
×
  • Create New...