У меня есть двоичный файл Linux без исходных текстов, который работает на одной машине, и я хотел бы создать автономный пакет, который работал бы на другом компьютере с той же архитектурой. Как это можно достичь?
В моем случае обе машины имеют одинаковую архитектуру, одинаковое ядро Ubuntu, но на целевой машине нет make
и неправильная версия файлов в / lib
и / usr
Одна из моих идей заключалась в том, чтобы использовать chroot
и воссоздать подмножество файловой системы, которую использует двоичный файл, возможно, используя strace
для выяснить, что ему нужно. Есть ли инструмент, который уже делает это?
Для потомков, вот как я выясняю, какие файлы открывает процесс
#!/usr/bin/python
# source of trace_fileopen.py
# Runs command and prints all files that have been successfully opened with mode O_RDONLY
# example: trace_fileopen.py ls -l
import re, sys, subprocess, os
if __name__=='__main__':
strace_fn = '/tmp/strace.out'
strace_re = re.compile(r'([^(]+?)\((.*)\)\s*=\s*(\S+?)\s+(.*)$')
cmd = sys.argv[1]
nowhere = open('/dev/null','w')#
p = subprocess.Popen(['strace','-o', strace_fn]+sys.argv[1:], stdout=nowhere, stderr=nowhere)
sts = os.waitpid(p.pid, 0)[1]
output = []
for line in open(strace_fn):
# ignore lines like --- SIGCHLD (Child exited) @ 0 (0) ---
if not strace_re.match(line):
continue
(function,args,returnval,msg) = strace_re.findall(line)[0]
if function=='open' and returnval!='-1':
(fname,mode)=args.split(',',1)
if mode.strip()=='O_RDONLY':
if fname.startswith('"') and fname.endswith('"') and len(fname)>=2:
fname = fname[1:-1]
output.append(fname)
prev_line = ""
for line in sorted(output):
if line==prev_line:
continue
print line
prev_line = line
Обновление
Проблема с решениями LD_LIBRARY_PATH
заключается в том, что / lib
жестко запрограммирован в интерпретаторе и имеет приоритет над LD_LIBRARY_PATH
, поэтому сначала загружаются собственные версии. Интерпретатор жестко запрограммирован в двоичный файл. Один из подходов может заключаться в том, чтобы исправить интерпретатор и запустить двоичный файл как patched_interpreter mycommandline
Проблема в том, что когда mycommandline
начинается с java
, это не работает, потому что Java устанавливает LD_LIBRARY_PATH
и перезапускается, используя старый интерпретатор. Решение, которое сработало для меня, заключалось в том, чтобы открыть двоичный файл в текстовом редакторе, найти интерпретатор ( /lib/ld-linux-x86-64.so.2
) и заменить его на путь той же длины. в исправленный интерпретатор