Jump to content

CredWriteW trying to add Attributes


Recommended Posts

Hello,

 

I'm trying to figure out how to add attributes to a Credentials Store.  I have been using it to store Creds and I was using the Comments to store some limited data but I'd really like to start using the 64 possible Attributes so I don't need to use the Registry to store misc information my script needs.

 

I have been trying to figure this our for a few days now and I'm able to create the structure, but it fails with Invalid Parameter when trying to add the item to the store.

 

Any ideas or pointers to where to get some further information on this?

Thanks,

Mike

#include <Crypt.au3>
#include <Array.au3>
#include <WinAPI.au3>

$sEncryptionKey = @ScriptName & 'MyS3cur!tyK3y' & @UserName

$sCredName = "AttributeTest"
$sUserID = "MyUserID"
$sPassword = "SecretP@ssw0rd"
$sDatabase = "StoredCommentHere"

$sAttribute1 = "ALM.NoReply"
$sAttribute2 = "Defect #?BG_BUG_ID in ?PROJECT, Status = ?BG_STATUS, Severity = ?BG_SEVERITY"
$sAttribute3 = "C:\Users\MyProfile\Documents\ALM_Reports"
$sAttribute4 = "UserName1,QA_Analyst|UserName2,Business_Analyst|UserName3,QA_Analyst|UserName4,QA_Analyst|UserName5,Business_Analyst|UserName6,QA_Analyst"

Global $aAttribute[4, 2] = [["eMailFrom", $sAttribute1], ["eMailSubject", $sAttribute2], ["reportFldr", $sAttribute3], ["DefaultUsers", $sAttribute4]]


;Add something to the Credential Store
    $aAdd = _Cred_Add_WithAttributes($sCredName, $sUserID, StringEncrypt(True, $sPassword, $sEncryptionKey), $sDatabase, 1, $aAttribute)
    If @error Then
        MsgBox(0, "Error", "Failed to add credentials to " & $sCredName)
        Exit
    EndIf


Func _Cred_Add_WithAttributes($sTarget, $sUser, $sPassword, $sComm = "", $iType = 2, $aAttribute = "")  ;Type: 2=Domain, 1=Local
    
    Local $structTarget = DllStructCreate("wchar[100]")                 ; Create a structure to hold the Target object name
    DllStructSetData($structTarget, 1, $sTarget)                        ; Insert the target name into that Structure

    Local $structUser = DllStructCreate("wchar[100]")                   ; Create a structure to hold the UserName to use
    DllStructSetData($structUser, 1, $sUser)                            ; Insert the user name into the structure

    Local $structPwd = DllStructCreate("wchar[100]")                    ; Create a structure to hold the password to use
    DllStructSetData($structPwd, 1, $sPassword)                         ; Insert the password into the structure

    Local $structComment = DllStructCreate("wchar[100]")                ; Comments seem to only work where Type = 1 legacy
    DllStructSetData($structComment, 1, $sComm)

;--------------------------------------------------------------------------------------------------------------------
;-- CREDENTIAL_ATTRIBUTE structure  https://msdn.microsoft.com/en-us/library/windows/desktop/aa374790(v=vs.85).aspx  
;--------------------------------------------------------------------------------------------------------------------
    Local $aAttrirb[UBound($aAttribute)]
    Local $tagCREDENTIAL_ATTRIBUTE = "" & _
        "wchar Keyword;" & _
        "DWORD Flags;" & _
        "DWORD ValueSize;" & _
        "wchar Value"

    For $i = 0 to UBound($aAttribute) - 1
        $aAttrirb[$i] = DllStructCreate($tagCREDENTIAL_ATTRIBUTE)
        If @error Then
            ConsoleWrite("Error on $aAttrib[" & $i & "] = " & @error & @CRLF)
            Exit
        EndIf

        DllStructSetData($aAttrirb[$i],"Keyword",StringRight($aAttribute[$i][0], 256))                      ;Name for the Attribute to use, 256 characters max
        If @error Then ConsoleWrite("Error adding Keyword to $aAttrib[" & $i & "] = " & @error & @CRLF)
        DllStructSetData($aAttrirb[$i],"Flags",0)                                                           ;Should always be 0
        If @error Then ConsoleWrite("Error adding Flags to $aAttrib[" & $i & "] = " & @error & @CRLF)
        DllStructSetData($aAttrirb[$i],"ValueSize",256)                                                     ;Max = 256
        If @error Then ConsoleWrite("Error adding ValueSize to $aAttrib[" & $i & "] = " & @error & @CRLF)
        DllStructSetData($aAttrirb[$i],"Value",StringRight($aAttribute[$i][1], 256))                        ;Take the right most 256 characters if they put in to many
        If @error Then ConsoleWrite("Error adding Value to $aAttrib[" & $i & "] = " & @error & @CRLF)
    Next
