☰
三星闭源ROM修改系统APK:odex合并与汉化实战指南
2026/10/28 2:58:20 网站建设 项目流程

简介:这份文档面向需要深度定制Android系统应用的进阶用户与ROM爱好者,聚焦三星等闭源系统下APK与ODEX合并这一相对复杂的操作场景,帮助读者在有限环境中完成系统应用的修改、汉化与重新打包。资源包共1个docx文件,约23KB,以图文步骤与命令说明的形式组织内容,便于对照操作。目前已有334人学习下载。文档围绕工具准备、系统应用提取、反编译与打包、签名替换及汉化修改等环节展开,结合三星I9000自定义framework等实际案例,给出apk manager脚本选项、keep目录处理、语言包增删与报错排查等具体思路,读者可据此理解系统应用定制的完整流程,掌握资源替换与汉化布局修改的实用方法,并规避常见打包错误。

1. 三星闭源 ROM 里改一个系统 APK,为什么绕不开 odex 合并

手里有一台老三星,系统是 FROYO,想改个 Launcher 的图标、汉化几个菜单,结果 apktool 一反编译就报错,或者改完推回去直接无限重启——这是很多人在折腾三星闭源 ROM 时遇到的第一道墙。墙的根源不在 apktool,而在于三星把系统应用拆成了xxx.apk加xxx.odex两份:apk 里只剩资源和一张空壳classes.dex,真正的 Dalvik 字节码被抽到 odex 里做了预优化。你反编译 apk 拿到的 smali 是不完整的,改资源能过,动代码就翻车。这篇笔记就围绕「apk 和 odex 合并」这条主线,把从提取系统应用、反编译、改资源、迂回打包到 smali 层合并 odex 的完整链路拆一遍,顺带讲清楚twframework-res.apk这个三星特有的坑。适合已经会刷机、想深入改系统应用但被闭源框架卡住的人,新手照着步骤也能走通资源汉化那一段。

2. 动手前的环境与工具链:apktool、apk manager 与三星 framework

2.1 工具选型:为什么老机器上 apk manager 比纯 apktool 顺手

这个年代的活,工具链其实就三样:JDK、Android SDK 里的 adb、以及 apktool 或 apk manager。apktool 是底层,负责真正的反编译和回编译;apk manager 4.9 本质是一层批处理脚本,把 apktool、adb、签名、zip 操作串成一个菜单。我推荐先用 apk manager,不是因为它强,而是因为它把「反编译 → 改 → 回编译 → 保留原始文件 → 生成未签名包」这条链路固化了,少记一堆命令行参数。纯 apktool 当然也能干,但每次都要手动处理-p框架目录、手动决定哪些文件回填,容易漏。

环境上要注意两点。第一,JDK 版本别太新,老版本 apktool 对高版本 JDK 的兼容性一般,报Unsupported class file major version这类错基本就是 JDK 太新。第二,adb 必须在 PATH 里,apk manager 的script.bat启动时会检测 adb,检测不到就直接退出,很多人卡在这一步以为是脚本坏了。检测不到就把 adb 可执行文件拷到 apk manager 主目录,脚本会优先用同目录的。

# 确认环境三件套是否就位 java -version adb version # apk manager 主目录下执行(Windows) script.bat

java -version看的是运行时版本,不是编译器版本,输出里带1.6、1.7这类老版本号是正常的。adb version能出版本号说明 PATH 配好了。script.bat跑起来后如果直接闪退,九成是 adb 没找到,按上面说的把 adb 拷进主目录再试。

2.2 提取系统应用:adb pull 与挂载 factoryfs 两条路

改之前得先把目标 apk 拿到电脑上。两条路:机器已经 root 并正常开机,直接adb pull;手上只有官方刷机包,就解包挂载factoryfs.rfs把整个/system拷出来。前者快,后者干净,适合批量提取。

# 路线一:机器已 root,直接拉整个 system 目录 adb pull /system/ ./system_dump/ # 路线二:只有官方包,Linux 下挂载 factoryfs 镜像 mkdir -p ./factoryfs_mnt mount -o loop,rw factoryfs.rfs ./factoryfs_mnt cp -a ./factoryfs_mnt/app ./system_dump_app/

