本文主要参考博客:
CSDN的大牛写的博客太简洁了,内存动态加载主要参考taoyuanxiaoqi的博文,写得比较详细。我的上一篇文章提到使用DexClassLoader
函数,把apk文件加载进来,不过这样的做法会导致apk文件躺在文件系统中,这样的做法并不安全,在4.0之后,可以通过封装Dalvik_dalvik_system_DexFile_openDexFile_bytearray
函数,可以在解密出dex文件的byteArray数组后,不需要保存到文件系统的路径上,直接通过4.0的函数在内存中读取。
参考博客他们的做法是,通过修改DexShellTool
,并不是把payload.apk
拼接到unshell.dex
的后面,只是把payload.apk
的classes.dex
拼接到unshell.dex
的后面。然后通过读取出classes.dex
数组,并不保存到文件系统中,实现在内存中动态加载。
但是我比较懒,不想修改DexShellTool
,还是把payload.apk
拼接到后面,然后把payload.apk
解压放到文件系统中,然后把里面的classes.dex
数组读出来,这样进行动态加载,主要是想验证Dalvik_dalvik_system_DexFile_openDexFile_bytearray
函数,文件系统还是躺着一个apk。
配置环境
本文的编译环境如下:
- Android Studio 1.2.1.1
- JDK 1.7.0_79
- SDK
- NDK
跟我的上一篇文章的环境是一样的,由于taoyuanxiaoqi的博文写的比较详细,代码我就不一一copy了,主要说一下编译过程中可能由于编译版本不同而提示的错误。 建立一个com.droider.dexunshellram
的project,app里面的build.gradle
如下,minSdkVersion
为14,安卓4.0。
1 | apply plugin: 'com.android.application' |
AndroidManifest.xml
如下:
1 | <manifest xmlns:android="http://schemas.android.com/apk/res/android" |
java层
在jni文件的编写,基本上是没有提示错误的,完全参考第二篇taoyuanxiaoqi博主那样编写就行了,编写3个文件,分别是com_droider_dexunshellram_unshellram.c
、com_droider_dexunshellram_unshellram.h
和dalvik_common.h
。 遇到的问题:
问题1
在java层中,主要是基于我上一篇文章的com.droider.dexunshell
应用修改。无意中发现上一篇文章的RefInvoke.java
有漏洞,因为taoyuanxiaoqi博主在DynamicDexClassLoader
中使用了import com.eebbk.mingming.k7utils.ReflectUtils
;,应该是别人写的反射函数,我想用回自己的RefInvoke
。但是上一篇文章中CSDN博主的RefInvoke
写法有问题。应该在invokeStaticMethod
函数中加入method.setAccessible(true)
;
1 | public static Object invokeStaticMethod(String class_name, String method_name, Class[] pareTyple, Object[] pareVaules){ |
问题2
在DynamicDexClassLoader.java
中,需要把defineClass
的defineClass
改成defineClassNative
,要不会提示找不到defineClass
的错误。
1 | private Class defineClass(String name, ClassLoader loader, int cookie) { |
问题3
在DynamicDexClassLoader.java
的findClass
函数中,需要加一个break
和注释两行函数,要不会一直不断defineClass
。
1 | protected Class findClass(String name) throws ClassNotFoundException { |
所以在Java层中按taoyuanxiaoqi博主的文章相应修改一下ProxyApplication.java
和RefInvoke.java
。然后添加DynamicDexClassLoader.java
和unshellram.java
。就大功告成,其实上面这些错误的解决方法是在taoyuanxiaoqi的博文评论中找到的。
编译通过后,也需要向我上一篇文章一样,运行一下DexShellTool
,把apk拼接到后面,再重新签名安装,apk为上一篇博文的crackme0201
。dexunshellram
程序app文件夹的代码包链接。
搞定,收工。