;--------------------------------------------------------------------------------------------------------------------


    Local $structCREDENTIAL= "" & _
        "DWORD Flags;" & _
        "DWORD Type;"  & _
        "Ptr TargetName;" & _
        "Ptr Comment;" & _
        "UINT64 LastWritten;" & _
        "DWORD CredintialBlobSize;" & _
        "Ptr CredentialBlob;" & _
        "DWORD Persist;" & _
        "DWORD AttributeCount;" & _
        "ptr Attributes;" & _
        "Ptr TargetAlias;" & _
        "Ptr Username"

    Local $NewCred = DllStructCreate($structCREDENTIAL)
    If @error Then
        MsgBox(0, "NewCred", "Error in DllStructCreate " & @error);
        Exit
    EndIf

    DllStructSetData($NewCred,"Flags",0)
    DllStructSetData($NewCred,"Type",$iType)        ;2 = Domain, 1 = Generic
    DllStructSetData($NewCred,"TargetName",DllStructGetPtr($structTarget))
    DllStructSetData($NewCred,"Persist",3)          ;save to roaming profile = 3


;Problem with this section, as if I comment out, it adds but I need Attributes.
    DllStructSetData($NewCred,"AttributeCount",UBound($aAttrib))    ;max = 64
    If @error Then ConsoleWrite("Error adding AttributeCount (1) = " & @error & @CRLF)
    
    For $i = 0 to UBound($aAttrirb) - 1
        DllStructSetData($NewCred,"Attributes", DllStructGetPtr($aAttrirb[$i]))
        If @error Then ConsoleWrite("Error adding Attributes (" & $i + 1 & ") = " & @error & @CRLF)
    Next


    DllStructSetData($NewCred,"UserName",DllStructGetPtr($structUser))
    DllStructSetData($NewCred,"CredentialBlob",DllStructGetPtr($structPwd))
    DllStructSetData($NewCred,"CredintialBlobSize",StringLen($sPassword)*2)
    DllStructSetData($NewCred,"Comment",DllStructGetPtr($structComment))

    Local $hAdvapi32 = DllOpen("Advapi32.dll")
    If $hAdvapi32 = -1 Then
        Msgbox(0, "Error", "Failed to connect to the Credentials Store")
        Exit
    Endif

    $aRet = DllCall($hAdvapi32, 'bool', 'CredWriteW', 'ptr', DllStructGetPtr($NewCred), 'dword', 0)
    If @error Then ConsoleWrite("DllCall Error:  " & @error & @CRLF)
    $NewCred = 0
    ConsoleWrite("GetLastError = (" & _WinAPI_GetLastError() & ")" & @CRLF)
        ;87 = ERROR_INVALID_PARAMETER

    If IsArray($aRet) Then
        ConsoleWrite("Successfully performed the CredWriteW DLL call, Return = " & $aRet[0] & @CRLF)
        if UBound($aRet) > 1 Then _ArrayDisplay($aRet, "DllCall Returned")
        Return $aRet
    Else
        ConsoleWrite("Failed to perform the CredWriteW DLL call" & @CRLF)
        Return SetError(1)
    EndIf

EndFunc



