Linux — Аннотирование двоичного файла C ++ с небольшим количеством информации

Я пытаюсь сделать «водяные знаки» двоичного файла с ++ с различной информацией. Включение этой информации во время сборки сложно, так как я не контролирую процесс сборки. Пока единственная идея, близкая к тому, что я имею в виду, я получила от Вот и это скрипт, который, если ему дан бинарный файл c ++, создает скрипт Bash, как показано ниже.

Короче говоря, он добавляет к исходному двоичному файлу bash if-else, который проверяет, является ли первый аргумент «—version» (в этом случае он выводит некоторую информацию) или нет (в этом случае он просто декодирует себя в файл «originalBinary»). затем запускается ./originalBinary).

Это явно не идеально:

  • Теперь у меня есть 2 копии двоичного файла (что для больших двоичных файлов может быть проблематичным) и
  • запуск процесса был начат ./originalBinary что сбивает с толку тех, кто не знает, что происходит

Мне интересно, смогу ли я сделать что-то вроде замены ./originalBinary позвонить с каким-то особенным exec $0 где я также могу сказать exec не читать файл с самого начала, а со смещением, скажем, 100 символов (или любой другой длины бита Bash в начале).

Другая идея состояла в том, чтобы заставить скрипт Bash редактировать сам, то есть удалить первые 21 строку с помощью sed, call ./$0 чтобы вызвать себя, а затем добавить if-else обратно, когда ./$0 команда возвращается. Это, однако, кажется хрупким (что, если машина выйдет из строя до того, как вызов вернется?).

Наконец, у меня складывается впечатление, что это не удастся, когда бинарный файл является общим ресурсом, так как компоновщик будет довольно смущен работой bash в начале, когда он попытается загрузить библиотеку 🙁

В качестве альтернативы, можете ли вы предложить какой-либо другой способ аннотирования двоичного кода после сборки c ++?

Я подумал о том, чтобы подготовить объектный файл с необходимой информацией, чем связать его с заданным двоичным файлом, но для этого необходимо, чтобы я каким-то образом преобразовал ELF обратно в объектные файлы, которые вошли в него, добавил мой объектный файл в список, а затем повторно связал (У меня сложилось впечатление от Вот что это можно сделать с objcopy но мне пока не удалось заставить это работать). Кроме того, проблема с этим подходом состоит в том, что нет хорошего способа вернуть информацию, как, например, вызов двоичного файла с «—version».

Разве то, что я пытаюсь сделать, невозможно? Надеюсь, я все объяснил ясно.

Благодарю.

#!/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

Решение

Вы можете использовать libelf, ELFsh или другие инструменты ELF, чтобы создать свой собственный «раздел» в двоичном файле и поместить в него все, что вы хотите. Этот вопрос имеет еще несколько ссылок. Если все Вы хотите сделать, это добавить блок данных в двоичный файл, может быть проще просто использовать objcopy — дополнительный раздел лайк ответил здесь.

1

Другие решения

Это что-то вроде хака, но подход, который вы можете использовать, — это вставить такую ​​строку:

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

в вашем коде. Ваша программа может распечатать это по мере необходимости. Убедитесь, что строка достаточно длинная, чтобы вместить всю информацию, которая вам понадобится для вашей реальной информации о версии. Затем вы можете отредактировать полученный бинарный файл, чтобы перезаписать эту строку вашим «водяным знаком». Вот (не очень красивый, но функциональный) скрипт Perl, который может сделать это:

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

По вопросам рекламы [email protected]