0%

使用苹果的Rosetta在Linux上跨架构运行应用

折腾了一圈感觉没什么特别实际的应用,但不失为一种玩法

本文基于Github仓库:https://github.com/CathyKMeow/rosetta-linux-asahi
原作者也介绍了:”Rosetta also runs on other ARM64 machines after being patched, but that’s not legal. Please use FEX / Box64 instead.”
即Rosetta转译工具可以在破解后在任意ARM64的机器上运行,但这并不是合法的,如有实际需求,更建议使用FEX或Box64

破解Rosetta

1
2
3
4
5
6
7
8
magicdian@rosettatest:/media/rosetta$ ls -l
total 2380
-rwxr-xr-x 1 root root 540360 Jan 9 14:15 rosetta
-rwxr-xr-x 1 root root 298600 Jan 9 14:12 rosettad
-rwxr-xr-x 1 root root 1595312 Jan 9 14:13 rosetta_latest
magicdian@rosettatest:/media/rosetta$ ./rosetta_latest
rosetta error: Rosetta is only intended to run on Apple Silicon with a macOS host using Virtualization.framework with Rosetta mode enabled
Trace/breakpoint trap (core dumped)

最新版的rosetta版本号是300多,具体多少我忘了,大小大概1.5MB,尝试运行的话会提示rosetta只允许运行在使用Virtualization.framework的macOS虚拟机中

而在github链接里没有直接提供破解后的rosetta文件,但提供了破解的方法,在仓库里有一个pkg文件

  1. 敲命令:pkgutil --check-signature RosettaUpdateAuto.pkg 这一步作用是检查签名是否是苹果的,防止下载过程文件错误或文件被篡改
  2. 解包pkg :pkgutil --expand-full RosettaUpdateAuto.pkg RosettaUpdateAuto.pkg-expanded 这一步操作后会生成一个RosettaUpdateAuto.pkg-expanded文件,实际上是一个文件夹
  3. 将 Linux Rosetta拷贝出来:cp RosettaUpdateAuto.pkg-expanded/RosettaUpdateAuto.pkg/Payload/Library/Apple/usr/libexec/oah/RosettaLinux/rosetta ./rosetta
  4. 修改rosetta文件
    1
    2
    dd if=<(printf '\x1f\x20\x03\xd5') of='rosetta' bs=1 seek=170828 conv=notrunc
    dd if=<(printf '\x1f\x20\x03\xd5') of='rosetta' bs=1 seek=170856 conv=notrunc

这样就完成了对 Linux 版 Rosetta 工具的破解,放到Linux里发现可以运行,版本是289.3

1
2
3
4
5
6
7
magicdian@rosettatest:/media/rosetta$ ./rosetta
Usage: rosetta <x86_64 ELF to run>

Optional environment variables:
ROSETTA_DEBUGSERVER_PORT wait for a debugger connection on given port

version: Rosetta-289.3

破解原理大概分析

本人基本没有逆向能力,只能大概看个门道,我将289.3原版的rosetta用IDA工具打开,IDA正确识别到这个程序是个ARM64的程序

大概思路先从原版禁止运行的信息入手,搜索Framework字符串,只有一个结果,刚好就是打印的Rosetta is only intended to run on Apple Silicon with a macOS host using Virtualization.framework with Rosetta mode enabled , 这个字符串对应的符号是aRosettaIsOnlyI,继续搜索这个符号,得到两个结果,一个是刚刚定义的地方,一个是实际调用的部分

这一串图俺看不懂,按F5快捷键反编译成C伪代码,这样便于分析,截取关键信息如下

1
2
3
4
5
6
7
8
9
10
11
12
  if ( (v13 & 1) != 0
|| (unsigned int)sub_800000022390(
v134,
"Our hard work\nby these words guarded\nplease don't steal\n© Apple Inc",
69LL) )
{
goto LABEL_174;
}

LABEL_174:
sub_8000000704CC(
"Rosetta is only intended to run on Apple Silicon with a macOS host using Virtualization.framework with Rosetta mode enabled");

大概可以看出来,如果判断到不在Apple Hypervisor框架下运行的话,会提示这是苹果公司的Hard Work,不要盗取,然后就会跳转到LABEL_174来打印禁止运行信息,破解的方法大致是将判断的部分进行了修改。

如果要对这个文件破解的话,感觉理论上,将(v13 & 1) != 0 修改成 (v13 & 1) == 0即可绕过限制,不过我我还没搞明白怎么用ida修改二进制文件,之后如果弄明白了再写吧。。。

使用Rosetta

  1. 创建Rosetta存放的目录 sudo mkdir /media/rosetta
  2. 将破解过的Rosetta可执行文件放在 /media/rosetta
  3. 安装binfmt sudo apt install binfmt-support 这个工具可以帮助Linux识别二进制的格式
  4. 配置binfmt,对于x86_64架构的应用使用Rosetta运行
    1
    2
    3
    4
    sudo /usr/sbin/update-binfmts --install rosetta /media/rosetta/rosetta \
    --magic "\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x3e\x00" \
    --mask "\xff\xff\xff\xff\xff\xfe\xfe\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff" \
    --credentials yes --preserve no --fix-binary yes

第一步中目录其实可以自定义,在第4步install后面配置为对应的目录即可

  1. 添加架构信息和源
    1
    sudo dpkg --add-architecture amd64
    将以下信息写入到 /etc/apt/source.list 文件中
    1
    2
    3
    4
    5
    6
    7
    8
    9
    deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ jammy main restricted
    deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ jammy-updates main restricted
    deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ jammy universe
    deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ jammy-updates universe
    deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ jammy multiverse
    deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ jammy-updates multiverse
    deb [arch=amd64] http://security.ubuntu.com/ubuntu jammy-security main restricted
    deb [arch=amd64] http://security.ubuntu.com/ubuntu jammy-security universe
    deb [arch=amd64] http://security.ubuntu.com/ubuntu jammy-security multiverse

执行 sudo apt update 命令更新源信息,最后安装amd64架构的libc6库即可
sudo apt-get install libc6:amd64

完成以上步骤后,理论上就可以运行amd64架构的应用了。