四处构建、四处运行的Actually Portable Executable
2024-9-6 21:55:50 Author: mp.weixin.qq.com(查看原文) 阅读量:4 收藏

标题: Unix系列(17)--Cosmopolitan简介

创建: 2024-09-05 16:10
修改: 2024-09-06 21:50
https://scz.617.cn/unix/202409051610.txt


目录:

    ☆ 背景介绍
    ☆ APE技术原理
    ☆ Cosmopolitan相关工具
    ☆ Linux测试
        1) 下载相关工具
        2) hello.c
    ☆ Windows测试
        1) 下载相关工具
        2) 准备编译环境
        3) hello.c
            3.1) 在cmd中测试
            3.2) 在PowerShell中测试
        x) 讨论
    ☆ binfmt_misc
        1) 加载binfmt_misc文件系统
        2) 向内核注册文件类型
        3) 用xxd执行some.bin
        4) 启用/禁用指定文件类型
        5) 从内核反注册文件类型
        6) APE与binfmt_misc
    ☆ cosmos中的游戏
        1) 任天堂模拟器
    ☆ Justine Tunney

☆ 背景介绍

Google有个非常牛的女程序员,名叫Justine Tunney。她搞了一套名为Cosmopolitan的东西,四海一家。简要地说,只有一份some.c,用cosmocc编译成some.exe,后者可在Windows、Linux、BSD、MacOS中运行,注意,只有一份some.exe,不是四份。我只测了AMD64,也支持ARM64。

她给some.exe的文件格式起名APE,是"Actually Portable Executable"的缩写,相比之下微软的PE一点也不Portable。APE的目标是"四处构建、四处运行",在任意受支持的平台上构建APE,在所有受支持的平台上运行同一份APE。与Java、Python等解释语言不同,APE无需安装庞大的解释器,some.exe自己搞掂一切,并不臃肿。

☆ APE技术原理

Actually Portable Executable - Justine Tunney <jtunney@gmail.com> [2020-08-24]
https://justine.lol/ape.html

APE Loader - [2022-06-11]
https://justine.lol/apeloader/

cosmopolitan libc
https://justine.lol/cosmopolitan/index.html

Cosmopolitan Third Edition - [2024-08-17]
https://justine.lol/cosmo3/

APE的基本原理是,首先它是PE格式,在Windows中按PE执行;其次,充分利用PE格式中不影响执行的区域存放shell脚本、ELF本体等等,在Linux中按ELF执行;APE整体上有点类似"壳"。

☆ Cosmopolitan相关工具

Cosmopolitan
https://github.com/jart/cosmopolitan

编译工具链
https://cosmo.zip/pub/cosmocc/cosmocc.zip

二进制工具集合
https://cosmo.zip/pub/cosmos/zip/cosmos.zip

cosmocc是编译工具链,cosmos是一堆APE格式的常用工具,比如bash、curl等等。

☆ Linux测试

1) 下载相关工具

cd /home/scz/src
mkdir cosmocc
wget https://cosmo.zip/pub/cosmocc/cosmocc.zip
unzip -q cosmocc.zip -d cosmocc
rm cosmocc.zip

Linux测试时,只需下载编译工具链cosmocc.zip,无需下载cosmos.zip。

2) hello.c

export PATH=/home/scz/src/cosmocc/bin:$PATH
printf '#include <stdio.h>\nint main() { printf("Hello World\\n"); }' > hello.c
cosmocc -Wall -pipe -s -o hello.exe hello.c
./hello.exe

cosmocc是个bash脚本,实际调用gcc。hello.exe可直接在Ubuntu 22和Win10中运行,与cosmocc.zip、cosmos.zip毫无关系。

$ file -b hello.exe
DOS/MBR boot sector; partition 1 : ID=0x7f, active, start-CHS (0x0,0,1), end-CHS (0x3ff,255,63), startsector 04294967295 sectors

$ xxd -g 1 -l 16 hello.exe
000000004d 571 46 70 44 3d 27 0000 10 00 f8 00 00  MZqFpD='........

☆ Windows测试

1) 下载相关工具

Windows测试时,需同时下载cosmocc.zip、cosmos.zip,将两个zip分别展开至:

