Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/28.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C `ar`库覆盖时间戳_C_Linux_Static Libraries_Unix Ar_.a - Fatal编程技术网

C `ar`库覆盖时间戳

C `ar`库覆盖时间戳,c,linux,static-libraries,unix-ar,.a,C,Linux,Static Libraries,Unix Ar,.a,.a存档格式标头需要时间戳。当我重建静态库时,这导致了无数的麻烦,主要是因为我不能准确地复制原始二进制文件 例如(这在我的Mac上,但在x64 linux上也会发生同样的情况): 为了向自己证明唯一的区别是时间,我根据hexdump进行了一次比较: $ diff <(hexdump libfoo.a) <(hexdump libfoo.a1) 2,3c2,3 < 0000010 20 20 20 20 20 20 20 20 31 33 31 31 30 34 33 30 &l

.a存档格式标头需要时间戳。当我重建静态库时,这导致了无数的麻烦,主要是因为我不能准确地复制原始二进制文件

例如(这在我的Mac上,但在x64 linux上也会发生同样的情况):

为了向自己证明唯一的区别是时间,我根据hexdump进行了一次比较:

$ diff <(hexdump libfoo.a) <(hexdump libfoo.a1)
2,3c2,3
< 0000010 20 20 20 20 20 20 20 20 31 33 31 31 30 34 33 30
< 0000020 38 36 20 20 35 30 31 20 20 20 32 30 20 20 20 20
---
> 0000010 20 20 20 20 20 20 20 20 31 33 31 31 30 34 32 38
> 0000020 37 31 20 20 35 30 31 20 20 20 32 30 20 20 20 20
$diff 00000 20 37 31 20 20 35 30 31 20 20 32 30 20 20 20 20 20
如果使用标头格式进行反解算,则其对应于时间字段

Manpage没有给出是否可以覆盖来自报头的时间戳的指示。有什么想法吗

编辑:是的,可以返回并对文件进行物理攻击以使用任意时间戳。是的,可以更改程序的行为。考虑到情况周围的环境(并非所有环境都是严格的技术性环境),手动更改时间戳的工具是不可接受的,修改后的
ar
,也不会影响实际的系统时间

编辑:在这种情况下,我必须证明,在不偏离构建路径的情况下,二进制文件可以从源代码生成。在某些行业(如金融业),这显然是一种标准做法。手动更改时间戳的工具是不可接受的(因为使用了不在原始构建路径中的特殊工具)。手动版本的
ar
是不可接受的(类似问题)。更改系统时钟的问题在于构建必须完全协调(这是一个一小时的构建,包含大量库和二进制文件)。可接受的解决方案包括:

  • 指向AR或其他程序的标志,这些程序可以覆盖库中的时间戳
  • 现有的(年龄>1岁)工具可以执行此操作
  • GCC的标志,可以在执行链接时覆盖来自ar的时间戳

默认答案是“ar工具无法完成”

使用dd可以覆盖所需文件的部分:

dd if=libfoo.a1 of=libfoo.a skip=30 seek=30 count=4 bs=1 conv=notrunc
当然,这意味着您需要在其他地方使用时间戳(您可以有一个非常基本的c程序,它获取当前时间并以小端或大端输出,然后使用dd可以覆盖库文件)。使用dd,我可以覆盖.a文件,并且不会得到任何差异结果

在ar中使用“确定性模式”。请参阅手册中ar的选项“D”

me@mybox:~$ rm libfoo.a; touch foo.o; ar rcsD libfoo.a foo.o; md5sum libfoo.a
3ecae045133ff919d1e42f6050ef56be  libfoo.a
me@mybox:~$ rm libfoo.a; touch foo.o; ar rcsD libfoo.a foo.o; md5sum libfoo.a
3ecae045133ff919d1e42f6050ef56be  libfoo.a

如果之后使用
ranlib
,请确保使用的是
ranlib-D
;否则,
ranlib
会将时间戳放回。

如果二进制文件的其余部分总是完全相同,那么您可以在
.a
文件中找到时间戳,并用固定值(如全零)覆盖它。

请原谅我的好奇,但为什么您希望新二进制文件与旧二进制文件完全匹配?也许有更好的方法来实现你想要的。@Frédéric Hamidi这不是重点。是的,我可以手动返回并破解所有的时间戳,但是想象一下有>10个库和>100个二进制文件的情况。您不能返回并手动执行此操作。我再也看不到任何问题。没有任何
ar
选项可以满足您的需要,您已经排除了编辑
.a
文件和构建自己的专用工具的可能性;这可以归结为一个简单的问题:你是否可以阅读手册页,而且你显然可以。这个工具不能做你需要它做的事情,你也不能使用不同的工具或修改现有的工具,问题在哪里?首先,它不是金融领域的标准做法。在金融领域,标准做法是将源代码管理标签嵌入到每个对象文件中,这样您就可以对二进制文件执行
strings
。第二,您的方法会用C++和匿名命名空间来打破,因为编译器在每个编译时为匿名命名空间生成新名称。@在实际道具交易平台上的MaxIM,对业务连续性有真正的关注,并且必须证明没有什么被省略或隐藏在某个地方。这就要求你准确地复制二进制文件,因为如果有一点偏差,你就有问题了(你如何区分“你的交易没有赚钱,因为今天与昨天不同”和“你的交易没有赚钱,因为你改变了二进制文件”)?这是一个残酷的地方,您可以避免篡改代码的问题。由于我知道我没有在问题中解释的原因,这类解决方案(编写工具手动更改时间戳)是不可接受的。不幸的是,这里存在非技术因素。我更新了问题。您更新了:可接受的解决方案包括:AR标志或其他可以覆盖库中时间戳的程序“那么,该解决方案为何不适用?我同意该解决方案符合OP的规定要求。这是最好的解决方案,值得+50。它不能解决问题,因为它仍然在篡改时间戳。另外,弗雷德里克在一周前提出了这个建议,我已经表达了对这个方法的关注。那么这个问题就无法回答了。为什么不干脆放弃使用库文件,并显式链接所需的对象文件集呢?请注意,“确定性模式”是一个相对较新的添加。您需要GNU binutils 2.20(发布于2009-10-16)或更新版本
ar--version
将告诉您所拥有的版本。非GNU版本的“ar”可能没有“D”选项(或者说,
--version
);它还刷新时间戳(它不完全复制库);然而,我已经添加了它来为将来的项目构建脚本。除了@KeithThompson,
ranlib
命令将时间戳添加回脚本。尽管
ranlib
提供了一个
-t
选项来“更新ti
me@mybox:~$ rm libfoo.a; touch foo.o; ar rcsD libfoo.a foo.o; md5sum libfoo.a
3ecae045133ff919d1e42f6050ef56be  libfoo.a
me@mybox:~$ rm libfoo.a; touch foo.o; ar rcsD libfoo.a foo.o; md5sum libfoo.a
3ecae045133ff919d1e42f6050ef56be  libfoo.a