2013-08-23 71 views
5

Có thể viết một tập lệnh bash, có chứa một chương trình thực thi nhị phân bên trong không?Tập lệnh Bash có chứa tệp nhị phân có thể thực thi

Tôi có nghĩa là một tập lệnh, có chứa một kết xuất của một tập tin thực thi trong một hình thức văn bản, mà sẽ được bán trở lại một tập tin thực thi bởi kịch bản này khi nó được thực hiện?

Tôi rất muốn biết một giải pháp, sẽ hoạt động ra khỏi hộp mà không cần cài đặt các gói bổ sung. Có thể không?

Cảm ơn!

+0

Tôi biết điều đó là có thể, bởi vì tôi đã thấy nó được thực hiện trong tập lệnh cài đặt MKL của Intel. Tôi không chắc chắn * làm thế nào * nó đã được thực hiện, nhưng nó là có thể. – SethMMorton

+1

có thể trùng lặp của [Nhúng một tệp nhị phân thực thi trong một tập lệnh shell] (http://stackoverflow.com/questions/10491704/embed-a-executable-binary-in-a-shell-script) – mschilli

+0

java 6 jdk đã từng có một dạng phân phối của một tệp '.sh' đơn 80+ MB, trong đó tập lệnh" đã kết thúc "với dòng' thoát 0' và các phần nhị phân theo sau nó. kịch bản trích xuất các phần nhị phân từ chính nó với một dòng như 'đuôi $ {tail_args} +189" $ 0 "> $ outname'; đã làm một 'trap' với' rm', đã làm một 'sum' cho checksum, một' chmod' và thực hiện nó như './$ outname' – n611x007

Trả lời

4

tôi không bao giờ làm điều gì đó như thế này trước đây;) này sẽ biên dịch một số nguồn c, tạo ra một kịch bản b.bash chứa nhị phân (và kịch bản ban đầu cho sự phát triển đơn giản)

(a.bash)

#!/bin/bash 

if [ "$0" == "b.bash" ];then 
    tail -n +$[ `grep -n '^BINARY' $0|cut -d ':' -f 1` + 1 ] $0 | base64 -d > a2.out 
    chmod +x a2.out 
    ./a2.out 
    echo $? 
    exit 
fi 

cat "$0" > b.bash 
echo "BINARY" >> b.bash 
cat > a.c << EOF 
int  main(){ 
     return 12; 
} 
EOF 
gcc a.c 
base64 a.out >> b.bash 

gọi với (a.bash tạo b.bash):

bash a.bash ;bash b.bash 

tôi không biết làm thế nào để tránh viết ra nhị phân thành một tệp tạm thời trước khi thực thi ...

+1

Đây là một câu trả lời rất hay - 'base64' là giải pháp tốt nhất mà chúng ta có thể sử dụng, vì nó được cài đặt mặc định trên tất cả các nền tảng và nó nhỏ gọn hơn hex xxd'. –

-1

Chắc chắn rồi!

Bạn có thể ví dụ như đổ bất kỳ nhị phân vào một tập tin với:

echo $binary > file 

Có rất nhiều kịch bản cài đặt mà làm những việc như thế.

+1

' printf '% s' "$ binary"> file' là an toàn hơn, như 'echo' sẽ nối thêm một dòng mới. Làm thế nào để vô hiệu hóa điều đó, cũng như điều trị các ký tự thoát-dấu gạch chéo trong '$ nhị phân', có thể khác nhau giữa việc triển khai' echo'. – chepner

+1

Điều này sẽ thất bại nếu '$ nhị phân' chứa NUL (ASCII 0), HT (ASCII 9) hoặc LF (ASCII 10) hoặc chuỗi nhiều SP liên tiếp (ASCII 20) hoặc nếu nó chứa'? 'Hoặc' * 'và' nullglob' tùy chọn được thiết lập. Rất nhiều trong số này có thể được giải quyết bằng cách viết '" $ binary "' thay vì '$ binary', nhưng thậm chí sau đó nó sẽ thất bại nếu' $ binary' chứa NUL. Đó là một dealbreaker cho nhiều tập tin nhị phân (nhất?). – ruakh

+0

@chepner: Câu hỏi chỉ định Bash. – ruakh

1

Bạn có thể chuyển đổi nhị phân thành văn bản, sau đó quay lại nhị phân bằng mã uuencode/uudecode.

