Jump to content

Base64 Machine Code Functions + Source


Beege
 Share

Recommended Posts

Here's 2 base64 machine code functions I wrote that came out pretty good. Both encode and decode are x64 capable. Comparing times for encoding/decoding the autoit.exe with Microsofts functions, I got them beat by a good percentage for both x84/x64 decode functions. I'm pretty sure thats due to my reverse index idea. It ended up working very well.  I beat there x86 encode by a little bit, but they got me beat by just a hair for x64 encode. The attachment includes example that has the time tests I did, plus has the assembly source. Let me know if you have any issues or see something that is scewing my results somehow. Thanks!

Func _B64Decode($sSource)

    Local Static $Opcode, $tMem, $tRevIndex, $fStartup = True

    If $fStartup Then
        If @AutoItX64 Then
            $Opcode = '0xC800000053574D89C74C89C74889D64889CB4C89C89948C7C10400000048F7F148C7C10300000048F7E14989C242807C0EFF3D750E49FFCA42807C0EFE3D750349FFCA4C89C89948C7C10800000048F7F14889C148FFC1488B064989CD48C7C108000000D7C0C0024188C349C1E30648C1E808E2EF49C1E308490FCB4C891F4883C7064883C6084C89E9E2CB4C89D05F5BC9C3'
        Else
            $Opcode = '0xC8080000FF75108B7D108B5D088B750C8B4D148B06D7C0C00288C2C1E808C1E206D7C0C00288C2C1E808C1E206D7C0C00288C2C1E808C1E206D7C0C00288C2C1E808C1E2060FCA891783C70383C604E2C2807EFF3D75084F807EFE3D75014FC6070089F85B29D8C9C21000'
        EndIf

        Local $aMemBuff = DllCall("kernel32.dll", "ptr", "VirtualAlloc", "ptr", 0, "ulong_ptr", BinaryLen($Opcode), "dword", 4096, "dword", 64)
        $tMem = DllStructCreate('byte[' & BinaryLen($Opcode) & ']', $aMemBuff[0])
        DllStructSetData($tMem, 1, $Opcode)

        Local $aRevIndex[128]
        Local $aTable = StringToASCIIArray('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/')
        For $i = 0 To UBound($aTable) - 1
            $aRevIndex[$aTable[$i]] = $i
        Next
        $tRevIndex = DllStructCreate('byte[' & 128 & ']')
        DllStructSetData($tRevIndex, 1, StringToBinary(StringFromASCIIArray($aRevIndex)))

        $fStartup = False
    EndIf

    Local $iLen = StringLen($sSource)
    Local $tOutput = DllStructCreate('byte[' & $iLen + 8 & ']')
    DllCall("kernel32.dll", "bool", "VirtualProtect", "struct*", $tOutput, "dword_ptr", DllStructGetSize($tOutput), "dword", 0x00000004, "dword*", 0)

    Local $tSource = DllStructCreate('char[' & $iLen + 8 & ']')
    DllStructSetData($tSource, 1, $sSource)

    Local $aRet = DllCallAddress('uint', DllStructGetPtr($tMem), 'struct*', $tRevIndex, 'struct*', $tSource, 'struct*', $tOutput, 'uint', (@AutoItX64 ? $iLen : $iLen / 4))

    Return BinaryMid(DllStructGetData($tOutput, 1), 1, $aRet[0])

EndFunc   ;==>_B64Decode


Func _B64Encode($sSource)

    Local Static $Opcode, $tMem, $fStartup = True

    If $fStartup Then
        If @AutoItX64 Then
            $Opcode = '0xC810000053574889CE4889D74C89C34C89C89948C7C10600000048F7F14889C14883FA00740348FFC1488B06480FC848C1E80EC0E802D788470748C1E806C0E802D788470648C1E806C0E802D788470548C1E806C0E802D788470448C1E806C0E802D788470348C1E806C0E802D788470248C1E806C0E802D788470148C1E806C0E802D788074883C6064883C708E2994883FA00743B49C7C5060000004929D54883FA03770349FFC54C29EF4883FA03741F4883FA01740E4883FA047408C6073D48FFC7EB0BC6073DC647013D4883C702C607005F5BC9C3'
        Else
            $Opcode = '0xC80800008B451499B903000000F7F189C1528B5D108B75088B7D0C83FA007401418B160FCAC1EA0888D0243FD7884703C1EA0688D0243FD7884702C1EA0688D0243FD7884701C1EA0688D0243FD7880783C60383C704E2C95A83FA00740DC647FF3D83FA027404C647FE3DC60700C9C21000'
        EndIf

        Local $aMemBuff = DllCall("kernel32.dll", "ptr", "VirtualAlloc", "ptr", 0, "ulong_ptr", BinaryLen($Opcode), "dword", 4096, "dword", 64)
        $tMem = DllStructCreate('byte[' & BinaryLen($Opcode) & ']', $aMemBuff[0])
        DllStructSetData($tMem, 1, $Opcode)

        $fStartup = False
    EndIf

    $sSource = Binary($sSource)
    Local $iLen = BinaryLen($sSource)

    $tSource = DllStructCreate('byte[' & $iLen & ']')
    DllStructSetData($tSource, 1, $sSource)

    Local $tOutput = DllStructCreate('char[' & Ceiling($iLen * (4 / 3) + 3) & ']')
    DllCall("kernel32.dll", "bool", "VirtualProtect", "struct*", $tOutput, "dword_ptr", DllStructGetSize($tOutput), "dword", 0x00000004, "dword*", 0)

    Local $sTable = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'

    DllCallAddress('none', DllStructGetPtr($tMem), 'struct*', $tSource, 'struct*', $tOutput, 'str', $sTable, 'uint', $iLen)

    Return DllStructGetData($tOutput, 1)

