(tye)Re: how do I swap 2 strings in a file?
by tye (Sage) on May 08, 2001 at 20:48 UTC
|
Executable files are generally not position-independent
which means you need to pad your replacement string to
be the same length as the original string.
-
tye
(but my friends call me "Tye")
| [reply] |
Re: how do I swap 2 strings in a file?
by TGI (Parson) on May 08, 2001 at 20:46 UTC
|
Definitely check out Death to Dot Star!.
Since I haven't really worked with binmode, I don't know what gotchas it introduces. You might want to try using the multiline (m) option on your regex.
Also, a better way to read in your file at one go is:
#Slurp up ORIG
{ local $/;
$string= <ORIG>
}
This works by undefing the input record separator, which causes any read from the filehandle to get the whole file. BTW, setting $/="" blank lines are the delimiter.
TGI says moo
| [reply] [d/l] |
(Boo)Re: how do I swap 2 strings in a file?
by boo_radley (Parson) on May 08, 2001 at 20:41 UTC
|
This may be a total red herring, but it worked when I debugged command.com to say goofy things, so it's probably got some grain of truth to it.
In some executables under dos, before a string, will come a byte which describes the length of the string. e.g. before "hello" will be 0x05. If you swap out "this program doesn't do DOS, baby!" for "hello", the dll may think the string is only 5 chars wide -- "this " -- and take "p" to mean 0x70, for a string 112 chars wide, allowing the DLL to mistranslate the remnant of the string, and possibly various other strings, code and whatnot as part of a string that shouldn't exist.
| [reply] [d/l] |
|
|
If I remember correctly, most executables compiled with Pascal will have this length byte at the head of each string.
| [reply] |
Re: how do I swap 2 strings in a file?
by cLive ;-) (Prior) on May 08, 2001 at 21:08 UTC
|
Add an s modifier (treat as single line) and amend regex to become:
$string =~s /($string_1)(.*?)($string_2)/$3$2$1/gs;
Should work, as far as I can see...
cLive ;-)
| [reply] [d/l] |
Re: how do I swap 2 strings in a file?
by converter (Priest) on May 08, 2001 at 23:03 UTC
|
I don't know if this will help or not, but I've noticed that in some segments of some executable binaries, strings are stored in arrays of integers, so that in a hex browser, the string IBM PC-DOS would look like:
I.B.M.P.C.-.D.O. 49 00 42 00 4d 00 20 00 50 00 43 00 2d 00 44 00 4f 0
+0
S. 53 00
Your best bet, when you're after replacing text in a file with 8-bit characters, is to use a hex browser to look at the text you want to replace and find out how it's actually stored, not how it's displayed when printed by the program.
In the above example, you could match "IBM" with:
/I\x00B\x00M\x00/
Or match and replace with "BAR" using:
s[I\x00B\x00M\x00]{B\x00A\x00R\x00};
P.S. I could have the byte order wrong in the example above, but if your text is stored this way, you'll understand what I'm referring to.
| [reply] [d/l] [select] |
Re: how do I swap 2 strings in a file?
by srawls (Friar) on May 08, 2001 at 21:58 UTC
|
Why don't you try this to switch the strings. It doesn't involve a regex, and is easier to follow:
while(<ORIG>){
if ($_ eq $string_1) {$string .= $string_2; next;}
elsif ($_ eq $string_2) {$string .= $string_1; next;}
$string.= $_;
}
The 15 year old, freshman programmer,
Stephen Rawls | [reply] [d/l] |
|
|
1221323asdl;lerTHIS IS
THE STRING I WANTasdlf
asdajla;sdfasdfasdfass
nothing will happen.
That being said, the above technique is a clever way to change (or slightly modified, insert) whole lines in a file.
TGI says moo
| [reply] |
|
|
Ok, agreed. But I'd still like to clean up that regex, so here it goes:
$string=~s/($string_1)(.*)($string_2)/$3$2$1/msg;
That should be a bit better than matching the whole string, also I added the /m modifier. I put the /s modifier in too because I thought /msg just looked cool : )
The 15 year old, freshman programmer,
Stephen Rawls | [reply] [d/l] |