Jump to content

help with DLLCall and DLLSTRUCTSETDATA


Recommended Posts

from the MSDN website, here is the function and the parameters.

int send(

__in SOCKET s,

__in const char* buf,

__in int len,

__in int flags

);

here is my code...

$dllhandle=DllOpen("WS2_32.dll")

$v_Data= "000C800000004291D01F46E2"

$v_Buffer = DllStructCreate("byte[12]")

DllStructSetData($v_Buffer, 1, $v_Data)

DllCall($dllhandle,'int','send','int',"1980",'ptr', DllStructGetPtr($v_Buffer), 'int', '12') ; - I orginally had the last parameter in for flags but it doesn't change anything, 'int', "0"

DllClose($dllhandle)

A few problems I have. First the data I have gotten I got from WPEPRO (a packet sniffer for anyone who doesn't know) and it is what I want to send to the specificed socket id. My problem is that AutoIt assumes it is a string and for the full length to be written to the dllstruct the size must be byte[24] - this is no good for me because I want AutoIt to put that data to the dllstruct as raw hex.

My second problem... not sure if it is a problem... the socket id, should that be in hex or is decimal fine?

My third problem/question is that I don't know if the type written in the dllcall should be 'ptr' for dllstructgetptr... my thought is that, if that returns the value of the pointer then shouldn't it be 'int'? I used 'ptr' because I saw in a dllcall example of kernel32.dll when they were using the function WriteProcessMemory.

I have already got the socket id with wpepro and I'm using ollydbg as well. I just want to send the packet to that location.

1. Final question. Say I wanted to send data to an ip and port... do I still need a socket id? I don't really understand the socket id thing... I just know I need it for this and I figured out how to get it with WPE PRO.

Link to comment
Share on other sites

from the MSDN website, here is the function and the parameters.

int send(

__in SOCKET s,

__in const char* buf,

__in int len,

__in int flags

);

here is my code...

$dllhandle=DllOpen("WS2_32.dll")

$v_Data= "000C800000004291D01F46E2"

$v_Buffer = DllStructCreate("byte[12]")

DllStructSetData($v_Buffer, 1, $v_Data)

DllCall($dllhandle,'int','send','int',"1980",'ptr', DllStructGetPtr($v_Buffer), 'int', '12') ; - I orginally had the last parameter in for flags but it doesn't change anything, 'int', "0"

DllClose($dllhandle)

A few problems I have. First the data I have gotten I got from WPEPRO (a packet sniffer for anyone who doesn't know) and it is what I want to send to the specificed socket id. My problem is that AutoIt assumes it is a string and for the full length to be written to the dllstruct the size must be byte[24] - this is no good for me because I want AutoIt to put that data to the dllstruct as raw hex.

My second problem... not sure if it is a problem... the socket id, should that be in hex or is decimal fine?

My third problem/question is that I don't know if the type written in the dllcall should be 'ptr' for dllstructgetptr... my thought is that, if that returns the value of the pointer then shouldn't it be 'int'? I used 'ptr' because I saw in a dllcall example of kernel32.dll when they were using the function WriteProcessMemory.

I have already got the socket id with wpepro and I'm using ollydbg as well. I just want to send the packet to that location.

1. Final question. Say I wanted to send data to an ip and port... do I still need a socket id? I don't really understand the socket id thing... I just know I need it for this and I figured out how to get it with WPE PRO.

I'm no expert on anything so below is what I think but might not be correct.

To set the data in the struct try this (I haven't)

for $n = 1 to 12

DllStructSetData($v_Buffer, $n, Dec(StringMid($v_Data,1+($n-1)*2,2))

next

Since it specifies a char buffer then it is expecting a string so are you sure that 12 bytes is correct?

There could be a problem to do with the way the data is read. MSB first or last?

Using a decimal value for the socket id should be fine I would think.

For the last parameter I would think it's best to include it even though you think it makes no difference.

I think you're correct about the ptr in the dll call. It's really just an int, (there're both 32 bits). I have done the same with no problems.

Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.
Link to comment
Share on other sites

I'm no expert on anything so below is what I think but might not be correct.

To set the data in the struct try this (I haven't)

for $n = 1 to 12

DllStructSetData($v_Buffer, $n, Dec(StringMid($v_Data,1+($n-1)*2,2))

next

I tried the code you put and it does not work and it yielded a 0 from the dllstructgetdata. I think the dllstructset data all needs to be in the first element, you have that as a variable.

The data is too long to be converted to decimal using Dec; I have tried and figured it would put it as a hex format into the dllstruct.

Since it specifies a char buffer then it is expecting a string so are you sure that 12 bytes is correct?

There could be a problem to do with the way the data is read. MSB first or last?

$v_Data= "000C800000004291D01F46E2" ; 12 bytes "00 0C 80 00 00 00 42 91 D0 1F 46 E2"

$v_Buffer = DllStructCreate("byte[12]")

DllStructSetData($v_Buffer, 1, $v_Data)

My $v_Data is really 12 bytes... "00 0C 80 00 00 00 42 91 D0 1F 46 E2" like so.. I don't want the dllstruct to save the ascii code for each number or letter. I want it to be raw hex, as it is - 12 bytes. As the code stands right now, the number of bytes must be set to 24 "bytes[24]", rather than 12 for it to load the data to the dllstruct. This tells me that it's loading it as a string and not raw data.

by the way... this is what I have been using to test the buffer data to see if I can get my data to 12 bytes in the buffer instead of 24...

$v_Data= dec("000C800000004291D01F46E2")

$v_Buffer = DllStructCreate("byte[12]")

DllStructSetData($v_Buffer, 1, $v_Data)

$data=DllStructGetData($v_buffer,1)

$len=DllStructGetSize($v_buffer)

MsgBox(1,"msg",$data & " " & $len)

Thanks for your time and to anyone else who is willing to help me thank you for putting an effort into this. :P

Link to comment
Share on other sites

I tried the code you put and it does not work and it yielded a 0 from the dllstructgetdata. I think the dllstructset data all needs to be in the first element, you have that as a variable.

The data is too long to be converted to decimal using Dec; I have tried and figured it would put it as a hex format into the dllstruct.

$v_Data= "000C800000004291D01F46E2" ; 12 bytes "00 0C 80 00 00 00 42 91 D0 1F 46 E2"

$v_Buffer = DllStructCreate("byte[12]")

DllStructSetData($v_Buffer, 1, $v_Data)

My $v_Data is really 12 bytes... "00 0C 80 00 00 00 42 91 D0 1F 46 E2" like so.. I don't want the dllstruct to save the ascii code for each number or letter. I want it to be raw hex, as it is - 12 bytes. As the code stands right now, the number of bytes must be set to 24 "bytes[24]", rather than 12 for it to load the data to the dllstruct. This tells me that it's loading it as a string and not raw data.

by the way... this is what I have been using to test the buffer data to see if I can get my data to 12 bytes in the buffer instead of 24...

$v_Data= dec("000C800000004291D01F46E2")

$v_Buffer = DllStructCreate("byte[12]")

DllStructSetData($v_Buffer, 1, $v_Data)

$data=DllStructGetData($v_buffer,1)

$len=DllStructGetSize($v_buffer)

MsgBox(1,"msg",$data & " " & $len)

Thanks for your time and to anyone else who is willing to help me thank you for putting an effort into this. :P

Yes, sorry, I should have tested first. I made a mistake. I should have said

DllStructSetData($v_Buffer, 1, Dec(StringMid($v_Data,1+($n-1)*2,2),$n)

This is what I used to test that the data is written correctly

$v_Data= "000C800000004291D01F46E2"
$v_Buffer = DllStructCreate("byte[12]")

for $n = 1 to 12
    $Val = StringMid($v_Data,1+($n-1)*2,2)
;ConsoleWrite(Dec($val) & @LF)
DllStructSetData($v_Buffer,1,Dec($val),$n);struct,element,data,index
next

For $n = 1 To 12
    
    MsgBox(0,$v_Data,'next byte read is ' & Hex(DllStructGetData($v_Buffer,1,$n),2))
    
Next
Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.
Link to comment
Share on other sites

for $n = 1 to 12

$Val = StringMid($v_Data,1+($n-1)*2,2)

;ConsoleWrite(Dec($val) & @LF)

DllStructSetData($v_Buffer,1,Dec($val),$n);struct,element,data,index - isn't index used for arrays?

This is very good. Thank you so much. I should have thought of writing it one byte at a time but I didn't think it was necessary. I have not yet tested the full dllcall but I will after I post this. Just wanted to say thank you after testing the function you gave me.

I do have a question about the index though, in the help file it says, "index If the element is an array, you need to specify which index to set, otherwise it sets index 1. ", but this isn't an array?

thanks for your reply :P

Link to comment
Share on other sites

I tested the code and to my dismay it does not work. Here's my code:

$dllhandle=DllOpen("WS2_32.dll")

$v_Data= "000C8000000082F660F94C6D" ; 00 0C 80 00 00 00 82 F6 60 F9 4C 6D

$v_Buffer = DllStructCreate("byte[12]")

for $n = 1 to 12 ; martins little function to load data to buffer byte by byte.

$Val = StringMid($v_Data,1+($n-1)*2,2)

DllStructSetData($v_Buffer,1,Dec($val),$n) ;struct,element,data,index

next

DllCall($dllhandle,'int','send','int',"1404",'ptr', DllStructGetPtr($v_Buffer), 'int', '12', 'int', "0") ; my dllcall

DllClose($dllhandle)

Afterwards, since it didn't work, I tried two things for debugging. First I nulled the dllcall, dllclose and dllopen commands and at the end I added:

$data=DllStructGetData($v_Buffer,1)

MsgBox(1,"msgbox",$data)

The message box was completely blank, I figured ok, well if it's raw data then it might show up blank.

I then tried this.

$data=DllStructGetData($v_Buffer,1,2)

MsgBox(1,"msgbox",$data)

The message box came up to be "12", which is the value of the second byte, '0c' in decimal.

My conclusion is that the data is stored as an array and not as a string of raw hex. ;)

If anyone has a solution FEEL FREE :P. Or if anyone has found any mistakes I made.

Link to comment
Share on other sites

I tested the code and to my dismay it does not work. Here's my code:

$dllhandle=DllOpen("WS2_32.dll")

$v_Data= "000C8000000082F660F94C6D" ; 00 0C 80 00 00 00 82 F6 60 F9 4C 6D

$v_Buffer = DllStructCreate("byte[12]")

for $n = 1 to 12 ; martins little function to load data to buffer byte by byte.

$Val = StringMid($v_Data,1+($n-1)*2,2)

DllStructSetData($v_Buffer,1,Dec($val),$n) ;struct,element,data,index

next

DllCall($dllhandle,'int','send','int',"1404",'ptr', DllStructGetPtr($v_Buffer), 'int', '12', 'int', "0") ; my dllcall

DllClose($dllhandle)

Afterwards, since it didn't work, I tried two things for debugging. First I nulled the dllcall, dllclose and dllopen commands and at the end I added:

$data=DllStructGetData($v_Buffer,1)

MsgBox(1,"msgbox",$data)

The message box was completely blank, I figured ok, well if it's raw data then it might show up blank.

I then tried this.

$data=DllStructGetData($v_Buffer,1,2)

MsgBox(1,"msgbox",$data)

The message box came up to be "12", which is the value of the second byte, '0c' in decimal.

My conclusion is that the data is stored as an array and not as a string of raw hex. ;)

If anyone has a solution FEEL FREE :P. Or if anyone has found any mistakes I made.

1) dllstruct("byte[12]") creates a 12 element array. It has 1 element, the array, and the array has 12 indexes. This was the mistake I made because I treated it as 12 separate elements which would have been created like this

DllStructCreate("byte;byte;byte;byte;byte;byte;byte;byte;byte;byte;byte;byte")

A string is an array of char.

2)The socket parameter should be the value returned by a call to a function to open a socket. I'm not sure that the socket id you are using is correct, it looks like a port number maybe.

3) Maybe I should have asked earlier, what are you trying to do? You might not need WS_32.dll at all. If the id you have is the port then UDP or TCP functions should do what you want.

Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.
Link to comment
Share on other sites

1) dllstruct("byte[12]") creates a 12 element array. It has 1 element, the array, and the array has 12 indexes. This was the mistake I made because I treated it as 12 separate elements which would have been created like this

DllStructCreate("byte;byte;byte;byte;byte;byte;byte;byte;byte;byte;byte;byte")

A string is an array of char.

2)The socket parameter should be the value returned by a call to a function to open a socket. I'm not sure that the socket id you are using is correct, it looks like a port number maybe.

3) Maybe I should have asked earlier, what are you trying to do? You might not need WS_32.dll at all. If the id you have is the port then UDP or TCP functions should do what you want.

