Skip to content

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

12 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 

Repository files navigation

ZenUI Keyboard APK 研究與重建專案

本儲存庫保存 ASUS ZenUI Keyboard APK 的反編譯成果,以及使用 Apktool 重新封裝、對齊與簽署 APK 的 GitHub Actions 工作流程。

Warning

這不是原始 Android Studio/Gradle 專案。儲存庫不包含原始 Java/Kotlin、C/C++、Gradle、Android NDK 或原始簽章金鑰;內容由既有 APK 解包與反編譯而來。apktool/ 才是可重建 APK 的來源目錄,jadx/ 僅供閱讀與研究,不能直接參與建置。

Caution

APK 包含 ASUS、Nuance XT9、Vision Objects/MyScript、Google、Facebook 等可能受授權或商標保護的元件與資產。持有、研究、修改、重新封裝、簽署或散布前,應自行確認原始 APK、native library、語言資料庫與其他內容的適用授權、裝置條款及法規。本儲存庫的結構說明不構成授權。

目錄

專案定位

此專案的工作模式是「APK 反編譯、檢視、有限修改與重新封裝」,不是一般從原始碼編譯的 Android app。其兩個主要目錄有完全不同的責任:

目錄 產生工具 用途 是否用於 APK 建置
apktool/ Apktool APK 的資源、Manifest、Smali、原生庫與原始封裝中保留的檔案 是
jadx/ JADX Dalvik bytecode 還原後的 Java 參考碼與資源副本 否

因此,修改行為必須依目標選擇正確位置:

  • 修改資源、Manifest、Smali、封裝檔案或 native library:修改 apktool/。
  • 追蹤 Java 類別、理解呼叫關係、搜尋 native API:閱讀 jadx/sources/。
  • 不要將 jadx/sources/ 當作可直接編譯的原始碼,也不要預期修改它會出現在輸出 APK。
  • 不要手動同步編輯 apktool/ 與 jadx/ 的資源副本;jadx/ 是分析快照,不是第二份真實來源。

目前 APK 資訊

下列資訊由 apktool/apktool.yml 與 apktool/AndroidManifest.xml 取得:

項目 值
套件名稱 com.asus.ime
APK 來源檔名 ZenUI_keyboard.apk
版本名稱 1.7.10.29_190130
版本代碼 1510710145
最低 Android API 19
目標 Android API 26
Manifest compile SDK 標記 23
主輸入法服務 com.asus.ime.IME
Application 類別 com.asus.ime.AsusImeApplication
目前封裝 native ABI 僅 armeabi-v7a

這些值描述的是反編譯來源 APK 的狀態,並不代表重新封裝後能取得原廠系統權限、原廠簽章信任或 OEM 預載整合。

快速建置

前置需求

本機建置至少需要:

  • Java 17
  • Android SDK Build Tools,包含 zipalign 與 apksigner
  • Apktool 2.x

GitHub Actions 已自動安裝 Java、Android SDK 與最新版 Apktool;本機可依相同流程操作。

產生、對齊與簽署 APK

以下命令假設 apktool、zipalign 和 apksigner 已位於 PATH:

apktool b apktool -o output/ZenUI_keyboard-unsigned.apk
zipalign -v -p 4 output/ZenUI_keyboard-unsigned.apk output/ZenUI_keyboard-aligned.apk

keytool -genkeypair -v \
  -keystore output/debug.keystore \
  -alias androiddebugkey \
  -keyalg RSA \
  -keysize 2048 \
  -validity 10000 \
  -storepass android \
  -keypass android \
  -dname "CN=Android Debug,O=Android,C=US"

apksigner sign \
  --ks output/debug.keystore \
  --ks-pass pass:android \
  --key-pass pass:android \
  --ks-key-alias androiddebugkey \
  --out output/ZenUI_keyboard.apk \
  output/ZenUI_keyboard-aligned.apk

apksigner verify -v output/ZenUI_keyboard.apk

CI 的實際腳本位於 .github/workflows/build-apk.yml。它會把產物上傳為 GitHub Actions artifact,並在 main 分支或 v* tag 時建立/更新 GitHub Release。

安裝前的重要事項

  • 新簽署的 APK 無法直接覆蓋以 ASUS 原始憑證簽署的 com.asus.ime。
  • 若目標裝置已有原廠 ZenUI Keyboard,通常必須先解除安裝原版,或先進行完整的 package/authority/intent 遷移後改用新套件名稱。
  • 解除安裝會清除該 package 的 app 資料與使用者詞典;請先備份必要資料。
  • 以不同簽章重裝系統預載 IME,可能失去系統整合、privileged 權限或 OEM 專用功能。

整體結構