EndFunc   ;==>_B64Encode

Results: x86

>_B64Encode avg =   121.71071578269
_Base64Encode_MS avg =  133.64460931775
>_B64Decode avg =   106.147524856932
_Base64Decode_MS avg =  149.362345205542

Results: x64

>_B64Encode avg =   123.473349548198
_Base64Encode_MS avg =  122.300780993821
>_B64Decode avg =   113.430527477353
_Base64Decode_MS avg =  170.667366205978

b64.zip

Edited by Beege
Link to comment
Share on other sites

  • 2 months later...

Beege,

Thanks for your work on this! I am trying to sign a request to amazon MWS servers and I need to convert the signed HMAC string to Base64.  Amazon provides a scratchpad site that I am using to test my algorithm to make sure it is hashing properly and converting to Base64 as well.  So far I am doing fine at hashing and encrypting the request strings, but when I use your function to convert to Base64 it does not consistently give me the same output.

For example when the hash is:

e900fe550acdf319cf68b924f5625323ab89b1954753b2e9e429775e774511f4

then Amazon shows the Base64 to be:

6QD+VQrN8xnPaLkk9WJTI6uJsZVHU7Lp5Cl3XndFEfQ=

After running your function 10 times I get the following for each run:

1)   6QD+VQrN8xnPaLkk9WJTI6uJsZVHU7Lp5Cl3XndFEfQ=

2)   6QD+VQrN8xnPaLkk9WJTI6uJsZVHU7Lp5Cl3XndFEfQ=

3)   6QD+VQrN8xnPaLkk9WJTI6uJsZVHU7Lp5Cl3XndFEfS=

4)   6QD+VQrN8xnPaLkk9WJTI6uJsZVHU7Lp5Cl3XndFEfS=

5)   6QD+VQrN8xnPaLkk9WJTI6uJsZVHU7Lp5Cl3XndFEfQ=

6)   6QD+VQrN8xnPaLkk9WJTI6uJsZVHU7Lp5Cl3XndFEfS=

7)   6QD+VQrN8xnPaLkk9WJTI6uJsZVHU7Lp5Cl3XndFEfQ=

8)   6QD+VQrN8xnPaLkk9WJTI6uJsZVHU7Lp5Cl3XndFEfT=

9)   6QD+VQrN8xnPaLkk9WJTI6uJsZVHU7Lp5Cl3XndFEfQ=

10) 6QD+VQrN8xnPaLkk9WJTI6uJsZVHU7Lp5Cl3XndFEfR=

So, 50% of the time I am getting the correct conversion, but it is not consistent, and I have no idea what is going on.  I am running this with Autoit V3.3.10.2 on Windows 7 32 bit. Any insight as to what I am doing wrong? Thanks.

Link to comment
Share on other sites

  • 3 weeks later...

Thanks greatbrains, I believe this fixes the issue you pointed out. My function was not following the base64 rules when there were on odd number of bytes. I still have to workout the 64bit version as thats a little trickier for me. 

Func _B64Encode($sSource)

    ;####### (BinaryStrLen = 272) ########################################################################################################################
    Local Static $Opcode = '0xC80000008B451499B903000000F7F189C18B5D108B75088B7D0C83FA007401418B060FC8C1E806C0E802D7884703C1E806C0E802D7884702C1E806C0E802D7884701C1E806C0E802D7880783C60383C704E2CD83FA0074288B46FD0FC883FA027411C1E8142430D78847FD66C747FE3D3DEB0DC1E80E243CD78847FEC647FF3DC60700C9C21000'
    Local Static $aMemBuff = DllCall("kernel32.dll", "ptr", "VirtualAlloc", "ptr", 0, "ulong_ptr", BinaryLen($Opcode), "dword", 4096, "dword", 64)
    Local Static $tMem = DllStructCreate('byte[' & BinaryLen($Opcode) & ']', $aMemBuff[0])
    Local Static $set = DllStructSetData($tMem, 1, $Opcode)
    ;####################################################################################################################################################################################

    $sSource = Binary($sSource)
    Local $iLen = BinaryLen($sSource)

    $tSource = DllStructCreate('byte[' & $iLen & ']')
    DllStructSetData($tSource, 1, $sSource)

    Local $tOutput = DllStructCreate('char[' & Ceiling($iLen * (4 / 3) + 3) & ']')
    DllCall("kernel32.dll", "bool", "VirtualProtect", "struct*", $tOutput, "dword_ptr", DllStructGetSize($tOutput), "dword", 0x00000004, "dword*", 0)

    Local $sTable = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
    DllCallAddress('none', DllStructGetPtr($tMem), 'struct*', $tSource, 'struct*', $tOutput, 'str', $sTable, 'uint', $iLen)

    Return DllStructGetData($tOutput, 1)

EndFunc   ;==>_B64Encode

#cs Source
Func _B64Encode($sSource)

    _FasmFunc('str, $sSource, str, $sDest, str, $sTable, uint, $iLen')

    _FasmAdd('mov eax, $iLen') ;    div $iLen / 3 to calculate number of loops
    _FasmAdd('cdq')
    _FasmAdd('mov ecx, 3')
    _FasmAdd('div ecx')
    _FasmAdd('mov ecx, eax') ;      Set loops

    _Fasmadd('mov ebx, $sTable') ;  move table to ebx. Used in xlatb instruction
    _Fasmadd('mov esi, $sSource') ; set esi = source string
    _Fasmadd('mov edi, $sDest') ;   set edi = output string

    _FasmJumpIf('edx = 0, EncodeNext') ; need one extra loop if mod <> 0
    _FasmAdd('inc ecx')

    _FasmAdd('EncodeNext:')
    _Fasmadd('mov eax, [esi]') ;    move 4 bytes from source string to dex
    _FasmAdd('bswap eax') ;         reverse bytes. ex :(Man) 00000000 01101110 01100001 01001101 -> 01001101 01100001 01101110 00000000

    _FasmAdd('shr eax, 6')
    _FasmAdd('shr al, 2')
    _FasmAdd('xlatb')
    _FasmAdd('mov [edi+3], al')

    _FasmAdd('shr eax, 6')
    _FasmAdd('shr al, 2')
    _FasmAdd('xlatb')
    _FasmAdd('mov [edi+2], al')

    _FasmAdd('shr eax, 6')
    _FasmAdd('shr al, 2')
    _FasmAdd('xlatb')
    _FasmAdd('mov [edi+1], al')

    _FasmAdd('shr eax, 6')
    _FasmAdd('shr al, 2')
    _FasmAdd('xlatb')
    _FasmAdd('mov [edi], al')

    _Fasmadd('add esi, 3') ;        increase source by 3 bytes
    _fasmadd('add edi, 4') ;        increase destination by 4 bytes
    _Fasmadd('loop EncodeNext')

    _FasmJumpIf('edx = 0, Finished')

    _Fasmadd('mov eax, [esi-3]') ;
    _FasmAdd('bswap eax')

    _FasmJumpIf('edx = 2, TWO')

    ; If there was only one significant input byte, only the first two base64 digits are picked (12 bits)
    _FasmAdd("ONE:") ;  the four least significant bits of the final 6-bit block are set to zero
    _FasmAdd('shr eax, 20')
    _FasmAdd("and al, 48") ;00110000
    _FasmAdd('xlatb')
    _FasmAdd('mov [edi-3], al')
    _FasmAdd("mov [edi-2], word 15677"); '=='
    _FasmAdd("jmp Finished")

    ; if there were two significant input bytes, the first three base64 digits are picked (18 bits).
    _FasmAdd("TWO:") ;  the two least significant bits of the final 6-bit block are set to zero
    _FasmAdd("shr eax, 14")
    _FasmAdd("and al, 60") ; 60 : 00111100
    _FasmAdd('xlatb')
    _FasmAdd('mov [edi-2], al')
    _FasmAdd('mov [edi-1], byte 61') ; '='

    _FasmAdd('Finished:')
    _Fasmadd('  mov [edi], byte 0') ; terminate string with null
    _FasmEndFunc()

    Return _FasmCompileMC('_B64Encode')

    $sSource = Binary($sSource)
    Local $iLen = BinaryLen($sSource)

    $tSource = DllStructCreate('byte[' & $iLen & ']')
    DllStructSetData($tSource, 1, $sSource)

    Local $tOutput = DllStructCreate('char[' & Ceiling($iLen * (4 / 3) + 3) & ']')
    DllCall("kernel32.dll", "bool", "VirtualProtect", "struct*", $tOutput, "dword_ptr", DllStructGetSize($tOutput), "dword", 0x00000004, "dword*", 0)

    Local $sTable = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
    ConsoleWrite(StringInStr($sTable, '4') & @LF)

    _FasmQuickCall('none', 0, 'struct*', $tSource, 'struct*', $tOutput, 'str', $sTable, 'uint', $iLen)

    Return DllStructGetData($tOutput, 1)

EndFunc   ;==>_B64Encode
#ce
Link to comment
Share on other sites

It hangs for a minute and gives me an AutoIt error on decode of an encoded and encrypted string. Encoding works fine. Removing the decode method removes the error.

P.S. I tried compiling x86 and trying it through CLI and the process stopped responding.

I'm not sure if it's related, but AutoIt returns "1073741819" when it closes and researching that number leads to a common error.

 

That error corresponds to 0xFFFFFFFFC0000005 which is an access violation error.

This generally happens when you try to access a section of memory that is not available to you.

This happens when you use uninitialized pointers.

#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Change2CUI=y
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
#include <Constants.au3>
#include <Crypt.au3>
#include <ComboConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <WinAPI.au3>
#include <WindowsConstants.au3>
#include <MsgBoxConstants.au3>

