2012-05-08 116 views
8

首先,我已经使用了google代码,但只找到了一个压缩文件(例如.tar.gz)嵌入shell脚本的例子。将一个可执行二进制文件嵌入到一个shell脚本中

基本上如果我有一个打印字符串的C程序(hello.c),说Hello World!

我编译得到可执行的二进制

gcc hello.c -o hello 

现在我有一个shell脚本testEmbed.sh

我所问的是,如果它是可以嵌入二进制(你好)里面的shell脚本,以便我运行时

./testEmbed.sh 

它执行二进制打印Hello World!

澄清: 一种替代方法是,我将可执行文件压缩到档案中,然后在脚本运行时将其解压缩。我问的是如果没有这个可以运行程序。

直到现在,我正在尝试方法here。但它不适合我。我想作者正在另一个架构上使用其他发行版。所以,基本上这不适合我。 :P

此外,如果C程序的工作流程与Java jar不同,我也想知道这一点!

回答

14

是的,这可以做到。它在概念上与您的链接文章非常相似。诀窍是使用uuencode将二进制文件编码为文本格式,然后将其粘贴到脚本的末尾。

然后,您的脚本以这样的方式编写,即它自己运行uudecode以创建二进制文件,然后更改权限并执行它。

uuencodeuudecode最初是为了将二进制内容转移到互联网的前体而创建的,它并没有很好地处理二进制信息。转换为文本意味着它可以作为shell脚本发送。如果由于某种原因,当您尝试运行uuencode时,您的分发抱怨,则可能意味着您必须安装它。例如,在Debian Squeeze上:

sudo aptitude install sharutils 

将为您获取相关的可执行文件。这是我经历的过程。首先创建和编译的C程序hello.c

pax> cat hello.c 

#include <stdio.h> 
int main (void) { 
    printf ("Hello\n"); 
    return 0; 
} 

pax> gcc -o hello hello.c 

然后创建一个shell脚本testEmbed.sh,这将自身解码:

pax> cat testEmbed.sh 

#!/bin/bash 
rm -f hello 
uudecode $0 
./hello 
rm -f hello 
exit 

第一rm声明显示,正在被这个重新创建的hello可执行脚本,而不是留在你的汇编中。由于您所需要的有效载荷文件中为好,装上编码的可执行到它的结束:

pax> uuencode hello hello >>testEmbed.sh 

之后,当你执行脚本testEmbed.sh,它提取的可执行文件,并运行它。

这部作品的原因是因为uudecode会在其输入(beginend)某些标记线,由uuencode放在那里,所以它只是试图编码的程序进行解码,而不是整个脚本:

pax> cat testEmbed.sh 

#!/bin/bash 
rm -f hello 
uudecode $0 
./hello 
rm -f hello 
exit 

begin 755 hello 
M?T5,[email protected]$!`0````````````(``P`!````$(,$"#0```#`[email protected]```````#0`(``' 
M`"@`'@`;``8````T````-(`$"#2`!`[email protected]````X`````4````$`````P```!0! 
: : : 
M:&%N9&QE`%]?1%1/4E]%3D1?7P!?7VQI8F-?8W-U7VEN:70`7U]B<W-?<W1A 
M<G0`7V5N9`!P=71S0$!'3$E"0U\R+C``7V5D871A`%]?:38X-BYG971?<&-? 
4=&AU;[email protected]`;6%I;@!?:6YI=``` 
` 
end 

还有其他一些你应该担心的事情,例如你的程序可能需要目标系统上不存在的共享库,但上面的过程基本上是你需要的。


JAR文件的过程非常相似,只是运行方式不同。它仍然是一个单一的文件,但你需要更换行:

./hello 

与能够运行的JAR文件,如东西:

java -jar hello.jar 
+2

向shell脚本添加一个'trap'rm -f hello'SIGINT'也是一个好主意,这样在用户Ctrl-C的程序中就可以清理临时文件。 –

+0

是的,我不怀疑您可以对该代码进行大量的改进,并且这是一个很好的改进。我不想把它复杂得太多,因为我只是试图理解这个概念。 – paxdiablo

+0

一个非常好的解释。谢谢 – Ankit

2

便携的方式做,这是与printf命令和八进制转义:

printf '\001\002\003' 

打印字节1,2和3。因为你很可能不希望所有的手工编写, od -b命令可用于生成文件的八进制转储,然后您可以使用sed脚本剥离垃圾并将正确的反斜杠就位。

+0

用八进制创建字符串的命令是'od - b BINARYFILE | sed -n's%[0-9] \ {4,\} \ \([0-9] \ {3 \}。* \)%\ 1%p'| perl -pe' ^%\\%; s%\%\\%g; s%\ n %%')'。这个创建的八进制字符串是'printf'必须有的参数。 – erik

相关问题