adb pull /system/会把整个 system 拉下来,几百 MB,慢但省事;只想拿单个应用就adb pull /system/app/TouchWiz30Launcher.apk。挂载那条路里-o loop是把镜像文件当块设备挂,rw表示可读写,其实只读拷贝的话用ro更安全,避免误写污染原始镜像。拷完记得umount,不然镜像文件一直被占用。

2.3 三星 framework 的特殊性:twframework-res.apk 必须先装

这是三星闭源系统最容易被忽略的一步。AOSP 机器反编译系统应用,装一个framework-res.apk当框架就够了;三星在framework-res.apk之外还叠了一层twframework-res.apk,位置在/system/framework/。系统应用里大量资源引用指向 twframework,你不装它,反编译时资源 ID 解析不出来,回编译必报资源找不到。

# 先装三星自己的框架,再装标准框架(顺序别反) apktool if twframework-res.apk apktool if framework-res.apk

apktool if的if是 install-framework 的缩写,把 apk 里的resources.arsc注册到本地框架缓存,后续反编译就能按 ID 查到资源。顺序上先 twframework 后 framework 更稳,因为 twframework 依赖标准 framework 的部分资源。用 apk manager 的话,它内部也是调 apktool,但框架安装要你自己在命令行先做一遍,脚本不会替你装。

3. 反编译与迂回打包:不改签名把 APK 推回 /system/app

3.1 反编译与回编译:apk manager 的 9 和 11 两个入口

apk manager 的菜单很长,真正天天用的就两个:9 是 Decompile,11 是 Compile。把目标 apk 丢进place-apk-here-for-modding目录,跑script.bat,选 9,反编译结果输出到projects/下同名目录。改完再选 11 回编译。

9 Decompile apk -> 输出到 projects/<apk名>/ 11 Compile apk -> 回编译,产物在 place-apk-here-for-modding/

反编译后目录结构里,res/是资源,smali/是反编译出来的字节码(如果 apk 里有 dex),AndroidManifest.xml是解码后的明文清单。这里有个关键认知:如果目标 apk 是 odex 化的,smali/目录要么不存在要么只有空壳,因为真正的代码在 odex 里。所以第 3 章这套流程只适合改资源、改布局、汉化;要动代码逻辑,得跳到第 5 章的 smali 合并。

3.2 系统应用的迂回打包:keep 目录与 resources.arsc 的处理

三星的系统应用你拿不到它的签名,重新签名后推回/system/app会因为签名不一致装不上或者起不来。所以正确姿势不是「签一个新包」,而是「把改过的文件塞回原始 apk 的壳里」,签名保持原样。apk manager 的 11 号编译流程里专门为这个场景留了口子。

11 Compile apk -> 提示是否系统文件,选 y -> 提示是否复制原始文件,选 y -> 提示按任意键继续,此时不要按键 -> 进入 keep/ 目录,按修改内容删除对应旧文件 -> 回到窗口按任意键 -> 生成 unsigner 前缀的新 apk

keep/目录里放的是从原始 apk 里抽出来的、回编译时会被原样打回去的文件。这里就是最容易翻车的地方:你改了res/values-zh-rCN/strings.xml,但keep/里还留着旧的resources.arsc,打包时旧 arsc 会覆盖你新编出来的资源表,结果推回去发现汉化没生效。所以规则是——改了 values 语言包,就去keep/删掉resources.arsc;改了 layout 或 xml 目录下的文件,就删掉keep/里对应的旧 xml。删对了,新编的才会进包。

3.3 回填与推送:用原始 apk 当壳,adb push 后重启

编译产物是带unsigner前缀的 apk,它没签名,不能直接装。做法是用压缩软件同时打开这个未签名包和原始 apk,把未签名包里你改过的文件拖进原始 apk 覆盖,保存。这样壳还是原厂的,签名没动,系统认。

# 回填后推回系统分区 adb push modified.apk /system/app/TouchWiz30Launcher.apk adb shell chmod 644 /system/app/TouchWiz30Launcher.apk adb reboot

chmod 644别省,push 上去的文件权限可能不对,权限错了系统应用起不来,表现就是桌面空白或者反复重启。推之前最好adb shell mount -o rw,remount /system把 system 分区挂成可写,不然 push 会报 read-only。重启后如果直接 FC 或者卡开机,进 recovery 用备份还原,所以动手前把原始 apk 备份一份是硬性习惯。

4. 汉化与资源裁剪:values 语言包、framework 与 twframework 的边界

4.1 语言包结构:values-xx 与 values-hdpi 不是一回事

反编译后res/下会看到一堆values-开头的目录,新手容易一刀切全删。要分清两类:values-en-rUS、values-it、values-zh-rCN这类是语言包,可以删可以加;values-hdpi、values-land、values-port这类是分辨率或屏幕方向限定资源,删了会缺资源导致编译失败或运行异常。汉化的标准动作是建一个values-zh-rCN,把values/下的strings.xml和arrays.xml拷进去翻译。

<!-- res/values-zh-rCN/strings.xml 片段 --> <string name="launcher">主屏幕</string> <string name="menu_settings">设置</string> <!-- arrays.xml 里带 _values 后缀的数组不要翻译 --> <string-array name="pref_values"> <item>0</item> <item>1</item> </string-array>

strings.xml里name是资源键,标签之间的文本才是要翻译的显示内容,别把name改了。arrays.xml里名字带_values的数组通常是程序内部用的枚举值,翻译了会导致逻辑判断失效,只翻名字不带_values的显示数组。一个应用汉化这两个文件基本够用,framework-res.apk另说。

4.2 删语言包报错:读 log、改 public.xml 的正确姿势

想只保留英简繁三语、把其他语言包删掉,回编译大概率报错。原因是被删语言包里有些 string 是该语言独享的,values/strings.xml里没有对应条目,资源表对不上就报resource not found。正确做法不是把语言包加回来,而是看 log 定位。

# apk manager 主目录下的 log 会给出类似信息 public.xml:1234: error: resource ... not found

打开res/values/public.xml,按 log 里的行号找到那条资源声明删掉。注意删的时候保留行号占位(比如留空行或注释),否则后面所有行号错位,log 里的行号就对不上了,越删越乱。删完重新编译,还报就再读 log 再删,循环到干净为止。这套流程的核心不是「猜为什么报错」,而是「读 log 按行号精确删」,不看 log 硬试的人基本会在这一步耗掉一晚上。

4.3 framework-res 与 twframework-res:语言选项与图片资源的两个层级

framework-res.apk里的语言包种类,基本决定了设置里语言切换列表能显示哪些选项。裁剪时删raw-xx只留raw、raw-zh-rCN、raw-zh-rTW;删values-xx和values-mcc数字-xx,但保留values-land、values-port、values-hdpi和中文相关目录。没有中文包就自己建,从values/拷过来翻译,里面的地图相关参数改成中国区域,参照其他中文 ROM 的写法。

twframework-res.apk是三星叠的那层,本质也是 apk,能反编译,但里面主要是图片资源、菜单和按钮样式,不能随意删。改它的方法和普通 apk 一样,但因为它被大量系统应用引用,改错一个资源 ID 影响面比改单个应用大得多。我的习惯是改 twframework 之前先做一个 recovery 刷机包备份,改完推回去重启,不 FC 再继续下一步,FC 就进 recovery 还原,小步快跑。

5. 合并 odex:baksmali/smali 拆解与 BOOTCLASSPATH 补齐

5.1 为什么合并 odex 只有 smali 一条路

odex 是 apk 里classes.dex经过预优化后的产物,格式和标准 dex 不同,直接反编译工具读不了。目前能走通的路只有一条:用 baksmali 把 odex 反汇编成 smali,再用 smali 把 smali 汇编回标准classes.dex,然后把这个 dex 塞回 apk,删掉 odex,系统启动时会重新做优化。所谓各种「一键合并工具」,底层都是这两条命令的批处理封装。

# odex 反汇编成 smali,输出到 out 目录 java -jar baksmali.jar -x TargetApp.odex # smali 汇编回标准 dex java -Xmx512M -jar smali.jar out -o classes.dex

-x是反汇编 odex 的开关,不加它 baksmali 会当成普通 dex 处理然后报错。-Xmx512M给 JVM 512MB 堆,大应用 smali 文件多,堆小了会 OOM。产物classes.dex就是标准格式,可以塞进 apk 的根目录替换原来的空壳 dex。

5.2 BOOTCLASSPATH:AOSP 五个 jar 与三星额外六个 jar

baksmali 反汇编 odex 时需要知道它依赖哪些框架类,这些依赖由 BOOTCLASSPATH 定义。AOSP 标准是五个:core.jar、ext.jar、framework.jar、android.policy.jar、services.jar。三星定制 ROM 在这之外还加了com.samsung.device.jar、seccamera.jar、sechardware.jar、twframework.jar、javax.obex.jar、com.google.android.maps.jar。少给一个,反汇编时就会报类找不到。