Example()

Func Example()
    _Crypt_Startup() ; To optimize performance start the crypt library.

    Local $bAlgorithm = $CALG_AES_256
    $hKey = "Qr80lsjAmsZ3fjDb47sFt5jG55V6w728";_Crypt_DeriveKey("Qr80lsjAmsZ3fjDb47sFt5jG55V6w728", $bAlgorithm) ; Declare a password string and algorithm to create a cryptographic key.
    Local $sRead = "Hello! This is a test string."
    Local $bEncrypted = _B64Encode(_Crypt_EncryptData($sRead, $hKey,$bAlgorithm));, $CALG_USERKEY) ; Encrypt the text with the new cryptographic key.
    Local $bDecrypted = _B64Decode(_Crypt_DecryptData($bEncrypted, $hKey, $bAlgorithm))

    ConsoleWrite("Encrypted Data: " & $bEncrypted & @CRLF)
    ConsoleWrite("Decrypted Data: " & BinaryToString($bDecrypted) & @CRLF)
    _Crypt_DestroyKey($hKey) ; Destroy the cryptographic key.
    _Crypt_Shutdown() ; Shutdown the crypt library.
EndFunc   ;==>Example

Func _B64Decode($sSource)

    Local Static $Opcode, $tMem, $tRevIndex, $fStartup = True

    If $fStartup Then
        If @AutoItX64 Then
            $Opcode = '0xC800000053574D89C74C89C74889D64889CB4C89C89948C7C10400000048F7F148C7C10300000048F7E14989C242807C0EFF3D750E49FFCA42807C0EFE3D750349FFCA4C89C89948C7C10800000048F7F14889C148FFC1488B064989CD48C7C108000000D7C0C0024188C349C1E30648C1E808E2EF49C1E308490FCB4C891F4883C7064883C6084C89E9E2CB4C89D05F5BC9C3'
        Else
            $Opcode = '0xC8080000FF75108B7D108B5D088B750C8B4D148B06D7C0C00288C2C1E808C1E206D7C0C00288C2C1E808C1E206D7C0C00288C2C1E808C1E206D7C0C00288C2C1E808C1E2060FCA891783C70383C604E2C2807EFF3D75084F807EFE3D75014FC6070089F85B29D8C9C21000'
        EndIf

        Local $aMemBuff = DllCall("kernel32.dll", "ptr", "VirtualAlloc", "ptr", 0, "ulong_ptr", BinaryLen($Opcode), "dword", 4096, "dword", 64)
        $tMem = DllStructCreate('byte[' & BinaryLen($Opcode) & ']', $aMemBuff[0])
        DllStructSetData($tMem, 1, $Opcode)

        Local $aRevIndex[128]
        Local $aTable = StringToASCIIArray('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/')
        For $i = 0 To UBound($aTable) - 1
            $aRevIndex[$aTable[$i]] = $i
        Next
        $tRevIndex = DllStructCreate('byte[' & 128 & ']')
        DllStructSetData($tRevIndex, 1, StringToBinary(StringFromASCIIArray($aRevIndex)))

        $fStartup = False
    EndIf

    Local $iLen = StringLen($sSource)
    Local $tOutput = DllStructCreate('byte[' & $iLen + 8 & ']')
    DllCall("kernel32.dll", "bool", "VirtualProtect", "struct*", $tOutput, "dword_ptr", DllStructGetSize($tOutput), "dword", 0x00000004, "dword*", 0)

    Local $tSource = DllStructCreate('char[' & $iLen + 8 & ']')
    DllStructSetData($tSource, 1, $sSource)

    Local $aRet = DllCallAddress('uint', DllStructGetPtr($tMem), 'struct*', $tRevIndex, 'struct*', $tSource, 'struct*', $tOutput, 'uint', (@AutoItX64 ? $iLen : $iLen / 4))

    Return BinaryMid(DllStructGetData($tOutput, 1), 1, $aRet[0])

EndFunc   ;==>_B64Decode


