14

I have an executable binary; let's call it a.out. I can see the binary contains strings

$ strings a.out
...
/usr/share/foo
....

I need to change the string /usr/share/foo to /usr/share/bar. Can I just replace the string with sed?:

sed -i 's@/usr/share/foo@/usr/share/bar@' a.out

This looks like a safe thing to do. Will this also work when the strings are not the same length?

17

I don't know if your version of sed will be binary-clean or if will choke on what it thinks are really long lines in its input, but barring those issues, editing the string in-place should work. To see whether it does, compare the old and new versions with cmp -l. It should tell you whether or not the only three differences between the two files are those 3 bytes.

Editing strings in a compiled executable will indeed work if the strings are of the same length, but it will almost always also work if you are shortening the string, due to the way that strings work in C. In C strings, everything after the NUL terminator does not count, so if you write a new NUL terminator before the position of the old one, you will effectively shorten the string.

In general, there is no way you can lengthen a string using this hack.

  • What about shortening the string with something like sed -i 's@longstring@foo@' a.out? This will make the whole binary smaller by 7 bytes, Will this not corrupt the binary ? – Martin Vegter Mar 9 '15 at 9:29
  • Yes, it will corrupt the binary. That's why you have to translate the string to one of the exact same length, but set a NUL terminator at an earlier position as I explained (although maybe too briefly). The trouble is that you can't have a NUL byte on the command line so you have to put your sed program into a file and refer to it with -f. On the other hand, the safer thing to do would be to use a tool that is designed to work with binary data instead of sed which is designed to work with text data. – Celada Mar 9 '15 at 9:46
  • 2
    Good answer. sed can do lots of things, but, in general, that's what binary editors were invented for. They can be challenging to use when navigating within a large binary file, but they will let you change things byte by byte. I use hexedit when I have to examine or change a binary file. You can use strings -t x file | less to locate the offsets of the (printable) strings you want to change before jumping into the editor. – Joe Mar 22 '15 at 5:26
  • Let's say I have a string in my C program: "My name was Mr Robot" and I want to replace 'was' with 'is', then padding \0 will have to be done carefully, because if the replacement does this: "My name is\0 Mr Robot", then while performing operations with the string, the '\0' character will create problems as the length will reduce unintentionally. – Nehal J Wani Nov 10 '16 at 8:31
  • @NehalJWani no, in that case you'd have to shift the whole rest of the string forward by one byte so that your new, extra, terminating NUL goes on the end, adjacent to the existing NUL. – Celada Nov 23 '16 at 21:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.