我收到了该设备作为礼物。每当我收到新设备时,我都会快速查看它。尤其是对于需要一些相当个人或业务关键数据的设备。尽管在这种情况下,我或多或少相信 Ratta 公司会尽最大努力保护我的数据 - 作为一家(部分)中国公司,我相信他们能做的事情有限。我们都知道围绕中国隐私法律法规状况的讨论。此外,我有理由相信设备是由同样位于中国大陆的第三方 OEM 制造商制造的,并且想看看该设备上还发生了什么。
TL;DR该设备可以通过多种攻击途径获得 root 权限。基于软件也基于硬件。
好消息:在检查该设备后,我没有发现任何明显损害间谍软件或其他入侵行为的东西。一些 Ratta 应用程序嵌入了部分混淆的腾讯组件。该设备似乎尊重您的遥测设置(请注意 Google、Apple 等),但会定期检查更新,这些更新至少可能会在位置和使用模式方面跟踪您。一些服务器显然位于中国,因此可能向中国政府开放。尽管该公司似乎意识到了这个话题并在美国推出了服务器。客观地说:任何嵌入式谷歌或亚马逊设备、任何流行的操作系统、任何智能手机或流行的社交媒体应用程序都会收集比我在这里发现的更多的有关您的信息。
警告:我不建议任何人在实践中遵循本文,因为您很可能会导致您的设备无法使用。其中大部分都是凭记忆写下来的。就我而言,这不太可靠。因此,可能存在错误或遗漏,从而增加设备无法使用以及保证失效的风险。
2022/08/08 更新:两周前我通知了 Ratta,让他们知道我会发布此信息。正如预期的那样,拉塔友善地回复并承诺解决这些问题。我还想指出,我在这里绝不暗示中国=邪恶。我表达了对我的数据安全和隐私的普遍愿望,并看到美国、欧洲、印度、俄罗斯……的隐私实践问题,就像我在中国看到的那样。
见上文。鉴于物理访问,该设备对于任何高度敏感的数据来说不能被认为是安全的。
鉴于其过时的 Android 版本的性质以及缺乏安全措施,我在任何情况下都不会向任何不受信任的方提供我的设备。我还建议永远不要将其连接到任何未知的计算机或公共充电电缆,因为其中一些攻击可以完全自动化的方式完成。
我不是保安人员。这花费了我两个周末的时间来收集公开数据。任何比我有足够动力和才华的人或团体都会更快。另外,由于 Ratta 承诺无论如何都允许侧载,并且看到设备完全打开并预装了 su 二进制文件、公共测试密钥、打开引导加载程序、(禁用、轻松解锁)adb 控制台界面和其他打开的门,我认为这不会创建任何意外的不便。
无论如何,该文档已于 2022 年 7 月 27 日通过电子邮件提供给 Ratta,比公开发布提前两周。
没有。在任何情况下,我都不会分发任何可能受到版权等保护的文件。如果您知道自己在做什么,那么这篇文章包含的信息就足够了。如果没有,请保持您的设备不变,并向 Ratta 请求对您设备的 shell/root 访问权限。
您可以通过安装 kindle 应用程序来查找有限数量的设备规格,截至撰写本文时,该应用程序是设备集成“应用程序商店”上唯一可用的应用程序。或者您只需解压 OTA update.zip。
该设备在 Rockchip PX30 平台上运行 Android 8.1,该平台由 1.5GHz 四核 ARM Cortex-A35、2 GB RAM 和 1404x1872 eink 显示屏组成。 Rockchip 平台似乎经常出现在汽车收音机和其他带有用户界面的嵌入式设备中。因此,您只需通过谷歌搜索即可找到很多官方和非官方信息。
像这样:rockchip.fr/PX30%20datasheet%20V1.1.pdf 或者这样:opensource.rock-chips.com/wiki_Main_Page
从 reddit 上有 /r/supernote 和 /r/supernote_beta 的事实来看,该设备存在一个测试程序。
Ratta 在那里及其网站上提供了有关发布测试版更新的信息:
当前的非测试版可以从这里下载:support.supernote.com/article/3/how-to-update-your-supernote
Beta 版不能,因为它的发行版与您设备的序列号相关(可以在SupernoteSettings.apk
中找到),因为与当前安装的版本无关,它连接到相同的服务器和 URL。请参阅下文了解更多深入信息。
更新是常见的、非加密的 Android OTA 文件,可以使用免费工具轻松解压和分析。请参阅下文了解更多信息。
update.zip 包含解压的 .br brotli 图像:
更新.zip:/系统
设备通过与device.supernote.com.cn
上的服务器协调来进行更新,以查看是否有可用的新更新:
curl -X POST -k -H 'Content-Type: application/json' -i 'https://device.supernote.com/official/system/business/android/update/download' --data '{"language":"EN", "equipmentNo":"SN100Bxxxxxxxx", "logicVersion":"Chauvet 2.4.15(566)", "configureList":[{"type":"1", "version":"Chauvet.D002.2203101001.566_release"}]}'
错误消息是中文的,但通常是设备不需要更新、序列号未知等。
如果有可用更新,设备会收到下载 URL 以及完整的变更日志等。
{"success":true,"errorCode":null,"errorMsg":null,"configureList":[{"type":"1","version":"Chauvet.xxxx.xxxxxxxxxx.xxx_xxxxxxx","fileName" :"Chauvet.xxxx.xxxxxxxxxx.xxx_xxxxxxx.zip","名称":null,"packageName":null,"版本否":null,"url":"https://prod-ratta-firmware.s3.ap-northeast-1.amazonaws.com/xxxxxx/update.zip","大小":xxxxxxxx,"md5":" abcdefabcdefabcdefabcdef"}],"totalSize":xxxxxxxx,"fixPointList":[{"当前":false,"版本":"Chauvet xxxx(xxx)","固定点":"
...
","opTime":"xxxx-xx-xx xx:xx:xx"}],"logicVersion":"Chauvet xxxx(xxx)","deployDate":"xxxx-xx-xx xx:xx:xx"}
然后将其下载并移交给恢复系统。
如果您按照手动更新说明将 update.zip 文件放入设备上的/EXPORT/
文件夹中并拔出 USB 电缆,也会发生同样的情况。设备发现该文件并询问您是否应该继续安装。
具体的机制可以从下面的代码中推导出来。
com.ratta.supernote.update.NetWorkConstant
public static final String DEV_BASE_URL = "http://10.20.22.32:9000" ;
public static final String DOWN_LOAD_URL = "" ;
public static final String NET_BASE_URL_PRODUCT = "http://10.20.22.32:8075/" ;
public static final String NET_BASE_URL_TEST = "https://test-ms-device.ratta.com.cn/" ;
public static final String RELEASE_BASE_URL = "https://device.supernote.com.cn/" ;
public static final String UAT_BASE_URL = "https://device.supernote.com" ;
public static final File DOWN_LOAD_PATH = new File ( "/cache" );
public static final String USBDisk_Path = Environment . getExternalStorageDirectory () + File . separator ;
public static final String FILE_TEST = USBDisk_Path + "EXPORT/test" ;
public static final String FILE_PRODUCT = USBDisk_Path + "EXPORT/product" ;
public static final String FILE_UAT = USBDisk_Path + "EXPORT/uat" ;
com.ratta.networklibrary.utils.C0598Utils
String str = Build . DISPLAY ; // i.E. Chauvet.D002.2203101001.566_release
boolean exists = new File ( Constant . FILE_USA ). exists ();
int lastIndexOf = str . lastIndexOf ( "_" );
if ( lastIndexOf != - 1 ) {
String substring = str . substring ( lastIndexOf + 1 );
String str2 = (( TextUtils . equals ( substring , "root" ) || TextUtils . equals ( substring , "hard" )) && exists ) ? Constant . USA_BASE_URL : Constant . RELEASE_BASE_URL ;
if ( new File ( Constant . FILE_TEST ). exists () || TextUtils . equals ( substring , "test" )) {
str2 = exists ? Constant . TEST_USA_BASE_URL : Constant . TEST_BASE_URL ;
} else if ( new File ( Constant . FILE_PRODUCT ). exists ()) {
str2 = Constant . DEV_BASE_URL ;
} else if ( new File ( Constant . FILE_UAT ). exists () || TextUtils . equals ( substring , "uat" )) {
str2 = Constant . UAT_BASE_URL ;
}
if (! TextUtils . equals ( substring , "release" ) && ! TextUtils . equals ( substring , "beta" )) {
return str2 ;
}
if ( exists ) {
return Constant . USA_BASE_URL ;
}
}
return Constant . RELEASE_BASE_URL ;
com.ratta.supernote.update.DownLoadService
@ POST ( "official/system/business/android/update/download" )
Call < DownResponse > downLoadFileInfo ( @ Body RequestBody requestBody );
com.ratta.supernote.update.UpDateAppService
LocalSystemInfoBean localSystemInfoBean = new LocalSystemInfoBean (); // see CURL request above for example values
localSystemInfoBean . setEquipmentNo ( DownPresenter . getDeviceVersion ());
localSystemInfoBean . setLanguage ( DownPresenter . getLanguage ( this ));
localSystemInfoBean . setLogicVersion ( DownPresenter . getLogicVersion ());
localSystemInfoBean . setConfigureList ( DownPresenter . getSystemAllPackageVersion ( this , new ArrayList ()));
RetrofitUtils retrofitUtils = RetrofitUtils . getInstance ();
final DownResponse downResponse = ( DownResponse ) retrofitUtils . execute ((( DownLoadService ) retrofitUtils . getService ( DownLoadService . class )). downLoadFileInfo ( DownLoadModel . getRequestBody ( localSystemInfoBean )));
com.ratta.supernote.update.UpDateAppService
if ( new File ( NetWorkConstant . DOWN_LOAD_PATH , "update.zip" ). exists ()) {
CacheInfoUtils . saveData ( CacheInfoUtils . updateFlagPath , UpDateAppService . USB_UPDATE_FLAG );
RecoverySystem . installPackage ( UpDateAppService . this , new File ( NetWorkConstant . DOWN_LOAD_PATH , "update.zip" )); // if unfamiliar: https://developer.android.com/reference/android/os/RecoverySystem
}
com.ratta.supernote.update.UpDateAppService
private void checkRestartUpdate () {
String str = SystemProperties . get ( ConstanceUtil . restartKey , Constance . FILE_SEVER_UFILE ); // FILE_SEVER_UFILE = "0"; restartKey = "ratta.launcher.restart";
LogUtils . m187d ( "ratta: " + str );
if (! str . equals ( "1" )) {
SystemProperties . set ( ConstanceUtil . restartKey , "1" );
this . firstSelectVersion = true ;
if ( new File ( Environment . getExternalStorageDirectory (). getAbsolutePath () + File . separator + "EXPORT" , "update.zip" ). exists ()) {
this . firstSelectVersion = false ;
usbUpdate ();
return ;
}
LogUtils . m187d ( "checkRestartUpdate: getVersionList" );
getVersionList ();
}
}
public void usbUpdate () {
if ( this . usbUpdateFlag ) {
return ;
}
final File file = new File ( Environment . getExternalStorageDirectory (). getAbsolutePath () + File . separator + "EXPORT" , "update.zip" );
if (! file . exists ()) {
LogUtils . m187d ( "onReceive: No USB upgrade file" );
return ;
}
GestureService . lockStatusbar = true ;
GestureService . lockSlidebar = true ;
this . usbUpdateFlag = true ;
LogUtils . m187d ( "usb update GestureService.lockStatusbar true" );
DialogUtils . getInstance (). build ( this ). createDefaultDelayDialog ( getString ( C0688R . string . usb_detection_tips ), 30 , new LibDialogDelayDefaultListener () { // "The upgrade pack is detected, do you want to install?"
// goes on with housekeeping like removing any existing update.zip and a couple of checks for enough battery etc and then moves the update.zip to /cache as seen above
正如您所看到的,没有进行健全性检查或任何类型的解密。因此,您基本上可以取出任何文件,将其移动到 /EXPORT/ 文件夹,然后让系统将其移交给恢复。
我从未检查过,但阅读代码后我认为您可以通过 USB 随意升级和降级您的设备。
不过,由于它是标准的 Android 恢复机制(我不太熟悉),它会检查文件是否使用已知的私钥进行签名。
该设备带有封闭的ADB接口。它需要adb reboot
命令,该命令允许您将其置于恢复adb reboot recovery
以及 fastboot adb reboot fastboot
或引导加载程序模式adb reboot loader
中。
在恢复模式下,设备允许以 root 身份运行 shell。可用的命令集有限,但已安装 busybox,所以没关系。一个合乎逻辑的步骤是通过创建如下脚本来解锁对 adb 的完全访问权限:
#! /bin/bash
echo " rebooting to recovery "
adb reboot recovery
ANSWER=0
while [ " $ANSWER " != " 1 " ] ; do
sleep 2
ANSWER= $( adb devices | grep rockchipplatform -c )
done
echo " device online, patching "
adb shell busybox mount -o rw,seclabel,relatime,data=ordered,inode_readahead_blks=8 /dev/block/by-name/system /system
adb shell sed -i " s/ro.debuggable=0/ro.debuggable=1/ " /system/etc/prop.default
echo " rebooting to system "
adb reboot
之后,该设备基本上可以通过标准 adb shell 完全访问,然后可以将其提升为 root:
对于非技术用户:这意味着您的设备以及所有文件基本上都是打开的。任何有动力的用户都可以随时复制或修改设备上的任何文件(只要有 USB 访问权限)。
由于引导加载程序已解锁,因此您可以随时通过将设备重新启动到此模式来刷新任何内核或分区,并使用fastboot flash boot boot.img
对于非技术用户:这意味着您的设备可以以您不会注意到的方式自由修改,从而使您的数据和隐私面临风险。
在此模式下,RKDevTool 等 Rockchip 开发工具会将设备检测为“加载模式”。从这里可以覆盖分区,可以更改分区布局......
...并且设备可以进入 Maskrom 模式。下面详细介绍一下。
对于非技术用户:这意味着您的设备可以以您不会注意到的方式自由修改,从而使您的数据和隐私面临风险。
当我查看/system/build.prop
时,我发现
ro.build.description=px30_ht_eink-userdebug 8.1.0 OPM8.190505.001 Chauvet.D002.2206171001.629_beta test-keys
ro.build.fingerprint=Android/htfy_px30:/Chauvet.D002.2206171001.629_beta_:userdebug
test-keys
不是一个好兆头。如果你是开发商。如果您正在寻找进入系统的大门,那么这是一个美丽的标志。
我不会详细介绍 Android OTA,但您可以在此处阅读。
通过查看 update.zip: /META-INF/com/android/otacert
我们可以查看更新的公共证书:
-----开始证书-----
MIID+zCCAuOgAwiIBAgIJAJKlKMdz16FBMA0GCSqGSIb3DQEBCwUAMIGUMQswCQYD
VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4g
VmlldzEQMA4GA1UECgwHQW5kcm9pZDEQMA4GA1UECwwHQW5kcm9pZDEQMA4GA1UE
AwwHQW5kcm9pZDEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTAe
Fw0xNDEyMjMwNjQ0MDhaFw00MjA1MTAwNjQ0MDhaMIGUMQswCQYDVQQGEwJVUzeT
MBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEQMA4G
A1UECgwHQW5kcm9pZDEQMA4GA1UECwwHQW5kcm9pZDEQMA4GA1UEAwwHQW5kcm9p
ZDEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTCCASAwDQYJKoZI
hvcNAQEBBQADggENADCCAQgCggEBALl71fjESroAzdrkBKrApCrK9qnZfH38S3U3
6jhBOQtrwxnh/AaRC3hOyO5ihjwv1MlSuTA1DygGMznwP8rOQbc9eH4uqdnerE87
v0bc8lPCj22AAterZBZESqgfRwND/25S6A22wA/kpR/CiXMuWHlQfS6Q9CHBOwVQ
5ZZUge2KC1TbH8EtDkxDacOeTbhN6UQxxm3jgaIzkwyrEEcYB1m93CrTFOtVV7Jw
wo7XE5LGwo6nTzNieXJqoYxcNAMpv9seKW+GZ1EGl78e9B37SMoxq0I7HuStz5tD
tS2Er2YrjQig+1ZqgroIvPfEJAEyoEr0r6kk7jBh878usWOuWB0CAQOjUDBOMB0G
A1UDDgQWBBTV37ltjIiA28uNs8Z1hb6zasy5UzAfBgNVHSMEGDAWgBTV37ltjIiA
28uNs8Z1hb6zasy5UzAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQAZ
7pvK3yDr+O0G8ggDfaISkEeg0agocRcXGT/MRiPBz+n45+bEoym4hC2SdCxvHXES
5AHkFxjWavoQqAD8We955NCmpGzDip4hUctlXzqxYfSTvGiLArG92+Hcbu5RNx/7
o3Of39Mdge2jVKQuKAALWnb8TgJ/2k3KAUFzVqMXPY4asmnWtyW2FIKLdZU/yYTX
+8Tp0AhP+N84HUGg5BwQRD10/OGGY54rLfFy2aSLPxUZQ+VTSZB9Z9XRLxohsF/V
XBcZyCdPP254wDYL5R0HGWZv7CeBlVjw3FqDRI9aljdYfLpAk+clnRBwWOWHsiOE
pJXgkkLmpq0uDXsSMJZ2
-----证书结束-----
在谷歌上搜索部分证书,至少可以得到 xda-developers.com 的一个结果,其中有人试图进入他们的 Android 8.1 Rockchip PX5 设备。
这是一个更糟糕的迹象。或者对我来说更美丽的一个。
接下来,我在 google 上搜索了有关 PX30 平台的 SDK,并在这里找到了一个:
en.t-firefly.com/doc/download/page/id/63.html#other_206
以及这里的文档:
wiki.t-firefly.com/en/Core-PX30-JD4/Android_development.html
在这里:
wiki.t-firefly.com/en/Firefly-RK3399/customize_android_firmware.html
下载 SDK 后,您可以解压 7z 存档并通过以下方式初始化包含的 git 存储库:
git clone PX30_Android8.1.0_LVDS_190706 directory_to_clone_into
经过长时间的克隆后,在/build/make/target/product/security
下找到 SDK 测试密钥,然后就可以开始了。
有趣的事实:该文件夹中的自述文件指出:
此目录中的测试密钥仅用于开发,切勿用于对公开发布的映像中的包进行签名(因为这会打开一个主要的安全漏洞)。
是的,确认了。
我将这项技术留给您 - 在 Windows 上工作时,我使用 Multi Image Kitchen 来解包、重新打包并签署 Android OTA。您必须将testkey.x509.pem
和testkey.pk8
移至该工具的bin
文件夹中,从那里开始将能够创建修改后的更新,当您将其放入 EXPORT 文件夹时,设备将别无选择,只能安装。
嗯,可能吧。
您在此处所做的所有操作都极易出错并导致设备软砖化。据我所知,所有 Rockchip 设备永远不可能完全软砖化,因为它们总是带有 maskrom 模式,这基本上是一个开放的编程接口。
通常可以通过短接CPU上的两个引脚来访问该接口。这也适用于您的 Supernote,但需要打开设备,并且很可能会使您可能拥有的任何剩余保证失效。
请参阅下文,了解有关 PX30 maskrom 以及如何恢复设备的所有信息。
备份 root adb shell 中的所有分区:
adb shell
例如通过发出以下命令:
cat /dev/block/mmcblk1p1 > /sdcard/EXPORT/uboot.img
cat /dev/block/mmcblk1p2 > /sdcard/EXPORT/trust.img
cat /dev/block/mmcblk1p3 > /sdcard/EXPORT/misc.img
cat /dev/block/mmcblk1p4 > /sdcard/EXPORT/resource.img
cat /dev/block/mmcblk1p5 > /sdcard/EXPORT/kernel.img
cat /dev/block/mmcblk1p6 > /sdcard/EXPORT/boot.img
cat /dev/block/mmcblk1p7 > /sdcard/EXPORT/recovery.img
cat /dev/block/mmcblk1p8 > /sdcard/EXPORT/backup.img
cat /dev/block/mmcblk1p9 > /sdcard/EXPORT/security.img
cat /dev/block/mmcblk1p10 > /sdcard/EXPORT/cache.img
cat /dev/block/mmcblk1p11 > /sdcard/EXPORT/system.img
cat /dev/block/mmcblk1p12 > /sdcard/EXPORT/metadata.img
cat /dev/block/mmcblk1p13 > /sdcard/EXPORT/vendor.img
cat /dev/block/mmcblk1p14 > /sdcard/EXPORT/oem.img
cat /dev/block/mmcblk1p15 > /sdcard/EXPORT/frp.img
甚至可能保存您的用户数据:
dd if=/dev/block/by-name/userdata bs=4096 count=1048576 of=/sdcard/EXPORT/userdata-1.img
dd if=/dev/block/by-name/userdata bs=4096 skip=1048576 count=1048576 of=/sdcard/EXPORT/userdata-2.img
dd if=/dev/block/by-name/userdata bs=4096 skip=2097152 count=1048576 of=/sdcard/EXPORT/userdata-3.img
dd if=/dev/block/by-name/userdata bs=4096 skip=3145728 count=1048576 of=/sdcard/EXPORT/userdata-4.img
dd if=/dev/block/by-name/userdata bs=4096 skip=4194304 count=1048576 of=/sdcard/EXPORT/userdata-5.img
dd if=/dev/block/by-name/userdata bs=4096 skip=5242880 count=1048576 of=/sdcard/EXPORT/userdata-6.img
backup -> /dev/block/mmcblk1p8
boot -> /dev/block/mmcblk1p6
cache -> /dev/block/mmcblk1p10
frp -> /dev/block/mmcblk1p15
kernel -> /dev/block/mmcblk1p5
metadata -> /dev/block/mmcblk1p12
misc -> /dev/block/mmcblk1p3
oem -> /dev/block/mmcblk1p14
recovery -> /dev/block/mmcblk1p7
resource -> /dev/block/mmcblk1p4
security -> /dev/block/mmcblk1p9
system -> /dev/block/mmcblk1p11
trust -> /dev/block/mmcblk1p2
uboot -> /dev/block/mmcblk1p1
userdata -> /dev/block/mmcblk1p16
vendor -> /dev/block/mmcblk1p13
rootfs / rootfs ro,seclabel,size=981980k,nr_inodes=245495 0 0
/dev/block/by-name/system /system ext4 ro,seclabel,relatime,data=ordered,inode_readahead_blks=8 0 0
/dev/block/by-name/vendor /vendor ext4 ro,seclabel,relatime,data=ordered,inode_readahead_blks=8 0 0
/dev/block/by-name/oem /oem ext4 ro,seclabel,noatime,nodiratime,block_validity,delalloc,barrier,noauto_da_alloc,user_xattr 0 0
/dev/block/by-name/cache /cache ext4 rw,seclabel,nosuid,nodev,noatime,nodiratime,discard,noauto_da_alloc,data=ordered 0 0
/dev/block/by-name/metadata /metadata ext4 rw,seclabel,nosuid,nodev,noatime,nodiratime,discard,noauto_da_alloc,data=ordered 0 0
/dev/block/by-name/userdata /data f2fs rw,lazytime,seclabel,nosuid,nodev,noatime,nodiratime,background_gc=on,discard,no_heap,user_xattr,inline_xattr,inline_data,inline_dentry,flush_merge,extent_cache,mode=adaptive,active_logs=6,alloc_mode=default,fsync_mode=posix 0 0
tmpfs /storage tmpfs rw,seclabel,relatime,mode=755,gid=1000 0 0
adb /dev/usb-ffs/adb functionfs rw,relatime 0 0
/data/media /mnt/runtime/default/emulated sdcardfs rw,nosuid,nodev,noexec,noatime,fsuid=1023,fsgid=1023,gid=1015,multiuser,mask=6,derive_gid 0 0
/data/media /storage/emulated sdcardfs rw,nosuid,nodev,noexec,noatime,fsuid=1023,fsgid=1023,gid=1015,multiuser,mask=6,derive_gid 0 0
/data/media /mnt/runtime/read/emulated sdcardfs rw,nosuid,nodev,noexec,noatime,fsuid=1023,fsgid=1023,gid=9997,multiuser,mask=23,derive_gid 0 0
/data/media /mnt/runtime/write/emulated sdcardfs rw,nosuid,nodev,noexec,noatime,fsuid=1023,fsgid=1023,gid=9997,multiuser,mask=7,derive_gid 0 0
我的设备上的更新已经附带了 su 二进制文件和许多快捷方式,使我可以轻松访问 root adb 界面。
我尝试过的一些修改是:
/system/etc/prop.default
security.perf_harden=0
ro.debuggable=1
sys.rkadb.root=1
ro.debug.build=true
ro.oem_unlock_supported=1
ro.secure=0
ro.adb.secure=0
persist.sys.usb.config=mtp,adb
虽然我阻止了非常频繁的更新检查和可选的遥测(还阻止了内置的应用程序商店,但这几乎没有用,因为我们现在可以将应用程序侧面加载到设备上)
/系统/etc/主机
127.0.0.1 device.supernote.com.cn
127.0.0.1 supernote.com.cn
127.0.0.1 www.supernote.com.cn
127.0.0.1 device.supernote.com
127.0.0.1 supernote.com
127.0.0.1 www.supernote.com
127.0.0.1 test-ms-device.ratta.com.cn
127.0.0.1 uat-ms-device.ratta.com.cn
127.0.0.1 ratta.com.cn
您从这里有一个工作根 adb 界面,可以旁加载应用程序并在发出mount -o remount,rw /system
后根据您的喜好完全修改 /system
然后我所做的第一步是安装一个正常工作的基于 SuperSU 系统的根解决方案。为此,我下载了最新的 supersu.zip,将其解压,查看安装脚本并以超级 hacky 的方式手动将文件放置到位:
/system/.ext/.su # useless I think? Didn't bother to understand
/system/xbin/daemonsu
/system/xbin/su
/system/xbin/sugote
/system/xbin/sugote-mksh
/system/xbin/supolicy
/system/lib64/libsupol.so
/system/app/SuperSU/SuperSU.apk
并修改/system/bin/install-recovery.sh
以结尾:
/system/xbin/daemonsu --auto-daemon &
/system/etc/install-recovery-2.sh
然后通过修改system_file_contexts.txt
来修改文件上下文和访问权限,以结尾:
/system/app/SuperSU/SuperSU.apk u:object_r:system_file:s0
/system/xbin/su u:object_r:system_file:s0
/system/bin/.ext/.su u:object_r:system_file:s0
/system/xbin/daemonsu u:object_r:system_file:s0
/system/xbin/sugote u:object_r:zygote_exec:s0
/system/xbin/supolicy u:object_r:system_file:s0
/system/lib64/libsupol.so u:object_r:system_file:s0
/system/xbin/sugote-mksh u:object_r:system_file:s0
和system_fs_config.txt
以结尾:
system/app/SuperSU 0 0 0755
system/app/SuperSU/SuperSU.apk 0 0 0644
system/xbin/su 0 2000 0755
system/bin/.ext 0 2000 0755
system/bin/.ext/.su 0 2000 0755
system/xbin/daemonsu 0 2000 0755
system/xbin/sugote 0 2000 0755
system/xbin/supolicy 0 2000 0755
system/lib64/libsupol.so 0 0 0644
system/xbin/sugote-mksh 0 2000 0755
工作得很好。
实现一个快速脚本本来很简单,但此时我刚刚进入 Android root,我的计划是安装适当的 Magisk 无系统 root。
Magisk 可以通过向其提供未修改的 boot.img 来生成预先修改的“rooted”boot.img 内核和 ramdisk。
从update.zip
的根目录中获取boot.img
并将其复制到/storage/emulated/0/Download
侧面加载最新的 Magisk,如下所示:
adb install Magisk-v25.x.apk
在设备上,转到Settings > Apps > My apps
使系统刷新应用程序列表并将 Magisk 添加到侧边栏。您可能需要滚动到那里才能找到它,因为启动器 UI 显然不适合拥有许多应用程序的人。
在能够在 Magisk 中选择要修补的文件之前,我需要安装一个 DocumentProvider,我选择将其作为 Total Commander(下载),因为它是免费且超级方便的。旁加载:
adb install tcandroidxxxx-universal.apk
执行与上面相同的操作,使其出现在侧边栏中。打开它并盲目点击右上角以打开一个“空”菜单,您尝试点击倒数第二个项目从深色主题切换到浅色主题,以便最终正确地看到所有内容。
打开 Magisk,(授予其 root 访问权限),点击更新,保留所有内容,点击下一步,“选择并修补文件”,选择 Total Commander(url...)作为提供程序,然后选择 boot.img。
再次将生成的magisk_patched-xxx.img
从默认工作文件夹/storage/emulated/0/Download
复制回您的计算机。
从将设备启动到快速启动:
adb reboot fastboot
并发布标准:
fastboot flash boot magisk_patched-xxx.img
和
fastboot reboot
如果一切顺利,您的设备将启动进入系统,您可以打开 Magisk,它会报告随Ramdisk 一起安装的版本: yes 。如果您之前安装了 SuperSU 或尚未删除预安装的 su 二进制文件,它会警告您安装已损坏,并要求您删除任何以前的 root。您可以通过删除添加的所有文件或仅删除预安装的su
和libsupol.so
来实现此目的
打开任何要求超级用户确保一切正常工作的应用程序,并会看到熟悉的超级用户提示:
我整理了一份可追溯到 v1.0.1(077) 的以前固件文件列表。
一旦我有时间就完成。
如果您的设备出现任何问题,请打开设备,拆下 CPU 的屏蔽,短接以下两个排针,同时按下电源开关旁边的重置开关。
这将使您的设备进入 maskrom 模式。我不会详细介绍如何准确恢复设备,但会为您留下最相关的信息以及在对设备进行任何修改之前备份所有分区的建议。
接下来安装 maskrom 驱动程序(确保在 Windows 中启用未签名的驱动程序,然后使用RKImageMaker
和AFPTool
等工具创建一个 update.img,该 update.img 可以通过 maskrom 中的 RKDevTool(从此处)进行刷新。RKDevTool 包含您需要创建的上述两个二进制文件更新包。
RKDevTool 默认情况下以中文显示,并对固件进行或多或少无用的验证检查,您可以使用它的 .ini 将其关闭:
[Language]
Selected=2
和
FW_NOT_CHECK=TRUE
RB_CHECK_OFF=TRUE
CHECK_MACHINE_MODEL=FALSE
总而言之,弄清楚这个过程是一次有趣的体验,因为 Rockchip SDK 和工具环境极其分散。
完整的 update.img 需要这些文件。您可以从您制作的分区备份之类的地方获取它们,也可以从上述 SDK 或谷歌搜索中获取部分内容。
自从我创建了一个工具链以来,krnl 文件就在那里,该工具链使用名为 imgRePackerRK(下载)的工具将原始 .img 文件转换为 Rockchip 兼容格式 (.img.krnl)。
该工具显然是为了取代 RKImageMaker 和 AFPTool 并成为创建 Rockchip update.img 的一体化解决方案。但它不会为我产生一致的结果。
但它可以转换与 Rockchip 恢复兼容的内核、启动和恢复映像。
Imageboot.img.krnl 与 Imageboot.img
因此,我使用它来方便地创建 .krnl 文件,然后运行我的 toolchain.bat 来构建工作 update.img,同时保留原始 .img 文件和 .krnl 文件。
move Imageboot.img Imageboot.img.tmp
move Imagerecovery.img Imagerecovery.img.tmp
move Imagekernel.img Imagekernel.img.tmp
move Imageboot.img.krnl Imageboot.img
move Imagerecovery.img.krnl Imagerecovery.img
move Imagekernel.img.krnl Imagekernel.img
copy Imageparameter.txt .parameter
Afptool -pack ./ Imagetmp-update.img
RKImageMaker.exe -RKPX30 ImageMiniLoaderAll.bin Imagetmp-update.img update.img -os_type:androidos
move Imageboot.img Imageboot.img.krnl
move Imagerecovery.img Imagerecovery.img.krnl
move Imagekernel.img Imagekernel.img.krnl
move Imageboot.img.tmp Imageboot.img
move Imagerecovery.img.tmp Imagerecovery.img
move Imagekernel.img.tmp Imagekernel.img
del Imagetmp-update.img
pause
为了帮助您一路前进,这里还有一个兼容的/Image/parameter.txt
: