众所周知 8gen3 是不支持 32 位的,突然发现只有小米 14 可以打开 32 位 app。猜测必定有软件实现的转译层,如果是小米自己实现的话那不可谓不领先(本人是做相关技术的,也做过类似的产品)。
到手后简单逆向
首先写个 32位 app demo 看 log:

logcat
可知该进程加载了 32 位系统库,包括 gles 驱动
然后看一下 proc maps

前4G 32 位地址空间
可以看到前 4G,相当于原 32 位地址空间加载了 32 位的原 so

64 位地址空间
64 位地址空间加载了 libxxx.so.tango,tango 文件应该是对应 32 位 so 的转译 AOT 文件。

转译器本体
最后发现了转译工具本体,类似 qemu userspace 以及 rosseta2
IDA 逆向


没有发现 IR 相关的代码,应该是类似 Box86 的直接转译
方案来源
https://www.amanieusystems.com/
最后我搜到了这个 tango translator 的方案来源,原来小米是买的第三方方案。。。
https://github.com/AmanieuSystems/tango32-module 方案商开源了内核模块,主要是配合用户态转译层处理 32-64 位地址问题

总结
- 8gen3 的 32 位兼容目前来看是小米独家提供,但不是独家技术,不排除其他厂商跟进
- 兼容层转译了整个地址空间,包括所有系统库以及 ART Runtime,这可以保证最大的兼容性,且实现较为简单,但性能可能会有大幅损失,尤其是 ART Runtime 的效率会收到影响,实际体验下来 32 位 app 启动也十分缓慢,比较卡。与之对应的 libhudini 则好很多,因为 ART 是原生的
- 其实这类类似 rosseta 的技术门槛是比较高的,本来以为真是小米做的还有点惊喜,不过产品层面能为用户考虑到也还算不错了