破解小米手表S3实现原神启动

admin 2024年6月20日19:51:46评论6 views字数 4091阅读13分38秒阅读模式

S3是小米最新发布的智能手表,搭载小米基于NUTTX系统二次开发的Vela系统。Vela是RTOS系统,与传统的安卓系统穿戴设备有一定区别。本文通过Hack小米S3手表,成功实现原神启动。

引言
小米手表S3搭载了小米基于NUTTX系统二次开发的Vela系统,这是一款实时操作系统,与传统的安卓穿戴设备有一定区别。S3的应用自然也不是安卓APK应用,而是快应用(QuickAPP),一个由国内几家手机厂商联合推动的一个类似微信小程序的应用标准,这种应用使用JS开发,使用了与安卓APK类似的签名机制。本文的研究目标就是破解S3手表,让它安装我们修改后的应用,实现原神启动。

要实现这一目标,我们需要解决以下两个挑战:
推送任意快应用进入S3手表安装很显然,我们需要把修改后的快应用推送到S3手表内安装。S3手表不具备网络通信功能,它与外界通信都是通过蓝牙实现的,协议分析有一定挑战性,但我们会介绍一个TRICK绕过这一难题。

具备快应用的签名能力修改快应用后不进行二次签名会无法通过完整性校验,导致安装失败。
方法

任意快应用安装


前文提到过,S3手表不具备网络连接能力,那么它是如何完成应用安装功能的呢?小米提供了一个小米运动健康APP,通过这个APP与手表配对后,在APP中的设备页面,有应用商店选项,点击进入后可以安装手表应用。在安卓手机上,这个过程是通过蓝牙串口通信协议完成的,用户先在小米健康APP上下载要安装的手表应用,然后通过蓝牙串口通信协议把下载的应用传输进入手表安装。

要实现任意应用安装,传统的方法是分析蓝牙通信协议,蓝牙通信协议相关代码在com.xiaomi.wearable.wear.api.SppConnection,com.xiaomi.wearable.wear.queue.BleTaskQueueV2中。但是其实可以使用一个TRICK绕过协议分析的问题,手表应用安装的过程首先需要下载应用到安卓本机,那么只需要在下载完成后替换下载的应用为我们修改的应用,就可以实现任意应用安装。

要实现替换应用,需要访问本机文件,Frida JS API没有文件访问API。我将演示如何使用我开发的pyfrida框架非常自然地完成替换过程。pyfrida框架支持直接使用Python编写Frida HOOK脚本,详细可以见文章末尾往期推送。

快应用下载相关代码在com.xiaomi.xms.wearable.ui.appshop.manager.AppDownloadManager类中,该类的getAppFilePath方法是我们需要HOOK的方法。因为在下载快应用后,会调用这个方法获取快应用在安卓本机上的路径,参数就是快应用包名。

接下来,我演示如何通过HOOK这个方法,把下载的快应用拉取到电脑。首先使用pyfrida编写HOOK脚本,然后在安卓手机上安装一个手表应用。如下图所示,get_filepath方法是我们的替换方法,在其中通过调用adb pull拉取下载的快应用到电脑。getAppFilePath方法被调用了两次,第一次调用是下载前被调用,作为下载目标路径,第二次调用是下载后调用,因为要把下载的快应用推送到S3手表。使用pyfrida框架可以很流畅地完成这个过程,因为可以直接使用Python编写Frida HOOK脚本,而如果使用传统的Frida HOOK脚本工作流程,则需要使用Socket通信实现类似功能,较为繁琐。

破解小米手表S3实现原神启动
破解小米手表S3实现原神启动

完整代码如下:

from pyfrida import pyfrida from pyfrida.pyfrida import JSObject, JSContext import frida import os def setup_hook(ctx: JSContext): clz = ctx.Java.use("com.xiaomi.xms.wearable.ui.appshop.manager.AppDownloadManager") clz.getAppFilePath.implementation = js_getfilepath def get_filepath(ctx: JSContext, a1: JSObject): r = ctx.this.getAppFilePath(a1) print("参数: ", a1.get_val(), "返回值: ", r.get_val()) os.system("adb pull %s 1.rpk" % (r.get_val(), )) return r device = frida.get_usb_device() fs = pyfrida.FridaScript() js_setup_hook = fs.add_js_function(setup_hook) js_getfilepath = fs.add_js_function(get_filepath) ps = device.get_process("小米运动健康") fs.attach(device, ps.pid) fs.exec_func_in_java(js_setup_hook) input()

