• Android DEX加壳


    此文的源码测试过,除了下面这个问题之外,基本没有什么大问题:

    package com.android.dexunshell;
    
    import java.io.IOException;
    import java.net.URL;
    import java.util.Enumeration;
    
    import com.eebbk.mingming.k7utils.ReflectUtils;
    
    import android.content.Context;
    import android.util.Log;
    import android.view.LayoutInflater;
    
    import dalvik.system.DexClassLoader;
    import dalvik.system.DexFile;
    
    public class DynamicDexClassLoder extends DexClassLoader {
         private static final String TAG = DynamicDexClassLoder.class.getName();
         private int cookie;
         private Context mContext;
    
         /**
          * 原构造
          *
          * @param dexPath
          * @param optimizedDirectory
          * @param libraryPath
          * @param parent
          */
         public DynamicDexClassLoder(String dexPath, String optimizedDirectory,
                            String libraryPath, ClassLoader parent) {
                   super(dexPath, optimizedDirectory, libraryPath, parent);
         }
    
         /**
          * 直接从内存加载 新构造
          *
          * @param dexBytes
          * @param libraryPath
          * @param parent
          * @throws Exception
          */
    
         public DynamicDexClassLoder(Context context, byte[] dexBytes,
                            String libraryPath, ClassLoader parent, String oriPath,
                            String fakePath) {
                   super(oriPath, fakePath, libraryPath, parent);
                   setContext(context);
                   setCookie(NativeTool.loadDex(dexBytes, dexBytes.length));
         }
    
         private void setCookie(int kie) {
                   cookie = kie;
         }
    
         private void setContext(Context context) {
                   mContext = context;
         }
    
         private String[] getClassNameList(int cookie) {
                   return (String[]) ReflectUtils.invokeStaticMethod(DexFile.class,
                                     "getClassNameList", new Class[] { int.class },
                                     new Object[] { cookie });
         }
    
         private Class defineClass(String name, ClassLoader loader, int cookie) {
                   return (Class) ReflectUtils.invokeStaticMethod(DexFile.class,
                                     "defineClass", new Class[] { String.class, ClassLoader.class,
                                                        int.class }, new Object[] { name, loader, cookie });
         }
    
         @Override
         protected Class<?> findClass(String name) throws ClassNotFoundException {
                   Log.d(TAG, "findClass-" + name);
                   Class<?> cls = null;
    
                   String as[] = getClassNameList(cookie);
                   for (int z = 0; z < as.length; z++) {
                            if (as[z].equals(name)) {
                                     cls = defineClass(as[z].replace('.', '/'),
                                                        mContext.getClassLoader(), cookie);
                                     break;
                            } else {
                                     defineClass(as[z].replace('.', '/'), mContext.getClassLoader(),
                                                        cookie);
                            }
                   }
    
                   if (null == cls) {
                            cls = super.findClass(name);
                   }
    
                   return cls;
         }
    
         @Override
         protected URL findResource(String name) {
                   Log.d(TAG, "findResource-" + name);
                   return super.findResource(name);
         }
    
         @Override
         protected Enumeration<URL> findResources(String name) {
                   Log.d(TAG, "findResources ssss-" + name);
                   return super.findResources(name);
         }
    
         @Override
         protected synchronized Package getPackage(String name) {
                   Log.d(TAG, "getPackage-" + name);
                   return super.getPackage(name);
         }
    
         @Override
         protected Class<?> loadClass(String className, boolean resolve)
                            throws ClassNotFoundException {
                   Log.d(TAG, "loadClass-" + className + " resolve " + resolve);
                   Class<?> clazz = super.loadClass(className, resolve);
                   if (null == clazz) {
                            Log.e(TAG, "loadClass fail,maybe get a null-point exception.");
                   }
                   return clazz;
         }
    
         @Override
         protected Package[] getPackages() {
                   Log.d(TAG, "getPackages sss-");
                   return super.getPackages();
         }
    
         @Override
         protected Package definePackage(String name, String specTitle,
                            String specVersion, String specVendor, String implTitle,
                            String implVersion, String implVendor, URL sealBase)
                            throws IllegalArgumentException {
                   Log.d(TAG, "definePackage" + name);
                  return super.definePackage(name, specTitle, specVersion, specVendor,
                                     implTitle, implVersion, implVendor, sealBase);
         }
    }

    注意:函数findClass处的改动!

    已经定义过的类不需要重新再定义,否则会导致app陷入无限循环,启动时有卡死状!

    在做ndk dex加密时,壳与被加密程序在通常是捆绑在一个APK包中。如果APP中libs目录下有so库,此时需要重写findLibrary函数,从getClass().getClassLoader()获取路径!否则,你需要自己把.so文件存到手机某个地方,然后把路径返回给出来!

    ndk解壳形式安全性比较高,但是内存加载dex所依赖的底层方法,只在4.0以上几个版本存在,5.0没有查询还是未知数,还没能满足通用性的要求,要需要进一步寻找方案。

    Ref: http://taoyuanxiaoqi.com/2015/01/16/apkshell2/

  • 相关阅读:
    LVS安装配置
    Ansible自动化运维工具的使用
    DHCP中继配置
    简单爬虫
    zlib1.2.8 编译小记
    varnish 4.0编译安装小记
    imdisk命令行使用及配置
    How to say all the keyboard symbols in English and Chinese
    qwt6在Windows下Qt5的编译,安装,初步使用
    4MLinux7.0 服务器配置详解 别名TheSSS
  • 原文地址:https://www.cnblogs.com/open-coder/p/12502232.html
Copyright © 2020-2023  润新知