用一些信息注释C++二进制文件

Annotating a C++ binary with bit of information

本文关键字:C++ 二进制文件 注释 信息      更新时间:2023-10-16

我正在尝试用各种信息为c ++二进制文件"加水印"。在构建时包含此信息很困难,因为我无法控制构建过程。到目前为止,唯一接近我的想法是从这里得到的,它是一个脚本,当给定一个 c++ 二进制文件时,会产生一个 Bash 脚本,如下所示。

简而言之,它会在原始二进制文件中附加一个 bash if-else,该参数检查第一个参数是否为"--version"(在这种情况下,它会回显一些信息)或不(在这种情况下,它只是将自身解码为文件"originalBinary"然后运行 ./originalBinary)。

这显然并不理想:

  • 我现在有 2 个二进制文件副本(对于大型二进制文件可能会有问题)和
  • 运行的进程是由./originalBinary启动的,这对于不知道发生了什么的人来说是令人困惑的

我想知道的是我是否可以做一些事情,比如用某种特殊exec $0替换./originalBinary调用,我也可以告诉 exec 不要从一开始就读取文件,而是偏移量为 100 个字符(或任何开头 Bash 位的长度)。

另一个想法是让 Bash 脚本自己编辑,即使用 sed 删除其前 21 行,调用./$0调用自身,然后在./$0命令返回时将 if-else 追加回来。然而,这似乎很脆弱(如果机器在调用返回之前崩溃怎么办?

最后,我的印象是,当二进制文件是共享资源时,这将失败,因为当链接器尝试加载库:(时,它一开始就会被 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 --add-section可能会更容易,就像这里回答的那样。

这有点黑客,但您可以采取的一种方法是嵌入如下字符串:

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 .= "" 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_magicE/$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 $modifiedn";