ZenUI_keyboard/
├── .github/
│   └── workflows/
│       └── build-apk.yml             # CI:解包目錄重建、zipalign、簽署、發布
├── apktool/                          # 唯一可由 Apktool 重建 APK 的目錄
│   ├── AndroidManifest.xml           # App 元件、權限、Intent、套件識別
│   ├── apktool.yml                   # Apktool 解包/重建描述與 APK 版本資訊
│   ├── assets/                       # 設定、XT9 語言資料庫與手寫資料
│   ├── lib/                          # 封裝的原生 .so,現有僅 armeabi-v7a
│   ├── original/                     # 原 APK 的簽章/封裝中繼資料保留區
│   ├── res/                          # Android 資源:layout、drawable、values、xml 等
│   ├── smali/                        # classes.dex 還原後的可建置 Dalvik bytecode
│   └── unknown/                      # Apktool 無法歸類而按原樣保留的檔案
├── jadx/                             # 僅用於閱讀與逆向分析的輸出
│   ├── resources/                    # JADX 擷取的 Manifest、res、assets、lib 副本
│   └── sources/                      # 還原的 Java 參考碼
└── README.md                         # 本文件

工具輸出的重複內容

apktool/ 與 jadx/ 都可能出現同一資產或 native library,例如:

apktool/lib/armeabi-v7a/libjni_xt9input.so
jadx/resources/lib/armeabi-v7a/libjni_xt9input.so

這不表示專案有兩個獨立的 XT9 實作,而是兩個反編譯工具各自輸出的副本。重建流程只會使用前者。

apktool/:可重建 APK 的工作目錄

apktool/AndroidManifest.xml

Manifest 定義 Android 元件、權限、深層連結、服務以及 OEM 整合。最重要項目如下:

類型 名稱/設定 用途與注意事項
Application com.asus.ime.AsusImeApplication 全域初始化;宣告 directBootAware=true
IME Service com.asus.ime.IME 透過 android.permission.BIND_INPUT_METHOD 註冊為輸入法
Clipboard Provider com.asus.ime.clipboard.provider.DatabaseProvider 私有剪貼簿資料 provider
設定 Activity com.asus.ime.settings.* 一般、外觀、智慧輸入、中文輸入等設定畫面
首次啟動 Activity com.asus.ime.firstlaunch.* 安裝後導覽、選擇語言與背景檢查
Nuance Connect Service com.nuance.connect.service.ConnectClient 語言/內容服務,運行於 :ACService 行程
Dialer API Receiver com.asus.ime.dialerapi.ApiReceiver 接收手寫初始化、辨識、釋放與支援清單廣播
Theme Store 元件 com.asus.ime.theme.*、com.asus.ime.store.* 佈景、商店、背景編輯;多數使用獨立 com.asus.ime.store.process 行程
外部資料傳輸 DataTransferReceiver、DataTransferService ASUS/FutureDial 資料傳輸整合

Manifest 同時宣告數個選用 shared library:

<uses-library android:name="com.visionobjects.im" android:required="false"/>
<uses-library android:name="com.visionobjects.myscript.engine" android:required="false"/>
<uses-library android:name="com.visionobjects.myscript.hwr" android:required="false"/>
<uses-library android:name="com.visionobjects.myscript.inksearch" android:required="false"/>

它們屬於 Vision Objects/MyScript 手寫功能的系統或 OEM 相依項。required=false 僅代表 package manager 不會因此拒絕安裝;程式實際使用相關功能時仍可能因庫不存在、ABI 不相容或系統 linker 限制而失敗。

權限概覽

Manifest 包含網路、儲存、震動、設定與系統整合權限,例如:

INTERNET
ACCESS_NETWORK_STATE
READ_EXTERNAL_STORAGE
WRITE_EXTERNAL_STORAGE
VIBRATE
WRITE_SETTINGS
WRITE_SECURE_SETTINGS
STATUS_BAR
INTERACT_ACROSS_USERS

其中 WRITE_SECURE_SETTINGS、STATUS_BAR、INTERACT_ACROSS_USERS 等通常是 signature、privileged 或受限權限。重新簽章後的一般側載 APK 即使在 Manifest 中保留宣告,也通常無法獲得授權;修改功能時必須將「未獲授權」視為正常環境,並提供安全降級。

apktool/apktool.yml

此檔是 Apktool 的解包描述,不是 Gradle 設定。它保存:

  • 原始 APK 檔名與 Apktool 版本。
  • minSdkVersion、targetSdkVersion、versionCode 與 versionName。
  • 重建資源時所需的 framework ID。
  • 不壓縮檔案清單,例如 resources.arsc、圖片與音效格式。
  • 需要按原樣保留的 unknown/ 檔案壓縮方式。

