我收到了該設備作為禮物。每當我收到新設備時,我都會快速查看它。尤其是對於需要一些相當個人或業務關鍵資料的設備。儘管在這種情況下,我或多或少相信 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","name":null,"packageName":null,"versionNo":null,"url":"https://prod-ratta-firmware.s3.ap- east-1.amazonaws.com/xxxxxx/update.zip","大小":xxxxxxxx,"md5":"abcdefabcdefabcdefabcdef"}],"totalSize":xxxxxxxx,"fixPointList":[{"目前":false,"版本":"Chauvet xxxx(xxx)","fixPoint":"
…
","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
或 bootloader 模式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
-----證書結束-----
在Google上搜尋部分證書,至少可以得到 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 或Google搜尋的地方獲取它們。
自從我創建了一個工具鏈以來,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
: