加密算法很简单,只是对每个字节进行异或一下 。
这里是为了简单,所以就用了很简单的加密算法,其实为了增加破解难度,我们应该使用更高效的加密算法,同时最好将加密操作放到native层去做 。
这里需要两个输入文件:
- 源程序APK文件:SourceApk.apk
- 壳程序的DEX文件:SourceApk.dex
第一个文件就是源程序项目编译之后的APK文件,第二个文件是下面要讲的第三个项目:壳程序项目中的classes.dex文件,修改名称之后得到 。3.壳程序项目:PackApk

文章插图
先来了解一下壳程序项目的工作:
- 通过反射置换android.app.ActivityThread中的mClassLoader为加载解密出APK的DexClassLoader,该DexClassLoader一方面加载了源程序,另一方面以原mClassLoader为父节点,这就保证即加载了源程序,又没有放弃原先加载的资源与系统代码 。关于这部分内容不了解的可以看一下Android动态加载之免安装运行程序这篇文章 。
- 找到源程序的Application,通过反射建立并运行 。这里需要注意的是,我们现在是加载一个完整的APK,让他运行起来 。一个APK运行的时候都是有一个Application对象的,这个也是一个程序运行之后的全局类,所以我们必须找到解密之后的源程序APK的Application类,运行它的onCreate方法,这样源程序APK才开始它的运行生命周期 。后面会说如何得到源程序APK的Application类:使用meta标签进行设置 。
下面看一下整体流程:

文章插图
下面看一下代码: ProxyApplication.java
- 得到壳程序APK中的DEX文件,然后从这个文件中得到源程序APK进行解密、加载
// 这是context赋值@Overrideprotected void attachBaseContext(Context base) { super.attachBaseContext(base); try { // 创建两个文件夹payload_odex、payload_lib,私有的,可写的文件目录 File odex = this.getDir("payload_odex", MODE_PRIVATE); File libs = this.getDir("payload_lib", MODE_PRIVATE); odexPath = odex.getAbsolutePath(); libPath = libs.getAbsolutePath(); apkFileName = odex.getAbsolutePath() + "/payload.apk"; File dexFile = new File(apkFileName); Log.i("demo", "apk size:"+dexFile.length()); if (!dexFile.exists()) { dexFile.createNewFile(); //在payload_odex文件夹内,创建payload.apk // 读取程序classes.dex文件 byte[] dexdata = https://www.isolves.com/it/cxkf/ydd/Android/2019-09-04/this.readDexFileFromApk();// 分离出解壳后的apk文件已用于动态加载 this.splitPayLoadFromDex(dexdata); } // 配置动态加载环境 Object currentActivityThread = RefInvoke.invokeStaticMethod( "android.app.ActivityThread", "currentActivityThread", new Class[] {}, new Object[] {});//获取主线程对象String packageName = this.getPackageName();//当前apk的包名 ArrayMap mPackages = (ArrayMap) RefInvoke.getFieldOjbect( "android.app.ActivityThread", currentActivityThread, "mPackages"); WeakReference wr = (WeakReference) mPackages.get(packageName); // 创建被加壳apk的DexClassLoader对象 加载apk内的类和本地代码(c/c++代码) DexClassLoader dLoader = new DexClassLoader(apkFileName, odexPath, libPath, (ClassLoader) RefInvoke.getFieldOjbect( "android.app.LoadedApk", wr.get(), "mClassLoader")); //把当前进程的mClassLoader设置成了被加壳apk的DexClassLoader RefInvoke.setFieldOjbect("android.app.LoadedApk", "mClassLoader", wr.get(), dLoader);Log.i("demo","classloader:"+dLoader); try{ Object actObj = dLoader.loadClass("com.example.sourceapk.MainActivity"); Log.i("demo", "actObj:"+actObj); }catch(Exception e){ Log.i("demo", "activity:"+Log.getStackTraceString(e)); } } catch (Exception e) { Log.i("demo", "error:"+Log.getStackTraceString(e)); e.printStackTrace(); }}这里需要注意的一个问题,就是我们需要找到一个时机,就是在壳程序还没有运行起来的时候,来加载源程序的APK,执行它的onCreate方法,那么这个时机不能太晚,不然的话,就是运行壳程序,而不是源程序了 。查看源码我们知道 。Application中有一个方法:attachBaseContext这个方法,它在Application的onCreate方法执行前就会执行了,所以我们的工作就需要在这里进行 。A) 从APK中获取到DEX文件
/** * 从apk包里面获取dex文件内容(byte) * @return * @throws IOException */private byte[] readDexFileFromApk() throws IOException { ByteArrayOutputStream dexByteArrayOutputStream = new ByteArrayOutputStream(); ZipInputStream localZipInputStream = new ZipInputStream( new BufferedInputStream(new FileInputStream( this.getApplicationInfo().sourceDir))); while (true) { ZipEntry localZipEntry = localZipInputStream.getNextEntry(); if (localZipEntry == null) { localZipInputStream.close(); break; } if (localZipEntry.getName().equals("classes.dex")) { byte[] arrayOfByte = new byte[1024]; while (true) { int i = localZipInputStream.read(arrayOfByte); if (i == -1) break; dexByteArrayOutputStream.write(arrayOfByte, 0, i); } } localZipInputStream.closeEntry(); } localZipInputStream.close(); return dexByteArrayOutputStream.toByteArray();}
推荐阅读
-
-
苹果手机|目前烂大街的三部手机,快看看你在用哪一部?
-
热点游戏|国产游戏如何破圈,光凭画面就能成3A?,好游戏都是国外的
-
食疗食补|这菜晒一晒,放一年不会坏,炒肉特别香,清肠瘦肚子,腰围变细了
-
「互联网乱侃秀」MateXs再被炒至好几万,有人说是国货之光,我认为是对品牌的伤害
-
芒果台■仝卓在网上正式道歉后,《快本》镜头全部被剪掉,芒果台P图师太牛了
-
『央视网』累计142例,新西兰新增40例新冠肺炎确诊病例
-
蔡少芬|蔡少芬首回应举家搬回港:一直租房卖豪宅太假,网友:大陆钱好赚
-
-
■谢谢您让这句“不可能”成为现实!重听袁隆平这句话泪流满面
-
『情感倾听』哪怕占一个,你就偷着乐吧!,女人这四个部位“毛”越多越好
-
高校▲2020年师范类大学排名,北师大位居榜首,东北师范退步明显!
-
洛杉矶快船队|社交圈:网友讽刺快船赢球靠裁判 小卡约老师都靠中指上热搜
-
品牌|这8个品牌的几十款毛茸外套,不仅保暖还显时髦,学生党也买得起
-
小米10pro有必要换小米11吗?小米10pro换购小米11
-
-
-
车家号:亿日圆资金,疫情冲击日产严重?,急筹资5,000
-
平顶山警方:新新街发生重大刑案,一名中年女性嫌疑人外逃
-
小霸王|除一人外,其他皆有争议,英雄联盟:国内媒体自制S9选手金字塔