Jump to content

Binary replacement by byte position


Recommended Posts

Hello,

I'm trying to replace some bytes in binary files but no luck, simple like this, 1- open a file, 2- replace the bytes and 3- save the new content as a new file, that's a very simple task in C or C++ but I didn't figure out how to do it in AutoIt. So, for now I can open the file and I have a variable with a binary content.

What I'm doing...

Open the file:

$hFile = FileOpen($sFileName, $FO_BINARY)
$bContent = FileRead($hFile)
FileClose($hFile)

Next step, replace the content of the bytes in the position 17, 18 and 19..

First try:

$bContent[17] = 'a'    ; Obviously this doesn't work.
$bContent[18] = 'b'
$bContent[19] = 'c'

Second try

$sContent = BinaryToString($bContent)     ; Looks logical, but also didn't work. The array have the same quantity of elements as the file size.
$aContent = StringSplit($sContent, "")    ; I also broke the file in 2 chars for element in the array, but it was much worst.
aContent[17] = 'a'
aContent[18] = 'b'
aContent[19] = 'c'
$sContent = _ArrayToString($aContent)
$bContent = StringToBinary($sContent)

Any other approach?

Link to comment
Share on other sites

The easiest way that I've found to work with binary data is to use a struct.

Example:

modify_binary_bytes_example()

Func modify_binary_bytes_example()
    Const $BIN_DATA = Binary("0x000102030405060708090A0B0C0D0E0F")
    Local $tByteBuffer


    ;Create a byte buffer struct and move the binary data to it
    $tByteBuffer      = DllStructCreate(StringFormat("byte data[%i]", BinaryLen($BIN_DATA)))
    $tByteBuffer.data = $BIN_DATA

    ;Display binary data & byte buffer contents before modification
    ConsoleWrite("$BIN_DATA            = " & $BIN_DATA & @CRLF)
    ConsoleWrite("$tByteBuffer before  = " & $tByteBuffer.data & @CRLF)

    ;Modify binary bytes 1, 8, and 16
    $tByteBuffer.data(01) = 0xFF
    $tByteBuffer.data(08) = 0xFF
    $tByteBuffer.data(16) = 0xFF

    ;Display the modified byte buffer
    ConsoleWrite("$tByteBuffer after   = " & $tByteBuffer.data & @CRLF)
EndFunc

Console output:

$BIN_DATA            = 0x000102030405060708090A0B0C0D0E0F
$tByteBuffer before  = 0x000102030405060708090A0B0C0D0E0F
$tByteBuffer after   = 0xFF010203040506FF08090A0B0C0D0EFF

 

Edited by TheXman
Link to comment
Share on other sites

Using file :

#include <Constants.au3>

Local $hFile = FileOpen("Test.txt", $FO_BINARY)
Local $dContent = FileRead($hFile)
ConsoleWrite($dContent & @CRLF)
$tByte = DllStructCreate("byte arr[" & BinaryLen($dContent) & "]")
DllStructSetData($tByte, 1, $dContent)
$tbyte.arr(11) = binary("a")
$tbyte.arr(12) = binary("b")
$tbyte.arr(13) = binary("c")
ConsoleWrite($tbyte.arr & @CRLF)
FileClose($hFile)
$hFile = FileOpen("TestNew.txt", $FO_CREATEPATH+$FO_BINARY+$FO_OVERWRITE)
FileWrite($hFile, $tbyte.arr)
FileClose($hFile)

 

Link to comment
Share on other sites

9 hours ago, Chuckero said:

simple like this, 1- open a file, 2- replace the bytes and 3- save the new content as a new file,

simple like this:

FileCopy("test.txt", "test.txt.new", 1)
$hFile = FileOpen("test.txt.new", 1 + 16)
FileSetpos($hFile, 17, 0)
FileWrite($hfile, Binary("abc"))
FileClose($hFile)

 

Code hard, but don’t hard code...

Link to comment
Share on other sites

Thanks to all for your prompt help.

I'll pick the @JockoDundee's answer because it's simpler, clearer and no workarounds.

That code also works like this, depending the way the file is formatted:

FileSetPos($hFile, 17, $FILE_BEGIN)
FileWrite($hFile, "abc")

FileSetPos($hFile, 17, $FILE_BEGIN)
FileWrite($hFile, Chr(97))
FileWrite($hFile, Chr(98))
FileWrite($hFile, Chr(99))

FileSetPos($hFile, 17, $FILE_BEGIN)
FileWrite($hFile, 'a')
FileWrite($hFile, 'b')
FileWrite($hFile, 'c')

 

Link to comment
Share on other sites

1 hour ago, JockoDundee said:

isn’t there a problem with this notation:

$tbyte.arr(11) = binary("a")

Is there a problem with that notation when using a standalone variable for the index, yes -- which neither of us did.  Is there a problem with that notation when using a literal as an index, no.

The reported issue seems to be related to using a standalone variable as in index.  When using that notation, I have had success with using a literal, an expression, or an enum as an index without any issues.  Hopefully the fix allows standalone variables to be used also.

If you have more questions, comments, or concerns related to the reported issue, it would probably be best to start a new topic.

 

Example:

#include <WinAPIDiag.au3>

Enum $THREE = 3, $FOUR
Global $i5 = 5, $i6 = 6

$tData = DllStructCreate("ushort value[8]")

$tData.value(1)      = 1
$tData.value(2)      = 2
$tData.value($THREE) = 3
$tData.value($FOUR)  = 4
$tData.value($i5)    = 5 ;fails
$tData.value($i6)    = 6 ;fails
$tData.value($i5+2)  = 7
$tData.value(8)      = 8

_WinAPI_DisplayStruct($tData, "ushort value[8]")

image.png.79f819a5630fec9b76a459917d3b3c39.png

Edited by TheXman
Link to comment
Share on other sites

24 minutes ago, TheXman said:

Is there a problem with that notation when using a literal as an index, no.

Thx for clarifying :)  

27 minutes ago, TheXman said:

If you have more questions, comments, or concerns related to the reported issue, it would probably be best to start a new topic.

I think that clears it up as far as the issue, however I think it adds value to be included in this thread, since although both examples use literals, if the code were to be adopted in any practical manner, it would likely be modified to use variables.

And, as I understand it, no error message is actually thrown, the assignment just doesn’t happen.  And since assignments are something that are probably the last thing to be suspected (when’s the last time you considered whether $a=$b is not working), it may spare someone considerable grief who blithely adopts the code.

Code hard, but don’t hard code...

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