Basically, I am working on making a.... "game aid". I have discovered that I need to use the send api from WS_32.dll because in ollydbg that is the function I put a break on to track down the encryption routine and therefore I figured that's the function I need to send the data. From that I also discovered the socket (which I know changes everytime I restart the game - from testing). If the send works properly then in the game my character should say the letter "h". With WPE Pro I have sent the exact data to the socket and have it has yielded that result. I want to make this "game aid" able to send to that socket id.
Link to comment
Share on other sites

Does anyone know how to use the function 'send' of WS_32.dll properly? I know the exact data I want to send and the socket id.... I just don't know what's wrong...

I still suspect that you do not have the correct value for the socket s. Msn says it is " A descriptor identifying a connected socket" . If the socket is just a number like you are using then how can the information you are using possibly be sent to a remote PC? To do that you need the ip address and a port number at least, so if the id means anything to ws2_32 it would only be because it had previously set up a connection to a particular ip and port and the id was a reference to that socket, but you would then have to have already used another function in ws2_32 to set up the socket. If it is wrong then the send function should return SOCKET_ERROR which I think is -1.

I don't know WPEPRO but I would expect that it will give the ip address of the sender(you), the receiver and the port number, so then I would try and use tcpsend, it's much simpler.

$ConnectedSocket = TCPConnect($szIPADDRESS,$nPORT)

