emendelson

Replace binary string at known location:

11 posts in this topic

#1 ·  Posted

I'm trying to replace a string in a 50MB binary file (a disk image of a Mac hard disk) with another string, and I know the exact location of the string that I want to replace. The content of the original string (the string I want to overwrite) doesn't matter, because I'll be working from a fresh copy of the file every time, and I know the exact location.

It looks to me as if this code should work, but it never writes the replacement string into the output file:

#include <String.au3>
$f = FileOpen("SetupCopy.dsk",16)
$d = FileRead($f)
FileClose($f)
$h = _StringToHex("H:USERS:ROSCOE")
$r = StringReplace($d, 23079424, $h)
$w = FileOpen("SetupCopyRevised.dsk", 18)
FileWrite($w, $r)
FileClose($w)

The SetupCopyRevised.dsk file gets created, but it's the same as the original file.

My hex editor tells me that the string I want to replace starts at 1602a00h, which is 23079424 dec.

I'm probably missing something obvious, but I can't imagine what. Can anyone tell me what I should have figured out for myself? When I add trace lines, no errors get reported.

Share this post


Link to post
Share on other sites



#2 ·  Posted

Add a MsgBox(0, "", @extended) after $r = ... to see how many times if any that the string was replaced.

Share this post


Link to post
Share on other sites

#3 ·  Posted

You could also try using:

#include <String.au3>
_StringInsert($d, $h, 23079424)

 

Share this post


Link to post
Share on other sites

#4 ·  Posted

But _StringInsert would insert string $h and not replace the existing data as the OP wants, right?


My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2017-04-18 - Version 1.4.8.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (NEW 2017-02-27 - Version 1.3.1.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2015-04-01 - Version 0.4.0.0) - Download - General Help & Support - Example Scripts
Excel - Example Scripts - Wiki
Word - Wiki
PowerPoint (2015-06-06 - Version 0.0.5.0) - Download - General Help & Support

Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites

#5 ·  Posted

@water  doh, you're correct, Mondayitis was thinking about keyboard insert functionality.

Share this post


Link to post
Share on other sites

#6 ·  Posted

:)


My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2017-04-18 - Version 1.4.8.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (NEW 2017-02-27 - Version 1.3.1.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2015-04-01 - Version 0.4.0.0) - Download - General Help & Support - Example Scripts
Excel - Example Scripts - Wiki
Word - Wiki
PowerPoint (2015-06-06 - Version 0.0.5.0) - Download - General Help & Support

Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites

#7 ·  Posted (edited)

2 hours ago, Subz said:

Add a MsgBox(0, "", @extended) after $r = ... to see how many times if any that the string was replaced.

The MsgBox shows 0. It does the same thing even if I use a different address. I tried the same thing with a smaller file. Still 0. Something seems to be wrong with the logic of my code, but I still can't see what.

Edited by emendelson

Share this post


Link to post
Share on other sites

#8 ·  Posted

What does MsgBox(0, "", StringLen($d)) return?

Share this post


Link to post
Share on other sites

#9 ·  Posted (edited)

7 minutes ago, Subz said:

What does MsgBox(0, "", StringLen($d)) return?

It returns 83,886,082 (I've added the commas). The file itself is actually 41,943,040 bytes long, so that sounds right. The file that gets written has the same number of bytes. (Same result if I ask the MsgBox for StringLen($r).)

Edited by emendelson

Share this post


Link to post
Share on other sites

#11 ·  Posted (edited)

OK, to answer my own question, this works, but I've got a question about it:

#include <WinAPI.au3>
Local $sTempFile, $hFile, $sText, $nBytes, $tBuffer, $iToWrite

FileCopy("SetupCopy.dsk", "test.dsk", 1)
$sTempFile = "test.dsk"
$sText = 'D:USERS:ROSCOE'
$iToWrite = StringLen($sText)
$tBuffer = DllStructCreate("byte[" & $iToWrite & "]")
DllStructSetData($tBuffer, 1, $sText)
$hFile = _WinAPI_CreateFile($sTempFile, 2, 4)
_WinAPI_SetFilePointer($hFile, 23079424)
_WinAPI_WriteFile($hFile, $tBuffer, $iToWrite, $nBytes)
_WinAPI_CloseHandle($hFile)
$tBuffer = 0

Question: In the help file $nBytes is defined as "ByRef $iWritten". I'm a complete beginner at this, so I'm guessing that ByRef means that something else in the function sets the actual number, and I don't have to think about it. Is that right?

Meanwhile, it would be good to know why my original code fails and this code works.

Edited by emendelson
Removing unused variable, again.

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