簡體   English   中英

Bash 包含二進制可執行文件的腳本

[英]Bash script containing binary executable

是否可以編寫一個 bash 腳本,其中包含一個二進制可執行程序?

我的意思是一個腳本,它包含一個文本形式的可執行文件的轉儲,當它被執行時,它會被這個腳本轉儲回一個可執行文件?

我很想知道一個解決方案,無需安裝額外的軟件包即可開箱即用。 是否可以?

謝謝!

我以前從未做過這樣的事情;)這將編譯一些c源代碼,創建一個包含二進制文件的b.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

調用(a.bash生成b.bash):

bash a.bash ;bash b.bash

我不知道如何逃避在執行前將二進制文件寫入臨時文件...

我嘗試了這個,它的工作原理。 十六進制是用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  ..>.......@.....
0000020: 4000 0000 0000 0000 000a 0000 0000 0000  @...............
0000030: 0000 0000 4000 3800 0800 4000 1e00 1b00  ....@.8...@.....
0000040: 0600 0000 0500 0000 4000 0000 0000 0000  ........@.......
0000050: 4000 4000 0000 0000 4000 4000 0000 0000  @.@.....@.@.....
...
0001960: 6400 5f65 6461 7461 006d 6169 6e00 5f69  d._edata.main._i
0001970: 6e69 7400                                nit.
EndHere
chmod +x foo
./foo

不要像其他幾個答案所暗示的那樣重新發明輪子,只需使用古老的shar命令,它正是通過設計精確地做到這一點。

假設要嵌入腳本的文件是binaryfile ,只需運行即可

$ shar binaryfile > binaryfile.shar

你被設定了。 你有一個名為binaryfile.shar的shell腳本,它在執行時會提取binaryfile

您可以將二進制文件轉換為文本,然后使用uuencode / uudecode返回二進制文件。

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

因此,您可以將二進制數據作為文本存儲在腳本中,並將其輸出到二進制文件中。

uuencode binaryFile> output.txt

然后將這些數據放入您的腳本中,並在創建二進制文件時使用uudecode。

那么,如果我做得對,你想在你的腳本中包含一個二進制文件並在腳本退出時執行它?

這是一個binarymaker腳本(這不僅創建一個提取二進制文件的腳本,而且將任何腳本與任何二進制文件合並):

#!/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

你應該像這樣運行它

./binarymaker myscript mybinary resultscript

如果你運行resultscript那么myscriptmybinary都將被執行。 您可以選擇在之后向rm二進制文件添加命令。

另外,不要忘記在腳本結束時退出 ,否則它將繼續並嘗試解析二進制數據。

如果你正在使用另一個腳本而不是二進制文件,那么它可以從管道執行,如下所示:

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

但它不適用於真正的二進制文件。 此外,如果您的bash版本低於4,則它不起作用

這是一種使用hexdump的單行方法,它生成一個 ascii shell 腳本,該腳本將 output 在只有 busybox 的系統上生成一個二進制文件,沒有其他任何東西。

hexdump -ve '"printf q" 16/1 "S%o" "q\n"' < INPUT_BINARY_PATH | tr Sq "\\\'" > OUTPUT.sh
sh OUTPUT.sh > OUTPUT_BINARY_PATH

字符Sq用於簡潔地解決 hexdump 格式字符串中的符號限制。 S被翻譯成反斜杠,以表示轉義的八進制字節。 q被翻譯成每行周圍的單引號,因此printf解釋這些轉義而不是 shell。

printf的使用可以替換為echo -ne 八進制轉義字節的使用可以替換為十六進制字節。 hexdump 的使用可能會被其他類似的實用程序所取代。 通過增加數字16可以將更多數據放在單個腳本行上。

我不得不制作一個安裝程序腳本,將它部署在一台甚至沒有tar的機器上,然后我結束了embbox busy(用於tar和gunzip)以及tarball部署在shell腳本上。 用dd方式做到

#!/usr/bin/env bash

get_length()
{
    ls -l "$1" | cut -f5 -d' '
}

# First parameter is the number of semicolons to add to second parameter
# NOTE: we do not use an "add_blanks" function directly because it seems bash
# removes duplicated blanks. The workaround is adding other character and
# replacing later using e.g. sed.
add_semicolons()
{
    scratch="$2"
    for n in $(seq 1 $1)
    do
        scratch+=";"
    done
    echo $scratch
}

# Default values
output="installer"
input="deployable.tar.gz"
shell="busybox"

shell_len=$(get_length "$shell")
payload_len=$(get_length "$input")

# START OF INSTALLATION SCRIPT GENERATION.
#
# Note: generated scripts reserves 9 digits for the skip (ibs) offsets.
# When the script is first written, these digits are written as semicolons.
# Later when the lengths are computed, these semicolons are replaced by the
# correct numbers, but the 9-digit length must be preserved by adding blanks
# until 9 digits are filled. Failure to do this will cause the script length
# to vary and offsets would need to be iteratively computed.

# Add shebang
echo "#!/usr/bin/env ash" > "$output"

echo "echo Extracting installer..." >> "$output"
# Add lines to extract binary data and extract payload
echo "mkdir -p /tmp/installer" >> "$output"
echo "dd if=\"$(basename $output)\" ibs=;;;;;;;;; skip=1 | dd ibs=$shell_len count=1 of=/tmp/installer/shell 2>/dev/null" >> "$output"
echo "chmod +x /tmp/installer/shell" >> "$output";
echo "dd if=\"$(basename $output)\" ibs=;;;;;;;;; skip=1 2>/dev/null of=/tmp/installer/payload.tar.gz 2>/dev/null" >> "$output"
# From here on, the binary extraction is completed, do something with extracted files...
# [...]
# Use exit command to avoid the shell script parsing to reach the binary part
echo "echo Done!" >> "$output"
echo "exit 0" >> "$output"

# We reserved 9 blanks for the ibs offsets. Thus fill offsets with blanks up to 9 chars total
script_len=$(get_length "$output")
skip_len=$((script_len + shell_len))

to_add=$((9 - ${#script_len}))
script_len_str=$(add_semicolons $to_add $script_len)
to_add=$((9 - ${#skip_len}))
skip_len_str=$(add_semicolons $to_add $skip_len)

# Add skip values
sed -i "4s/ibs=;;;;;;;;;/ibs=$script_len_str/" "$output"
sed -i "4s/;/ /g" "$output"
sed -i "6s/ibs=;;;;;;;;;/ibs=$skip_len_str/" "$output"
sed -i "6s/;/ /g" "$output"

cat "$shell" >> "$output"
cat "$input" >> "$output"
chmod +x "$output"

當然是啦!

例如,您可以將任何二進制文件轉儲到文件中:

echo $binary > file

有很多安裝腳本可以做這樣的事情。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM