У меня есть двоичный файл 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
) и заменить его на путь длины до исправленного интерпретатора