Func _B64Encode($sSource)

    Local Static $Opcode, $tMem, $fStartup = True

    If $fStartup Then
        If @AutoItX64 Then
            $Opcode = '0xC810000053574889CE4889D74C89C34C89C89948C7C10600000048F7F14889C14883FA00740348FFC1488B06480FC848C1E80EC0E802D788470748C1E806C0E802D788470648C1E806C0E802D788470548C1E806C0E802D788470448C1E806C0E802D788470348C1E806C0E802D788470248C1E806C0E802D788470148C1E806C0E802D788074883C6064883C708E2994883FA00743B49C7C5060000004929D54883FA03770349FFC54C29EF4883FA03741F4883FA01740E4883FA047408C6073D48FFC7EB0BC6073DC647013D4883C702C607005F5BC9C3'
        Else
            $Opcode = '0xC80800008B451499B903000000F7F189C1528B5D108B75088B7D0C83FA007401418B160FCAC1EA0888D0243FD7884703C1EA0688D0243FD7884702C1EA0688D0243FD7884701C1EA0688D0243FD7880783C60383C704E2C95A83FA00740DC647FF3D83FA027404C647FE3DC60700C9C21000'
        EndIf

        Local $aMemBuff = DllCall("kernel32.dll", "ptr", "VirtualAlloc", "ptr", 0, "ulong_ptr", BinaryLen($Opcode), "dword", 4096, "dword", 64)
        $tMem = DllStructCreate('byte[' & BinaryLen($Opcode) & ']', $aMemBuff[0])
        DllStructSetData($tMem, 1, $Opcode)

        $fStartup = False
    EndIf

    $sSource = Binary($sSource)
    Local $iLen = BinaryLen($sSource)

    $tSource = DllStructCreate('byte[' & $iLen & ']')
    DllStructSetData($tSource, 1, $sSource)

    Local $tOutput = DllStructCreate('char[' & Ceiling($iLen * (4 / 3) + 3) & ']')
    DllCall("kernel32.dll", "bool", "VirtualProtect", "struct*", $tOutput, "dword_ptr", DllStructGetSize($tOutput), "dword", 0x00000004, "dword*", 0)

    Local $sTable = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'

    DllCallAddress('none', DllStructGetPtr($tMem), 'struct*', $tSource, 'struct*', $tOutput, 'str', $sTable, 'uint', $iLen)

    Return DllStructGetData($tOutput, 1)

EndFunc   ;==>_B64Encode

;QzTySku6eU/2VQhAFgXXntXGwz2cpKVccOC8zLJNguE=
Console output:

>"C:\Program Files (x86)\AutoIt3\SciTE\AutoIt3Wrapper\AutoIt3Wrapper.exe" /run /prod /ErrorStdOut /in "C:\Users\Owner\Dropbox\!Projects\!AutoIt\!Active\TeamViewer_Manager\TEMPTESTING.au3" /UserParams   
+>15:24:58 Starting AutoIt3Wrapper v.2.1.4.4 SciTE v.3.3.7.0 ;  Keyboard:00000409  OS:WIN_7/Service Pack 1  CPU:X64 OS:X64    Environment(Language:0409  Keyboard:00000409  OS:WIN_7/Service Pack 1  CPU:X64 OS:X64)
>Running AU3Check (3.3.10.2)  from:C:\Program Files (x86)\AutoIt3
+>15:24:59 AU3Check ended.rc:0
>Running:(3.3.10.2):C:\Program Files (x86)\AutoIt3\autoit3.exe "C:\Users\Owner\Dropbox\!Projects\!AutoIt\!Active\TeamViewer_Manager\TEMPTESTING.au3"   
--> Press Ctrl+Alt+F5 to Restart or Ctrl+Break to Stop
!>15:25:05 AutoIt3.exe ended.rc:-1073741819
+>15:25:05 AutoIt3Wrapper Finished..
>Exit code: -1073741819    Time: 6.883
Edited by BinaryBrother

SIGNATURE_0X800007D NOT FOUND

Link to comment
Share on other sites

You are misusing _Crypt* functions and base64decode is in the wrong place:

#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Change2CUI=y
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
#include <Constants.au3>
#include <Crypt.au3>
#include <ComboConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <WinAPI.au3>
#include <WindowsConstants.au3>
#include <MsgBoxConstants.au3>

Example()

Func Example()
    _Crypt_Startup() ; To optimize performance start the crypt library.

    Local $bAlgorithm = $CALG_AES_256
    $hKey = _Crypt_DeriveKey("Qr80lsjAmsZ3fjDb47sFt5jG55V6w728", $bAlgorithm)   ; Declare a password string and algorithm to create a cryptographic key.
    Local $sRead = "Hello! This is a test string."
    Local $bEncrypted = _B64Encode(_Crypt_EncryptData($sRead, $hKey, $CALG_USERKEY))    ; Encrypt the text with the new cryptographic key.
    Local $bDecrypted = _Crypt_DecryptData(_B64Decode($bEncrypted), $hKey, $CALG_USERKEY)

    ConsoleWrite("Encrypted Data: " & $bEncrypted & @CRLF)
    ConsoleWrite("Decrypted Data: " & BinaryToString($bDecrypted) & @CRLF)
    _Crypt_DestroyKey($hKey) ; Destroy the cryptographic key.
    _Crypt_Shutdown() ; Shutdown the crypt library.
EndFunc   ;==>Example

