如何使Unix二进制自包含? [英] How to make Unix binary self-contained?

查看:72
本文介绍了如何使Unix二进制自包含?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Linux二进制文件,没有源代码,可以在一台机器上运行,并且我想制作一个独立的程序包,该程序包可以在同一体系结构的另一台机器上运行.实现这一目标的方法是什么?

I have a Linux binary, without sources, that works on one machine, and I'd like to make a self-contained package that would run on a different machine of the same architecture. What is a way of achieving this?

在我的情况下,两台计算机具有相同的体系结构,相同的Ubuntu内核,但目标计算机没有make,并且/lib/usr

In my case, both machines have the same architecture, same Ubuntu kernel, but target machine doesn't have make and has wrong version of files under /lib and /usr

我的一个想法是使用chroot并重新创建二进制文件使用的文件系统的一个子集,可能使用strace来确定它的需求.有没有已经执行此操作的工具?

One idea I had was to use chroot and recreate a subset of the filesystem that the binary uses, possibly using strace to figure out what it needs. Is there a tool that does this already?

为后代,这是我找出进程打开哪些文件的方式

For posterity, here's how I figure out which files a process opens

#!/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身份运行二进制文件.问题是,当mycommandlinejava开头时,此操作不起作用,因为Java设置了LD_LIBRARY_PATH并自行重新启动,这导致老口译员.对我有用的解决方案是在文本编辑器中打开二进制文件,找到解释器(/lib/ld-linux-x86-64.so.2),并将其替换为修补程序解释器的等长路径

Update The problem with LD_LIBRARY_PATH solutions is that /lib is hardcoded into interpreter and takes precedence over LD_LIBRARY_PATH, so native versions will get loaded first. The interpreter is hardcoded into the binary. One approach might be to patch the interpreter and run the binary as patched_interpreter mycommandline Problem is that when mycommandline is starts with java, this doesn't work because Java sets-up LD_LIBRARY_PATH and restarts itself, which resorts to the old interpreter. A solution that worked for me was to open the binary in the text editor, find the interpreter (/lib/ld-linux-x86-64.so.2), and replace it with same-length path to the patched interpreter

推荐答案

有点 CDE 专为完全满足您的需求而设计的软件.这是谷歌技术谈 http://www.youtube.com/watch?v=6XdwHo1BWwY

There's CDE a bit of software designed to do exactly what you want. Here's a google tech talk about it http://www.youtube.com/watch?v=6XdwHo1BWwY

这篇关于如何使Unix二进制自包含?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