android基础11-dex文件改造-

学习笔记,自用,整理中

摘要:

面试:

apk打包流程:as电脑里面有给appdata/local/android/sdk/build-tools/aapt aidl

一系列工具完成的;gradle处理了。

运行时解密;

attachbasecontext 开始解密;

tinker:腾讯热修复

hook 勾子 :反射技术去反射 android源码的过程

大部分手机是23以上的

------------------------------------------------------------------------------------

内容:









--------------------------------------------------------------------------------------------------------------------

加密:

public class MyMain {

public static void main(String[] args)throws Exception {

byte[] mainDexData; //�洢Դapk�е�Դdex�ļ�

      byte[] aarData;    // �洢���еĿ�dex�ļ�

      byte[] mergeDex;    // �洢��dex ��Դdex �ĺϲ�����dex�ļ�

      File tempFileApk =new File("source/apk/temp");

      if (tempFileApk.exists()) {

File[]files = tempFileApk.listFiles();

        for(File file: files){

if (file.isFile()) {

file.delete();

            }

}

}

File tempFileAar =new File("source/aar/temp");

      if (tempFileAar.exists()) {

File[]files = tempFileAar.listFiles();

        for(File file: files){

if (file.isFile()) {

file.delete();

            }

}

}

/**

* ��һ�� ����ԭʼapk ����dex

*

*/

        AES.init(AES.DEFAULT_PWD);

        //��ѹapk

        File apkFile =new File("source/apk/app-debug.apk");

        File newApkFile =new File(apkFile.getParent() + File.separator +"temp");

        if(!newApkFile.exists()) {

newApkFile.mkdirs();

        }

File mainDexFile = AES.encryptAPKFile(apkFile,newApkFile);

        if (newApkFile.isDirectory()) {

File[] listFiles = newApkFile.listFiles();

        for (File file : listFiles) {

if (file.isFile()) {

if (file.getName().endsWith(".dex")) {

String name = file.getName();

                  System.out.println("rename step1:"+name);

                  int cursor = name.indexOf(".dex");

                  String newName = file.getParent()+ File.separator + name.substring(0, cursor) +"_" +".dex";

                  System.out.println("rename step2:"+newName);

                  file.renameTo(new File(newName));

              }

}

}

}

/**

* �ڶ��� ����aar ��ÿ�dex

*/

      File aarFile =new File("source/aar/mylibrary-debug.aar");

        File aarDex  = Dx.jar2Dex(aarFile);

//        aarData = Utils.getBytes(aarDex);  //��dex�ļ�����byte ����

        File tempMainDex =new File(newApkFile.getPath() + File.separator +"classes.dex");

        if (!tempMainDex.exists()) {

tempMainDex.createNewFile();

      }

//        System.out.println("MyMain" + tempMainDex.getAbsolutePath());

        FileOutputStream fos =new FileOutputStream(tempMainDex);

        byte[] fbytes = Utils.getBytes(aarDex);

        fos.write(fbytes);

        fos.flush();

        fos.close();

        /**

* ��3�� ���ǩ��

*/

        File unsignedApk =new File("result/apk-unsigned.apk");

        unsignedApk.getParentFile().mkdirs();

//        File disFile = new File(apkFile.getAbsolutePath() + File.separator+ "temp");

        Zip.zip(newApkFile, unsignedApk);

        //���ò���Ͳ����Զ�ʹ��ԭapk��ǩ��...

        File signedApk =new File("result/apk-signed.apk");

        Signature.signature(unsignedApk, signedApk);

    }

private static FilegetMainDexFile(File apkFile) {

// TODO Auto-generated method stub

      File disFile =new File(apkFile.getAbsolutePath() +"unzip");

      Zip.unZip(apkFile, disFile);

      File[] files = disFile.listFiles(new FilenameFilter() {

@Override

        public boolean accept(File dir, String name) {

if (name.endsWith(".dex")) {

return true;

            }

return false;

        }

});

      for (File file: files) {

if (file.getName().endsWith("classes.dex")) {

return file;

        }

}

return null;

  }

}

----------------------------------------------------------------------------------------------------------------------------

解密:

public class ShellApplicationextends Application {

private static final StringTAG ="ShellApplication";