TCPSend($ConnectedSocket,$v_Data)

Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.
Link to comment
Share on other sites

I still suspect that you do not have the correct value for the socket s. Msn says it is " A descriptor identifying a connected socket" . If the socket is just a number like you are using then how can the information you are using possibly be sent to a remote PC? To do that you need the ip address and a port number at least, so if the id means anything to ws2_32 it would only be because it had previously set up a connection to a particular ip and port and the id was a reference to that socket, but you would then have to have already used another function in ws2_32 to set up the socket. If it is wrong then the send function should return SOCKET_ERROR which I think is -1.

I don't know WPEPRO but I would expect that it will give the ip address of the sender(you), the receiver and the port number, so then I would try and use tcpsend, it's much simpler.

$ConnectedSocket = TCPConnect($szIPADDRESS,$nPORT)

TCPSend($ConnectedSocket,$v_Data)

There is already a connection between my pc and the recieving server. It's a game - I am trying to emulate packets. There are two pictures I've attached: the first is of what data my debugger showed during a break on the send function which happened whenever I typed messaged or clicked anything in the game. The second was taken from WPEPro after capturing a packet that makes me say the letter 'h' from that I set the send socket id with the one which the packet was captured... it's just in decimal form.

post-21743-1195915913_thumb.jpg

OllyDBG view also notice how in the stack, (bottom right window) there are the parameters for the send function given in the appropriate order... I thought if I copied that it would work.

post-21743-1195915922_thumb.jpg

WPE Pro view

All in all, you can take a look at it and tell me what you think. I'm going to try that tcpsend you suggested and let you know what comes from it.

Link to comment
Share on other sites

There is already a connection between my pc and the recieving server. It's a game - I am trying to emulate packets. There are two pictures I've attached: the first is of what data my debugger showed during a break on the send function which happened whenever I typed messaged or clicked anything in the game. The second was taken from WPEPro after capturing a packet that makes me say the letter 'h' from that I set the send socket id with the one which the packet was captured... it's just in decimal form.

post-21743-1195915913_thumb.jpg

OllyDBG view also notice how in the stack, (bottom right window) there are the parameters for the send function given in the appropriate order... I thought if I copied that it would work.

post-21743-1195915922_thumb.jpg

WPE Pro view

All in all, you can take a look at it and tell me what you think. I'm going to try that tcpsend you suggested and let you know what comes from it.

Yes, I would try ip address 202.157.171.135 port 1973 and see what happens. But everything I've said so far is just guesswork so if I'm misleading you I offer my apologies.
Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.
Link to comment
Share on other sites

This is what I used:

$szIPADDRESS="202.157.171.136"

$nPORT=1973

$v_Data=0x000C80000000C81A6805B21C ; 12 bytes 00 0c 80 00 00 00 c8 1a 68 05 b2 1c

$ConnectedSocket = TCPConnect($szIPADDRESS,$nPORT)

TCPSend($ConnectedSocket,$v_Data)

I get the same error as before:

>Running:(3.2.2.0):F:\Programming\AutoIt3\autoit3.exe "F:\Programming\AutoIt3\AutoIt downloaded files\1.au3"

F:\Programming\AutoIt3\AutoIt downloaded files\1.au3 (41) : ==> Unable to parse line.: <<<<<----------------------------------

$v_Data=0x000C80000000C81A6805B21C

$v_Data=0x000C80000000C81A6805B21C^ ERROR

->19:15:57 AutoIT3.exe ended.rc:1

+>19:15:59 AutoIt3Wrapper Finished

>Exit code: 1 Time: 10.286

It said this when I was doing the other way as well.... "Unable to parse line" I don't know what that means but it will not let me store that hex as the data I want to send.

Link to comment
Share on other sites

This is what I used:

$szIPADDRESS="202.157.171.136"

$nPORT=1973

$v_Data=0x000C80000000C81A6805B21C ; 12 bytes 00 0c 80 00 00 00 c8 1a 68 05 b2 1c

$ConnectedSocket = TCPConnect($szIPADDRESS,$nPORT)

TCPSend($ConnectedSocket,$v_Data)

I get the same error as before:

>Running:(3.2.2.0):F:\Programming\AutoIt3\autoit3.exe "F:\Programming\AutoIt3\AutoIt downloaded files\1.au3"

F:\Programming\AutoIt3\AutoIt downloaded files\1.au3 (41) : ==> Unable to parse line.: <<<<<----------------------------------

$v_Data=0x000C80000000C81A6805B21C

$v_Data=0x000C80000000C81A6805B21C^ ERROR

->19:15:57 AutoIT3.exe ended.rc:1

+>19:15:59 AutoIt3Wrapper Finished

>Exit code: 1 Time: 10.286

It said this when I was doing the other way as well.... "Unable to parse line" I don't know what that means but it will not let me store that hex as the data I want to send.

Try

$v_Data = Binary("0x000C80000000C81A6805B21C")

TCPSend($ConnectedSocket,$v_Data)

Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.
Link to comment
Share on other sites

Try

$v_Data = Binary("0x000C80000000C81A6805B21C")

TCPSend($ConnectedSocket,$v_Data)

+>10:39:04 Starting AutoIt3Wrapper v.1.7.6

>Running AU3Check (1.54.6.0) params: from:F:\Programming\AutoIt3

+>10:39:05 AU3Check ended.rc:0

>Running:(3.2.2.0):F:\Programming\AutoIt3\autoit3.exe "F:\Programming\AutoIt3\AutoIt downloaded files\1.au3"

F:\Programming\AutoIt3\AutoIt downloaded files\1.au3 (41) : ==> Unable to parse line.: <<<<------ same error :P

$v_Data=BinaryString(0x000C80000000C81A6805B21C)

$v_Data=BinaryString(0x000C80000000C81A6805B21C^ ERROR

->10:39:06 AutoIT3.exe ended.rc:1

+>10:39:07 AutoIt3Wrapper Finished

This yielded the same error. I don't understand what 'unable to parse line' means and why it's happeneing.

Link to comment
Share on other sites

You left out the quotes around the data to send. AutoIt converts the string into the proper format, but the error code you show doesn't have it as a string (has to have quotes), so AutoIt doesn't know what to do with it, and tells you as much by saying it can't figure out how to read/parse that line.

Add the quotes just like martin had, and it should work.

Link to comment
Share on other sites

You left out the quotes around the data to send. AutoIt converts the string into the proper format, but the error code you show doesn't have it as a string (has to have quotes), so AutoIt doesn't know what to do with it, and tells you as much by saying it can't figure out how to read/parse that line.

Add the quotes just like martin had, and it should work.

I've done it with quotes before and it doesn't send the data properly. I want it to be sent as raw hex. If I add quotes it's going to make it into a string of characters, not the raw data which I want to be sent. So instead of sending "00 0C 80 00 00 00 82 F6 60 F9 4C 6D" it sends the ascii values to make each of those characters so the bytes are twice the length required in the dllstructcreate. I know this, I've tried it. There should only be 12 bytes required to send this. If I add quotes the size needed to store the entire string of data goes up to 24 bytes, I've done some tests to figure that out. Because it is exactly double I have came to the conclusion that it is storing ascii values rather then the data I want.

Link to comment
Share on other sites

That's what the call to Binary() is for. When passed a normal string, it converts the characters to the ASCII equivalent, but when the string starts with that "0x", it knows that the following is the hex values to be stored, and TCPSend() will send those values when passed in a Binary type variable.

To test this, try the following:

$string = Binary("This is a test")
ConsoleWrite($string & @CRLF)
$binary = Binary("0x000C8000000082F660F94C6D")
ConsoleWrite($binary & @CRLF)

First console output is the hex values of all the chars of the string, second one should be a mirror copy of the binary you pass in. TCPSend() the second one, and that's exactly what will get sent.

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