# 把这些 jar 从机器上拉下来,丢到 smali 工作目录 adb pull /system/framework/core.jar . adb pull /system/framework/framework.jar . adb pull /system/framework/twframework.jar . # ... 其余 jar 同理 # 反汇编时通过 -d 指定框架目录(baksmali 会按 BOOTCLASSPATH 找) java -jar baksmali.jar -x -d ./framework_jars TargetApp.odex

-d指向存放这些 jar 的目录,baksmali 会按内部约定的 BOOTCLASSPATH 顺序去里面找。三星机器上这步最容易漏twframework.jar,漏了就会在反汇编到引用三星私有类的 smali 时报错。判断方法很简单:报错里出现com.samsung开头的类找不到,就是 twframework 没给。

5.3 合并后的回填与验证:dex 塞回 apk、删 odex、重启观察

拿到classes.dex后,用压缩软件打开原始 apk,把 dex 拖进去覆盖(如果 apk 里原本没有 dex 就直接加),保存。然后把 apk 推回/system/app,同时把对应的.odex删掉或改名备份,重启让系统重新优化。

adb shell mount -o rw,remount /system adb push TargetApp.apk /system/app/TargetApp.apk adb shell rm /system/app/TargetApp.odex adb shell chmod 644 /system/app/TargetApp.apk adb reboot

删 odex 是关键一步,不删的话系统可能继续用旧 odex,你的新 dex 不生效。重启后观察目标应用能否正常启动,能起说明合并成功;起不来就adb logcat看是不是ClassNotFoundException或VerifyError,前者多半是 BOOTCLASSPATH 漏 jar 导致 smali 不完整,后者多半是 smali 汇编时版本不匹配。这套流程没有后悔药,改之前把 apk 和 odex 都备份到电脑上。

6. 避坑清单:五条血泪记录与一个验证习惯

6.1 现象:回编译报资源找不到,删了语言包就炸

原因是被删语言包里有独享 string,values/strings.xml没有对应条目,资源表对不上。解决是读 apk manager 主目录的 log,按行号去public.xml精确删对应声明,删时保留行号占位避免错位,循环到编译通过。别靠猜,log 里写得很清楚。

6.2 现象:汉化推回去没生效,菜单还是英文

原因是keep/目录里旧的resources.arsc覆盖了新编的资源表。解决是改 values 语言包后,进keep/删掉resources.arsc再打包;改 layout 或 xml 同理删对应旧文件。这条坑我踩过不止一次,本质是没理解 keep 目录的「原样回填」语义。

6.3 现象:push 上去重启后桌面空白或无限重启

原因通常是文件权限不对,或者 system 分区没挂可写导致 push 实际失败但没报错。解决是 push 前mount -o rw,remount /system,push 后chmod 644,重启前ls -l确认文件在、权限对。另外签名被破坏也会这样,回填时务必用原始 apk 当壳,别用重新签名的包。

6.4 现象:baksmali 反汇编 odex 报类找不到

原因是 BOOTCLASSPATH 不全,三星机器最常见是漏了twframework.jar或com.samsung.device.jar。解决是把/system/framework/下所有相关 jar 拉到本地,用-d指过去,报错里出现哪个包名就补哪个 jar。AOSP 五个加三星六个,一个都不能少。

6.5 现象:合并 dex 后应用能起但功能异常

原因是 smali 反汇编再汇编过程中,某些优化信息丢失或版本不匹配,导致运行时校验失败。解决是先确认 baksmali 和 smali 是同一版本配套的 jar,别混用;再adb logcat看具体异常类型,VerifyError基本是版本问题,换配套版本重来。这类问题没有通用修法,只能靠 log 定位。

6.6 一个验证习惯:改 framework 前先做 recovery 备份包

改framework-res.apk或twframework-res.apk这种全局资源,影响面大,FC 了可能连桌面都进不去。我的习惯是每次改之前,把原始文件打成一个能刷的 recovery 包放手机里,改完推回去重启,不 FC 再继续;FC 就进 recovery 刷回备份,再改再测。这个习惯救过我很多次,尤其是汉化 framework 那种要反复试错的长活。从那以后我每次动系统框架文件,都强制先走一遍备份再动手,希望这个习惯也能帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询