X:\path\cosmocc\
X:\path\cosmos\

cosmocc是个bash脚本,需在bash环境中运行,cosmos.zip提供有APE格式的bash。

2) 准备编译环境

Windows测试时还需一些额外动作

copy X:\path\cosmos\bin\bash X:\path\cosmos\bin\bash.exe

虽然这个bash已是APE格式,但cmd中执行时,需要任一扩展名;若在PowerShell中用Start-Process执行bash,扩展名则不是必须的。

修改

X:\path\cosmocc\bin\cosmocc

该脚本第一行本来是

#!/bin/sh

修改成

#!/X/path/cosmos/bin/bash

否则cosmocc脚本执行不起来

3) hello.c

3.1) 在cmd中测试

cd /d X:\src
echo %PATH%
set PATH=X:\path\cosmocc\bin;X:\path\cosmos\bin;%PATH%
X:\path\cosmos\bin\bash.exe -l

在bash中执行

printf '#include <stdio.h>\nint main() { printf("Hello World\\n"); }' > hello.c
cosmocc -Wall -pipe -s -o hello.exe hello.c
hello.exe
exit

在cmd中执行

hello.exe

该hello.exe可直接在Ubuntu 22中运行。

从cmd进bash后,快速编辑模式被关闭,Copy/Paste不方便。可通过左上角的属性选项,再次打开快速编辑模式。但是,在bash中每执行一次命令,快速编辑模式就被关闭一次,烦不胜烦,未找到永久打开的办法,只能一次次再次打开。稍好一点的办法是,每次先Ctrl-M临时进入编辑模式,再鼠标框选复制,最后Ctrl-V粘贴。

3.2) 在PowerShell中测试

cd X:\src
$env:PATH
$env:PATH="X:\path\cosmocc\bin;X:\path\cosmos\bin;$env:PATH"
Start-Process -FilePath X:\path\cosmos\bin\bash -ArgumentList "-l" -Wait -NoNewWindow

-NoNewWindow参数不可少,否则新开的bash窗口执行命令有问题,原因不明。进bash环境后,其余操作同cmd测试。从PowerShell进bash后,快速编辑模式同样被关闭,不幸的是,未找到再次打开的办法。临时缓解方案是,按住Shift不松的情况下,鼠标框选复制、粘贴。

x) 讨论

实测过自己开发的一些实用工具,包括二十多年前的nsfocus_scan.c,用cosmocc成功编译并运行,确实能做到"四处构建、四处运行"。Justine Tunney本人提供过其他更具说服力、更复杂的示例。

但我碰上select、poll的超时机制不起作用,指定超时的情况下,不会超时结束,同一APE,在Ubuntu、Win10上俱如此,不知是不是BUG?

从网络安全角度看,APE可能为恶意软件所用。

☆ binfmt_misc

参看

Kernel Support for miscellaneous Binary Formats (binfmt_misc)
https://docs.kernel.org/admin-guide/binfmt-misc.html

binfmt_misc是Linux内核提供的功能,可指定用某程序打开某类文件,类似Windows的ftype、assoc命令以及"按文件类型指定默认应用"。

1) 加载binfmt_misc文件系统

$ mount | grep ^binfmt_misc
binfmt_misc on /proc/sys/fs/binfmt_misc type binfmt_misc (rw,nosuid,nodev,noexec,relatime)

若未加载,则手工加载

mount -t binfmt_misc none /proc/sys/fs/binfmt_misc

2) 向内核注册文件类型

命令模板如下

echo ':name:type:offset:magic:mask:interpreter:flags' > /proc/sys/fs/binfmt_misc/register

echo指定的参数最长1920字符,参数解释如下

(见TXT,此处略)

3) 用xxd执行some.bin

$ xxd -g 1 some.bin
0000000073 63 75f 69 73 5f 68 65 72 65                 scz_is_here

以root身份注册文件类型

echo ':scz:M::scz_::/bin/xxd:' > /proc/sys/fs/binfmt_misc/register

以普通用户测试

$ chmod +x some.bin
$ ./some.bin
000000007363 7a5f 6973 5f68 6572 65              scz_is_here