變更版本或重建行為前,應理解 Apktool 的格式與限制;不要將它誤認為 app 的 build configuration。

apktool/res/

此目錄包含 Android 編譯資源。資源限定詞保留了原 APK 的螢幕尺寸、方向、密度、語系和 API 版本適配,例如:

路徑模式 目的
layout/、layout-land/ 一般與橫向介面 layout
layout-sw600dp/、layout-sw720dp/ 平板或較大螢幕 layout
drawable-* 密度、方向、尺寸與 API 等級對應的圖片/shape 資源
mipmap-* App icon 等 launcher 資源
values/ 預設字串、色彩、樣式、尺寸、陣列與設定值
values-zh-rTW/、values-zh-rCN/、values-zh-rHK/ 中文地區化資源
其他 values-<locale>/ 多國語系翻譯
xml/ IME method metadata、keyboard layout、偏好與其他 XML 設定
raw/ 原始音訊或不適合轉成一般資源的檔案
menu/、anim/、color/ 功能選單、動畫與顏色狀態資源

資源修改注意事項:

  • 保留資源名稱與引用關係,否則 Smali 中的 R 資源 ID 引用可能失效。
  • 不應隨意刪除同一資源的密度、螢幕寬度或 API 版本變體。
  • 反編譯的 res/ 可重建但不一定和原始開發專案的資源結構完全一致;大型重構前先保留完整備份並驗證 APK。

apktool/smali/

Smali 是 DEX bytecode 的文字表示,重建 APK 時由 Apktool 編譯回 DEX。這是本專案中唯一能實際修改 app 邏輯的位置。

主要命名空間包含:

路徑 內容
smali/com/asus/ime/ 輸入法 UI、控制器、XT9 wrapper、設定、佈景、剪貼簿、資料傳輸與手寫入口
smali/com/nuance/ XT9、Connect/SwypeConnect 及相關服務邏輯
smali/com/visionobjects/ MyScript/Vision Objects 手寫包裝層
smali/jp/co/omronsoft/openwnn/ OpenWnn 相關資料結構與日文輔助邏輯
smali/android/support/、smali/androidx/ 或第三方命名空間 隨 APK 打包的支援函式庫與第三方程式

smali/com/asus/ime/ 的重要類別:

類別 職責
IME.smali Android InputMethodService 主入口,管理輸入生命週期與視圖
InputMethods.smali 管理語言、輸入模式、目前 engine 與功能能力
InputView.smali、InputViewSwitcher.smali 輸入面板建立及不同視圖切換
KeyboardViewEx.smali、KeyboardEx.smali 鍵盤繪製、按鍵、觸控與版面資料
AlphaInput.smali、ChineseInput.smali、KoreanInput.smali 各語系輸入引擎的 Java/Smali facade
NativeAlphaInput.smali、NativeChineseInput.smali、NativeConfigInput.smali 對 libjni_xt9input.so 的 JNI 宣告
japanese/ 日文轉換、羅馬字與日文 XT9 wrapper
hw/ T9 Write 與 Vision Objects/MyScript 手寫流程
CandidatesListView.smali、WordListViewContainer.smali 候選字 UI 與選字處理
EmojiInputView.smali、EmojiContainerView.smali Emoji 輸入介面
clipboard/ 剪貼簿資料與 provider
settings/ 設定 Activity 與偏好處理
theme/、store/ 主題、背景與商店功能
connect/ 語言、詞典或內容下載整合
dialerapi/ 撥號器/外部手寫 API

修改 Smali 時應注意:

  • .locals、.registers、invoke 指令參數與型別必須正確。
  • Java 反編譯碼可用來理解意圖,但不能保證與 Smali 一一對應。
  • native 方法簽名、類別名稱與 package 名稱是 JNI 合約的一部分;任意重新命名會讓 native library 無法註冊或找不到方法。
  • 對 AndroidManifest.xml、res/ 或 package 名稱的修改,往往也需要同步處理 Smali 內的硬編碼字串、authority、intent action 和資源引用。

apktool/assets/

assets/ 不經 Android 資源 ID 編譯,程式以 AssetManager 或檔案路徑讀取。

apktool/assets/
├── conf/                             # XT9/MyScript 執行期設定
└── databases/                        # XT9 詞典、鍵盤、手寫與使用者資料設定

詳見後面的資料庫、詞典與手寫資料。

apktool/lib/

APK 內的 native library 依 ABI 分類。目前唯一目錄為:

apktool/lib/armeabi-v7a/
├── libjni_xt9input.so
├── libminizip.so
└── libCV-crypto.so

詳見原生函式庫與 ABI。

apktool/original/

此目錄保留原 APK 的封裝中繼資料,通常包含原始 META-INF 簽章檔案與原始 manifest 等內容。它的用途是保留解包資訊與協助重建,不代表輸出 APK 仍能維持原始簽章。

重新封裝後必須使用自己的合法 keystore 簽署;不要嘗試將原始 META-INF 簽章檔直接沿用到已修改的 APK。

apktool/unknown/

這裡存放 Apktool 無法分類、但必須以原始路徑與壓縮方式保留的檔案,例如 AIDL 或 GWT XML。除非已確認其消費端與封裝規則,否則應避免刪除或改名。

jadx/:唯讀程式碼參考

JADX 將 DEX 還原成較接近 Java 的形式,適合搜尋與理解邏輯:

jadx/
├── resources/
│   ├── AndroidManifest.xml            # Manifest 參考副本
│   ├── assets/                        # assets 參考副本
│   ├── lib/                           # native library 參考副本
│   └── res/                           # 資源參考副本
└── sources/
    ├── com/asus/ime/                  # ZenUI Keyboard 主要邏輯
    ├── com/nuance/                    # XT9/Connect 邏輯
    ├── com/visionobjects/             # MyScript/Vision Objects wrapper
    ├── jp/co/omronsoft/openwnn/       # OpenWnn 相關程式
    └── 其他第三方套件

最常用的分析起點

目的 建議先閱讀的檔案
IME 啟動與 Android 生命週期 jadx/sources/com/asus/ime/IME.java
Native engine 載入 jadx/sources/com/asus/ime/Input.java
XT9 build info 與語言列舉 jadx/sources/com/asus/ime/NativeConfigInput.java
拉丁輸入流程 AlphaInput.java、AlphaInputView.java、NativeAlphaInput.java
中文輸入流程 ChineseInput.java、ChineseInputView.java、NativeChineseInput.java
日文輸入流程 japanese/JapaneseInput.java、japanese/NativeJapaneseInput.java
T9 手寫 hw/t9/ 與 NativeWriteAlpha.java、NativeWriteChinese.java
Vision Objects 手寫 hw/vo/ 與 com/visionobjects/im/
語言/詞典設定 DatabaseConfig.java、Utils.java、connect/
鍵盤資料轉換與 native callback Input.java、XT9KeyboardDatabase.java
設定、語言切換與 UI InputMethods.java、Settings.java、settings/

JADX 輸出的限制

  • 類別、變數與泛型名稱可能不完整或由工具推測。
  • 控制流程、匿名類別、例外處理、switch 與型別轉換可能與原始碼不同。
  • 某些程式可能無法完整反編譯,或附帶 JADX 警告。
  • Java 參考碼絕不能取代實際 apktool/smali/ 的驗證。

遇到不一致時,以 Smali、DEX 行為與實機測試為準。

輸入法架構與執行流程

高階元件圖

Android Input Method Framework
            |
            v
com.asus.ime.IME (InputMethodService)
            |
            v
InputMethods / InputViewSwitcher
            |
            +--> AlphaInput / AlphaInputView -----------+
            +--> ChineseInput / ChineseInputView --------+--> Native*Input JNI facade
            +--> JapaneseInput / JapaneseInputView ------+          |
            +--> T9 Write handwriting -------------------+          v
                                                               libjni_xt9input.so (ARMv7 only)
                                                                          |
                                                                          +--> XT9 LDB/HDB/HWR assets
                                                                          +--> UDB/ASDB/DLM runtime data

            +--> Vision Objects handwriting
                         |
                         v
                    com.visionobjects.im wrapper
                         |
                         v
                    OEM/system MyScript libraries and handwriting resources

Vision Objects/MyScript 手寫是獨立 native 相依鏈,並不完全由 libjni_xt9input.so 提供。

XT9 初始化重點

Input 類別固定載入 jni_xt9input:

System.loadLibrary("jni_xt9input");

對應封裝檔為:

apktool/lib/armeabi-v7a/libjni_xt9input.so

Input.java 的 static initializer 會捕捉並忽略載入例外。這不是 fallback:若 library 載入失敗,後續第一次呼叫 native API 時仍可能以 UnsatisfiedLinkError、初始化錯誤或功能崩潰表現。修改時應避免繼續吞掉可診斷錯誤。

NativeConfigInput 在 InputMethods 建立期間查詢 build info、核心版本與可用語言,因此 XT9 library 缺失不只影響輸入候選,也可能使輸入法啟動期失敗。

JNI facade 範圍