    public static StringgetPassword(){

return "abcdefghijklmnop";

    }

//    static {

//        System.loadLibrary("native-lib");

//    }

    @Override

    protected void attachBaseContext(Context base) {

super.attachBaseContext(base);

        AES.init(getPassword());

        File apkFile =new File(getApplicationInfo().sourceDir);

        //data/data/包名/files/fake_apk/

        File unZipFile = getDir("fake_apk", MODE_PRIVATE);

        File app =new File(unZipFile, "app");

        if (!app.exists()) {

Zip.unZip(apkFile, app);

            File[] files = app.listFiles();

            for (File file : files) {

String name = file.getName();

                if (name.equals("classes.dex")) {

}else if (name.endsWith(".dex")) {

try {

byte[] bytes = getBytes(file);

                            FileOutputStream fos =new FileOutputStream(file);

                            byte[] decrypt = AES.decrypt(bytes);

//                        fos.write(bytes);

                            fos.write(decrypt);

                            fos.flush();

                            fos.close();

                        }catch (Exception e) {

e.printStackTrace();

                    }

}

}

}

List list =new ArrayList<>();

        Log.d("FAKE", Arrays.toString(app.listFiles()));

        for (File file : app.listFiles()) {

if (file.getName().endsWith(".dex")) {

list.add(file);

            }

}

Log.d("FAKE", list.toString());

        try {

V19.install(getClassLoader(), list, unZipFile);

        }catch (IllegalAccessException e) {

e.printStackTrace();

        }catch (NoSuchFieldException e) {

e.printStackTrace();

        }catch (InvocationTargetException e) {

e.printStackTrace();

        }catch (NoSuchMethodException e) {

e.printStackTrace();

        }

}

private static FieldfindField(Object instance, String name)throws NoSuchFieldException {

Class clazz = instance.getClass();

        while (clazz !=null) {

try {

Field e = clazz.getDeclaredField(name);

                if (!e.isAccessible()) {

e.setAccessible(true);

                }

return e;

            }catch (NoSuchFieldException var4) {

clazz = clazz.getSuperclass();

            }

}

throw new NoSuchFieldException("Field " + name +" not found in " + instance.getClass());

    }

private static MethodfindMethod(Object instance, String name, Class... parameterTypes)

throws NoSuchMethodException {

Class clazz = instance.getClass();

//        Method[] declaredMethods = clazz.getDeclaredMethods();

//        System.out.println("  findMethod ");

//        for (Method m : declaredMethods) {

//            System.out.print(m.getName() + "  : ");

//            Class[] parameterTypes1 = m.getParameterTypes();

//            for (Class clazz1 : parameterTypes1) {

//                System.out.print(clazz1.getName() + " ");

//            }

//            System.out.println("");

//        }

        while (clazz !=null) {

try {

Method e = clazz.getDeclaredMethod(name, parameterTypes);

                if (!e.isAccessible()) {

e.setAccessible(true);

                }

return e;

            }catch (NoSuchMethodException var5) {

clazz = clazz.getSuperclass();

            }

}

throw new NoSuchMethodException("Method " + name +" with parameters " + Arrays.asList

                (parameterTypes) +" not found in " + instance.getClass());

    }

private static void expandFieldArray(Object instance, String fieldName, Object[]

extraElements)throws NoSuchFieldException, IllegalArgumentException,

            IllegalAccessException {

Field jlrField =findField(instance, fieldName);

        Object[] original = (Object[]) ((Object[]) jlrField.get(instance));

        Object[] combined = (Object[]) ((Object[]) Array.newInstance(original.getClass()

.getComponentType(), original.length + extraElements.length));

        System.arraycopy(original, 0, combined, 0, original.length);

        System.arraycopy(extraElements, 0, combined, original.length, extraElements.length);

        jlrField.set(instance, combined);

    }

private static final class V19 {

private V19() {

}

private static void install(ClassLoader loader, List additionalClassPathEntries,

                                    File optimizedDirectory)throws IllegalArgumentException,

                IllegalAccessException, NoSuchFieldException, InvocationTargetException,

