Jump to content

DllCall CryptGenRandom


Pain
 Share

Recommended Posts

As far as I know CryptAcquireContext works so that's not the problem, the problem gotta be somewhere else...

I'm not sure if I got right types but according to binaryworld it should be long, long, string but other pages says it should be long, dword, byte.

I'm confused :/

Func CryptGenRandom()
Local $hProv = CryptAcquireContext()
If @error = 0 Then
Local $dwLen = 8
Local $pbBuffer = DLLStructCreate("byte[" & 16 & "]")
Local $call = DllCall("advapi32.dll", "long", "CryptGenRandom", _
"long", $hProv, _
"long", $dwLen, _
"str", DllStructGetPtr($pbBuffer))
Return $call[0]
Else
MsgBox(0, "An Error Occurred", "Error")
EndIf
EndFunc

I've been using these links to get information from

http://msdn.microsoft.com/en-us/library/aa379942.aspx

http://binaryworld.net/Main/ApiDetail.aspx?ApiId=955

Btw, this is the first time I'm making a DllCall on my own.

Edited by Pain
Link to comment
Share on other sites

Since you've only provided part of the code and I can't test unless I write a working CryptAcquireContext(),

But as a guess you need to check the $pbBuffer for the returned data..

Also from what I can see last data type is also incorrect in the dll call eg:

"str", DllStructGetPtr($pbBuffer)

should be something like

"ptr", DllStructGetPtr($pbBuffer)

As I say though I don't feel like writing the whole thing from scratch so I'm only speculating.

Cheers

Link to comment
Share on other sites

Here you got, I didn't write this myself, I only modified it (and I even made an UDF with it).

Func CryptAcquireContext()
    Local $phProv = DllStructCreate("dword")
    If @error <> 0 Then
        SetError(99)
        Return 0
    EndIf
    Local $call = DllCall("advapi32.dll", "long", "CryptAcquireContextA", _
                        "ptr", DllStructGetPtr($phProv), _
                        "ptr", 0, _
                        "ptr", 0, _
                        "long", 1, _
                        "long", 0)

    If @error = 0 And $call[0] <> 0 Then
        Return DllStructGetData($phProv, 1)
    ElseIf @error = 0 Then
        $call = DllCall("kernel32.dll", "long", "GetLastError")
        If $call[0] = 0x80090016 Then
            $call = DllCall("advapi32.dll", "long", "CryptAcquireContextA", _
                            "ptr", DllStructGetPtr($phProv), _
                            "ptr", 0, _
                            "ptr", 0, _
                            "long", 1, _
                            "long", 0x00000008)

            If @error = 0 And $call[0] <> 0 Then
                Return DllStructGetData($phProv, 1)
            ElseIf @error = 0 Then
                $call = DllCall("kernel32.dll", "long", "GetLastError")
                SetError(1, $call[0])
                Return 0
            Else
                SetError(98)
                Return 0
            EndIf
        Else
            SetError($call[0])
            Return 0
        EndIf
    Else
        SetError(97)
        Return 0
    EndIf
EndFunc;==>CryptAcquireContext

edit: after changing to long, long, ptr and return the 3rd parameter I got a hex but it didn't change.

Edited by Pain
Link to comment
Share on other sites

I had to Google around a bit for this one myself, but the following seems to work for me. YMMV

Func CryptGenRandom($dwLen = 8)
    Local $hProv = CryptAcquireContext()
    If @error = 0 Then
        Local $pbBuffer = DLLStructCreate("byte[" & $dwLen & "]")
        Local $call = DllCall("advapi32.dll", "int", "CryptGenRandom", _
                            "ptr", $hProv, _
                            "dword", $dwLen, _
                            "ptr", DllStructGetPtr($pbBuffer))
        Return DllStructGetData($pbBuffer, 1)
    Else
        MsgBox(0, "An Error Occurred", "Error")
    EndIf
EndFunc

Func CryptAcquireContext()
    Local $phProv = DllStructCreate("ulong_ptr")
    Local $call = DllCall("advapi32.dll", "long", "CryptAcquireContext", _
                        "ptr", DllStructGetPtr($phProv), _
                        "str", '', _
                        "str", '', _
                        "dword", 1, _
                        "dword", 0xF0000000)

    If @error = 0 And $call[0] <> 0 Then
        Return DllStructGetData($phProv, 1)
    ElseIf @error = 0 Then
        $call = DllCall("kernel32.dll", "int", "GetLastError")
        If $call[0] = 0x80090016 Then
            $call = DllCall("advapi32.dll", "long", "CryptAcquireContext", _
                            "ptr", DllStructGetPtr($phProv), _
                            "ptr", 0, _
                            "ptr", 0, _
                            "long", 1, _
                            "long", 0xF0000008)

            If @error = 0 And $call[0] <> 0 Then
                Return DllStructGetData($phProv, 1)
            ElseIf @error = 0 Then
                $call = DllCall("kernel32.dll", "long", "GetLastError")
                SetError(1, $call[0])
                Return 0
            Else
                SetError(98)
                Return 0
            EndIf
        Else
            SetError($call[0])
            Return 0
        EndIf
    Else
        SetError(97)
        Return 0
    EndIf
EndFunc;==>CryptAcquireContext
Link to comment
Share on other sites

Thanks alot SkinnyWhiteGuy, it's working but I still can't understand how to get the correct type. Everywhere I look it's different even if the code is to the same language. However I do know that types like int and long are same as far as I know.

Any tips or hints would be appreciated.

Link to comment
Share on other sites

The types on the MSDN page you listed are right, and they should be, Microsoft made the dll we're using. The reason other people use other types is that some types are the same size internally to the operating system, so whether it thinks of it as one or the other doesn't really matter, until you get into end cases, as well as 32-bit vs 64-bit.

For AutoIt, Jon and the others who work on the help file were nice enough to put a chart in there (under the function helps for DllCall() and DllStructCreate() ) that detail the specific sizes of types, and some conversions from Microsoft world to AutoIt world. I read through some of those, along with a good many articles on MSDN, till I came up with the set of those that I have.

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...