标题: 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.htmlAPE 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 0, 4294967295 sectors
$ xxd -g 1 -l 16 hello.exe
00000000: 4d 5a 71 46 70 44 3d 27 0a 0a 00 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
00000000: 73 63 7a 5f 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
00000000: 7363 7a5f 6973 5f68 6572 65 scz_is_here
相当于执行"xxd some.bin"
若未注册或未启用相应文件类型,Linux执行some.bin将之视为shell script
$ ./some.bin
./some.bin: line 1: scz_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.nesPlease 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们属于能推动技术前进的那种天才程序员,实在是难望其项背。