Sign in to follow this  
Followers 0
SOChaos

May I ask of some assistance (DllCall Problem)

13 posts in this topic

Alrighty, so here I go. Basically, for the past week, I've had problems with this code... I've been trying to write a DLLCall function that is relevant to decrypting a packet from Maplestory. (Part of trying to create a Private server Autoit Based). I've come up with this so far:

Func MapleDecrypt($Data, $Key)
    Dim $PacketLength = StringLen($Data)
    $Dll = DllOpen("MapleCrypto.dll")
    $InBuff = DllStructCreate("byte[" & $PacketLength & "];")
    DllStructSetData($InBuff, 1, $Data)
    $OutBuff = DllStructCreate("byte[" & $PacketLength & "];") 
    DllStructSetData($OutBuff, 1, $Data)
    $IVStructure = DllStructCreate("byte[" & $Key & "];")
    DllStructSetData($IVStructure, 1, $Key)
    DLLCall($Dll, "none", "Decrypt", "str", $Key, _
                                     "ptr", DllStructGetPtr($InBuff), _
                                     "ptr", DllStructGetPtr($OutBuff), _
                                     "int", $PacketLength)
    $Output = DllStructGetData($OutBuff, 1)
    Return $Output
EndFunc

Now, Data would be the Packet incoming from the client, and key would be the SentIV (Which in this case is randomly generated at the beginning of my code..)

But when it runs through the DLLcall, the output is the same as the packet I was trying to decrypt, meaning it's not decrypting at all.. Just outputting the same packet.

Here's how it's called in C#

[DllImport("MapleCrypto.dll")]
        public static extern _ERRCODE Decrypt(byte[] IV, byte[] InputBuffer, byte[] OutputBuffer, int Length);

And if you need the DLL itself, I attached it... I had to rar it due to it's size.

But if anyone can help me figure this out, I'm guessing I'm just missing something in the DLLCall, I guess I'm just thinking about it too hard...

Thankyou in advance.

Share this post


Link to post
Share on other sites



In the C# code, the first parameter is listed as a byte array, but in your AutoIt code you used a string. That might be part of the problem, but it's possible that it's not.

Share this post


Link to post
Share on other sites

Yeah I noticed that after I posted it, but there was still nothing changed. I'm wondering what I possibly did wrong. I mean, I know it's my code, but it's driving me nuts.

Share this post


Link to post
Share on other sites

A suggestion, try not setting outbuff. Declare it but leave it empty. See if that works.

Share this post


Link to post
Share on other sites

If it's converted to wide char within the DLL you also may want to do StringLen * 2


[center]Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.[/center]

Share this post


Link to post
Share on other sites

Oh, and I also just noticed, you are using a return type of "none" in the script but the C# returns _ERRCODE which is probably where the code is failing. Find out what _ERRCODE is.

Share this post


Link to post
Share on other sites

Take Roberts suggestion above, I'm not familiar with C# near as much as he is.

Might try this approach:

Func _MapleDecrypt($s_data, $s_key)
    Local $i_packetlen = StringLen($s_data)
    Local $i_keylen = StringLen($s_key)
    
    Local $t_iv = DllStructCreate("byte[" & $i_keylen + 2 & "]")
    DllStructSetData($t_iv, 1, $s_key)
    
    Local $t_inbuffer = DllStructCreate("byte[" & $i_packetlen & "]")
    DllStructSetData($t_inbuffer, 1, $s_data)
    
    Local $t_outbuffer = DllStructCreate("byte[" & $i_packetlen & "]")
    
    DllCall("MapleCrypto.dll", "int", "Decrypt", _
            "ptr", DllStructGetPtr($t_iv), _
            "ptr", DllStructGetPtr($t_inbuffer), _
            "ptr", DllStructGetPtr($t_outbuffer), _
            "int", $i_packetlen)
    
    Return DllStructGetData($t_outbuffer, 1)
EndFunc

[center]Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.[/center]

Share this post


Link to post
Share on other sites

#8 ·  Posted (edited)

Yeah, I'm testing your script right now, it's deffenetly teaching alot about DllCalling. I'm not that great at it. But anyways, you wanted to know what _ERRCODE is, here's the whole DLL Wrapper in C# Form below:

namespace MapleCryptoAPI
{
    public enum _ERRCODE
    {
        ERR_NOERR   = 00,
        ERR_INIT    = 10,
        ERR_NOTINIT = 20,
        ERR_IV    = 30,
        ERR_INPUT   = 40,
        ERR_MEM  = 50,
        ERR_LEN  = 60,
    }

    public enum _CHECK
    {
        True = 1,
        False = 0,
    }

    public class MapleCrypto
    {     
        [DllImport("MapleCrypto.dll")]
        public static extern _ERRCODE Initialize();

        [DllImport("MapleCrypto.dll")]
        public static extern _ERRCODE Finalize();

        [DllImport("MapleCrypto.dll")]
        public static extern _ERRCODE Encrypt(byte[] IV, byte[] InputBuffer, byte[] OutputBuffer, int Length);

        [DllImport("MapleCrypto.dll")]
        public static extern _ERRCODE Decrypt(byte[] IV, byte[] InputBuffer, byte[] OutputBuffer, int Length);

        [DllImport("MapleCrypto.dll")]
        public static extern _ERRCODE EncryptWithHeaderToClient(int Version, byte[] IV, byte[] InputBuffer, byte[] OutputBuffer, int Length);

