jazzyjeff Posted September 21, 2011 Posted September 21, 2011 Hello, I need my program to be able to add credentials in Credential manager in Windows 7. I have used the "net use x: \\servername\sharename /savecred' Command, but it doesn't seem very clean and I am not always guaranteed that it works as sometimes CMD hangs. I see there is an API to add credentials on the MSDN site called CredWrite. I have made my best attempt to get this to work, but I am not having much luck. I am hoping someone can look at my code and help point me in the right direction. Here is the code I have for a UDF function:Func _WinAPI_CredWrite($credential[11],$credential[6],$credential[2]) $credential[0] = 4 ;Flags $credential[1] = 2 ;Type $credential[2] = "" ;TargetName - Servername $credential[3] = "" ;Comment $credential[4] = @HOUR & ":" & @MIN ;LastWritten $credential[5] = 512 ;CredentialBlobSize $credential[6] = "" ;CredentialBlob - Password? $credential[7] = 2 ;Persist $credential[8] = 64 ;AttributeCount $credential[9] = "" ; Attributes $credential[10] = "" ;TargetAlias $credential[11] = "" ;Username Local $Ret = DllCall('advapi32.dll', 'int', 'CredWriteW', 'ptr', $credential, 'dword', 0) EndFunc ;==>_WinAPI_CredWrite The URL for the API function is:http://msdn.microsoft.com/en-us/library/aa375187(v=VS.85).aspx Thanks for any help! Jeff
Shaggi Posted September 21, 2011 Posted September 21, 2011 You need to use a dllstruct, not an array... i formatted the struct for ya: expandcollapse popup#cs typedef struct _CREDENTIAL { DWORD Flags; DWORD Type; LPTSTR TargetName; LPTSTR Comment; FILETIME LastWritten; DWORD CredentialBlobSize; LPBYTE CredentialBlob; DWORD Persist; DWORD AttributeCount; PCREDENTIAL_ATTRIBUTE Attributes; LPTSTR TargetAlias; LPTSTR UserName; } CREDENTIAL, *PCREDENTIAL; typedef struct _CREDENTIAL_ATTRIBUTE { LPTSTR Keyword; DWORD Flags; DWORD ValueSize; LPBYTE Value; } CREDENTIAL_ATTRIBUTE, *PCREDENTIAL_ATTRIBUTE; #ce $tagFILETIME = "DWORD lowpart;DWORD highpart;" $tagCREDENTIAL_ATTRIBUTE = "wchar* Keyword;DWORD Flags; DWORD ValueSize; byte* Value;" $tagCREDENTIAL= "" & _ "DWORD Flags;" & _ "DWORD Type;" & _ "wchar* TargetName;" & _ "wchar* Comment;" & _ $tagFILETIME & _ "DWORD CredintialBlobSize" & _ "byte* CredentialBlob" & _ "DWORD Persist;" & _ "DWORD AttributeCount;" & _ "ptr Attributes;" & _ ; CREDENTIAL_ATTRIBUTE * Attributes, that is, array of those "wchar* TargetAlias;" &_ "wchar* Username;" Set data like this: $Cred = DllStructCreate($tagCREDENTIAL) DllStructSetData($Cred,"Flags",0x04); Anything called "ptr" or has an asterisk needs a seperate dllstruct since they themselves are pointers to other structs.. following me? Ever wanted to call functions in another process? ProcessCall UDFConsole stuff: Console UDFC Preprocessor for AutoIt OMG
jazzyjeff Posted September 22, 2011 Author Posted September 22, 2011 Thanks for your response Shaggi. I feel like I understand what you are saying and then I read through the help file to learn about the DLLStructs and I feel more confident about using those. However, I still don't know how you implement the DLLStruct with the DLLCall. Here is what I now have with your help. $tagFILETIME = "DWORD lowpart;DWORD highpart;" $tagCREDENTIAL_ATTRIBUTE = "wchar* Keyword;DWORD Flags; DWORD ValueSize; byte* Value;" $tagCREDENTIAL= "" & _ "DWORD Flags;" & _ "DWORD Type;" & _ "wchar* TargetName;" & _ "wchar* Comment;" & _ $tagFILETIME & _ "DWORD CredintialBlobSize" & _ "byte* CredentialBlob" & _ "DWORD Persist;" & _ "DWORD AttributeCount;" & _ "ptr Attributes;" & _ ; CREDENTIAL_ATTRIBUTE * Attributes, that is, array of those "wchar* TargetAlias;" & _ "wchar* Username;" $Cred = DllStructCreate($tagCREDENTIAL) DllStructSetData($Cred,"Flags",0x04); DllStructSetData($Cred,"Type",0x02); DllStructSetData($Cred,"TargetName","\\servername"); DllStructSetData($Cred,"Comment",""); DllStructSetData($Cred,$tagFILETIME,@HOUR & ":" & @MIN); DllStructSetData($Cred,"CredentialBlobSize",512); DllStructSetData($Cred,"CredentialBlob","Password"); DllStructSetData($Cred,"Persist",0x02); DllStructSetData($Cred,"AttributeCount",64); DllStructSetData($Cred,"TargetAlias","Servername"); DllStructSetData($Cred,"Username","domain\username"); DllCall('advapi32.dll', 'int', 'CredWriteW', 'ptr', $cred, 'dword', 0) I feel like once I have set the data in the DLL Struct, I then just run a DLLCall with the $cred variable. This doesn't seem to work though, so I am obviously missing something here.
Beege Posted September 22, 2011 Posted September 22, 2011 if it is asking for a ptr to a "credential structure", then you need to use dllstructgetptr(). DllCall('advapi32.dll', 'int', 'CredWriteW', 'ptr', DllStructGetPtr($cred), 'dword', 0) Assembly Code: fasmg . fasm . BmpSearch . Au3 Syntax Highlighter . Bounce Multithreading Example . IDispatchASMUDFs: Explorer Frame . ITaskBarList . Scrolling Line Graph . Tray Icon Bar Graph . Explorer Listview . Wiimote . WinSnap . Flicker Free Labels . iTunesPrograms: Ftp Explorer . Snipster . Network Meter . Resistance Calculator
Shaggi Posted September 22, 2011 Posted September 22, 2011 Thanks for your response Shaggi. I feel like I understand what you are saying and then I read through the help file to learn about the DLLStructs and I feel more confident about using those. However, I still don't know how you implement the DLLStruct with the DLLCall. Here is what I now have with your help. $tagFILETIME = "DWORD lowpart;DWORD highpart;" $tagCREDENTIAL_ATTRIBUTE = "wchar* Keyword;DWORD Flags; DWORD ValueSize; byte* Value;" $tagCREDENTIAL= "" & _ "DWORD Flags;" & _ "DWORD Type;" & _ "wchar* TargetName;" & _ "wchar* Comment;" & _ $tagFILETIME & _ "DWORD CredintialBlobSize" & _ "byte* CredentialBlob" & _ "DWORD Persist;" & _ "DWORD AttributeCount;" & _ "ptr Attributes;" & _ ; CREDENTIAL_ATTRIBUTE * Attributes, that is, array of those "wchar* TargetAlias;" & _ "wchar* Username;" $Cred = DllStructCreate($tagCREDENTIAL) DllStructSetData($Cred,"Flags",0x04); DllStructSetData($Cred,"Type",0x02); DllStructSetData($Cred,"TargetName","\\servername"); DllStructSetData($Cred,"Comment",""); DllStructSetData($Cred,$tagFILETIME,@HOUR & ":" & @MIN); DllStructSetData($Cred,"CredentialBlobSize",512); DllStructSetData($Cred,"CredentialBlob","Password"); DllStructSetData($Cred,"Persist",0x02); DllStructSetData($Cred,"AttributeCount",64); DllStructSetData($Cred,"TargetAlias","Servername"); DllStructSetData($Cred,"Username","domain\username"); DllCall('advapi32.dll', 'int', 'CredWriteW', 'ptr', $cred, 'dword', 0) I feel like once I have set the data in the DLL Struct, I then just run a DLLCall with the $cred variable. This doesn't seem to work though, so I am obviously missing something here. Do like beege said. However, there are some thing you still need to work on: Anything called "ptr" or has an asterisk needs a seperate dllstruct since they themselves are pointers to other structs.. following me? What that really means is, that if you for example want to put a string in your struct, you need to make a new struct, put the data in that, and set the member in the old struct as the pointer to the new... It is done like this so it doesn't screw up the struct size. Example: WRONG: DllStructSetData($Cred,"TargetName","\\servername"); GOOD: $TargetName = DllStructCreate("wchar[100]") DllStructSetData($TargetName,1,"\\servername") DllStructSetData($Cred,"TargetName",DllStructGetPtr($TargetName)) I know it seems a little tricky... But autoit wasn't really designed to do this kind of stuff painless. Nested structs makes it even worse. But youre on the right track! Ever wanted to call functions in another process? ProcessCall UDFConsole stuff: Console UDFC Preprocessor for AutoIt OMG
jazzyjeff Posted September 22, 2011 Author Posted September 22, 2011 Thanks Beege and Shaggi. I'm not ignoring your responses, I am just trying to figure everything you have told me out. I'll keep you posted on how I make out. Thanks for all your help.
jazzyjeff Posted September 22, 2011 Author Posted September 22, 2011 You guys have been great help and I feel like I am learning a lot about this... just not enough to get it working. So I have been reading the help file more about DLLStructs, and so I figured I would try output the values to the Console. expandcollapse popup$tagFILETIME = "DWORD lowpart;DWORD highpart;" $tagCREDENTIAL_ATTRIBUTE = "wchar* Keyword;DWORD Flags; DWORD ValueSize; byte* Value;" $tagCREDENTIAL= "" & _ "DWORD Flags;" & _ "DWORD Type;" & _ "wchar* TargetName;" & _ "wchar* Comment;" & _ $tagFILETIME & _ "DWORD CredintialBlobSize;" & _ "byte* CredentialBlob;" & _ "DWORD Persist;" & _ "DWORD AttributeCount;" & _ "ptr Attributes;" & _ ; CREDENTIAL_ATTRIBUTE * Attributes, that is, array of those "wchar* TargetAlias;" & _ "wchar* Username;" $Cred = DllStructCreate($tagCREDENTIAL) DllStructSetData($Cred,"Flags",0x04); DllStructSetData($Cred,"Type",0x02); DllStructSetData($Cred,"Persist",0x02); DllStructSetData($Cred,"AttributeCount",64); DllStructSetData($Cred,$tagFILETIME,@HOUR & ":" & @MIN); DllStructSetData($Cred,"CredentialBlobSize",512); $targetName = DllStructCreate("wchar[100]") DllStructSetData($targetName,1,"[url="file://\\servername"]\\servername[/url]") DllStructSetData($Cred, "TargetName",DllStructGetPtr($targetName)) $comment = DllStructCreate("wchar[100]") DllStructSetData($comment,1,"Comment") DllStructSetData($Cred,"Comment",DllStructGetPtr($targetName)) $credentialBlob = DllStructCreate("byte[100]") DllStructSetData($credentialBlob,1,"Password") DllStructSetData($Cred,"CredentialBlob",DllStructGetPtr($credentialBlob)); $targetAlias = DllStructCreate("wchar[100]") DllStructSetData($targetAlias,1,"Server") DllStructSetData($Cred,"TargetAlias",DllStructGetPtr($targetAlias)); $username = DllStructCreate("wchar[100]") DllStructSetData($username,1,"domain\username") DllStructSetData($Cred,"Username",DllStructGetPtr($username)); DllCall('advapi32.dll', 'int', 'CredWriteW', 'ptr', DllStructGetPtr($Cred), 'dword', 0) $1 = DllStructGetData($Cred,"Flags") $2 = DllStructGetData($Cred,"Type") $3 = DllStructGetData($Cred,"TargetName") $4 = DllStructGetData($Cred,"Comment") $5 = DllStructGetData($Cred, $tagFILETIME) $6 = DllStructGetData($Cred,"CredentialBlobSize") $7 = DllStructGetData($Cred,"CredentialBlob") $8 = DllStructGetData($Cred,"Persist") $9 = DllStructGetData($Cred,"AttributeCount") $10 = DllStructGetData($Cred,"TargetAlias") $11 = DllStructGetData($Cred,"Username") ConsoleWrite(@CRLF & $1 & @CRLF & $2 & @CRLF & $3 & @CRLF & $4 & @CRLF & $5 & @CRLF & $6 & @CRLF & $7 & @CRLF & $8 & @CRLF & $9 & @CRLF & $10 & @CRLF & $11 & @CRLF) All the values come to 0, so I am sure I am not obtaining the data properly from the DLLStruct.So your example said to create a new DLLStruct when there is a string(?). Do you also have to do that for hex and decimal values? I did try on one and it didn't make a difference. I'll explain how I am reading this and then perhaps you can tell me how I am looking at this all wrong. We first create 2 variables:$tagFILETIME - I have no idea really what information we are trying to get here.$tagCredential_Attribute - Here we are telling the DLLStruct Types how to interpret the data. i.e. wchar* is a string/keyword. $tagCredential - As required by the API we obtain/assign data that is used/required by the function in the DLL. i.e.TargetName, Username etc.We then create the DLLStruct with the values in $tagCredential. We then are required to set the data/values for each attribute set in the DLLStruct. I.e. set the value of "Flags" to 0x04.Now I create a new struct for the Attributes in $tagCredential and point the new struct back to the $cred struct.Once I have repeated this for the other structs with string values, I then call the DLL with the function and point it to the variable of the first struct I created. If you can offer anymore advice. Sorry for sounding a dumb ass, but as much as it may seem that I am not following along, I do feel like I am learning here! :-)
jazzyjeff Posted September 23, 2011 Author Posted September 23, 2011 Hello, So I think I have a better understanding of why $tagCredential is there. I found the MSDN notes on the "Attributes" part of the DLLStruct and I realise the point of the array as mentioned in the notes. So I now have that implemented in the script. I am still not able to ouptut values to the console that I have specified though. Looking at how Yashied codes his API's I see that he seems to call the DLL first. I have tried this, but that doesn't make a difference to the result I get. If I could get some more help in understanding this, that would be great. Thanks, Jeff expandcollapse popupGlobal $attributes,$comment,$Cred,$credentialBlob,$tagCREDENTIAL,$tagCREDENTIAL_ATTRIBUTE,$tagFILETIME,$targetAlias,$targetName,$username DllCall('advapi32.dll', 'int', 'CredWriteW', 'ptr', DllStructGetPtr($Cred), 'dword', 0) $tagFILETIME = "DWORD lowpart;DWORD highpart;" $tagCREDENTIAL_ATTRIBUTE = "wchar* Keyword;DWORD Flags; DWORD ValueSize; byte* Value;" $tagCREDENTIAL= "" & _ "DWORD Flags;" & _ "DWORD Type;" & _ "wchar* TargetName;" & _ "wchar* Comment;" & _ $tagFILETIME & _ "DWORD CredintialBlobSize;" & _ "byte* CredentialBlob;" & _ "DWORD Persist;" & _ "DWORD AttributeCount;" & _ "ptr Attributes;" & _ ; CREDENTIAL_ATTRIBUTE * Attributes, that is, array of those "wchar* TargetAlias;" & _ "wchar* Username;" $Cred = DllStructCreate($tagCREDENTIAL) DllStructSetData($Cred,"Flags",0x04); DllStructSetData($Cred,"Type",0x02); DllStructSetData($Cred,"Persist",0x02); DllStructSetData($Cred,"AttributeCount",0); DllStructSetData($Cred,$tagFILETIME,@HOUR & ":" & @MIN); DllStructSetData($Cred,"CredentialBlobSize",512); $attributes = DllStructCreate($tagCREDENTIAL_ATTRIBUTE) DllStructSetData($attributes,1,"") DllStructSetData($Cred, "Keyword",DllStructGetPtr($attributes)) $attributes = DllStructCreate($tagCREDENTIAL_ATTRIBUTE) DllStructSetData($attributes,2,0) DllStructSetData($Cred, "Flags",DllStructGetPtr($attributes)) $attributes = DllStructCreate($tagCREDENTIAL_ATTRIBUTE) DllStructSetData($attributes,3,256) DllStructSetData($Cred, "ValueSize",DllStructGetPtr($attributes)) $attributes = DllStructCreate($tagCREDENTIAL_ATTRIBUTE) DllStructSetData($attributes,4,"") DllStructSetData($Cred, "Value",DllStructGetPtr($attributes)) $targetName = DllStructCreate("wchar[100]") DllStructSetData($targetName,1,"\\servername") DllStructSetData($Cred, "TargetName",DllStructGetPtr($targetName)) $comment = DllStructCreate("wchar[100]") DllStructSetData($comment,1,"Comment") DllStructSetData($Cred,"Comment",DllStructGetPtr($targetName)) $credentialBlob = DllStructCreate("byte[100]") DllStructSetData($credentialBlob,1,"Password") DllStructSetData($Cred,"CredentialBlob",DllStructGetPtr($credentialBlob)); $targetAlias = DllStructCreate("wchar[100]") DllStructSetData($targetAlias,1,"Server") DllStructSetData($Cred,"TargetAlias",DllStructGetPtr($targetAlias)); $username = DllStructCreate("wchar[100]") DllStructSetData($username,1,"domain\username") DllStructSetData($Cred,"Username",DllStructGetPtr($username)); $1 = DllStructGetData($Cred,"Flags") $2 = DllStructGetData($Cred,"Type") $3 = DllStructGetData($Cred,"TargetName") $4 = DllStructGetData($Cred,"Comment") $5 = DllStructGetData($Cred, $tagFILETIME) $6 = DllStructGetData($Cred,"CredentialBlobSize") $7 = DllStructGetData($Cred,"CredentialBlob") $8 = DllStructGetData($Cred,"Persist") $9 = DllStructGetData($Cred,"AttributeCount") $10 = DllStructGetData($Cred,"Attributes",1) $11 = DllStructGetData($Cred,"Attributes",2) $12 = DllStructGetData($Cred,"Attributes",3) $13 = DllStructGetData($Cred,"Attributes",4) $14 = DllStructGetData($Cred,"TargetAlias") $15 = DllStructGetData($Cred,"Username") ConsoleWrite(@CRLF & $1 & @CRLF & $2 & @CRLF & $3 & @CRLF & $4 & @CRLF & $5 & @CRLF & $6 & @CRLF & $7 & @CRLF & $8 & @CRLF & $9 & @CRLF & $10 & @CRLF & $11 & @CRLF & $12 & @CRLF & $13 & @CRLF & $14 & @CRLF & $15 & @CRLF)
Shaggi Posted September 24, 2011 Posted September 24, 2011 Check @error after creating the struct, autoit might not support type pointers iirc. To solve this, replace every xxx* with ptr and try again. Ever wanted to call functions in another process? ProcessCall UDFConsole stuff: Console UDFC Preprocessor for AutoIt OMG
KarlEm Posted May 1, 2014 Posted May 1, 2014 (edited) Too sad, that not the final code was posted. Here is my code. For Domain Credentials: DllStructSetData($NewCred,"Type",2) For Generic change:  DllStructSetData($NewCred,"Type",1)        Global $Target =  "MeinServer" Global $User = "MeineDomainMeinUser" Global $Password = "MeinPWD" Global $Comm = "mein Kommentar"  Global $Comment = DllStructCreate("wchar[100]") DllStructSetData($Comment,1,$Comm)  Global $targetName = DllStructCreate("wchar[100]") DllStructSetData($targetName,1,$Target)  Global $userName = DllStructCreate("wchar[100]") DllStructSetData($userName,1,$User)  Global $credentialBlob = DllStructCreate("wchar[100]") DllStructSetData($credentialBlob,1,$Password)   Global $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"   Global $NewCred = DllStructCreate($structCREDENTIAL) If @error Then MsgBox(0, "NewCred", "Error in DllStructCreate " & @error); Exit EndIf   DllStructSetData($NewCred,"Flags",0)    DllStructSetData($NewCred,"Type",2)    DllStructSetData($NewCred,"TargetName",DllStructGetPtr($targetName))    DllStructSetData($NewCred,"Persist",3)  DllStructSetData($NewCred,"AttributeCount",0)  DllStructSetData($NewCred,"UserName",DllStructGetPtr($userName))  DllStructSetData($NewCred,"CredentialBlob",DllStructGetPtr($credentialBlob))  DllStructSetData($NewCred,"CredintialBlobSize",StringLen($Password)*2)  DllStructSetData($NewCred,"Comment",DllStructGetPtr($Comment))  #comments-start MsgBox(0, "DllStruct", "Data:" & @CRLF & _     "Flags: " & DllStructGetData($NewCred, "Flags") & @CRLF & _ "Type: " & DllStructGetData($NewCred,"Type") & @CRLF & _   "TargetName: " &  DllStructGetData($NewCred,"TargetName") & @CRLF & _   "Persist: " & DllStructGetData($NewCred,"Persist") & @CRLF & _ "AttributeCount: " &  DllStructGetData($NewCred,"AttributeCount") & @CRLF & _ "UserName: " &  DllStructGetData($NewCred,"UserName") & @CRLF & _ "CredentialBlob: " &  DllStructGetData($NewCred,"CredentialBlob") & @CRLF & _ "CredintialBlobSize: " &  DllStructGetData($NewCred,"CredintialBlobSize") & @CRLF & _ "Comment: " &  DllStructGetData($NewCred,"Comment")) #comments-end  Local $hAdvapi32 = DllOpen("Advapi32.dll") If @error Then Msgbox (0,"Error","Cannot open Advapi32.dll") Exit Endif $Ret = DllCall($hAdvapi32, 'bool', 'CredWriteW', 'ptr', DllStructGetPtr($NewCred), 'dword', 0)  $NewCred = 0 Edited May 1, 2014 by KarlEm
garbb Posted June 23, 2014 Posted June 23, 2014 (edited) I was able to use that code to do CredWrite successfully and even got CredDelete to work, but I can't get CredRead to work. You can see the entry written appear in windows control panel->credential manager. Here is what I have so far: expandcollapse popup#include <array.au3> ;~ CredWrite("MeinServer", "MeineDomain\MeinUser", "MeinPWD", "mein Kommentar") ;~ CredDelete("MeinServer") CredRead("MeinServer") Func CredRead($Target) Local $targetName = DllStructCreate("wchar[100]") DllStructSetData($targetName,1,$Target) Local $Comment = DllStructCreate("wchar[100]") Local $userName = DllStructCreate("wchar[100]") Local $credentialBlob = DllStructCreate("wchar[100]") 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 $OutCred = DllStructCreate($structCREDENTIAL) DllStructSetData($OutCred,"TargetName",DllStructGetPtr($targetName)) DllStructSetData($OutCred,"UserName",DllStructGetPtr($userName)) DllStructSetData($OutCred,"CredentialBlob",DllStructGetPtr($credentialBlob)) DllStructSetData($OutCred,"Comment",DllStructGetPtr($Comment)) Local $hAdvapi32 = DllOpen("Advapi32.dll") $Ret = DllCall($hAdvapi32, 'bool', 'CredReadW', 'ptr', DllStructGetPtr($targetName), 'dword', 1, 'dword', 0, 'ptr', DllStructGetPtr($OutCred)) _ArrayDisplay($Ret) $user = DllStructGetData($userName, 1) ConsoleWrite( $user & @CR) Return $user EndFunc func CredDelete($Target) Local $targetName = DllStructCreate("wchar[100]") DllStructSetData($targetName,1,$Target) Local $hAdvapi32 = DllOpen("Advapi32.dll") $Ret = DllCall($hAdvapi32, 'bool', 'CredDeleteW', 'ptr', DllStructGetPtr($targetName), 'dword', 1, 'dword', 0) EndFunc Func CredWrite($Target, $User, $Password, $Comm) Local $targetName = DllStructCreate("wchar[100]") DllStructSetData($targetName,1,$Target) Local $userName = DllStructCreate("wchar[100]") DllStructSetData($userName,1,$User) Local $credentialBlob = DllStructCreate("wchar[100]") DllStructSetData($credentialBlob,1,$Password) Local $Comment = DllStructCreate("wchar[100]") DllStructSetData($Comment,1,$Comm) 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",1) DllStructSetData($NewCred,"TargetName",DllStructGetPtr($targetName)) DllStructSetData($NewCred,"Persist",3) DllStructSetData($NewCred,"AttributeCount",0) DllStructSetData($NewCred,"UserName",DllStructGetPtr($userName)) DllStructSetData($NewCred,"CredentialBlob",DllStructGetPtr($credentialBlob)) DllStructSetData($NewCred,"CredintialBlobSize",StringLen($Password)*2) DllStructSetData($NewCred,"Comment",DllStructGetPtr($Comment)) Local $hAdvapi32 = DllOpen("Advapi32.dll") If @error Then Msgbox (0,"Error","Cannot open Advapi32.dll") Exit Endif $Ret = DllCall($hAdvapi32, 'bool', 'CredWriteW', 'ptr', DllStructGetPtr($NewCred), 'dword', 0) $NewCred = 0 EndFunc The DLL call to CredReadW will only return 1 if I call it with a Targetname for a credential that actually exists so I believe that it is working but I can't seem to get the data out of the output Credential struct. Or at least I think its a struct... For CredWrite MSDN says that the PCREDENTIAL parameter is pointer to a credential structure but for CredRead it says that PCREDENTIAL is a "Pointer to a single allocated block buffer to return the credential." Is this a pointer to a credential structure or something else? Does anyone know? Either that or it is a pointer to a struct and I just can't get the data out. What is confusing me is that the credential structure has pointers to other structures/data types. What I did is create the other datatypes (like strings) and put their pointers into a credential structure and then pass the pointer of that credential structure to the CredRead function. I expected that the data I was interested in would be in the first data structures I made after the dll call was successful, but they contain nothing or a null string. Is this the correct way to do this? Here is some code on stackoverflow that does credwrite and credread in C? or some other language. Edited June 23, 2014 by garbb Parsix 1
Danyfirex Posted June 23, 2014 Posted June 23, 2014 I really don't know why the structure has no the data(I just see a little bit), but if you do something like this can see that you want: expandcollapse popupFunc CredRead($Target) Local $targetName = DllStructCreate("wchar[100]") DllStructSetData($targetName,1,$Target) Local $Comment = DllStructCreate("wchar[100]") Local $userName = DllStructCreate("wchar[100]") Local $credentialBlob = DllStructCreate("wchar[100]") 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 $OutCred = DllStructCreate($structCREDENTIAL) ;~ DllStructSetData($OutCred,"TargetName",DllStructGetPtr($targetName)) ;~ DllStructSetData($OutCred,"UserName",DllStructGetPtr($userName)) ;~ DllStructSetData($OutCred,"CredentialBlob",DllStructGetPtr($credentialBlob)) ;~ DllStructSetData($OutCred,"Comment",DllStructGetPtr($Comment)) Local $hAdvapi32 = DllOpen("Advapi32.dll") $Ret = DllCall($hAdvapi32, 'bool', 'CredReadW', 'ptr', DllStructGetPtr($targetName), 'dword', 1, 'dword', 0, 'ptr*', 0) _ArrayDisplay($Ret) Local $tdata=DllStructCreate("byte[200]",$Ret[4]) FileWrite("data.txt",(DllStructGetData($tdata,1))) ShellExecute("data.txt") Return 0 EndFunc Saludos Parsix and garbb 1 1  Danysys.com     AutoIt...  UDFs: VirusTotal API 2.0 UDF - libZPlay UDF - Apps: Guitar Tab Tester - VirusTotal Hash Checker Examples: Text-to-Speech ISpVoice Interface - Get installed applications - Enable/Disable Network connection  PrintHookProc - WINTRUST - Mute Microphone Level - Get Connected NetWorks - Create NetWork Connection ShortCut  Â
garbb Posted June 23, 2014 Posted June 23, 2014 (edited) Thank you! I didn't realize that I could specify a ptr* as a parameter type or that I could create a struct and tell it to use a pointer. I finally made it work. Here's the working CredRead function: expandcollapse popupFunc CredRead($Target) Local $FuncRet[3] Local $targetName = DllStructCreate("wchar[100]") DllStructSetData($targetName,1,$Target) Local $hAdvapi32 = DllOpen("Advapi32.dll") Local $Ret = DllCall($hAdvapi32, 'bool', 'CredReadW', 'ptr', DllStructGetPtr($targetName), 'dword', 1, '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) Local $Comment = DllStructCreate("wchar[100]", DllStructGetData($tdata, 'Comment')) Local $Comm = DllStructGetData($Comment, 1) Dim $FuncRet[] = [$User, $Password, $Comm] Return $FuncRet EndFunc It returns the username, password, and comment in an array. Edited June 23, 2014 by garbb
Danyfirex Posted June 23, 2014 Posted June 23, 2014 You're welcome. I did as you say first, but it did not work.(maybe I forget something.) :S Saludos  Danysys.com     AutoIt...  UDFs: VirusTotal API 2.0 UDF - libZPlay UDF - Apps: Guitar Tab Tester - VirusTotal Hash Checker Examples: Text-to-Speech ISpVoice Interface - Get installed applications - Enable/Disable Network connection  PrintHookProc - WINTRUST - Mute Microphone Level - Get Connected NetWorks - Create NetWork Connection ShortCut  Â
Schnuffel Posted August 5, 2014 Posted August 5, 2014 Hi @ all, i need a function that read the Domain credentials. As MSDN write's there is a difference in getting the result from the dllcall. Generic Credentials are Read like this: http://msdn.microsoft.com/en-us/library/windows/desktop/ff714499(v=vs.85).aspx Domain Credentials are read like that: http://msdn.microsoft.com/en-us/library/windows/desktop/ff714500(v=vs.85).aspx The difference is, that in the output there is a double **, that means that there is a Ptr to a Ptr to an Array... Plese help to get the above function from garbb working with domain Credentials. Thank You all for Helping ^^ Schnuffel The two basic principles of Windows system administration: For minor problems, reboot -- For major problems, reinstall "Sarkasm is the lowest form of humor, but the highest form of intelligenz" Val McDermid  no advertising: If you want to translate your texts into another language, I can only recommend deepl.com. I am very satisfied with the translations.
garbb Posted August 5, 2014 Posted August 5, 2014 It looks like a pointer to a pointer to an array of ENCRYPTED_CREDENTIALW structures and each one of those has as its first member a pointer to a CREDENTIAL structure which is the same as I was using in my credread() above to pull out the username and password: Local $structCREDENTIAL= "" & .... etc But then you may have a problem because it says on the MSDN page for the CREDENTIAL structure that Also, for CRED_TYPE_DOMAIN_PASSWORD, this member can only be read by the authentication packages.  And if you google for more info about this you will find that: Domain network password method uses more stricter technique for encrypting the credentials thus providing better security over other methods. Only system process, LSASS.EXE can encrypt or decrypt these kind of passwords. LSASS is a Windows core system process responsible for enforcing the security and executing various security oriented tasks.  So in order to decrypt domain passwords one has to perform decryption in the context of LSASS process. This can be achieved by injecting remote thread into LSASS process using CreateRemoteThread function  And so I think in order to read stored domain passwords you must do a bit more hackery. There is other software that exists (of varying legitimacy) that will get you the information that you want... ...of course I am assuming that whatever you are trying to do is all for legitimate purposes...
Schnuffel Posted August 7, 2014 Posted August 7, 2014 ty a lot garbb, as i don't want to "hack" the credentials i decided to go a different way without reading the domain cred's. I delete the Cred's that are in my interst and write them new with the user and Pass the user put in my Prog. I only wanted to check the cred's on a domain if they are locked or something like that. thx a lot Schnuffel The two basic principles of Windows system administration: For minor problems, reboot -- For major problems, reinstall "Sarkasm is the lowest form of humor, but the highest form of intelligenz" Val McDermid  no advertising: If you want to translate your texts into another language, I can only recommend deepl.com. I am very satisfied with the translations.
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now