Search code examples
c++linuxbashexecutableembedding

Annotating a C++ binary with bit of information


I'm trying to 'watermark' a c++ binary with various bits of information. Including this information at build time is difficult, as I don't control the build process. So far, the only idea close to what I have in mind I got from here and it is a script which, when given a c++ binary, produces a Bash script as the one below.

In short, it appends to the original binary a bash if-else which checks if the first argument is "--version" (in which case it echos some information) or not (in which case it simply decodes itself into the file "originalBinary" then runs ./originalBinary).

This obviously isn't ideal:

  • I now have 2 copies of the binary (which for large binaries can be problematic) and
  • the process running was started by ./originalBinary which is confusing for someone who doesn't know what's going on

What I'm wondering is whether I might be able to do something like replace the ./originalBinary call with some sort of special exec $0 where I can also tell exec not to read the file from the start, but with an offset of say 100 characters (or whatever the length of the Bash bit at the beginning is).

Another idea was to make the Bash script edit itself, i.e. remove its first 21 lines with sed, call ./$0 to invoke itself, then append the if-else back when the ./$0 command returns. This, however, seems brittle (what if the machine crashes before the call returns?).

Finally, I get the impression that this will fail when the binary is a shared resource, as the linker will be rather confused by the bash stuff at the beginnig when it tries to load the library :(

Alternatively, can you suggest any other way of annotating a c++ binary post-build?

I considered preparing an object file with the required information, than linking it into the given binary, but this requires that I somehow transform the ELF back into the object files that went into it, add my object file to the list, then re-link (I get the impression from here that this can be done with objcopy but I haven't yet managed to get this to work). Also, the problem with this approach is that there is no nice way of getting the information back out, like calling the binary with "--version".

Is what I'm trying to do impossible? I hope I explained things clearly.

Thanks.

#!/bin/bash

function PrintInformation()
{
    echo "various bits of information"
}

if [[ $# -eq 1 && "$1" == "--version" ]]; then
    PrintInformation
    exit 0
else
    uudecode $0
    ./originalBinary
    exit 0
fi

begin 755 originalBinary
M?T5,1@(!`0````````````(`/@`!````X`9```````!``````````'`1````
M`````````$``.``)`$``'@`;``8````%````0`````````!``$```````$``
M0```````^`$```````#X`0````````@``````````P````0````X`@``````
M`#@"0```````.`)````````<`````````!P``````````0`````````!````
M!0````````````````!``````````$```````*0*````````I`H`````````
M`"````````$````&````\`T```````#P#6```````/`-8```````6`(`````
M``"8`P``````````(````````@````8````@#@```````"`.8```````(`Y@
M``````#``0```````,`!````````"``````````$````!````%0"````````
M5`)```````!4`D```````$0`````````1``````````$`````````%#E=&0$
M````L`D```````"P"4```````+`)0```````-``````````T``````````0`
M````````4>5T9`8`````````````````````````````````````````````
M````````````"`````````!2Y71D!````/`-````````\`U@``````#P#6``
...............// my uuencode'd binary here
end

Solution

  • You can use libelf, ELFsh, or other ELF tools to create your own "section" in the binary and put whatever you want in it. This question has some more links. If all you want to do is add a blob of data to a binary, it might be easier to just use objcopy --add-section like answered here.