Facade Native 功能
NativeConfigInput XT9 build info、核心版本、可用語言
NativeAlphaInput 拉丁輸入、候選、校正、手勢、UDB、ASDB、DLM
NativeChineseInput 拼音、注音、倉頡、筆畫、中文候選與詞典
japanese/NativeJapaneseInput 日文轉換、候選、羅馬字、範圍轉換
hw/t9/NativeWriteAlpha 拉丁 T9 手寫
hw/t9/NativeWriteChinese 中文 T9 手寫
com.nuance.xt9.input.* 舊式 Nuance/XT9 API 與部分中文/辨識流程

這些 JNI API 的規模很大。替換一個 native library、換用不同世代 XT9 blob 或改寫其中一個 facade,都不能只以 library 能被 System.loadLibrary 載入為驗收標準。

原生函式庫與 ABI

目前封裝的 native library

檔案 載入/用途 目前 ABI 狀態
libjni_xt9input.so XT9 主輸入 engine;拉丁、中文、日文、T9 Write、設定查詢 僅 armeabi-v7a
libminizip.so Content Vendor 壓縮檔處理 僅 armeabi-v7a
libCV-crypto.so Content Vendor 加解密;Java 同時嘗試載入 crypto 與 CV-crypto 僅 armeabi-v7a

libjni_xt9input.so 是 32 位元 ARM ELF。現有專案中沒有:

  • arm64-v8a/ native library。
  • XT9 的 C/C++ 原始碼。
  • Nuance XT9 SDK header、靜態庫或可重編譯資產。
  • Android.mk、Application.mk、CMakeLists.txt、Gradle NDK 設定。

arm64 限制

Android 64 位元程序不能載入 32 位元 ARM ELF。因此下列作法無效:

將 armeabi-v7a/libjni_xt9input.so 複製到 arm64-v8a/
只改檔名或壓縮 APK
重新簽署 APK
修改 ABI 資料夾名稱

若 APK 只帶 armeabi-v7a,它僅能在系統仍提供 32 位元 app runtime 時以 32 位元程序執行。部分 arm64 裝置仍支援這種相容模式;64-bit-only 裝置則無法執行,且不能透過 Manifest 或 target SDK 修復。

若要支援 arm64

完整功能的最低前提是取得具合法使用與再散布權的、相容版本的完整 arm64 元件組,而非單一檔案:

arm64-v8a/libjni_xt9input.so
arm64-v8a/libminizip.so
arm64-v8a/libCV-crypto.so
任何實際使用的其他 JNI library
相容的 XT9 語言/手寫資料庫
相容的 MyScript/Vision Objects arm64 相依或可接受的功能降級

候選 arm64 library 應至少驗證:

  1. 檔案為 ELF64 與 AArch64,不是將 ARMv7 blob 改名。
  2. 所有 DT_NEEDED 相依庫可在目標 Android 版本與 linker namespace 中載入。
  3. 現有 Java/Smali JNI 合約可完整註冊及呼叫。
  4. 現有 LDB/HDB/HWR、使用者詞典與設定格式相容,或有明確遷移方式。
  5. Alpha、Chinese、Japanese、T9 Write 與設定語言列舉均可實機測試。
  6. 沒有相容元件的手寫功能必須在 UI 和外部 API 層明確停用,不能等到使用時崩潰。

資料庫、詞典與手寫資料

資料目錄

apktool/assets/
├── conf/
│   ├── Engine.properties              # MyScript/Vision Objects engine 路徑設定
│   ├── LanguageManager.properties     # 手寫語言管理設定
│   ├── Recognizer.properties          # 手寫辨識設定
│   └── <locale>.lang                  # 多語系設定資料
└── databases/
    ├── config/
    │   └── databases.conf             # 語言 ID、LDB、手寫、UDB、ASDB 等映射
    ├── ldb/                           # XT9 language database
    ├── hldb/                          # 中文手寫相關 XT9 資料
    ├── hwr/                           # 手寫模板與辨識資料
    ├── kdb/                           # 鍵盤資料庫/版面相關資料(如存在)
    └── mdb/                           # OEM 補充詞庫資料(如存在)

實際可用的子目錄與檔名由原 APK 決定;重建前不應自行假設所有資料都能由替代引擎讀取。

databases.conf

apktool/assets/databases/config/databases.conf 是 XT9 資料映射的核心設定。主要 section 包含:

Section 用途
[kdb] 鍵盤資料庫映射與 layout/language ID 關係
[ldb] 語言 ID 至 XT9 language database 的映射
[hwr_dic] 手寫字典;缺少時可由 XT9 LDB 在執行期轉換
[hwr_db_template] 手寫辨識模板資料
[mdb] OEM 補充詞庫
[udb] 執行期產生的使用者詞典
[asdb] 自動替換資料庫
[cdb] 中文附加字典資料

