Tengo un binario de Linux, sin fuentes, que funciona en una máquina, y me gustaría crear un paquete independiente que se ejecute en una máquina diferente de la misma arquitectura. ¿Cuál es una forma de lograr esto?¿Cómo hacer que Unix sea binario autónomo?
En mi caso, las dos máquinas tienen la misma arquitectura, mismo kernel de Ubuntu, pero la máquina de destino no tiene make
y tiene una versión incorrecta de los archivos bajo /lib
y /usr
Una idea que tenía era de usar y chroot
recree un subconjunto del sistema de archivos que utiliza el binario, posiblemente usando strace
para descubrir lo que necesita. ¿Hay alguna herramienta que ya lo haga?
Para la posteridad, así es como puedo averiguar qué archivos de un proceso abre
#!/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
actualización El problema con LD_LIBRARY_PATH
soluciones es que /lib
está codificada en intérprete y tiene prioridad sobre LD_LIBRARY_PATH
, por lo que las versiones nativas ser cargado primero El intérprete está codificado en el binario. Un enfoque podría ser parchar el intérprete y ejecutar el código binario como patched_interpreter mycommandline
El problema es que cuando mycommandline
se inicia con java
, esto no funciona porque Java configura LD_LIBRARY_PATH
y se reinicia a sí mismo, que recurre al antiguo intérprete. Una solución que funcionó para mí fue abrir el binario en el editor de texto, encontrar el intérprete (/lib/ld-linux-x86-64.so.2
) y reemplazarlo con la misma longitud del intérprete parcheado
Parece que quieres un binario estático. Construye en todas las bibliotecas que usa. –
Lo que dijo @VLC, tienes que marcarlo para enlaces estáticos, lo que puede ser un poco molesto. –
¿Construiste el binario en cuestión? Si lo hizo, es muy posible que pueda reconstruirlo estáticamente. – Cascabel