Отметка времени переопределения библиотеки `ar`

Заголовок формата архива.a требует отметки времени. Это привело к бесчисленным головным болям, когда я перестраивал статическую библиотеку, главным образом потому, что я не могу точно воспроизвести исходный двоичный файл.

Например (это на моем Mac, но то же самое происходит в Linux x64):

$ 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    

Чтобы доказать себе, что единственной разницей было время, я взял diff на основе 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

который, если вы выполняете обратное преобразование с использованием формата заголовка, соответствует полю времени.

Manpage не указывает, возможно ли переопределить метку времени из заголовка. Какие-нибудь мысли?

Изменить: да, можно вернуться и физически взломать файл, чтобы использовать произвольную метку времени. да, можно изменить поведение программы. Принимая во внимание обстоятельства, связанные с ситуацией, не все из которых носят сугубо технический характер, инструмент для ручного изменения метки времени не является приемлемым, а также модифицированная версия arи не влияет на текущее системное время.

Изменить: В этом случае я должен доказать, что без каких-либо недопустимых отклонений от пути сборки, двоичные файлы могут быть получены из источника. В некоторых отраслях (например, в сфере финансов) это, по-видимому, стандартная практика. Инструмент с ручным управлением для изменения меток времени недопустим (потому что использовался специальный инструмент, которого не было в исходном пути сборки). Ручная версия ar недопустимо (похожая проблема). Проблема с изменением системных часов заключается в том, что сборка должна быть идеально скоординирована (это часовая сборка с большим количеством библиотек и двоичных файлов). Приемлемые решения включают в себя:

  • флаги для AR или других программ, которые могут переопределить метку времени в библиотеке
  • существующий (возраст> 1 года) инструмент для этого
  • флаги GCC, которые могут переопределять метку времени, приходящую от ar, когда выполняется связывание

5 ответов

Решение

Если остальная часть двоичного файла всегда одинакова, вы можете найти метку времени в .a файл и переопределить его с фиксированным значением (как и все нули).

Используйте "детерминированный режим" в ар. Смотрите опцию "D" для ar в руководстве.

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 вернет отметку времени.

Использование dd позволит вам перезаписать ту часть файла, которую вы хотите:

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

конечно, это означает, что вам понадобится ваша временная метка где-то еще (у вас может быть очень простая программа на с, которая берет текущее время и выводит его с прямым или прямым порядком байтов, а затем с помощью dd вы можете перезаписать файл библиотеки). используя dd, я могу перезаписать файл.a и не получить результатов сравнения

Я написал скрипт Python в своем GitHub для сброса временных меток для более старых версийarу которого не было-Dвариант.

Я тестировал Python 3.8.10 и Python 2.6.6.

https://gist.github.com/Supermanuu/ccdbe0c5d15d41dd1df75ad288e2a30a

Используйте пример для очистки временных меток:

      ./manageStaticLibTimestamp.py cw *.a

Использование:

      Usage: ./manageStaticLibTimestamp.py [pcw] <static library paths ...>
 p - print timestamps
 c - clear timestamps
 w - write timestamps

Ответ по умолчанию: "Это не может быть сделано инструментом ar"

Другие вопросы по тегам