• Android APK脱壳--腾讯乐固、360加固一键脱壳



    另外,参考电子书 https://crifan.github.io/android_app_security_crack/website/


    编码前线关注

    112018.09.28 17:22:18字数 478阅读 86,192

    概述

    现在使用Proguard进行混淆的代码,也很容易被破解,所以就出现了加固工具,让反编译的难度更大。但是有了加固技术,就会有反加固技术,正所谓道高一尺魔高一丈。

    经过加固后的apk,通过dex2jar反编译:

    腾讯乐固:

    legu.png

    360加固:

    360jiagu.png

    从上面可以看出,经过加固后的apk,通过常规方法反编译无法获取到源码。

    下载工具
    脱壳工具FDex2

    通过Hook ClassLoader的loadClass方法,反射调用getDex方法取得Dex(com.android.dex.Dex类对象),在将里面的dex写出。

    下载地址:

    链接:https://pan.baidu.com/s/1smxtinr 密码:dk4v

    VirtualXposed

    VirtualXposed:无需root手机即可使用xp框架。

    下载地址:

    https://vxposed.com/

    脱壳

    Step1:

    VirtualXposedFDex2需要脱壳的应用都安装到手机上。

    Step2:

    启动VirtualXposed,并在VirtualXposed中安装FDex2:

    vp-install-fdex2.gif

    Step3:

    VirtualXposed中激活FDex2:

    active-fdex2.gif

    Step4:

    VirtualXposed中安装要脱壳的应用,方法和Step2一样。

    Step5:

    启动VirtualXposed中的FDex2,并配置要脱壳的应用。

    fdex2-config.png

    Step6:

    VirtualXposed中运行要脱壳的应用。

    Step7:

    脱壳后的dex文件:

    shelling-dex.png

    导出脱壳的dex文件:

    root设备:

    adb root
    adb pull /data/user/0/iv.va.exposed/virtual/data/user/0/{packageName}   {电脑上的目录}
    

    未root设备:

    VirtualXposed中,设置-->高级设置-->文件管理,安装文件管理器,然后通过文件管理器进入到指定的目录,通过分享功能发到电脑上。

    Step8:

    通过dex2jar对 脱壳的dex进行反编译:

    shelling-dex2jar.png

    从上图就可以看到脱壳后的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;
     
     
        public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) throws Throwable {
            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);
            String str = "java.lang.ClassLoader";
            String str2 = "loadClass";
     
            XposedHelpers.findAndHookMethod(str, lpparam.classLoader, str2, String.class, Boolean.TYPE, new XC_MethodHook() {
                protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                    super.afterHookedMethod(param);
                    Class cls = (Class) param.getResult();
                    if (cls == null) {
                        //XposedBridge.log("cls == null");
                        return;
                    }
                    String name = cls.getName();
                    XposedBridge.log("当前类名:" + name);
                    byte[] bArr = (byte[]) Dex_getBytes.invoke(getDex.invoke(cls, new Object[0]), new Object[0]);
                    if (bArr == null) {
                        XposedBridge.log("数据为空:返回");
                        return;
                    }
                    XposedBridge.log("开始写数据");
                    String dex_path = "/data/data/" + packagename + "/" + packagename + "_" + bArr.length + ".dex";
                    XposedBridge.log(dex_path);
                    File file = new File(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]);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            }
     
        }
     
        public  void writeByte(byte[] bArr, String str) {
            try {
                OutputStream outputStream = new FileOutputStream(str);
                outputStream.write(bArr);
                outputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
                XposedBridge.log("文件写出失败");
            }
        }
    }
    
    参考链接
    1. 【手机端】腾讯乐固,360加固一键脱壳
    2. 安卓xposed脱壳工具FDex2
  • 相关阅读:
    电商项目(上)
    Java开发快速上手
    iOS 总结网页常用的东西
    osstatus -9801 workerman websocket 小程序不带端口
    ListView+EditText使用遇到的坑
    关于微信浏览器不支持offset()的兼容性处理
    关于TS返回 Can't use function return value in write context 问题
    tableView刷新中的问题
    解决 ecshop 搜索特殊字符关键字(如:*,+,/)导致搜索结果乱码问题
    新用户注册用户名可以被修改导致其他平台出现相关问题
  • 原文地址:https://www.cnblogs.com/cute/p/13322484.html
Copyright © 2020-2023  润新知