Func _Cred_Get($sTarget, $iType = 2)  ;Type: 2=Domain, 1=Local.  CAN'T DECRYPT DOMAIN PASSWORDS!!!
    Local $FuncRet[3]

    Local $structTarget = DllStructCreate("wchar[100]")
    DllStructSetData($structTarget,1,$sTarget)

    Local $hAdvapi32 = DllOpen("Advapi32.dll")
    If $hAdvapi32 = -1 Then
        Msgbox(0, "Error", "Failed to connect to the Credentials Store")
        Exit
    Endif

    Local $Ret = DllCall($hAdvapi32, 'bool', 'CredReadW', 'ptr', DllStructGetPtr($structTarget), 'dword', $iType, 'dword', 0, 'ptr*', 0)

    if $ret[0]=0 then Return SetError(1,0,$FuncRet)

    Local $structCREDENTIAL= "" & _
        "DWORD Flags;" & _
        "DWORD Type;"  & _
        "Ptr TargetName;" & _
        "Ptr Comment;" & _
        "UINT64 LastWritten;" & _
        "DWORD CredintialBlobSize;" & _
        "Ptr CredentialBlob;" & _
        "DWORD Persist;" & _
        "DWORD AttributeCount;" & _
        "Ptr Attributes;" & _
        "Ptr TargetAlias;" & _
        "Ptr Username"

    Local $tdata=DllStructCreate($structCREDENTIAL, $Ret[4])

    Local $userName = DllStructCreate("wchar[100]", DllStructGetData($tdata, 'Username'))
    Local $User = DllStructGetData($userName, 1)

    Local $CredentialBlobSize = DllStructGetData($tdata, 'CredintialBlobSize')
    Local $credentialBlob = DllStructCreate("wchar[100]", DllStructGetData($tdata, 'CredentialBlob'))
    Local $Password = StringLeft(DllStructGetData($credentialBlob, 1), $CredentialBlobSize/2)

    ;Once the Add Attributes is working, I need to figure out how to retrieve the Attributes that I want, below is un-tested.
    ; Local $eMailFrom = DllStructCreate("wchar[256]", DllStructGetData($tdata, 'eMailFrom'))
    ; Local $eMail = DllStructGetData($eMailFrom, 4)
    ; Consolewrite("eMailFrom Attribute = (" & $eMail & ")" & @crlf )

    Local $Comment = DllStructCreate("wchar[100]", DllStructGetData($tdata, 'Comment'))
    Local $Comm = DllStructGetData($Comment, 1)

    Dim $FuncRet[] = [$User, $Password, $Comm]
    If IsArray($FuncRet) Then
        Return $FuncRet
    Else
        Return SetError(1)
    EndIf
EndFunc

 

Link to post
Share on other sites

Hello. I have no too much time to check your code. But as far I can see  "wchar Keyword and "wchar Value" need to be pointer to wchar and BYTE.

 

Saludos

Link to post
Share on other sites
  • 1 year later...

@FrancescoDiMuro Is your man there. 

I am suprised to see an unswered topic here :D .

He will take this as a challenge I am sure :) . 

My video tutorials : ( In construction )  || My Discord : https://discord.gg/S9AnwHw

How to Ask Help ||  UIAutomation From Junkew || WebDriver From Danp2 || And Water's UDFs in the Quote

Spoiler

 Water's UDFs:
