Processing binaries (eg Unicode "eml"==>"mht")

Jul 24, 2014 at 5:50 PM
Edited Jul 27, 2014 at 12:39 PM
[Added later: I think fnr is the wrong tool for the operation I discuss below on a binary file; there are tools specifically for this job, such as gsar, General Search And Replace, so it's probably not appropriate to add this functionality to fnr. At the end of this posting there is a brief description of using fnr to edit VMWare .VMX text files to swap between a mode in which all changes are discarded to one where all is preserved; that remains relevant.]

Original content:
I need to edit each new version I receive of an .EXE program, to replace "eml" (Unicode) embedded in the executable file with "mht", so it creates files with extension mht rather than eml. Maybe I am missing something, but I haven't been able to do this with fnr 1.7.

[Background: The file being processed is a program that creates .eml files; my system doesn't recognise this Microsoft email extension, but can open the files if named with the .mht extension, the structure is the same. It is the PopTrayU.exe binary, extracted from the PopTrayU 5.0 beta 12 distribution. I can provide details if relevant, though any binary with embedded Unicode will probably behave the same. I can make PopTrayU create files with extension .mht by replacing Unicode .eml everywhere by .mht (.eml: 00 2e 00 65 00 6d 00 6c; .mht: 00 2e 00 6d 00 68 00 74), using a hex editor; this works well. I can obviously manually rename files created by PopTrayU, changing the extension from .eml to .mht]

I'm not sure whether to add this to the the existing topic "Feature request - option to ignore binary file detection". That ended with "v1.4 now allows this", so I think a new topic is called for.

i have been trying to use fnr with the --skipBinaryFileDetection switch to handle executable files, and failing miserably. fnr in command-line mode finds matches to my 3-character Unicode string and replaces them if --alwaysUseEncoding is "utf-8" (or "utf-7"), but completely garbles the file (changes every byte, increases the size by a factor of about 3 or 2). In GUI mode the --alwaysUseEncoding switch is ignored, so I can only work in command-line mode.

I have been trying commands such as
"R:\fnr.exe" --cl --dir "R:" --fileMask "PopTrayU.exe" --SkipBinaryFileDetection --alwaysUseEncoding "utf-8" --find "eml" --replace "mht"

fnr would let me make a CMD file once and for all, instead of tediously using a hex editor for each release. Can fnr make this replacement; if so how? Some additional related suggestions:
  1. It would be useful, whatever else is done, to enable fnr in GUI mode to find and report the location of, if not replace, strings in any file, including binaries.
  2. It would be useful to enable --alwaysUseEncoding in GUI mode as well as CLI, possibly by including it, without --cl, in the command used to invoke the program. It would only make sense to allow replacement if clean replacement is possible (without corrupting the whole file).
  3. it would be useful to allow clean replacement of strings in binary files, perhaps with a check that the replacement string is of the same length (with user notification rather than block). Obviously, only the specified string should be changed (I say this because the present replace massively corrupts the whole file), with a replacement by default restricted to be of the same length.
Editing binaries may of course cause problems, but is safe enough if tested on a backed-up file, and followed by a comparison. An attempt to edit a binary should be flagged, rather than blanket-banned as by the present GUI.

Having said that, fnr is brilliant. I use it to edit VMWare virtual machine .vmx files, interchanging a 4-line block; constructing a command line by hand would have been a pain, fnr's Gen Replace Command Line is brilliant to create batch files. I swap the entire blocks:

[hash]Lose changes this session at shutdown:
scsi0:0.mode = "independent-nonpersistent"
snapshot.action = "autoRevert"
snapshot.disabled = "TRUE"
displayName = "XP (no save)"

[hash]Keep changes:
scsi0:0.mode = "persistent"
snapshot.action = "keep"
snapshot.disabled = "FALSE"
displayName = "XP (SAVES)"