相当于执行"xxd some.bin"

若未注册或未启用相应文件类型,Linux执行some.bin将之视为shell script

$ ./some.bin
./some.bin: line 1scz_is_here: command not found

4) 启用/禁用指定文件类型

$ ls -l /proc/sys/fs/binfmt_misc/scz
-rw-r--r-- 1 root root 0 Sep  6 13:50 /proc/sys/fs/binfmt_misc/scz

$ cat /proc/sys/fs/binfmt_misc/scz
enabled
interpreter /bin/xxd
flags:
offset 0
magic 73637a5f

禁用指定文件类型

echo 0 > /proc/sys/fs/binfmt_misc/scz

$ cat /proc/sys/fs/binfmt_misc/scz
disabled
...

启用指定文件类型

echo 1 > /proc/sys/fs/binfmt_misc/scz

$ cat /proc/sys/fs/binfmt_misc/scz
enabled
...

启用/禁用所有文件类型(慎用)

echo 1 > /proc/sys/fs/binfmt_misc/status
echo 0 > /proc/sys/fs/binfmt_misc/status

5) 从内核反注册文件类型

反注册指定文件类型

echo -1 > /proc/sys/fs/binfmt_misc/scz

$ ls -l /proc/sys/fs/binfmt_misc/scz
ls: cannot access '/proc/sys/fs/binfmt_misc/scz': No such file or directory

反注册所有文件类型(慎用)

echo -1 > /proc/sys/fs/binfmt_misc/status

6) APE与binfmt_misc

APE并不绝对依赖binfmt_misc,用的话效率高一些,不用也能跑

wget -O /usr/bin/ape https://cosmo.zip/pub/cosmos/bin/ape-$(uname -m).elf
chmod +x /usr/bin/ape
echo ':APE:M::MZqFpD::/usr/bin/ape:' > /proc/sys/fs/binfmt_misc/register
echo ':APE-jart:M::jartsr::/usr/bin/ape:' > /proc/sys/fs/binfmt_misc/register

☆ cosmos中的游戏

1) 任天堂模拟器

参看

Cosmopolitan NESEMU1 - [2023-08-01]
https://justine.lol/nesemu1.html
https://justine.lol/nesemu1-1.2.com
https://cosmo.zip/pub/cosmos/bin/nesemu1
https://cosmo.zip/pub/cosmos/tiny/nesemu1

在bash中执行nesemu1,或添加.exe扩展名后在cmd中执行

X:\path\cosmos\bin\nesemu1.exe

内置三款游戏

COSMOPOLITAN NESEMU1

  [0] /zip/usr/share/rom/tetris.nes
  [1] /zip/usr/share/rom/zelda.nes
  [2] /zip/usr/share/rom/mario.nes

Please choose a game (or CTRL-C to quit) [default 0]:

tetris.nes即"俄罗斯方块",空格是调方向。

mario.nes即"超级马利奥",空格是跳。

后来小宋给我一个BattleCity.nes,这是"坦克大作战",这样加载:

X:\path\cosmos\bin\nesemu1.exe X:\path\cosmos\bin\BattleCity.nes

无需进bash,不依赖cosmos其他文件。空格是发射炮弹。

☆ Justine Tunney

readyu向我推荐了Cosmopolitan项目,他评价说,这姐们对编程语言、编译器、文件格式、操作系统的理解非常人所及,此人还是占领华尔街的社会活动家。这里有她的照片:

Justine Alexandra Roberts Tunney (born 1984)
https://en.wikipedia.org/wiki/Justine_Tunney

我的感受是,Justine Tunney与Fabrice Bellard一样,TA们属于能推动技术前进的那种天才程序员,实在是难望其项背。


文章来源: https://mp.weixin.qq.com/s?__biz=MzUzMjQyMDE3Ng==&mid=2247487572&idx=1&sn=44035b8256b85151ab1722eb5a1bb35f&chksm=fab2d36bcdc55a7d2448eed9c6e72a23b938639c45fd415cee6f7a239ea4b74182309a8dcc2c&scene=58&subscene=0#rd
如有侵权请联系:admin#unsafe.sh