基于pyfrida框架,如果要实现替换应用也很简单,只需要在触发HOOK时,执行adb push上传应用即可。

快应用签名


刚刚下载到的RPK文件是一个ZIP包,与安卓APK类似,它也有两处签名。一处是简单的完整性校验,有一个文件记录了ZIP包内其它条目的SHA256摘要,类似安卓V1签名,一处是修改校验,它在ZIP包中添加了签名快,类似安卓V2签名。接下来依次介绍这些签名。

V1签名


首先把RPK文件解压,在META-INF目录中存在一个CERT文件,这也是一个ZIP包,解压后,得到hash.json文件。hash.json文件内容如下图所示,保存有ZIP包中除CERT文件以外的所有文件的SHA-256值。
破解小米手表S3实现原神启动

V2签名

在CERT文件,与RPK文件中,都存在与安卓APK V2签名类似的签名块,如下图所示,只是将Magic从APK Sig Block 42修改为RPK Sig Block 42。

破解小米手表S3实现原神启动


再签名


快应用的开发工具链是hap-toolkit^1,属于NodeJS生态系,可以直接使用npm install -g hap-toolkit安装。

开发工具链里面肯定有签名算法,并且hap-toolkit直接将签名过程暴露出来了,运行hap,输出中有resign命令,很显然这个命令就是用来对快应用再签名的。找到hap-toolkit的安装目录,bin/index.js文件中有该命令的描述,如下所示。这个签名算法也可以在hap-toolkit的源代码^2里面找到,见signZipBufferForPackage函数。

program .command('resign') .description('resign the rpk/rpks packages') .option('--sign <dir>', 'folder where your signature stored', 'sign/release') .option('--file <dir>', 'rpk that need to be re-signed') .option('--origin <dir>', 'folder where unsigned rpk(s) stored', 'dist') .option('--dest <dir>', 'folder where re-signed rpk(s) stored', 'dest') .action((options) => { const { resign } = require('../lib/commands/resign') resign(options) })

简单描述一下这个命令的用法,它是为未签名的应用添加签名的。未签名的应用指的是只进行了V1签名,还没有进行V2签名的应用。那么再签名的过程也很简单,简单来说就是根据修改的文件,生成hash.json,并打包成ZIP改名为CERT替换原CERT,而后将目录打包ZIP,改后缀名为RPK,使用刚刚提到的resign命令重新签名即可通过校验。这个过程比较繁琐并且可以自动化,我编写了一个快应用重打包工具,该工具已开源至GitHub^3。简单介绍一下这个工具的使用流程。
1.首先解包快应用,得到如下目录:


破解小米手表S3实现原神启动
2.直接修改该目录中的文件

本例中需要修改两处,一处是替换 common/logo.png,这是应用启动LOGO,还有一处是 pages/index/index/index.js,修改调用setTimeout时的参数,后面的参数控制了启动LOGO的显示时间,修改为5000。Patch点如下图所示。
破解小米手表S3实现原神启动
3.重新打包

使用重打包工具生成快应用,调用命令如下,其中,第一个参数是解包目录,第二个参数是输出的文件名。
python repackage.py C:UserschengruiDesktop博客文章归档小米手表破解1 test.rpk

完成这3步之后,我们就获得了一个再签名过的RPK。而后使用上一节提到的替换下载应用的方法,我们就可以在S3手表上安装我们修改过的应用。最后原神启动效果如下图所示:

破解小米手表S3实现原神启动

外部链接


[1] hap-toolkit
https://www.npmjs.com/package/hap-toolkit

[2] 签名算法实现函数
https://github.com/hapjs-platform/hap-toolkit/blob/503e2ab5bf3f933fc6f7c6d5fbf65e27bda8cab6/packages/hap-packager/src/signature/index.js#L109

[3] 快应用重打包工具
https://github.com/ddddhm1234/quickappresign

破解小米手表S3实现原神启动

看雪ID:天水姜伯约

https://bbs.kanxue.com/user-home-783210.htm

*本文为看雪论坛优秀文章,由 天水姜伯约 原创,转载请注明来自看雪社区

原文始发于微信公众号(看雪学苑):破解小米手表S3实现原神启动

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年6月20日19:51:46
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   破解小米手表S3实现原神启动https://cn-sec.com/archives/2868025.html

发表评论

匿名网友 填写信息