操作步骤
1.设备 xiaomi 8SE 已root , Android 9.0通过解BL锁刷机
2.安装需要用到的工具,Xposed 不支持 Android 9.0,借助Magisk安装EdXposed
2.1下载TWRP app
2.2下载 twrp img (需要根据设备型号来选择,我的是 xiaomi 8 SE xmsirius)
2.3安装twrp app后授权root,选择TWRP flash 选择下载好的img 刷机
3.安装magisk app
选择最新的release包目前是25.2(2022-10-05)
打开magisk 授权root 查看“Ramdisk 是” 必须为是 ,点击安装 ->直接安装
安装完后会在主页提示 卸载magisk
4.下载 riru 插件选择版本23
magisk-> 模块 本地安装 选择下载的文件,安装完成后重启手机
5.下载 EdXposedManager apk安装apk.
安装完成后即可创建xposed模块项目
6.下载ZjDroid project
原版没有维护,没有兼容art虚拟机因此无法使用,下载魔改版本
7.编译ZjDroid项目
mac OS Android studio(2021.2.1) 添加ndk-build命令 Preferences->Tools->External Tools -> add
name: ndk-build
program:$ModuleSdkPath$/ndk/21.4.7075529/build/ndk-build
Working directory:$ProjectFileDir$/app/src/main/jni
21.4.7075529
为你安装的ndk版本
可能需要在elfinfo.cpp中加入依赖以免报错:
#include <string.h>
在jni
文件夹上点击右键 选择 external tools->ndk-build
编译生成so库,编译完成后引入.
sourceSets {
main() {
jniLibs.srcDirs = ['src/main/libs']
jni.srcDirs = []
}
}
// 下面这个配置对于我的环境无效,所以替换为先打so包再引入进来
// externalNativeBuild {
// ndkBuild {
// path 'src/main/jni/Android.mk'
// }
// }
编译成功后安装app,可能会遇到其他错误,需要根据实际情况修改.
最后在 EdXposedManager中启用模块并重启设备
8.dump 运行中app的dex文件
8.1先创建一个简单的app作为被dump app,简单起见没有对该应用做加固处理.
8.2打开app后使用adb获取pid
adb shell dumpsys activity top |grep packageName
可以另外起一个终端查看日志
adb shell
logcat -s zidroid-shell-packageName
8.3根据日志获取的pid获取mCookie信息
am broadcast -a com.zjdroid.invoke --ei target **pid** --es cmd '{action:dump_dexinfo}'
这里不知道是否因为root的原因,可以看到非常多的系统app的mCookie信息,查看ZjDroid源码
com.android.reverse.collecter.DexFileInfoCollecter
private static HashMap<Long, DexFileInfo> dynLoadedDexInfo = new HashMap<Long, DexFileInfo>();
public HashMap<Long, DexFileInfo> dumpDexFileInfo() {
HashMap<Long, DexFileInfo> dexs = new HashMap<Long, DexFileInfo>(dynLoadedDexInfo);
...
}
发现是dynLoadedDexInfo
赋值了所有系统app信息,修改:
HashMap<Long, DexFileInfo> dexs = new HashMap<Long, DexFileInfo>();
修改后重新编译安装ZjDroid app,再次执行dump_dexinfo,可以看到只有目标app的mCookie信息列表了.
8.4执行dump dex文件
根据获取的mCookie列表执行dump dex
am broadcast -a com.zjdroid.invoke --ei target **pid** --es cmd '{"action":"dump_dexfile","mCookie":" mCookieValue"}'
这里需要说明必须先进入adb shell 才能发送上面的广播命令,否则无法接收到该广播.
之后会发现报错:
java.io.FileNotFoundException: /data/user/0/com.miui.catcherpatch/xm_code_cache/xm_secondary-sos/libdvmnative.so (Permission denied)
看源码,libdvmnative.so会被拷贝到一个临时文件夹中但是这个文件夹被指向了com.miui.catcherpatch
,看日志是因为在目标app开启后·com.miui.catcherpatch
这个app触发了
com.android.reverse.mod.ReverseXposedModule
@Override
public void handleLoadPackage(LoadPackageParam lpparam) throws Throwable {
APPINFO_DATA_DIR = lpparam.appInfo.dataDir;
...
}
之后APPINFO_DATA_DIR
就指向了com.miui.catcherpatch
.
修改移动到当前app的判断逻辑中:
else if (lpparam.isFirstApplication && !ZJDROID_PACKAGENAME.equals(lpparam.packageName)) {
XMMultiDex.install(ReverseXposedModule.class.getClassLoader(),MODULE_PATH,lpparam.appInfo);
APPINFO_DATA_DIR = lpparam.appInfo.dataDir;
...
}
这样只有目标app第一次运行的时候APPINFO_DATA_DIR
才会赋值.
再次编译执行,这次能够正常打印出将dex文件保存的log了.
the dexfile data save to =/data/user/0/packageName/files/dexdump506910917696.odex
8.5解析dex转为jar包
使用IDA打开odex文件,会发现Magic number是cdex.001,在安卓9中为了减少内存的使用量,引入了cdex,这导致我们dump出来的dex不是一个正常的Dex结构,无法被jadx等反编译。
这里就需要我们将app删除重新安装,第一次安装运行的时候还没有优化为cdex格式(旧版本优化为odex格式),再次dump dex 查看Magic number显示为64 65 78 0A 30 33 37 00 (dex.037)
.
尝试用d2j-dex2jar转jar包
./d2j-dex2jar.sh dexdump.odex
报错
提示 com.googlecode.d2j.DexException: not support version.
原因是在源码中会判断版本号是否大于53,然后抛出异常.
使用IDA打开文件将Magic number version 改为53
64 65 78 0A 30 33 35 00 (dex.035)
操作路径
1.Edit->Patch program-> change byte
2.Edit->Patch program-> Apply patches to input file
保存文件后再次转jar成功了.