免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 6400 | 回复: 13
打印 上一主题 下一主题

shell脚本中如何嵌入二进制数据 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-08-06 10:09 |只看该作者 |倒序浏览
5可用积分
有谁知道shell脚本中如何嵌入二进制数据?以前有人在论坛里问过,但没有人给出确切的答案,在网上搜索也没有结果,有没有高人指点迷津?

下面的脚本已经去掉了后面紧跟着的二进制数据。

#! /bin/sh
skip=222
# This script was generated using Makeself 1.5.5
CRCsum=3603969685
MD5=00000000000000000000000000000000
label="CrossOver Linux Professional"
script=./setup.sh
targetdir=cxoffice
scriptargs=""
keep=n
TMPROOT=${TMPDIR:=/tmp}
finish=true
xterm_loop=""
# Shells really don't like CR/LFs. So use some CR/LF-resistant
# code to perform a quick sanity check.
crlf_sentry=
if [ -n "$crlf_sentry" ]; then #
  echo "Line ends have been converted to CR/LF." #
  echo  #
  echo "You need to download the installer again, as this one" #
  echo "has been corrupted." #
  echo  #
  echo "If your download appeared to be successful, try a different" #
  echo "browser. Some browsers, such as Netscape, are known to corrupt" #
  echo "some types of binary files by trying treating them as text." #
  echo  #
  exit 2 #
fi #
LOKISCRIPTPATH=`which $0 2>/dev/null`
if [ ! -f "$LOKISCRIPTPATH" ]; then
  LOKISCRIPTPATH=$0
fi
echo $LOKISCRIPTPATH | egrep "^/" >/dev/null
rc=$?
if [ $rc -ne 0 -a -f "$LOKISCRIPTPATH" -a -f "`pwd`/$LOKISCRIPTPATH" ]; then
  LOKISCRIPTPATH="`pwd`/$LOKISCRIPTPATH"
fi
export LOKISCRIPTPATH
if tail -n 1 /dev/null >/dev/null 2>&1
then
  TAIL_CMD="tail -n"
else
  TAIL_CMD="tail"
fi
[ x"$1" = x-xwin ] && {
finish="echo Press Return to close this window...; read junk"; xterm_loop=1; shift 1;
}
if [ x"$1" = "x-help" -o x"$1" = "x--help" ]; then
  cat << tac
1) Getting help or info about $0 :
  $0 --help   Print this message
  $0 --info   Print embedded info : title, default target directory, embedded script ...
  $0 --lsm    Print embedded lsm entry (or no LSM)
  $0 --list   Print the list of files in the archive
  $0 --check  Checks integrity of the archive

2) Running $0 :
  $0 [options] [additional arguments to embedded script]
  with following options (in that order)
  --confirm             Ask before running embedded script
  --keep                Do not erase target directory after running embedded script
  --target NewDirectory Extract in NewDirectory
tac
  exit 0;
fi
if [ x"$1" = "x-lsm" -o x"$1" = "x--lsm" ]; then
  cat << EOF_LSM
no LSM
EOF_LSM
  exit 0;
fi
if [ "$1" = "--info" ]; then
        echo Identification: $label
        echo Target directory: $targetdir
        echo Uncompressed size: 63244 KB
        echo Compression: gzip
        echo Date of packaging: Fri Jan  5 12:24:05 CST 2007
        echo script run after extraction: $script $scriptargs
        [ x"$keep" = xy ] && echo "directory $targetdir is permanent" || echo "$targetdir will be removed after extraction"
        exit 0;
fi
if [ "$1" = "--list" ]; then
        echo Target directory: $targetdir
        $TAIL_CMD +$skip "$0" | gzip -cd | tar tvf -
        exit 0;
fi
if [ "$1" = "--check" ]; then
sum1=`$TAIL_CMD +6 "$0" | cksum | sed -e 's/ /Z/' -e 's/        /Z/' | cut -dZ -f1`
[ "$sum1" != "$CRCsum" ] && {
  echo "Error in checksums $sum1 != $CRCsum"
  exit 2;
}
if [ $MD5 != "00000000000000000000000000000000" ]; then
# space separated list of directories
  [ x"$GUESS_MD5_PATH" = "x" ] && GUESS_MD5_PATH="/usr/local/ssl/bin"
  MD5_PATH=""
  for a in $GUESS_MD5_PATH; do
    if which $a/md5 >/dev/null 2>&1 ; then
       MD5_PATH=$a;
    fi
  done
  if [ -x $MD5_PATH/md5 ]; then
    md5sum=`$TAIL_CMD +6 "$0" | $MD5_PATH/md5`;
    [ $md5sum != $MD5 ] && {
      echo Error in md5 sums $md5sum $MD5
      exit 2
    } || { echo check sums and md5 sums are ok; exit 0; }
  fi
  if [ ! -x $MD5_PATH/md5 ]; then
      echo an embedded md5 sum of the archive exists but no md5 program was found in $GUESS_MD5_PATH
      echo if you have md5 on your system, you should try :
      echo env GUESS_MD5_PATH=\"FirstDirectory SecondDirectory ...\" $0 -check
  fi
else
  echo check sums are OK ; echo $0 does not contain embedded md5 sum ;
fi
        exit 0;
fi
[ x"$finish" = x ] && finish=true
parsing=yes
x11=y
while [ x"$parsing" != x ]; do
    case "$1" in
      -confirm|--confirm) verbose=y; shift;;
      -keep|--keep) keep=y; shift;;
      -nox11|--nox11) x11=n; shift;;
      -target|--target) if [ x"$2" != x ]; then targetdir="$2"; keep=y; shift 2; fi;;
      *) parsing="";;
    esac
done
mask=`umask`
umask 077
if [ x"$keep" = xy ]; then echo "Creating directory $targetdir"; tmpdir=$targetdir;
else tmpdir="$TMPROOT/selfgz$$"; fi
mkdir $tmpdir || {
        echo 'Cannot create target directory' $tmpdir >&2
        echo 'you should perhaps try option -target OtherDirectory' >&2
        eval $finish; exit 1;
}

# Create a wrapper script which can be exec'd so we don't lock the CD
wrapperbase=`basename "$LOKISCRIPTPATH"`-wrapper
wrapperpath="$tmpdir/$wrapperbase"
echo '#!/bin/sh' >"$wrapperpath"
[ x"$keep" = xy ] || echo "trap 'echo Signal caught, cleaning up > /dev/tty; cd \"$TMPROOT\"; /bin/rm -rf \"$tmpdir\"; exit 15' 1 2 15" >>"$wrapperpath"
echo "$script $scriptargs $*" >>"$wrapperpath"
echo "cd $TMPROOT" >>"$wrapperpath"
if [ x"$keep" = xy ] ; then
    echo "exec rm -f \"$wrapperpath\"" >>"$wrapperpath"
else
    echo "exec rm -rf \"$tmpdir\"" >>"$wrapperpath"
fi
chmod +rx "$wrapperpath"
umask $mask
location="`pwd`"
if [ -x /usr/bin/printf ]
then
  echo_n=/usr/bin/printf
elif [ -x /usr/ucb/echo ]
then
  echo_n="/usr/ucb/echo -n"
else
  echo_n="echo -n"
fi
if [ x$SETUP_NOCHECK != x1 ]; then
    $echo_n "Verifying archive integrity..."
    sum1=`$TAIL_CMD +6 "$0" | cksum | sed -e 's/ /Z/' -e 's/        /Z/' | cut -dZ -f1`
    [ "$sum1" != "$CRCsum" ] && {
        echo "Error in check sums $sum1 != $CRCsum"
        echo
        echo "You need to download the installer again, as it is corrupt."
        echo
        echo "If your download appeared to be successful, try a different"
        echo "browser. Some browsers, such as Netscape, are known to corrupt"
        echo "some types of binary files by trying treating them as text."
        echo
        eval $finish; exit 2;
    }
    echo OK
fi
if [ $MD5 != "00000000000000000000000000000000" ]; then
# space separated list of directories
  [ x$GUESS_MD5_PATH = x ] && GUESS_MD5_PATH="/usr/local/ssl/bin"
  MD5_PATH=""
  for a in $GUESS_MD5_PATH; do
    if which $a/md5 >/dev/null 2>&1 ; then
       MD5_PATH=$a;
    fi
  done
  if [ -x $MD5_PATH/md5 ]; then
    md5sum=`$TAIL_CMD +6 "$0" | $MD5_PATH/md5`;
    [ $md5sum != $MD5 ] && {
      echo "Error in md5 sums $md5sum $MD5"
      eval $finish; exit 2;
    }
  fi
fi
UnTAR() { tar xvf - || { echo Extraction failed. > /dev/tty; kill -15 $$; } ; }
echo "Uncompressing $label"
cd $tmpdir ; res=3
[ "$keep" = y ] || trap 'echo Signal caught, cleaning up > /dev/tty; cd $TMPROOT; /bin/rm -rf $tmpdir; eval $finish; exit 15' 1 2 15
if (cd "$location"; $TAIL_CMD +$skip "$0"; ) | gzip -cd | UnTAR |  (while read a; do $echo_n .; done; echo; ); then
        uid=`id | sed -e 's/^uid=\([0-9]*\)(.*/\1/'`
        gid=`id | sed -e 's/^.* gid=\([0-9]*\)(.*/\1/'`
        chown -Rf $uidgid .
    res=0; if [ x"$script" != x ]; then
                if [ x"$verbose" = xy ]; then
                        echo "OK to execute: $script $scriptargs $* ? [Y/n] "
                        read yn
                        [ x"$yn" = x -o x"$yn" = xy -o x"$yn" = xY ] && { exec "./$wrapperbase"; res=$?; }
                else
                        exec "./$wrapperbase" ; res=$?
                fi
                #[ $res != 0 ] && echo "The program returned an error code ($res)"
        fi
    [ "$keep" = y ] || { cd $TMPROOT; /bin/rm -rf $tmpdir; }
else
  echo "Cannot decompress $0"; eval $finish; exit 1
fi
eval $finish; exit $res
END_OF_STUB

最佳答案

查看完整内容

分割线是就是准备让你分割数据时用的,如果你不用这条线怎么分割?

论坛徽章:
8
摩羯座
日期:2014-11-26 18:59:452015亚冠之浦和红钻
日期:2015-06-23 19:10:532015亚冠之西悉尼流浪者
日期:2015-08-21 08:40:5815-16赛季CBA联赛之山东
日期:2016-01-31 18:25:0515-16赛季CBA联赛之四川
日期:2016-02-16 16:08:30程序设计版块每日发帖之星
日期:2016-06-29 06:20:002017金鸡报晓
日期:2017-01-10 15:19:5615-16赛季CBA联赛之佛山
日期:2017-02-27 20:41:19
2 [报告]
发表于 2008-08-06 10:09 |只看该作者
原帖由 hinux 于 2008-8-6 15:29 发表
sed '1,/^__ARCHIVE_FOLLOWS__/d' $0 >$$.tar.gz
在这条语句里也用到了__ARCHIVE_FOLLOWS__,是不是也起到变量的作用?

分割线是就是准备让你分割数据时用的,如果你不用这条线怎么分割?

论坛徽章:
8
摩羯座
日期:2014-11-26 18:59:452015亚冠之浦和红钻
日期:2015-06-23 19:10:532015亚冠之西悉尼流浪者
日期:2015-08-21 08:40:5815-16赛季CBA联赛之山东
日期:2016-01-31 18:25:0515-16赛季CBA联赛之四川
日期:2016-02-16 16:08:30程序设计版块每日发帖之星
日期:2016-06-29 06:20:002017金鸡报晓
日期:2017-01-10 15:19:5615-16赛季CBA联赛之佛山
日期:2017-02-27 20:41:19
3 [报告]
发表于 2008-08-06 10:24 |只看该作者

论坛徽章:
0
4 [报告]
发表于 2008-08-06 14:46 |只看该作者
看不大懂简单模拟:
cat >test.sh <<\EOF
#! /bin/bash
sed '1,/^__ARCHIVE_FOLLOWS__/d' $0 >$$.tar.gz
tar tzvf $$.tar.gz
rm -f $$.tar.gz
exit
__ARCHIVE_FOLLOWS__
EOF
chmod +x test.sh
echo this is a test >test
tar -czf - test >>test.sh
./test.sh


有没有关于这方面的更详细的说明?

论坛徽章:
8
摩羯座
日期:2014-11-26 18:59:452015亚冠之浦和红钻
日期:2015-06-23 19:10:532015亚冠之西悉尼流浪者
日期:2015-08-21 08:40:5815-16赛季CBA联赛之山东
日期:2016-01-31 18:25:0515-16赛季CBA联赛之四川
日期:2016-02-16 16:08:30程序设计版块每日发帖之星
日期:2016-06-29 06:20:002017金鸡报晓
日期:2017-01-10 15:19:5615-16赛季CBA联赛之佛山
日期:2017-02-27 20:41:19
5 [报告]
发表于 2008-08-06 15:09 |只看该作者

回复 #3 hinux 的帖子

只要第一行的 #!写好
后面几进制都无所谓,这个不需要更详细说明吧?

论坛徽章:
0
6 [报告]
发表于 2008-08-06 15:16 |只看该作者
-_"
#!是shell脚本称为“幻行”的开头我当知道啦,我想知道的是怎么把包或二进制的可执行文件植入shell脚本中,然后是怎样执行的。

论坛徽章:
0
7 [报告]
发表于 2008-08-06 15:18 |只看该作者
./test.sh
+ sed '1,/^__ARCHIVE_FOLLOWS__/d' ./test.sh
+ tar tzvf 31780.tar.gz
-rwx--x--x root/root        15 2008-08-06 14:40:33 test
+ rm -f 31780.tar.gz
+ exit

还是没看出__ARCHIVE_FOLLOWS__的作用来。

论坛徽章:
8
摩羯座
日期:2014-11-26 18:59:452015亚冠之浦和红钻
日期:2015-06-23 19:10:532015亚冠之西悉尼流浪者
日期:2015-08-21 08:40:5815-16赛季CBA联赛之山东
日期:2016-01-31 18:25:0515-16赛季CBA联赛之四川
日期:2016-02-16 16:08:30程序设计版块每日发帖之星
日期:2016-06-29 06:20:002017金鸡报晓
日期:2017-01-10 15:19:5615-16赛季CBA联赛之佛山
日期:2017-02-27 20:41:19
8 [报告]
发表于 2008-08-06 15:26 |只看该作者
原帖由 hinux 于 2008-8-6 15:18 发表
./test.sh
+ sed '1,/^__ARCHIVE_FOLLOWS__/d' ./test.sh
+ tar tzvf 31780.tar.gz
-rwx--x--x root/root        15 2008-08-06 14:40:33 test
+ rm -f 31780.tar.gz
+ exit

还是没看出__ARCHIVE_FOLL ...



那只是分割“包或二进制的可执行文件”与脚本的线,随便你写成什么都行啊

论坛徽章:
0
9 [报告]
发表于 2008-08-06 15:29 |只看该作者
sed '1,/^__ARCHIVE_FOLLOWS__/d' $0 >$$.tar.gz
在这条语句里也用到了__ARCHIVE_FOLLOWS__,是不是也起到变量的作用?

论坛徽章:
0
10 [报告]
发表于 2008-08-06 16:56 |只看该作者
waker忽略了一点,sed会自动给数据最后加上\n,这样数据就有问题了,用tail没有问题。
错了,是我用vi编辑的时候添加的。
还是注释一下吧:
walkerxk@www:~/test$ cat a.sh
#!/bin/bash
tail -n +3 $0 > hash;exit         #把从第三行开始的数据保存到hash文件,并且退出。这里要求文件前面的脚本是2行,如果行数不对,自己改-n后面的+3
walkerxk@www:~/test$ cat a.sh bash >b.sh     #合并脚本和二进制文件
walkerxk@www:~/test$ bash b.sh                 #运行脚本
walkerxk@www:~/test$ md5sum *ash           #校验文件,发现文件一样
807b337f4c3804cf9a196359dcc61e2b  bash
807b337f4c3804cf9a196359dcc61e2b  hash
walkerxk@www:~/test$
当然,那行脚本你可以写很多东西,比如:
tail -n +3 $0 > a.tar.gz;tar -zxf a.tar.gz -C /tmp/a/;cd /tmp/a/;bash install.sh;exit
或者拆成多行的话是这样:
tail -n +7 $0 > a.tar.gz
tar -zxf a.tar.gz -C /tmp/a/
cd /tmp/a/
bash install.sh
exit

[ 本帖最后由 walkerxk 于 2008-8-6 17:39 编辑 ]
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP