Paste executable binary into shell script

Firstly, I already googled, but only found examples where a compressed file (e.g. .tar.gz ) is embedded in the shell script.

Basically, if I have a C program ( hello.c ) that prints a line, say Hello World! .

I will compile it to get binary executable

 gcc hello.c -o hello 

Now I have a shell script testEmbed.sh

I ask if it is possible to embed a binary file ( hello ) inside a shell script so that when run

 ./testEmbed.sh 

it runs the binary to print Hello World! .

Explanation : One option is that I compress the executable into an archive and then extract it when the script runs. I ask if it is possible to run a program without this.

So far I have been trying to use the method here . But this does not work for me. I assume that the author used a different distribution on a different architecture. So basically this did not work for me .: P

Also, if the workflow for program C is different from the Java jar , I would also like to know that!

+8
java c shell binary
source share
3 answers

Yes, it can be done. This is actually very similar to the concept of your related article. The trick is to use uuencode to encode the binary into text format, and then bind it to the end of your script.

Then your script is written in such a way that it runs uudecode on its own to create the binary, modifying it and then executing it.

uuencode and uudecode were originally created to offset binary content around the precursor to the Internet, which did not handle binary information well. Converting to text means that it can be sent as a shell script. If for some reason your distribution complains when you try to run uuencode , this probably means you should install it. For example, on Debian Squeeze:

 sudo aptitude install sharutils 

will receive the appropriate executable files for you. This is the process I went through. First create and compile your C hello.c program:

 pax> cat hello.c #include <stdio.h> int main (void) { printf ("Hello\n"); return 0; } pax> gcc -o hello hello.c 

Then create a shell script testEmbed.sh that will decode itself:

 pax> cat testEmbed.sh #!/bin/bash rm -f hello uudecode $0 ./hello rm -f hello exit 

The first rm statement demonstrates that the hello executable is recreated by this script, rather than being left to your compilation. Since you need the payload in the file, attach the encoded executable to the end:

 pax> uuencode hello hello >>testEmbed.sh 

Then, when you execute testEmbed.sh script, it extracts the executable and runs it.

The reason for this is because uudecode looking for specific marker lines at its input ( begin and end ) that are placed there by uuencode , so it only tries to decode the encoded program, not the whole script:

 pax> cat testEmbed.sh #!/bin/bash rm -f hello uudecode $0 ./hello rm -f hello exit begin 755 hello M?T5,1@$!`0````````````(``P`!````$(,$"#0```#`!@```````#0`(``' M`"@`'@`;``8````T````-(`$"#2`!`C@````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;FLN8G@`;6%I;@!?:6YI=``` ` end 

Other things you should probably worry about, for example, the possibility that your program might require shared libraries that do not exist on the target system, but you mostly need the process described above.


The process for a JAR file is very similar, except that the way it is run is different. This is another file, but you need to replace the line:

 ./hello 

with something capable of running JAR files, for example:

 java -jar hello.jar 
+14
source share

I think makeself is what you describe.

+2
source share

A portable way to do this is with the printf command and octal screens:

 printf '\001\002\003' 

to print bytes 1, 2, and 3. Since you probably don't want to write everything manually, the od -b command can be used to create an octal dump of the file, then you can use a sed script to take the garbage out and put the backslash in place.

+2
source share

All Articles