                NoSuchMethodException {

Field pathListField =findField(loader, "pathList");

            Object dexPathList = pathListField.get(loader);

            ArrayList suppressedExceptions =new ArrayList();

            Log.d(TAG, "Build.VERSION.SDK_INT " + Build.VERSION.SDK_INT);

            if (Build.VERSION.SDK_INT >=23) {

expandFieldArray(dexPathList, "dexElements", makePathElements(dexPathList, new

                                ArrayList(additionalClassPathEntries), optimizedDirectory,

                        suppressedExceptions));

            }else {

expandFieldArray(dexPathList, "dexElements", makeDexElements(dexPathList, new

                                ArrayList(additionalClassPathEntries), optimizedDirectory,

                        suppressedExceptions));

            }

if (suppressedExceptions.size() >0) {

Iterator suppressedExceptionsField = suppressedExceptions.iterator();

                while (suppressedExceptionsField.hasNext()) {

IOException dexElementsSuppressedExceptions = (IOException)

suppressedExceptionsField.next();

                    Log.w("MultiDex", "Exception in makeDexElement",

                            dexElementsSuppressedExceptions);

                }

Field suppressedExceptionsField1 =findField(loader,

                        "dexElementsSuppressedExceptions");

                IOException[] dexElementsSuppressedExceptions1 = (IOException[]) ((IOException[])

suppressedExceptionsField1.get(loader));

                if (dexElementsSuppressedExceptions1 ==null) {

dexElementsSuppressedExceptions1 = (IOException[]) suppressedExceptions

.toArray(new IOException[suppressedExceptions.size()]);

                }else {

IOException[] combined =new IOException[suppressedExceptions.size() +

dexElementsSuppressedExceptions1.length];

                    suppressedExceptions.toArray(combined);

                    System.arraycopy(dexElementsSuppressedExceptions1, 0, combined,

                            suppressedExceptions.size(), dexElementsSuppressedExceptions1.length);

                    dexElementsSuppressedExceptions1 = combined;

                }

suppressedExceptionsField1.set(loader, dexElementsSuppressedExceptions1);

            }

}

private static Object[]makeDexElements(Object dexPathList,

                                                ArrayList files, File

optimizedDirectory,

                                                ArrayList suppressedExceptions)throws

                IllegalAccessException, InvocationTargetException, NoSuchMethodException {

Method makeDexElements =findMethod(dexPathList, "makeDexElements", new

                        Class[]{ArrayList.class, File.class, ArrayList.class});

                return ((Object[]) makeDexElements.invoke(dexPathList, new Object[]{files,

                        optimizedDirectory, suppressedExceptions}));

          }

}

/**

* A wrapper around

    * {@code private static final dalvik.system.DexPathList#makePathElements}.

*/

    private static Object[]makePathElements(

Object dexPathList, ArrayList files, File optimizedDirectory,

            ArrayList suppressedExceptions)

throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {

Method makePathElements;

        try {

makePathElements =findMethod(dexPathList, "makePathElements", List.class, File.class,

                    List.class);

        }catch (NoSuchMethodException e) {

Log.e(TAG, "NoSuchMethodException: makePathElements(List,File,List) failure");

            try {

makePathElements =findMethod(dexPathList, "makePathElements", ArrayList.class, File.class, ArrayList.class);

            }catch (NoSuchMethodException e1) {

Log.e(TAG, "NoSuchMethodException: makeDexElements(ArrayList,File,ArrayList) failure");

                try {

Log.e(TAG, "NoSuchMethodException: try use v19 instead");

                    return V19.makeDexElements(dexPathList, files, optimizedDirectory, suppressedExceptions);

                }catch (NoSuchMethodException e2) {

Log.e(TAG, "NoSuchMethodException: makeDexElements(List,File,List) failure");

                    throw e2;

                }

}

}

return (Object[]) makePathElements.invoke(dexPathList, files, optimizedDirectory, suppressedExceptions);

    }

private byte[]getBytes(File file)throws Exception {

RandomAccessFile r =new RandomAccessFile(file, "r");

        byte[] buffer =new byte[(int) r.length()];

        r.readFully(buffer);

        r.close();

        return buffer;

    }

}

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,843评论 6 502
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,538评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,187评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,264评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,289评论 6 390
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,231评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,116评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,945评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,367评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,581评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,754评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,458评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,068评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,692评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,842评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,797评论 2 369
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,654评论 2 354

推荐阅读更多精彩内容