        [DllImport("MapleCrypto.dll")]
        public static extern _ERRCODE EncryptWithHeaderToServer(int Version, byte[] IV, byte[] InputBuffer, byte[] OutputBuffer, int Length);

        [DllImport("MapleCrypto.dll")]
        public static extern _CHECK HeaderCheckFromClient(int Version, byte[] IV, byte[] Header, int Datalength);

        [DllImport("MapleCrypto.dll")]
        public static extern _CHECK HeaderCheckFromServer(int Version, byte[] IV, byte[] Header, int Datalength);

        [DllImport("MapleCrypto.dll")]
        public static extern _ERRCODE GenerateIV(byte[] IV);

        [DllImport("MapleCrypto.dll")]
        public static extern int GetPacketLengthFromHeader(byte[] Header);
    }
}

Looks like it's just error codes, but Anyways.

I tested your's, Smoke. Seems as if it's just returning nothing but 0x000000000000000000000000. I will continue to work with it. Deffenetly a better code than mine so yeah :) Lol.

Edited by SOChaos

Share this post


Link to post
Share on other sites

It will be sending back byte data more than likely, so you'll need to do something like:

Return BinaryToString(DllStructGetData($t_outbuffer, 1))

If it's only returning Nulls though, there's either an error with the data your sending, or the way we are sending it.


[center]Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.[/center]

Share this post


Link to post
Share on other sites

Smoke, it's Richard, please. :)

Can I see an example where the function is being called in C# too? That would allow me to translate it better.

Share this post


Link to post
Share on other sites

You don't need an example, just make a difference between byte and char, also, the DLL needs initialisation:

CODE
$MapleDLL = DllOpen("MapleCrypto.dll")

; Init DLL

$ret = DllCall($MapleDLL,"long","Initialize")

MsgBox(0, '0=Success', $ret[0])

$CryptKey = StringToBinary("Key001") ; The Key must be in Binary Format

$StringToEncrypt = "The string in packet"

$BinaryData = StringToBinary($StringToEncrypt) ; The Func needs Binary Data

$Crypted = _MapleEncrypt($MapleDLL,$CryptKey,$BinaryData)

MsgBox(0, 'EnCrypted Data', "Data in Binary Format: " & @CRLF & $Crypted & @CRLF& _

@CRLF & "Data as String: "& @CRLF&BinaryToString($Crypted))

$DeCrypted = _MapleDecrypt($MapleDLL,$CryptKey,$Crypted)

MsgBox(0, 'DeCrypted Data', "Data in Binary Format: " & @CRLF & $DeCrypted & @CRLF& _

@CRLF & "Data as String: "& @CRLF&BinaryToString($DeCrypted))

;UnInit DLl

$ret = DllCall($MapleDLL,"long","Finalize")

MsgBox(0, '0=Success', $ret[0])

; $hDll : Handle to MapleCrypt.Dll from DllOpen

; Key and Data as Binary e.g. from BinaryToString

; Returns Encrypted Data as Binary

Func _MapleEncrypt($hDLL, $bKey, $bData)

Local $i_packetlen = BinaryLen($bData)

Local $i_keylen = BinaryLen($bKey)

Local $t_iv = DllStructCreate("byte[" & $i_keylen & "]")

DllStructSetData($t_iv, 1, $bKey)

Local $t_inbuffer = DllStructCreate("byte[" & $i_packetlen & "]")

DllStructSetData($t_inbuffer, 1, $bData)

Local $t_outbuffer = DllStructCreate("byte[" & $i_packetlen & "]")

DllCall($hDLL, "int", "Encrypt", _

"ptr", DllStructGetPtr($t_iv), _

"ptr", DllStructGetPtr($t_inbuffer), _

"ptr", DllStructGetPtr($t_outbuffer), _

"int", $i_packetlen)

Return DllStructGetData($t_outbuffer, 1)

EndFunc

; $hDll : Handle to MapleCrypt.Dll from DllOpen

; Key and Data as Binary e.g. from BinaryToString

; ( Data should normally be Binary when you get it ...)

; Returns Decrypted Data as Binary

Func _MapleDecrypt($hDLL, $bKey, $bData)

Local $i_packetlen = BinaryLen($bData)

Local $i_keylen = BinaryLen($bKey)

Local $t_iv = DllStructCreate("byte[" & $i_keylen & "]")

DllStructSetData($t_iv, 1, $bKey)

Local $t_inbuffer = DllStructCreate("byte[" & $i_packetlen & "]")

DllStructSetData($t_inbuffer, 1, $bData)

Local $t_outbuffer = DllStructCreate("byte[" & $i_packetlen & "]")

DllCall($hDLL, "int", "Decrypt", _

"ptr", DllStructGetPtr($t_iv), _

"ptr", DllStructGetPtr($t_inbuffer), _

"ptr", DllStructGetPtr($t_outbuffer), _

"int", $i_packetlen)

Return DllStructGetData($t_outbuffer, 1)

EndFunc


*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Share this post


Link to post
Share on other sites

Ah, I see. This makes much more since, I really appreciate it. Thankyou everyone for helping.

Share this post


Link to post
Share on other sites

Nice .dll, but why does this have to have #RequireAdmin to work?

Share this post


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
Sign in to follow this  
Followers 0