11

.aアーカイブ形式のヘッダーにはタイムスタンプが必要です。これは、主に元のバイナリを正確に再現できないために、静的ライブラリを再構築するときに数え切れないほどの頭痛の種になりました。

たとえば(これは私のMacにありますが、x64 linuxでも同じことが起こります):

$ cat foo.h
int foo();
$ cat foo.c
#include "foo.h"
int foo() { return 3; }
$ gcc -fno-pic -m64 -arch x86_64 -I/usr/local/include -O3 -c foo.c -o foo.o -fpic
$ ar rcs libfoo.a foo.o
$ md5 libfoo.a
MD5 (libfoo.a) = 0d0e6606185de4e994c47f4a0e54c1c4
$ mv libfoo.a libfoo.a1
$ ar rcs libfoo.a foo.o
$ md5 libfoo.a
MD5 (libfoo.a) = 22a69d42e1325ae8f978c2a18a4886da    

唯一の違いが時間であることを自分自身に証明するために、私は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

これは、ヘッダー形式を使用してバックソルブする場合、時間フィールドに対応します。

マンページには、ヘッダーのタイムスタンプを上書きできるかどうかは示されていません。何かご意見は?

編集:はい、任意のタイムスタンプを使用するために戻ってファイルを物理的にハッキングすることは可能です。はい、プログラムの動作を変更することは可能です。状況を取り巻く状況を考えると、そのすべてが本質的に厳密に技術的であるとは限らないため、タイムスタンプを手動で変更するツールは受け入れられず、の修正バージョンでarも、実際のシステム時刻を台無しにすることもありません。

編集:この状況では、ビルドパスからの許容できない逸脱なしに、バイナリをソースから生成できることを証明する必要があります。一部の業界(金融など)では、これは明らかに標準的な方法です。タイムスタンプを変更するための手動ツールは使用できません(元のビルドパスになかった特別なツールが使用されたため)。のハンドロールバージョンarは受け入れられません(同様の問題)。システムクロックを変更する際の問題は、ビルドを完全に調整する必要があることです(これは、多くのライブラリとバイナリを含む1時間のビルドです)。受け入れ可能なソリューションは次のとおりです。

  • ライブラリ内のタイムスタンプを上書きする可能性のあるARまたはその他のプログラムへのフラグ
  • これを行うための既存の(年齢> 1歳)ツール
  • リンクを行うときにarからのタイムスタンプをオーバーライドできるGCCへのフラグ
4

4 に答える 4

20

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は、タイムスタンプを戻します。

于 2011-07-25T23:40:43.600 に答える
5

dd を使用すると、ファイルの必要な部分を上書きできます。

dd if=libfoo.a1 of=libfoo.a skip=30 seek=30 count=4 bs=1 conv=notrunc

もちろん、これは別の場所でタイムスタンプが必要になることを意味します (現在の時刻を取得してリトル エンディアンまたはビッグ エンディアンで出力し、dd を使用してライブラリ ファイルを上書きできる、非常に基本的な C プログラムを作成できます)。dd を使用して、.a ファイルを上書きし、差分結果を取得できません

于 2011-07-25T00:56:51.480 に答える
0

残りのバイナリが常にまったく同じである場合は、ファイル内のタイムスタンプを見つけて.a、固定値 (すべてゼロなど) でオーバーライドできます。

于 2011-07-31T02:50:19.973 に答える
-3

デフォルトの回答は「ar ツールでは実行できません」です。

于 2011-07-24T15:28:09.227 に答える