一个 Android 应用的绝大部分代码(使用 Java 编写)都会编译到 dex 文件中。当你使用 MT 打开一个 dex 文件时,它将会弹出打开方式菜单,你可以选择 Dex 编辑器、Dex 编辑器++、Dex 修复、翻译模式。
Dex 编辑器和 Dex 编辑器++ 均可以修改 dex 文件内的代码,两者均使用了开源项目 JesusFreke/smali 来实现,但 Dex 编辑器用的是 dexlib,已经在多年前停止了维护更新,而 Dex 编辑器++ 使用的是最新版的 dexlib2,和 smali 项目保持同步。
当你遇到某个 dex 文件无法正常打开时,你可以尝试使用 Dex 修复功能。注意必须把 dex 文件解压后才能使用该功能,不能在压缩包内进行修复。使用该功能需要开通 VIP。
翻译模式将会在后面统一进行介绍。
开发 Dex 编辑器++ 的目的就是为了取代 Dex 编辑器,虽然由于历史原因仍然在新版本中保留了后者,但还是推荐大家使用 Dex 编辑器++。
打开一个 dex 文件,选择 Dex 编辑器++,进入后可以看到浏览、最近、搜索三个标签页。
- 浏览界面采用树形方式进行包名和类的浏览
- 最近界面记录最近打开的文件和被修改过的文件
- 搜索界面可进行搜索以及显示搜索结果你可以把看到的类都当成一个个 smali 文件,点击进去之后看到的也是这个类对应的 Smali 代码。
如果你开通了 VIP,你还可以在菜单中选择将 Smali 转成 Java 代码,并且 MT 提供了多个 Java 反编译引擎,当你发现 Java 中某个方法反编译失败时,可以尝试切换反编译引擎。
注意反编译出来的 Java 代码只是用作参考,无法修改。要修改的话只能去修改 Smali 代码,然后再重新反编译成 Java 代码,对照查看修改是否正确。
做完修改后,你就可以回到编辑器主界面,点击菜单中的编译,生成新的 dex 文件。
DEX 工程
在 Dex 编辑器++ 中,MT 引入了工程这个概念。如果你是使用 Dex 编辑器,每当你修改完退出时,要么选择不保存,要么选择编译成新的 dex 文件,但不论如何,你添加的注释、哪些是新加的类、哪些类被修改了,这些记录都会丢失。
但是我们在修改 dex 文件时,一般不是一遍就能修改完的,需要多次修改和测试,保留上面所说的这些记录就十分有用,而现在,Dex 编辑器++ 都能做到这些。
创建工程
首先你要使用 Dex 编辑器++ 打开一个 dex 文件时,此时MT自动为我们创建了一个临时Dex工程。临时工程在退出后是会被删除的,所以你需要点击左上角的菜单,选择保存为工程。
保存完之后,当你在 Dex 编辑器++ 的主界面时,都可以放心地退出,不用担心丢失任何数据,更不用每次退出前还需要手动保存。
打开工程
在 MT 主界面打开侧拉栏,就可以看到你保存的所有工程了。
点击就可以打开该工程并进入 Dex 编辑器++。注意,一定要从侧拉栏中打开工程,而不是打开之前的 dex 文件,直接打开 dex 文件是创建临时工程。
编译 Dex
修改完成之后,在 Dex 编辑器++ 的主界面,点击菜单中的编译即可生成新的 dex 文件。
如果你是在临时工程中编译,那么编译后会替换掉原来的 dex 文件。
如果你是在正式工程中编译,那么编译后的 dex 文件会放在工程目录下,你需要手动把 dex 替换到 apk 中。
工程目录
所有工程均放在 内部存储/MT2/projects 文件夹中,不能移动。
侧拉栏中长按工程即可快速进入工程目录。
进入工程目录后可以看到 data 和 smali 两个文件夹。(2.5.0 版本开始支持多dex编辑,新增了 config、build 和 _dex 文件夹)
- _dex 存放编译后的dex文件
- build 存放进行编译时产生的一些文件,可提高下一次编译的速度
- conifg 存放工程配置文件,建议不要自己修改
- data 存放原dex文件和代码缓存,缓存可以提高搜索代码的速度
- smali 存放各个文件夹用于对应不同的dex,每个文件夹存放编辑过的类和自己添加的类我们还可以在工程目录中自行放其它文件,比如可以放apk文件,以方便打包dex。
删除和重命名
所有工程均放在 内部存储/MT2/projects 文件夹中,首先你要进入这个文件夹(可以先快速进入一个工程目录,再返回上级),如果你要删除工程,那么就删掉和工程名字一样的文件夹,同理如果你要重命名工程,那么就重命名对应的文件夹。
类名问题
初始化时,每个类都是根据它的类名和包名进行存放,当我们在 smali 代码中修改了一个类的类名或包名时,它的位置和名称并不会改变,实际还是以 smali 代码中的定义为准。
举个例子,浏览界面中打开 com/android/example 中的 ClassA,在 smali 第一行定义了它的完整类名 Lcom/android/example/ClassA;,将它改成 Lcom/android/ClassB; 并保存后,你可能以为它会移动到 com/android 中,并且名称变成 ClassB,其实不会,你依旧需要在 com/android/example 中的 ClassA 打开它。
总的来说,smali 的文件名不需要与该文件中定义的类名一样,smali 文件所在的目录不需要与该文件中定义的包名对应,一切以 smali 文件内容中的定义为准。
搜索功能
Dex编辑器++支持搜索代码、类名、方法名、字段名、字符串、整数,可指定搜索路径、是否搜索子目录、是否区分大小写,支持正则表达式,支持在当前搜索结果中搜索,支持撤销搜索。
发起搜索的方式有两种,一是切换到搜索界面,直接点击对应选项,二是在浏览界面长按文件夹,点击弹出菜单中的搜索。
搜索字符串和代码的区别
字符串包含于代码。代码就是 smali 代码,而字符串是 smali 代码中的 “xxxxxx”,即引号中的那部分内容。
常见问题
如何添加外部 smali 文件到工程中?
进入工程目录,打开 smali 文件夹,进入某个dex对应的文件夹,把你要添加的 smali 文件复制进去,再次打开工程即可看到添加的文件。
怎么修改 Java 代码?
反编译出来的 Java 代码只是用作参考,无法修改。要修改的话只能去修改 Smali 代码,然后再重新反编译成 Java 代码,对照查看修改是否正确。
怎么快速跳转到另一个类?
在编辑 smali 代码时,完整选中一个类名,类名以 L 开头 ; 结尾,例如 Lcom/aaa/bbb/ccc;,然后你就可以在弹出菜单中看到跳转,点击后,如果该类存在于当前 dex,就可以直接跳转到它到 smali 代码中。
字符常量池功能在哪?
暂时没有该功能,如果需要请使用旧版 Dex 编辑器。
如何往现有工程添加新的dex
MT管理器从2.5.0开始支持多dex编辑,如果要往现有工程添加新的dex,只需将欲添加的文件重命名去掉 “.dex” 后缀,然后复制到 “工程目录/data/dex” 文件夹内。