Func _B64Decode($sSource)

    Local Static $Opcode, $tMem, $tRevIndex, $fStartup = True

    If $fStartup Then
        If @AutoItX64 Then
            $Opcode = '0xC800000053574D89C74C89C74889D64889CB4C89C89948C7C10400000048F7F148C7C10300000048F7E14989C242807C0EFF3D750E49FFCA42807C0EFE3D750349FFCA4C89C89948C7C10800000048F7F14889C148FFC1488B064989CD48C7C108000000D7C0C0024188C349C1E30648C1E808E2EF49C1E308490FCB4C891F4883C7064883C6084C89E9E2CB4C89D05F5BC9C3'
        Else
            $Opcode = '0xC8080000FF75108B7D108B5D088B750C8B4D148B06D7C0C00288C2C1E808C1E206D7C0C00288C2C1E808C1E206D7C0C00288C2C1E808C1E206D7C0C00288C2C1E808C1E2060FCA891783C70383C604E2C2807EFF3D75084F807EFE3D75014FC6070089F85B29D8C9C21000'
        EndIf

        Local $aMemBuff = DllCall("kernel32.dll", "ptr", "VirtualAlloc", "ptr", 0, "ulong_ptr", BinaryLen($Opcode), "dword", 4096, "dword", 64)
        $tMem = DllStructCreate('byte[' & BinaryLen($Opcode) & ']', $aMemBuff[0])
        DllStructSetData($tMem, 1, $Opcode)

        Local $aRevIndex[128]
        Local $aTable = StringToASCIIArray('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/')
        For $i = 0 To UBound($aTable) - 1
            $aRevIndex[$aTable[$i]] = $i
        Next
        $tRevIndex = DllStructCreate('byte[' & 128 & ']')
        DllStructSetData($tRevIndex, 1, StringToBinary(StringFromASCIIArray($aRevIndex)))

        $fStartup = False
    EndIf

    Local $iLen = StringLen($sSource)
    Local $tOutput = DllStructCreate('byte[' & $iLen + 8 & ']')
    DllCall("kernel32.dll", "bool", "VirtualProtect", "struct*", $tOutput, "dword_ptr", DllStructGetSize($tOutput), "dword", 0x00000004, "dword*", 0)

    Local $tSource = DllStructCreate('char[' & $iLen + 8 & ']')
    DllStructSetData($tSource, 1, $sSource)

    Local $aRet = DllCallAddress('uint', DllStructGetPtr($tMem), 'struct*', $tRevIndex, 'struct*', $tSource, 'struct*', $tOutput, 'uint', (@AutoItX64 ? $iLen : $iLen / 4))

    Return BinaryMid(DllStructGetData($tOutput, 1), 1, $aRet[0])

EndFunc   ;==>_B64Decode


Func _B64Encode($sSource)

    Local Static $Opcode, $tMem, $fStartup = True

    If $fStartup Then
        If @AutoItX64 Then
            $Opcode = '0xC810000053574889CE4889D74C89C34C89C89948C7C10600000048F7F14889C14883FA00740348FFC1488B06480FC848C1E80EC0E802D788470748C1E806C0E802D788470648C1E806C0E802D788470548C1E806C0E802D788470448C1E806C0E802D788470348C1E806C0E802D788470248C1E806C0E802D788470148C1E806C0E802D788074883C6064883C708E2994883FA00743B49C7C5060000004929D54883FA03770349FFC54C29EF4883FA03741F4883FA01740E4883FA047408C6073D48FFC7EB0BC6073DC647013D4883C702C607005F5BC9C3'
        Else
            $Opcode = '0xC80800008B451499B903000000F7F189C1528B5D108B75088B7D0C83FA007401418B160FCAC1EA0888D0243FD7884703C1EA0688D0243FD7884702C1EA0688D0243FD7884701C1EA0688D0243FD7880783C60383C704E2C95A83FA00740DC647FF3D83FA027404C647FE3DC60700C9C21000'
        EndIf

        Local $aMemBuff = DllCall("kernel32.dll", "ptr", "VirtualAlloc", "ptr", 0, "ulong_ptr", BinaryLen($Opcode), "dword", 4096, "dword", 64)
        $tMem = DllStructCreate('byte[' & BinaryLen($Opcode) & ']', $aMemBuff[0])
        DllStructSetData($tMem, 1, $Opcode)

        $fStartup = False
    EndIf

    $sSource = Binary($sSource)
    Local $iLen = BinaryLen($sSource)

    $tSource = DllStructCreate('byte[' & $iLen & ']')
    DllStructSetData($tSource, 1, $sSource)

    Local $tOutput = DllStructCreate('char[' & Ceiling($iLen * (4 / 3) + 3) & ']')
    DllCall("kernel32.dll", "bool", "VirtualProtect", "struct*", $tOutput, "dword_ptr", DllStructGetSize($tOutput), "dword", 0x00000004, "dword*", 0)

    Local $sTable = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'

    DllCallAddress('none', DllStructGetPtr($tMem), 'struct*', $tSource, 'struct*', $tOutput, 'str', $sTable, 'uint', $iLen)

    Return DllStructGetData($tOutput, 1)

EndFunc   ;==>_B64Encode

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Link to comment
Share on other sites

  • 8 months later...

Downloaded the file, placed it in my local directory

Executed the test (touched nothing)

Got This:

