Jump to content

Replace binary string at known location:


Recommended Posts

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.

Link to comment
Share on other sites

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 2022-02-19 - Version 1.6.1.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki
Task Scheduler (NEW 2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki

Standard UDFs:
Excel - Example Scripts - Wiki
Word - Wiki

Tutorials:
ADO - Wiki
WebDriver - Wiki

 

Link to comment
Share on other sites

:)

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2022-02-19 - Version 1.6.1.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki
Task Scheduler (NEW 2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki

Standard UDFs:
Excel - Example Scripts - Wiki
Word - Wiki

Tutorials:
ADO - Wiki
WebDriver - Wiki

 

Link to comment
Share on other sites

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
Link to comment
Share on other sites

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
Link to comment
Share on other sites

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