http://linux.die.net/man/1/uuencode

Vì vậy, bạn có thể lưu trữ dữ liệu nhị phân dưới dạng văn bản trong kịch bản của bạn và đầu ra nó vào một tập tin nhị phân.

uuencode binaryFile> output.txt

Và sau đó đưa dữ liệu đó vào kịch bản của bạn và khi tạo nhị phân sử dụng tập tin uudecode.

4

Tôi đã thử tính năng này và hoạt động. Hex được tạo với xxd.

#!/bin/bash 

xxd -r >foo <<'EndHere' 
0000000: 7f45 4c46 0201 0100 0000 0000 0000 0000 .ELF............ 
0000010: 0200 3e00 0100 0000 e003 4000 0000 0000 ..>[email protected] 
0000020: 4000 0000 0000 0000 000a 0000 0000 0000 @............... 
0000030: 0000 0000 4000 3800 0800 4000 1e00 1b00 [email protected][email protected] 
0000040: 0600 0000 0500 0000 4000 0000 0000 0000 [email protected] 
0000050: 4000 4000 0000 0000 4000 4000 0000 0000 @[email protected]@[email protected] 
... 
0001960: 6400 5f65 6461 7461 006d 6169 6e00 5f69 d._edata.main._i 
0001970: 6e69 7400        nit. 
EndHere 
chmod +x foo 
./foo 
+2

+1. 'base64' là phù hợp hơn' xxd' mặc dù. Đó là cách nhỏ gọn hơn. –

+0

Có, nhưng nếu bạn có một bãi chứa hex xxd là con đường để đi. – stark

0

Vì vậy, nếu tôi hiểu đúng, bạn muốn đưa mã nhị phân vào tập lệnh của mình và thực thi nó trên lối ra tập lệnh?

Dưới đây là một kịch bản binarymaker (Điều này không chỉ tạo ra một kịch bản mà trích ra một nhị phân, nhưng kết hợp bất kỳ kịch bản của bạn với bất kỳ nhị phân):

#!/bin/bash 

lineCount=$(wc -l "$1" | cut -f 1 -d ' ') # just get the line count 
((lineCount+=2)) # because we are going to append a line 

head -n 1 "$1" > "$3" # this is done to ensure that shebang is preserved 
echo "trap 'tail -n +$lineCount \$0 > binary; chmod +x binary; ./binary' EXIT" >> "$3" 
tail -n +2 "$1" >> "$3" 
cat "$2" >> "$3" 

exit 0 

Bạn nên chạy nó như thế này

./binarymaker myscript mybinary resultscript 

Nếu bạn chạy resultscript thì cả hai myscriptmybinary sẽ được thực hiện. Bạn có thể tùy ý thêm lệnh vào rm nhị phân sau đó.

Ngoài ra, đừng quên thoát ở cuối tập lệnh của bạn vì nếu không nó sẽ tiếp tục và cố gắng phân tích cú pháp dữ liệu nhị phân.

Nếu bạn đang làm việc với một kịch bản và không phải là một nhị phân, sau đó nó có thể được thực hiện từ ống như thế này:

tail -n +$lineCount \$0 | source /dev/stdin 

Nhưng nó không phải là đi làm việc trên mã nhị phân thực. Ngoài ra, nó không hoạt động nếu phiên bản bash của bạn dưới 4

1

Không phát minh lại bánh xe giống như một số câu trả lời khác được đề xuất, chỉ cần sử dụng lệnh đáng kính shar.

Giả sử các tập tin bạn muốn để nhúng vào kịch bản của bạn là binaryfile, chỉ cần chạy

$ shar binaryfile > binaryfile.shar 

và bạn thiết lập. Bạn có tập lệnh shell có tên là binaryfile.shar khi được thực thi sẽ trích xuất binaryfile.

+1

Nhưng bạn cần cài đặt gói 'sharutils', không phải là mặc định. 'base64' luôn luôn có sẵn, vì nó là một phần của các lõi của GNU. – erik

+0

@erik Bạn cho rằng OP đang sử dụng Gnu/Linux nhưng điều này không được nêu. 'base64' không phải là POSIX nhiều hơn' shar' do đó không được đảm bảo có sẵn trên nền tảng Unix. – jlliagre