V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Distributions
Ubuntu
Fedora
CentOS
中文资源站
网易开源镜像站
lirunext
V2EX  ›  Linux

shc 对 arm 设备不兼容,如何解决?

  •  
  •   lirunext · 115 天前 · 1549 次点击
    这是一个创建于 115 天前的主题,其中的信息可能已经有所发展或是发生改变。
    一句话描述:通过 shc 和交叉编译链把脚本编译为可执行文件,在 arm 设备不能正常运行

    楼主想要:解决这个问题,或者有其他的把 sh 脚本加密成二进制或其它方式可以在 arm 设备运行的方法



    楼主写了一个.sh 脚本文件在某 arm 设备运行正常,需要共享出去使用,但涉及设备的某些私有接口因此需要加密,使用 shc 加密为.c 格式文件,在 x86 电脑使用交叉编译链编译为 arm 平台的可执行文件,在 arm 设备运行提示:./xxxx: ▒▒▒AP▒h▒▒▒4F▒kK▒,▒


    为了验证是交叉编译链的问题,还是脚本的问题,或者又是 shc 这个工具对 ARM 平台的兼容问题,做了以下验证:

    1 ,写了一个最简易的 c 文件,只包含显示 hello world 。在 x86 电脑直接使用 gcc 编译,在 x86 设备可以正常运行;在 x86 电脑交叉编译后,在 arm 设备也可以正常运行;————说明交叉编译链没问题

    2 ,写了一个最简易的脚本 testsh.sh ,只包含显示 hello world ,使用 shc 加密为.c 文件和编译,在 x86 设备可以正常运行;使用交叉编译链编译.c 文件,在 arm 设备运行会报错:./testsh: Ʈ▒▒{▒▒-▒0M:1▒t(————说明脚本也没问题,是 shc 对 ARM 平台的兼容问题
    23 条回复    2024-01-17 20:52:04 +08:00
    424778940
        1
    424778940  
       115 天前
    注意 shc 的文档有这么一句话 "The compiled binary will still be dependent on the shell specified in the first line of the shell code (i.e shebang) (i.e. #!/bin/sh), thus shc does not create completely independent binaries."

    你最好看看是不是 arm 自带的 sh 的问题, 有很多精简系统用的是 busybox 然后可能还不是 bash 而是 ash 之类的
    424778940
        2
    424778940  
       115 天前
    再说这个问题如果不是很复杂的脚本直接拿 cpp 写了编译不行吗?
    leonshaw
        3
    leonshaw  
       115 天前 via Android
    arm 上原生编译不行吗?
    ysc3839
        4
    ysc3839  
       114 天前 via Android
    我在 Android Termux 上试了下并没问题,原因不明。
    另外提醒一下,这些“shell 脚本加密”基本上都是掩耳盗铃,因为最终都是要用外部 shell 解释运行的,除非自身包含 shell 代码。
    看了下 shc 的运行流程,首次启动后会计算一个密钥,存放到环境变量中,然后用 exec 重启自身(是 sh -c exec "<自身路径>" 来重启的,而不是直接 exec 自身路径,原因不明),再用环境变量中的密钥解密出脚本,然后把解密后的脚本内容通过命令行传递给 shell 执行。
    破解起来也非常简单,直接 cat /proc/<进程 ID>/cmdline 就能看到解密后的脚本。
    所以脚本不复杂的话建议用 C 重写,如果可以的话建议把脚本发出来,不复杂的话我可以帮忙用 C 重写。
    liberize
        5
    liberize  
       114 天前 via Android
    https://github.com/liberize/ssc
    试试我写的类似的用 pipe 方式的工具,比命令行参数方式更隐蔽一点。
    lsk569937453
        6
    lsk569937453  
       114 天前
    @424778940 +1
    c/cpp/rust 楼主你有很多种选择的
    suyuyu
        7
    suyuyu  
       114 天前
    想起了免流脚本
    kkhaike
        8
    kkhaike  
       114 天前
    我有个问题很好奇。。既然 shc 编译后还是要依赖 bash 。那么编译的意义是不是就是打包的效果?
    lirunext
        9
    lirunext  
    OP
       114 天前
    @424778940
    谢谢,感觉可能和你说的有关系,我在提问前试过把脚本开头分别写为#!/bin/bash 和#!/bin/bash ,shc 加密和交叉编译后,在设备运行都是报错乱码;

    我这 arm 设备里面是有自带 busybox 的,但不知道是否是默认用这个。我看到你说了 busybox 后,尝试过
    1 、把脚本开头写成#!/bin/busybox ,shc 带与不带-B 都会提示 shc Unknown shell (busybox): specify [-i][-x][-l]
    shc: Success


    2 、查到加 shc 加上-B 参数可以兼容 busybox ,把脚本开头分别写为#!/bin/sh 和#!/bin/bash ,shc 加密和交叉编译后,在设备运行都提示:
    /bin/sh: cannot execute binary file


    现在不清楚脚本首行到底应该写啥



    以下是一些信息,不知是否有用

    在终端运行:cat /etc/shells
    结果是:
    # /etc/shells: valid login shells
    /bin/sh
    /bin/bash


    在终端运行:echo $SHELL
    结果是:/bin/sh

    在终端运行:ls -l /bin/ | grep bash
    结果是:
    lrwxrwxrwx 1 root root 14 Jul 24 11:10 bash -> /bin/bash.bash
    -rwxr-xr-x 1 root root 912864 Jul 24 10:50 bash.bash
    lrwxrwxrwx 1 root root 14 Jul 24 11:10 sh -> /bin/bash.bash
    lirunext
        10
    lirunext  
    OP
       114 天前
    @424778940 发生这个问题问题后,我也动过拿 cpp 写了后编译的念头,奈何不会 C 语言,工作太忙学习成本有点高。。。尝试用 chatGPT ,上传脚本让它转为一样效果的 c 文件,这家伙绕来绕去只给一小段代码。。。所以就搁置了。
    lirunext
        11
    lirunext  
    OP
       114 天前
    @ysc3839 感谢,可能是我的 arm 设备有点特殊的问题。。这个破解的话关系不大,安全等级没那么高,主要是有规定不能是明文给用户,所以只能想“加层壳”。。。
    我也想过用 c 重写,奈何不懂 c ,再加上工作太忙,所以学习成本比较高。脚本还是有点复杂的,近 800 行了。。主要是涉及到一些公司的私有接口,不适合发出来呢。。。
    lirunext
        12
    lirunext  
    OP
       114 天前
    @kkhaike 是的,加层壳,不要像文本文件那样可以轻松阅读就可以
    lirunext
        13
    lirunext  
    OP
       114 天前
    @424778940 打错,应该是“我在提问前试过把脚本开头分别写为#!/bin/sh 和#!/bin/bash”
    duke000
        14
    duke000  
       113 天前
    遇到过同样的问题,当时的解决方案是:

    在每个板子上执行 shc 和 gcc

    然后把板子的 TF 卡插到同款其它板子上,运行这个程序也会出错,每个板子都要单独执行 shc 和 gcc
    lirunext
        15
    lirunext  
    OP
       113 天前
    @ysc3839 感觉有可能是一楼网友说的 busybox 的原因,我使用 shc 加上-B 参数后,再使用交叉编译链进行编译,在 arm 设备运行,就不会提示乱码了,而是提示/bin/sh: cannot execute binary file ,请问这样能判断是已经解密出脚本,是通过命令行传递给 shell 过程执行这个过程出的问题吗?
    hpc4you
        16
    hpc4you  
       110 天前
    @liberize
    不晓得是 bug 还是我弄错了.
    在 scriptA 中调用 scriptB, 遭遇以下提示信息:
    ```
    /bin/bash: --: invalid option
    Usage: /bin/bash [GNU long option] [option] ...
    /bin/bash [GNU long option] [option] script-file ...
    GNU long options:
    --debug
    --debugger
    --dump-po-strings
    --dump-strings
    --help
    --init-file
    --login
    --noediting
    --noprofile
    --norc
    --posix
    --pretty-print
    --rcfile
    --rpm-requires
    --restricted
    --verbose
    --version
    Shell options:
    -ilrsD or -c command or -O shopt_option (invocation only)
    -abefhkmnptuvxBCHP or -o option
    ```

    其中, scriptB 也是脚本, 先用 ssc 编译为二进制, 比如名字是 scriptB.x,
    在 scriptA 中, 采用/full/path/scriptB.x 调用, 然后看到了如上的输出信息.
    liberize
        17
    liberize  
       110 天前 via Android
    @hpc4you 同样参数直接终端手动调用试试。
    hpc4you
        18
    hpc4you  
       103 天前
    @liberize 抱歉, 我实在很外行. 我尽量详尽的描述我的操作过程.

    其中, scriptB, 是采用 shell 编写的, 如果单纯运行 bash scriptB --help, 可以打印简单的使用说明.
    比如可以实现 bash scriptB --sync_do "XXXX“之类的操作. 当然也支持./scriptB --sync_do "XXXX".

    scriptA 当然也是 bash shell.

    使用 SHC, 先编译 scriptB, 然后再从 scriptA 调用编译后的 scriptB.x, 运行符合预期.
    再把 scriptA 使用 SHC 编译为 scriptA.x, 运行./scriptA.x 结果也是符合预期的.

    按照同样的流程, 使用 ssc 先编译了 scriptB, 得到 scriptB.y, 运行 ./scriptB.y --help, 就会看到前序报告的提示信息.

    我技能有限, 能分享的信息, 叙述完毕.
    liberize
        19
    liberize  
       103 天前
    @hpc4you 重新拉一下最新代码试试
    liberize
        20
    liberize  
       103 天前
    另外,dev 分支用了另一种方式实现,解决了脚本不能读取标准输入的问题
    hpc4you
        21
    hpc4you  
       101 天前
    @liberize 感谢.
    dev 分支可以解决问题. 实际操作中, scriptB 需要提示用户输入部分内容. 使用 dev 分支后, 运行负荷预期.

    默认 master 分支, 会跳过读取输入操作.

    输入读取采用的是`read -p`, 非常简陋的 bash SHELL.

    再次感谢.
    liberize
        22
    liberize  
       101 天前 via Android   ❤️ 1
    @hpc4you 提醒一下,应该选一个 glibc 版本尽量低的系统运行 ssc ,这样生成的二进制文件依赖的 glibc 版本比较低,在老系统上也能运行
    hpc4you
        23
    hpc4you  
       101 天前
    @liberize 多谢提醒.

    经过测试确认, dev branch, 可以处理屏幕输入, 目前看来符合我的应用场景.

    经过测试, 在 centOS7.9, 编译的二进制, 可以顺利在 Rocky8.8, AlmaLinux9.0, centOS7.9 运行.
    推测, 在 Ubuntu Focal, Jammy 也是可以运行的.

    再次感谢.
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   918 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 20:02 · PVG 04:02 · LAX 13:02 · JFK 16:02
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.