Sign in to follow this  
Followers 0
MangiS

binary to int/int to binary

10 posts in this topic

#1 ·  Posted (edited)

#include <string.au3>
$packet = Binary("0x0F000001FC")
$protocolid = BinaryMid($packet, 1, 1)
$clientvers = BinaryMid($packet, 2)
MsgBox(0, "NUMBER:", "Protocol Id:" & Int($protocolid) & ". ClientVers:" & $clientvers)

; test 2
$lalz = Binary(Int(508))
MsgBox(0, "508 Binary", $lalz & ".")

So the problem is in 'decoding'

the protocol id is correct (15)

but the problem is in the clientvers

clientvers should be 508 but i get 0

then with test 2 i tried to get binary value of Int 508

and its reversed (wtf?!!)

FC010000 when the packet 000001FC

and if i try to convert it back to int (FC010000) i get 252

Please explain me how to do this im newbie in theese things :mellow:

Edited by MangiS

Share this post


Link to post
Share on other sites



Welcome too the little-endian world of Intel x86/x64. Whereas the data is stored from lowest to highest bytes (read in binary as 'left-to-right' as 0x00,0x00,0x01,0xFC), the data is grabbed on an x86/x64 Intel machine in little-endian form. This means that if a 16-bit variable is grabbed, you will wind up with 0x0000, or if you grab from BinaryMid($packet,4) you will wind up with 0xFC01. If you grab a 32-bit variable, it will be 0xFC010000. big-endian machines are the opposite of course.

In machine code there's a simple way of reversing endianness (the instruction 'bswap'). However, in higher level languages you need code tricks like below:

$clientvers = Number("0x"&Hex(BinaryMid($packet, 2)))

Wikipedia article on Endianness

Share this post


Link to post
Share on other sites

Welcome too the little-endian world of Intel x86/x64. Whereas the data is stored from lowest to highest bytes (read in binary as 'left-to-right' as 0x00,0x00,0x01,0xFC), the data is grabbed on an x86/x64 Intel machine in little-endian form. This means that if a 16-bit variable is grabbed, you will wind up with 0x0000, or if you grab from BinaryMid($packet,4) you will wind up with 0xFC01. If you grab a 32-bit variable, it will be 0xFC010000. big-endian machines are the opposite of course.

In machine code there's a simple way of reversing endianness (the instruction 'bswap'). However, in higher level languages you need code tricks like below:

$clientvers = Number("0x"&Hex(BinaryMid($packet, 2)))

Wikipedia article on Endianness

Thank you very much :mellow:

Share this post


Link to post
Share on other sites

MangiS, just to keep this in the thread (and out of my PM):

So now my problem is that i cant convert binary (long) to int

the packet is 0x00E3206C03CEC7E7 and it should be 63930468005758951 but when i try to convert it i fail..

first the swapping trick does not work here and u can't directly full value

so i tried to split it to 2 parts (0x00E3206C and 0x03CEC7E7) but then i still don't get requed value , so can you help me convert this ? :mellow:

Since this is a 64-bit value, you can instead use something like Int("0x"&"00E3206C03CEC7E7"), but this will fail when the upper bit is set (it will return a negative value).

Likewise, the following will give you a signed 64-bit integer:

$stTemp=DllStructCreate("int64")
DllStructSetData($stTemp,1,"0x00E3206C03CEC7E7")
ConsoleWrite("value:"&DllStructGetData($stTemp,1)&@CRLF)

IMPORTANT: There's currently no workaround for signed integers (any 64-bit value with the top bit set), however, you can check if it is negative, add a value to 'pop' the top bit (add (-9223372036854775807-1) [you must write it like that otherwise AutoIT will truncate it]), and then manually calculate an addition of '9223372036854775808'.. using string addition, I guess. Maybe someone else would have a better way to get a positive 64-bit number when the top bit is set though? I can't think of any easy way at the moment.

Share this post


Link to post
Share on other sites

MangiS, just to keep this in the thread (and out of my PM):

Since this is a 64-bit value, you can instead use something like Int("0x"&"00E3206C03CEC7E7"), but this will fail when the upper bit is set (it will return a negative value).

Likewise, the following will give you a signed 64-bit integer:

$stTemp=DllStructCreate("int64")
DllStructSetData($stTemp,1,"0x00E3206C03CEC7E7")
ConsoleWrite("value:"&DllStructGetData($stTemp,1)&@CRLF)

IMPORTANT: There's currently no workaround for signed integers (any 64-bit value with the top bit set), however, you can check if it is negative, add a value to 'pop' the top bit (add (-9223372036854775807-1) [you must write it like that otherwise AutoIT will truncate it]), and then manually calculate an addition of '9223372036854775808'.. using string addition, I guess. Maybe someone else would have a better way to get a positive 64-bit number when the top bit is set though? I can't think of any easy way at the moment.

tried dll struct , but it returns 0 :mellow:

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

Grab the Binary section (up to 8 bytes - or 16 characters using hex notation), and put it in the struct using String():

Something like:

$bBin=BinaryMid($bDataStream,1,8)
$stTemp=DllStructCreate("int64")
DllStructSetData($stTemp,1,String($bBin))
ConsoleWrite("value:"&DllStructGetData($stTemp,1)&@CRLF)

It seems odd but it has to be converted to "0x##.." before being put into that 64-bit element.

Edited by Ascend4nt

Share this post


Link to post
Share on other sites

#7 ·  Posted (edited)

Grab the Binary section (up to 8 bytes - or 16 characters using hex notation), and put it in the struct using String():

Something like:

$bBin=BinaryMid($bDataStream,1,8)
$stTemp=DllStructCreate("int64")
DllStructSetData($stTemp,1,String($bBin))
ConsoleWrite("value:"&DllStructGetData($stTemp,1)&@CRLF)

It seems odd but it has to be converted to "0x##.." before being put into that 64-bit element.

$bDataStream = Binary("0x00E3206C03CEC7E7")
$bBin=BinaryMid($bDataStream,1,8)
$stTemp=DllStructCreate("int64")
DllStructSetData($stTemp,1,String($bBin))
ConsoleWrite("value:"&DllStructGetData($stTemp,1)&@CRLF)

still 0 what im doing wrong?

Edited by MangiS

Share this post


Link to post
Share on other sites

Running what you posted, I get this:

value:63930468005758951

Make sure you are using the latest AutoIT (v 3.3.6.1)

Share this post


Link to post
Share on other sites

#9 ·  Posted (edited)

Running what you posted, I get this:

value:63930468005758951

Make sure you are using the latest AutoIT (v 3.3.6.1)

Thank you so much again :P i was using older AutoIT

now i almost done packet decoder :mellow:

Edit:

As i saw in newest version it can be done only using Int()

but one more stupid question how to do from int64 to binary? :party:'

because using Binary() it converts it to like 0x363339333034333830303537

Edited by MangiS

Share this post


Link to post
Share on other sites

Look on the forums for some decimal to hexadecimal conversion routines, there's plenty of them around, though I think many have issues with signed numbers or >32-bit numbers. After the conversion is done, prefix it with "0x" and convert it to binary with Binary($sHexString).

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