脱壳原理
通过Hook ClassLoader的loadClass方法,反射调用getDex方法取得Dex(com.android.dex.Dex类对象),在将里面的dex写出。
云盘下载提取码: kdst
支持模块
需VirtualXposed或者Xposed才能用,不在叙述怎么安装,具体得自己找资料
VirtualXposed:https://vxposed.com/
Xposed:https://repo.xposed.info/
实践实践
我这里安装得是Android4.4 Xposed
因为VirtualXposed不支持X86,就是不支持模拟器。穷屌丝我没钱
打开Xposed得模块

开启FDex2

打开FDex2要进行脱壳得软件

之后在脱壳软件得data/data/软件目录下把DEX拷贝出来

脱出得DEX效果如下;

灰常不错。。。
FDex2核心代码MainHook
- package com.ppma.xposed;
 -  
 - import java.io.File;
 - import java.io.FileOutputStream;
 - import java.io.IOException;
 - import java.io.OutputStream;
 - import java.lang.reflect.Method;
 -  
 - import de.robv.android.xposed.IXposedHookLoadPackage;
 - import de.robv.android.xposed.XC_MethodHook;
 - import de.robv.android.xposed.XSharedPreferences;
 - import de.robv.android.xposed.XposedBridge;
 - import de.robv.android.xposed.XposedHelpers;
 - import de.robv.android.xposed.callbacks.XC_LoadPackage;
 -  
 - public class MainHook implements IXposedHookLoadPackage {
 -  
 -     XSharedPreferences xsp;
 -     Class Dex;
 -     Method Dex_getBytes;
 -     Method getDex;
 -     String packagename;
 -  
 -  
 -         xsp = new XSharedPreferences("com.ppma.appinfo", "User");
 -         xsp.makeWorldReadable();
 -         xsp.reload();
 -         initRefect();
 -         packagename = xsp.getString("packagename", null);
 -         XposedBridge.log("设定包名:"+packagename);
 -         if ((!lpparam.packageName.equals(packagename))||packagename==null) {
 -             XposedBridge.log("当前程序包名与设定不一致或者包名为空");
 -             return;
 -         }
 -         XposedBridge.log("目标包名:"+lpparam.packageName);
 -  
 -                 super.afterHookedMethod(param);
 -                 Class cls = (Class) param.getResult();
 -                 if (cls == null) {
 -                     //XposedBridge.log("cls == null");
 -                     return;
 -                 }
 -                 XposedBridge.log("当前类名:" + name);
 -                 if (bArr == null) {
 -                     XposedBridge.log("数据为空:返回");
 -                     return;
 -                 }
 -                 XposedBridge.log("开始写数据");
 -                 XposedBridge.log(dex_path);
 -                 if (file.exists()) return;
 -                 writeByte(bArr, file.getAbsolutePath());
 -             }
 -             } );
 -     }
 -  
 -     public void initRefect() {
 -         try {
 -             Dex = Class.forName("com.android.dex.Dex");
 -             Dex_getBytes = Dex.getDeclaredMethod("getBytes", new Class[0]);
 -             getDex = Class.forName("java.lang.Class").getDeclaredMethod("getDex", new Class[0]);
 -             e.printStackTrace();
 -             e.printStackTrace();
 -         }
 -  
 -     }
 -  
 -         try {
 -             outputStream.write(bArr);
 -             outputStream.close();
 -             e.printStackTrace();
 -             XposedBridge.log("文件写出失败");
 -         }
 -     }
 - }
 
参考链接