C ++ binary annotation with bit of information

I am trying to “wet” a C ++ binary with various bits of information. Including this information during assembly is difficult as I do not control the assembly process. So far, the only idea close to what I have in mind is what I got from here , and this is a script that, when setting the C ++ binary, creates a Bash script, as shown below.

In short, it adds to the original binary a Bash if-else, which checks if the first argument is “--version” (in this case it passes some information) or not (in this case it simply decodes itself into the file “originalBinary” then executed. / originalBinary).

This is obviously not ideal:

  • Now I have 2 copies of the binary (which can be problematic for large binary files) and
  • process start started with ./originalBinary , which confuses someone who doesn't know what is going on

I am wondering if I can do something like replacing the ./originalBinary call with a special exec $0 , where I can also tell exec not to read the file from the very beginning, but using an offset of, say, 100 characters (or whatever the length of the bits Bash at the beginning was not).

Another idea was to do a Bash script editing, i.e. delete the first 21 lines with sed, call ./$0 to call yourself, and then add if-else back when the ./$0 command ./$0 . This, however, seems fragile (what if the machine works before the call returns?).

Finally, it seems that this will fail if the binary is a shared resource, since the linker will be confused with the Bash material at the beginning when it tries to load the library :(

Alternatively, can you suggest any other way to annotate a C ++ binary post build?

I considered the question of preparing an object file with the necessary information, rather than tying it to a given binary file, but this requires that I somehow convert ELF back to the object files that came 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 have not yet managed to get this to work). In addition, the problem with this approach is that there is no good way to return information, for example, invoke binary code using "--version".

Am I trying to do something impossible? I hope I clearly explained the situation.

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 
+4
source share
2 answers

You can use libelf, ELFsh, or other ELF tools to create your own “section” in binary format and put whatever you want in it. This question contains a few more links. If all you want to do is add a blob of data to the binary, it would be easier to just use objcopy --add-section , for example here .

+1
source

This is a bit hacky, but the approach you can take is to insert a line such as:

 static const char *version = "<<<VERSION-INFORMATION-HERE>>>"; 

in your code. Your program can print this if necessary. Make sure the string is long enough to store all the information needed for your real version. You can then edit the resulting binary to overwrite this line with a watermark. Here's a (not very pretty, but functional) Perl script that can do this:

 die "Usage $0 original-binary-file output-binary-file version-info" unless ($#ARGV == 2); $original = $ARGV[0]; $modified = $ARGV[1]; $new_version = $ARGV[2]; $version_magic = "<<<VERSION-INFORMATION-HERE>>>"; if (length($new_version) > length($version_magic)) { die "$0: Length of version string '$new_version' must be less than that of '$version_magic'\n" } $new_version .= "\0" x (length($version_magic) - length($new_version)); open(IN, $original) or die "\nCan't open $original for reading: $!\n"; open(OUT, ">$modified") or die "\nCan't open $modified for writing: $!\n"; binmode IN; binmode OUT; my $buffer; my $size = -s $original; read(IN, $buffer, $size) or die "$0: Failed to read $size bytes from $original: $!\n"; $buffer =~ s/\Q$version_magic\E/$new_version/; print OUT $buffer or die "$0: Failed to write $size bytes to $modified: $!\n"; close IN or die "$0: Can't close $original: $!\n"; close OUT or die "$0: Can't close $modified: $!\n"; chmod 0755, $modified; print "Created $modified\n"; 
0
source

Source: https://habr.com/ru/post/1447028/


All Articles