Active Directory (NEW 2018-10-19 - Version 1.4.10.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (2018-10-31 - Version 1.3.4.1) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
PowerPoint (2017-06-06 - Version 0.0.5.0) - Download - General Help & Support
Excel - Example Scripts - Wiki
Word - Wiki
 
Tutorials:

ADO - Wiki

 

Link to post
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
  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By IndianSage
      Hi,
      My AutoIt script is as folllows:
      ;use for calling function add2NosA in dll ;Local $vNo1 = 33 ;Local $vNo2 = 11 ;use for calling function sortNos in dll Local $vNo1 = [11,7,9] Local $vNo2 = [1,3,2] ; _ArrayDisplay($vNo1, "vNo1 display") ; _ArrayDisplay($vNo2, "vNo2 display") ;Local $hWnd = DllOpen("E:\CV-Dell-1\autoit3\myComObj1.dll") Local $hWnd = ObjCreate("myComObj1.clsMath") if (@error) Then MsgBox (0, "Error", "Error1 = " & @error) Exit EndIf ;function call method - DllCall with function name ;Local $aRes = DllCall($hWnd, "int", "addNosA", "int", $vNo1, "int", $vNo2) ;Local $aRes = DllCall($hWnd, "Ptr", "sortNos", "Array", $vNo1, "Array", $vNo2) ;function call method - $hWnd.<function name> ;Local $aRes = $hWnd.add2NosA($vNo1, $vNo2) ; this works fine with ObjCreate Local $aRes = $hWnd.sortNos($vNo1, $vNo2) if (@error) Then MsgBox (0, "Error", "Error2 = " & @error) DllClose($hWnd) Exit EndIf ;use appropriate msgbox ;MsgBox(0,"Result", "Result = " & $vNo1[0]) MsgBox(0,"Result", "Result = " & $aRes) _ArrayDisplay($vNo1, "vNo1 display") _ArrayDisplay($aRes , "aRes display") DllClose($hWnd) My VB.Net - ClassLibrary - Dll - COM obj is as follows - has 2 functions - add2NosA and sortNos:
      <ComClass(clsMath.ClassId, clsMath.InterfaceId, clsMath.EventsId)> Public Class clsMath Public Const ClassId As String = "3A42F85E-24C8-4BAA-91B5-AE56C4683C13" Public Const InterfaceId As String = "D99D7C79-2BA7-4A33-B7BC-9B7F19FDF828" Public Const EventsId As String = "CA128AC4-580C-4112-9EAD-8D1599E3F37A" Public Sub New() MyBase.New() End Sub Public Function add2NosA(ByVal no1 As Integer, ByVal no2 As Integer) As Integer Return (no1 + no2) End Function Public Sub sortNos(ByRef no1 As Array, ByRef no2 As Array) Array.Sort(no1) no2 = no1 End Sub End Class  Over all I tried various 8 options mentioned in the attached Excel file - with only 1 combination working.
      Overall could not make Array returned capture in AutoIt script. 
      Can someone help please?
      Thanks in  advance.
      Options-Tried-Matrix-Results.xlsx
    • By IndianSage
      I have create a function in FreeBasic like below:
      Extern "Windows-MS" Type tA f1 As Integer f2 As Integer End Type Public Function _switchOrder(ByVal no1 As Integer, ByVal no2 As Integer) As tA Export Dim result As Integer Dim taa As tA taa.f1 = no2 taa.f2 = no1 Return taa End Function End Extern Caller AutoIt code is:
      #include <MsgBoxConstants.au3> Global Const $sTag_ftdi_version_info="struct; int no1a; int no2a; endstruct" Local $aRet=DllCall("Math1.dll","Ptr","_switchOrder", "Int", 10, "Int", 30) ;MsgBox (0,"",@error & "-" & $aRet[0] & "-" & $aRet[1]& "-" & $aRet[2]) Local $t_ftdi_version_info=DllStructCreate($sTag_ftdi_version_info,$aRet[0]) MsgBox (0,"msg1=",@error & "---" & $aRet[0] & "-" & $aRet[1]& "-" & $aRet[2]) ;Local $retData1 = DllStructGetData($t_ftdi_version_info,"",1) Local $retData1 = DllStructGetData($t_ftdi_version_info,"no1a") MsgBox (0,"msg2=",@error & "--" & $retData1) ;Local $retData1 = DllStructGetData($t_ftdi_version_info,"",2) Local $retData1 = DllStructGetData($t_ftdi_version_info,"no2a") MsgBox (0,"msg2=",@error & "--" & $retData1) ;ConsoleWrite(DllStructGetData($t_ftdi_version_info,"",2) & "--" & @error) ;ConsoleWrite(DllStructGetData($t_ftdi_version_info,"no2a") & @CRLF) ;ConsoleWrite(DllStructGetData($tversion_str,1) & @CRLF) Getting error 2 for DllStructGetData or it give Close Application AutoIt popup message. 
      Certainly DllCall is not returning pointer to the Structure in $aRet[0] hence issue.
      Can someone help me fix this please?
      Thanks in advance.
       
       
    • By xYuri
      This simple dllcall gives me error 5, access denied,
      Func _WinAPI_VkKeyScan($__key) _WinAPI_SetLastError(0) $res = DllCall('User32.dll', 'SHORT', 'VkKeyScan', 'CHAR', $__key) _xConsole('res: '&$res) $_LastErr = _WinAPI_GetLastError() If $_LastErr <> 0 Then _xConsole('Err: {' & $_LastErr & '}> ' & _WinAPI_GetLastErrorMessage()) Return $res EndFunc Am i doing something wrong?
      Also tried VkKeyScanA and W
      Edit:
      I want to send `:` via PostMessage() WM_KEYDOWN
    • By Skysnake
      This is relevant
      From here https://stackoverflow.com/questions/3454315/is-it-possible-to-pin-a-dll-in-memory-to-prevent-unloading
      I use several UDFs on the Forum to do various things.  Those UDFs work very well.
      Effectively the UDFs are DLL wrappers, that make it possible to access DLL functions easily without the long hard slog of DLLCall() every time.
      However, I have now run into the issue that multiple UDF DLLCalls are slow. Not mind numbingly slow, but slow enough to become noticeable with a large of repeated function calls.
      So I was wondering, is it possible to "load a DLL into memory" and leave it there for the duration of my script's lifetime, avoid repeated DLL on-disk reads with a persistent in memory DLL?
      From Microsoft
      https://docs.microsoft.com/en-us/windows/desktop/dlls/about-dynamic-link-libraries
      Looks like what I want to do is: load-time dynamic linking,
      So next question, (a) how do I do this with AutoIt (b) How would this impact on standard AutoIt type DLL calls?
       
      The point is speed.  Is there a different approach?
      Or am I barking up the wrong tree?
      Skysnake
    • By supersonic
      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"?
      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.
×
×
  • Create New...