C:\Users\Everseeker\Documents\AutoIT3\Projects\6Connect\b64.au3(36,148) : ERROR: syntax error (illegal character)
    Local $aRet = DllCallAddress('uint', DllStructGetPtr($tMem), 'struct*', $tRevIndex, 'struct*', $tSource, 'struct*', $tOutput, 'uint', (@AutoItX64 ?
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
C:\Users\Everseeker\Documents\AutoIT3\Projects\6Connect\b64.au3(36,150) : ERROR: unbalanced paranthesis expression.
    Local $aRet = DllCallAddress('uint', DllStructGetPtr($tMem), 'struct*', $tRevIndex, 'struct*', $tSource, 'struct*', $tOutput, 'uint', (@AutoItX64 ? $iLen
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
C:\Users\Everseeker\Documents\AutoIT3\Projects\6Connect\b64.au3(36,168) : ERROR: syntax error (illegal character)
    Local $aRet = DllCallAddress('uint', DllStructGetPtr($tMem), 'struct*', $tRevIndex, 'struct*', $tSource, 'struct*', $tOutput, 'uint', (@AutoItX64 ? $iLen : $iLen / 4))
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
C:\Users\Everseeker\Documents\AutoIT3\Projects\6Connect\b64 Tests.au3(70,153) : ERROR: syntax error
    Local $aSize = DllCall("Crypt32.dll", "bool", 'CryptBinaryToString', 'struct*', $tByteArray, 'dword', BinaryLen($Binary), 'dword', $iFlags, 'str', Null,
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
C:\Users\Everseeker\Documents\AutoIT3\Projects\6Connect\b64 Tests.au3(70,169) : ERROR: syntax error
    Local $aSize = DllCall("Crypt32.dll", "bool", 'CryptBinaryToString', 'struct*', $tByteArray, 'dword', BinaryLen($Binary), 'dword', $iFlags, 'str', Null, 'dword*', Null)
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
C:\Users\Everseeker\Documents\AutoIT3\Projects\6Connect\b64 Tests.au3 - 5 error(s), 0 warning(s)
!>14:56:56 AU3Check ended.rc:2

thoughts?

Edited by everseeker

Everseeker

Link to comment
Share on other sites

You need to update your version of AutoIt to support the new Ternary operator.

If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Link to comment
Share on other sites

You need to update your version of AutoIt to support the new Ternary operator.

OK, After

1. correcting my serious blunder (On comp with old version...)

2. Modifying input to take a smaller file $sFile = FileRead("Instructions.txt")

3. adding a few more consoleWrites...

ConsoleWrite(StringLen($sFile) & @LF)
$sEncoded = _B64Encode($sFile)
ConsoleWrite($sEncoded & @CRLF)
$sDecoded = _B64Decode($sEncoded)
$sDecoded = BinaryToString($sDecoded)
ConsoleWrite($sDecoded & @CRLF)
 
I get this:
8568
 
SGVsbG8gUGF0cmljay4gIFRoZSBuZXh0IHN0ZXAgaW4gdGhlICJVbmljb3JuIFRhbWVyL1FBIEVuZ2luZWVyIiBzZWxlY3Rpb24gcHJvY2VzcyBpcyBhIHNpbXBsZSB0ZXN0IG9mIHlvdXIgbWV0dGxlLiAgQWxzbyAtIHdlIGxpa2VkIHlvdXIgcmVzcG9u <SNIPPED>
 
!>16:34:27 AutoIt3.exe ended.rc:-1073741819
So, looks like encode may work, but it dies on decode

Everseeker

Link to comment
Share on other sites

Changed to a snippet of text. 

New code:

#AutoIt3Wrapper_UseX64=n
#include <b64.au3>

;Test to verify data encoded gets decoded back properly
$sText = "qwertyuiopasdfghjklzxcvbnm"
$sText = $sText & $sText & $sText

ConsoleWrite(StringLen($sText) & " - " & $sText & @LF)
$sEncoded = _B64Encode($sText)
ConsoleWrite($sEncoded & @CRLF)
$sDecoded = _B64Decode($sEncoded)
$sDecoded = BinaryToString($sDecoded)
ConsoleWrite($sDecoded & @CRLF)
ConsoleWrite(StringLen($sDecoded) & @LF)
If StringCompare($sText, $sDecoded) = 0 Then
    ConsoleWrite('Strings are Equal' & @LF & @LF)
Else
    ConsoleWrite('Strings NOT Equal!!' & @LF & @LF)
EndIf

ConsoleWrite(StringLen($sText) & @LF)
$sEncoded = _Base64Encode_MS($sText)
$sDecoded = _Base64Decode_MS($sEncoded)
$sDecoded = BinaryToString($sDecoded)
ConsoleWrite(StringLen($sDecoded) & @LF)
If StringCompare($sText, $sDecoded) = 0 Then
    ConsoleWrite('Strings are Equal' & @LF & @LF)
Else
    ConsoleWrite('Strings NOT Equal!!' & @LF & @LF)
EndIf


;Test time
Local $timeencode, $timeencodems, $timedecode, $timedecodems, $iLoops = 10
For $i = 1 To $iLoops
    $time = TimerInit()
    $sEncode = _B64Encode($sText)
    $diff = TimerDiff($time)
    $timeencode += $diff
    ConsoleWrite('>_B64Encode = ' & @TAB & @TAB & $diff & @LF)

    $time = TimerInit()
    $sEncodeMS = _Base64Encode_MS($sText)
    $diff = TimerDiff($time)
    $timeencodems += $diff
    ConsoleWrite('_Base64Encode_MS = ' & @TAB & $diff & @LF & @LF)

    $time = TimerInit()
    $sDecode = _B64Decode($sEncode)
    $diff = TimerDiff($time)
    $timedecode += $diff
    ConsoleWrite('>_B64Decode = ' & @TAB & @TAB & $diff & @LF)

    $time = TimerInit()
    $sDecodeMS = _Base64Decode_MS($sEncodeMS)
    $diff = TimerDiff($time)
    $timedecodems += $diff
    ConsoleWrite('_Base64Decode_MS = ' & @TAB & $diff & @LF & @LF)

Next
ConsoleWrite('>_B64Encode avg = ' & @TAB & $timeencode / $iLoops & @LF)
ConsoleWrite('_Base64Encode_MS avg = ' & @TAB & $timeencodems / $iLoops & @LF)
ConsoleWrite('>_B64Decode avg = ' & @TAB & $timedecode / $iLoops & @LF)
ConsoleWrite('_Base64Decode_MS avg = ' & @TAB & $timedecodems / $iLoops & @LF)



Func _Base64Encode_MS($Binary, $iFlags = 0x40000001)
    $Binary = Binary($Binary)
    Local $tByteArray = DllStructCreate('byte[' & BinaryLen($Binary) & ']')
    DllStructSetData($tByteArray, 1, $Binary)
    Local $aSize = DllCall("Crypt32.dll", "bool", 'CryptBinaryToString', 'struct*', $tByteArray, 'dword', BinaryLen($Binary), 'dword', $iFlags, 'str', Null, 'dword*', Null)
    Local $tOutput = DllStructCreate('char[' & $aSize[5] & ']')
    Local $aEncode = DllCall("Crypt32.dll", "bool", 'CryptBinaryToString', 'struct*', $tByteArray, 'dword', $aSize[2], 'dword', $iFlags, 'struct*', $tOutput, 'dword*', $aSize[5])
    If @error Or (Not $aEncode[0]) Then Return SetError(1, 0, 0)
    Return DllStructGetData($tOutput, 1)
EndFunc   ;==>_Base64Encode_MS

Func _Base64Decode_MS($input_string)
    Local $tInput = DllStructCreate('char[' & StringLen($input_string) + 1 & ']')
    DllStructSetData($tInput, 1, $input_string & 0)
    Local $aSize = DllCall("Crypt32.dll", "bool", "CryptStringToBinary", "struct*", $tInput, "dword", 0, "dword", 1, "ptr", 0, "dword*", 0, "ptr", 0, "ptr", 0)
    Local $tDecoded = DllStructCreate("byte[" & $aSize[5] & "]")
    Local $aDecode = DllCall("Crypt32.dll", "bool", "CryptStringToBinary", "struct*", $tInput, "dword", 0, "dword", 1, "struct*", $tDecoded, "dword*", $aSize[5], "ptr", 0, "ptr", 0)
    If Not $aDecode[0] Or @error Then Return SetError(1, 0, 0)
    Return DllStructGetData($tDecoded, 1)
EndFunc   ;==>_Base64Decode_MS
>"C:\Program Files (x86)\AutoIt3\SciTE\AutoIt3Wrapper\AutoIt3Wrapper.exe" /run /prod /ErrorStdOut /in "C:\Users\Everseeker\Documents\AutoIT3\Projects\6Connect\b64 Tests.au3" /UserParams    
+>16:43:13 Starting AutoIt3Wrapper v.14.801.2025.0 SciTE v.3.4.4.0   Keyboard:00000409  OS:WIN_81/  CPU:X64 OS:X64    Environment(Language:0409)
+>         SciTEDir => C:\Program Files (x86)\AutoIt3\SciTE   UserDir => C:\Users\Everseeker\AppData\Local\AutoIt v3\SciTE\AutoIt3Wrapper   SCITE_USERHOME => C:\Users\Everseeker\AppData\Local\AutoIt v3\SciTE 
>Running AU3Check (3.3.12.0)  from:C:\Program Files (x86)\AutoIt3  input:C:\Users\Everseeker\Documents\AutoIT3\Projects\6Connect\b64 Tests.au3
+>16:43:13 AU3Check ended.rc:0
>Running:(3.3.12.0):C:\Program Files (x86)\AutoIt3\autoit3.exe "C:\Users\Everseeker\Documents\AutoIT3\Projects\6Connect\b64 Tests.au3"    
--> Press Ctrl+Alt+Break to Restart or Ctrl+Break to Stop
78 - qwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnm
cXdlcnR5dWlvcGFzZGZnaGprbHp4Y3Zibm1xd2VydHl1aW9wYXNkZmdoamtsenhjdmJubXF3ZXJ0eXVpb3Bhc2RmZ2hqa2x6eGN2Ym5t
!>16:43:13 AutoIt3.exe ended.rc:-1073741819
+>16:43:13 AutoIt3Wrapper Finished.
>Exit code: 3221225477    Time: 0.9627

But same outcome...

Edited by everseeker

Everseeker

Link to comment
Share on other sites

  • 4 weeks later...

everseeker,

thank you for pointing to the crypt32.dll. That was exactly what I am looking for. Your code is running without errors, when you replace the line

DllStructSetData($tInput, 1, $input_string & 0)

within the function _Base64Decode_MS($input_string) by

DllStructSetData($tInput, 1, $input_string & chr(0))

i.e. $input_string has to be terminated by a null-byte, not a string "0".

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

×
×
  • Create New...