例如繁體與簡體中文 LDB 包含:

ZHtbUNps_Big5_bpmf_pinyin_CJ_xt9.ldb
ZHsbUNps_GB18030_xt9_big.ldb

副檔名相同不等於格式相容。不同 XT9 世代、OEM 客製版本或替代引擎可能無法載入既有 .ldb、.hldb、.hdb、.bin、UDB、ASDB 或 DLM 資料。

執行期資料位置

程式會把 APK assets 的資料複製到 app 私有工作目錄,並以該目錄作為資料庫與使用者資料的實際位置。部分設定同時保留原廠 /system/usr/xt9/databases/ldb/ 路徑假設。

這表示側載環境必須測試:

  • assets 是否確實被複製到 app 私有目錄。
  • 無法讀取 /system/usr/xt9/ 時是否能使用 app 內建資料。
  • 升級、重新簽章、改 package 或清除資料後,UDB/ASDB/DLM 的行為是否符合預期。
  • 資料庫載入失敗時是否會安全降級,而非讓 IME 在啟動時崩潰。

Vision Objects/MyScript 設定

apktool/assets/conf/Engine.properties 明確記錄 Android ARMv7 平台名稱,並設定:

com.visionobjects.myscript.engine.library=/system/lib/libMyScriptEngine.so

這是原廠系統映像相依的證據。現代裝置可能改用不同分區、64 位元庫目錄、linker namespace 或完全不提供該 library。不要把此設定視為可跨裝置保證運作的公開 SDK 配置。

Android 元件與系統整合

IME 入口

輸入法服務由以下 Manifest 項目註冊:

<service
    android:name="com.asus.ime.IME"
    android:permission="android.permission.BIND_INPUT_METHOD">
    <intent-filter>
        <action android:name="android.view.InputMethod"/>
    </intent-filter>
    <meta-data android:name="android.view.im" android:resource="@xml/method"/>
</service>

修改 IME 名稱、service 類別、輸入 subtype 或 package 時,應同步檢查:

  • res/xml/method.xml 或其對應 IME metadata。
  • InputMethodManager 設定與選取流程。
  • 設定 Activity、首次啟動流程與 Launcher entry。
  • 任何指向 com.asus.ime 的硬編碼 intent、provider authority、shared preference、檔案路徑與 broadcast action。

外部與內部 API

Manifest 宣告多種對外或跨程序介面:

介面 例子 風險
Broadcast receiver 手寫、輸入裝置、佈景、資料傳輸 action exported 狀態與輸入驗證要重新檢視
Content provider 剪貼簿、佈景偏好、Facebook provider 改 package 時 authority 必須唯一且同步更新
Bound service IME、RemoteService、RemoteSettingService AIDL descriptor、permission 與外部客戶端相容性
Deep link asusime://settings、佈景頁面 package/host 路由與 exported 安全性
獨立 process :ACService、com.asus.ime.store.process 資料可見性、初始化順序、native library 載入與 crash 隔離

特別是 ApiReceiver 的手寫廣播入口,即使一般鍵盤 UI 未顯示手寫功能,外部呼叫仍可能觸發 native library 載入。因此功能降級時必須同時處理 UI 和 API 入口。

套件名稱遷移

若無法移除原廠 com.asus.ime,通常需要改用新的 package/application ID。這是高風險改動,至少涉及:

  • Manifest 根節點 package、每個 component 與相對類別名稱。
  • provider authority,例如 com.asus.ime.provider.clipboard 與 com.asus.ime.store.preference。
  • Java/Smali 中的 package、class name、反射字串與 intent action。
  • AIDL、Binder descriptor、外部 API、深層連結與分享 URI。
  • app 私有資料目錄、資料庫遷移、使用者詞典及偏好設定。
  • JNI class/method 名稱或 RegisterNatives 對應關係。

不要將 package rename 視為單純替換字串;必須在獨立分支中進行,並逐項做安裝、啟動、IME 啟用、provider、手寫和資料遷移測試。

CI 建置與輸出

工作流程檔: .github/workflows/build-apk.yml

觸發條件

事件 條件
Push main 分支或 v* tag
Pull request 目標為 main
手動執行 GitHub Actions workflow_dispatch

建置步驟

Checkout
  -> 安裝 Temurin JDK 17
  -> 安裝 Android SDK
  -> 下載最新版 Apktool
  -> apktool b apktool
  -> zipalign
  -> 產生 CI 用 debug keystore
  -> apksigner sign
  -> apksigner verify
  -> 上傳 artifact
  -> main / tag 時發布 GitHub Release

產物

