Я пытаюсь сделать «водяные знаки» двоичного файла с ++ с различной информацией. Включение этой информации во время сборки сложно, так как я не контролирую процесс сборки. Пока единственная идея, близкая к тому, что я имею в виду, я получила от Вот и это скрипт, который, если ему дан бинарный файл c ++, создает скрипт Bash, как показано ниже.
Короче говоря, он добавляет к исходному двоичному файлу bash if-else, который проверяет, является ли первый аргумент «—version» (в этом случае он выводит некоторую информацию) или нет (в этом случае он просто декодирует себя в файл «originalBinary»). затем запускается ./originalBinary).
Это явно не идеально:
./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
Вы можете использовать libelf, ELFsh или другие инструменты ELF, чтобы создать свой собственный «раздел» в двоичном файле и поместить в него все, что вы хотите. Этот вопрос имеет еще несколько ссылок. Если все Вы хотите сделать, это добавить блок данных в двоичный файл, может быть проще просто использовать objcopy — дополнительный раздел лайк ответил здесь.
Это что-то вроде хака, но подход, который вы можете использовать, — это вставить такую строку:
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";