檔案 用途
output/ZenUI_keyboard-unsigned.apk Apktool 原始重建結果,不能安裝
output/ZenUI_keyboard-aligned.apk 已 zipalign,尚未簽署
output/ZenUI_keyboard-signed.apk 已簽署的中間產物
output/ZenUI_keyboard.apk CI 上傳 artifact 與 Release 發布檔

CI 簽章警告

目前工作流程每次執行都建立新的 debug keystore。這代表每次 CI build 的簽章可能不同,因此:

  • 新版無法直接覆蓋舊版,除非使用相同 keystore。
  • 無法作為正式發布或長期更新機制。
  • 安裝測試版前可能需要先解除安裝舊測試版。

若需要可更新的測試或正式版本,應以安全的 GitHub Actions secret 管理固定且合法的 signing key,並設計金鑰備份、輪替、版本與發布政策。不得把私人或正式 keystore 直接提交到儲存庫。

修改指引

修改資源與文案

適用範圍:圖示、layout、字串、顏色、樣式、XML 設定。

  1. 在 apktool/res/ 找到目標資源與所有相關限定詞版本。
  2. 保留資源名稱和 XML 結構,避免破壞既有 R ID 引用。
  3. 執行 apktool b apktool。
  4. 安裝到測試裝置,至少檢查直向、橫向、不同密度與語系。

修改行為

適用範圍:輸入模式、設定、UI 邏輯、功能開關與錯誤處理。

  1. 在 jadx/sources/ 搜尋對應 Java 類別、呼叫端與資源引用。
  2. 在 apktool/smali/ 找到相同類別的實際可建置版本。
  3. 僅做最小變更,確認 register 數量、型別與控制流程。
  4. 建置、簽署、安裝後,驗證 cold start、啟用 IME、實際輸入與設定切換。
  5. 對所有 native 相關路徑,觀察 logcat 中的 UnsatisfiedLinkError、dlopen failed、SIGSEGV、SIGABRT 與 tombstone。

修改詞典或語言資料

適用範圍:LDB、HDB、HLDB、MDB 與 databases.conf。

  1. 先記錄原檔雜湊、大小、語言 ID 與來源版本。
  2. 確認目標 engine 支援該資料庫格式;檔案副檔名相同不足以證明相容。
  3. 修改 [ldb]、[hwr_dic]、[hwr_db_template] 等映射時,檢查 app 私有工作目錄與系統路徑 fallback。
  4. 測試所有受影響語言的載入、輸入、候選、使用者詞典與 process restart。

修改或移除 native 功能

適用範圍:XT9、手寫、Content Vendor、壓縮或加密功能。

  1. 先列出 System.loadLibrary、System.load、native 方法及其所有呼叫端。
  2. 在 UI、初始化流程、Broadcast API、Service 和背景任務都加入一致的 capability gate。
  3. 不要只在單一畫面隱藏按鈕;外部 receiver 或啟動期 NativeConfigInput 仍可能載入 library。
  4. 必須有明確 fallback、停用狀態或使用者可理解的錯誤訊息。
  5. 以不含該庫的測試 APK 驗證所有錯誤路徑不會崩潰。

不建議直接做的變更

  • 將 armeabi-v7a 的 .so 改放到 arm64-v8a/。
  • 以反編譯 Java 宣告推導或重建 Nuance XT9 native engine。
  • 未驗證下刪除 unknown/、original/ 或系統整合 manifest 元件。
  • 未取得相容性與授權確認就替換為其他 OEM 的同名 XT9 blob。
  • 未盤點 provider、AIDL、JNI、hard-coded package string 前直接全域取代 com.asus.ime。
  • 將 CI 自動產生的 debug signing key 視為可穩定更新的發行簽章。

已知限制與風險

1. 不是完整原始碼

反編譯結果可供研究與有限調整,但會遺失原始專案結構、註解、型別資訊、建置腳本、原始 native source、依賴版本與簽章供應鏈資訊。任何較大規模功能開發都應評估重新建立一個合法、可維護的 Android 原始碼專案。

2. 僅支援 32 位元 ARM native code

目前沒有 arm64-v8a library。64-bit-only 裝置不能使用現有 native 功能,這是二進位 ABI 問題,不是資源、Manifest 或重新簽章問題。

3. 原廠/OEM 系統相依

程式、設定與 manifest 顯示它原本是 ASUS 預載環境的一部分,可能依賴:

  • 原廠簽章與 privileged/signature permission。
  • /system/usr/xt9/ 資料庫。
  • /system/lib/libMyScriptEngine.so 與 Vision Objects shared library。
  • ASUS 系統 app、服務、property、佈景與資料傳輸協定。

因此「能重建 APK」不代表「在所有現代 Android 裝置上所有功能都可用」。

4. 簽章與 package 衝突

不同簽章的 APK 無法升級已安裝的原廠同 package app。改 package 號會避開衝突,但需要完整遷移 component、provider、資料與 JNI 相依。

5. 舊 Android target 與平台行為

來源 APK 的 targetSdkVersion=26。現代 Android 對 exported 元件、儲存空間、背景執行、隱私、網路安全、安裝來源與 IME 行為有更嚴格的要求;若目標是正式長期維護,不能只停留在重打包。

6. IME 安全性

輸入法可接觸極敏感的使用者輸入。對網路、下載、分析、第三方 SDK、剪貼簿、外部 API、使用者詞典和 crash log 的任何修改,都應以最小權限、資料最小化、離線優先與清楚告知為原則。

驗證清單

每次修改後至少確認下列項目。

建置與安裝

  • apktool b apktool 成功,沒有資源或 Smali 編譯錯誤。
  • zipalign -c -v 4 <apk> 驗證成功。
  • apksigner verify -v <apk> 驗證成功。
  • APK 可安裝於測試裝置,並已處理原廠 package/簽章衝突。
  • 冷啟動、強制停止後啟動、重新開機後啟動均正常。

IME 核心

  • 可在系統設定中啟用輸入法。
  • 可切換為目前輸入法並顯示鍵盤。
  • 英文/拉丁按鍵、Shift、Caps Lock、退格、Enter、數字、符號與 Emoji 正常。
  • 直向、橫向、窄螢幕與平板 layout 不重疊或崩潰。
  • 設定畫面、首次啟動流程與語言切換正常。

XT9 與資料

  • System.loadLibrary("jni_xt9input") 在目標 ABI 成功,或功能被安全停用。
  • Alpha 引擎可建立、開始、輸入、取得候選、完成與釋放。
  • 中文模式可載入對應 LDB,並測試拼音/注音/倉頡/筆畫中產品聲稱支援的模式。
  • 日文模式可進行羅馬字、假名與候選轉換。
  • 使用者詞典、ASDB、DLM 在 app 重啟後行為符合預期。
  • 無 /system/usr/xt9/ 或資料庫檔遺失時不崩潰。

手寫與外部 API

  • T9 Write 拉丁與中文手寫正常,或功能明確停用。
  • Vision Objects/MyScript 手寫正常,或 UI/API 均安全降級。
  • ApiReceiver 的初始化、辨識、支援清單、釋放 action 不會在 native library 缺失時崩潰。
  • 未授予 privileged permission 時,相關功能不會使 app 無法啟動。

診斷與安全

  • 檢查 logcat,沒有 UnsatisfiedLinkError、dlopen failed、SIGSEGV、SIGABRT 或 native tombstone。
  • 檢查 exported receiver/provider/service,確認不會接受未驗證的敏感輸入。
  • 在無網路情境下測試,確保下載/分析服務不阻擋本地輸入。
  • 在密碼與敏感欄位中確認候選、學習、剪貼簿與網路行為符合隱私政策。

名詞與路徑對照

名詞 本專案中的位置或含義
APK 重建來源 apktool/
Java 研究參考碼 jadx/sources/
實際可修改邏輯 apktool/smali/
Android Manifest apktool/AndroidManifest.xml
APK 解包描述 apktool/apktool.yml
Android 資源 apktool/res/
非資源原始檔 apktool/assets/
XT9 主 JNI library apktool/lib/armeabi-v7a/libjni_xt9input.so
XT9 語言資料庫 apktool/assets/databases/ldb/
XT9 資料映射 apktool/assets/databases/config/databases.conf
MyScript engine 路徑設定 apktool/assets/conf/Engine.properties
CI 工作流程 .github/workflows/build-apk.yml
主要 IME service com.asus.ime.IME
JNI 載入入口 jadx/sources/com/asus/ime/Input.java
XT9 能力查詢 jadx/sources/com/asus/ime/NativeConfigInput.java

維護原則

  1. 將 apktool/ 視為唯一可發布產物的編輯來源。
  2. 將 jadx/ 視為閱讀、搜尋與驗證假設的輔助資料。
  3. 每次變更保持小範圍,建立、簽署並在實機驗證後再繼續。
  4. 不要隱藏 native library、系統庫或權限失敗;要有可觀察的 log 與可預期的降級行為。
  5. 對 package rename、ABI 遷移、詞典格式替換、原生 blob 更新或手寫引擎替換,先做獨立可行性驗證,再進入完整實作。
  6. 對 IME 的輸入資料、詞典、剪貼簿、網路與遙測功能採取最高標準的隱私與安全審視。

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages