andoridapk反逆向解决方案

上传人:自*** 文档编号:79620093 上传时间:2019-02-17 格式:DOCX 页数:11 大小:467.55KB
返回 下载 相关 举报
andoridapk反逆向解决方案_第1页
第1页 / 共11页
andoridapk反逆向解决方案_第2页
第2页 / 共11页
andoridapk反逆向解决方案_第3页
第3页 / 共11页
andoridapk反逆向解决方案_第4页
第4页 / 共11页
andoridapk反逆向解决方案_第5页
第5页 / 共11页
点击查看更多>>
资源描述

《andoridapk反逆向解决方案》由会员分享,可在线阅读,更多相关《andoridapk反逆向解决方案(11页珍藏版)》请在金锄头文库上搜索。

1、Andorid APK反逆向解决方案:梆梆加固原理探寻2013-06-27 09:33 Jack_Jia 看雪安全论坛 字号:T | T梆梆是一个面向Android开发者的应用保护解决方案,它可以有效的阻止Android APK包被逆向工程破解,从而保护开发者的利益,防治打包党。那么它到底是如何实现这一效果的呢,梆梆的解决方案真的无懈可击吗?来看网友对其技术实现的分析。AD: 2013云计算架构师峰会课程资料下载 一、序言目前Android市场充斥着大量的盗版软件,开发者的官方应用被“打包党”们恶意篡改。如何使程序代码免受盗版篡改就成了开发者面临的头等大事,今天我们将分析一个不错的解决方案-梆

2、梆加固(http:/ 加固前后静态文件结构变化(左为加固前,右为加固后)加固后apk新增以下文件: assetsmeta-datamanifest.mf /APK文件列表SHA1-Digest assetsmeta-datarsa.pub /RSA公钥信息 assetsmeta-datarsa.sig /数字签名文件 assetsclasses.jar /已加密原classes.dex文件 assetscom.example.hellojni /ARM平台二进制可执行文件 assetscom.example.hellojni.x86 /x86功能同上 libsarmeabilibsecexe.

3、so /ARM平台共享库文件 libsx86libsecexe.so /x86功能同上加固后修改文件: AndroidMainfest.xml /(如果应用配置有Application信息,则该文件加固前后相同,如果应用未配置Application信息,则该文件加固前后不相同,梆梆会配置Application信息为自己实现类) classes.dex对classes.dex进行反编译,观察代码树结构变化:(左为加固前,右为加固后)(2)加固前后动态运行时变化运行原程序,系统仅创建一个相关进程,但是加固的程序,系统会为其同时创建三个相关程序进程:进程启动顺序:597进程创建605进程,605进程

4、又创建了607进程通过查看maps文件获取597进程映射文件信息通过map文件可以看出,597进程为主进程,android各组件在该进程中运行。605和607进程并无与apk文件相关文件信息,通过cmdline查看启动参数:初步怀疑该进程为assetscom.example.hellojni 可执行文件运行结果。2、梆梆加固保护效果分析我们通过逆向分析加固后的app,来看看梆梆加固对app的保护效果。程序代码的第一执行点是Application对象,首先查看TestApplication类对象。程序的Util类完成大部分的java层逻辑,ACall类主要完成对libsecexe.so JNI的

5、调用:查看libsecexe.so文件导出函数,发现所有函数名都经过加密处理,与我们平时jni调用产生的函数名并不同。平时jni产生的函数名应该为这样格式Java_com_secapk_wrapper_ACall_函数名抗静态分析:Util类通过MyClassLoader完成对加密classes.jar的动态加载,内存中解密classes.jar,完成动态加载。jni方法对应so函数名的混淆。抗动态调试: 当使用IDA动态调试该程序时,程序无法建立连接调试。梆梆加固可以有效常用的逆向分析方法。三、梆梆加固技术实现关键点猜想(1)如何使DexClassLoader动态加载组件具有生命周期?根据A

6、PK文件是否在AndroidManifest.xml配置Applicaiton信息,梆梆加固会做不同的处理:通过上传Applicaiton不同配置的APK文件,我们发现:当APK配置有Applicaition信息时,梆梆加固重写Application类当APK未配置Application信息时,梆梆加固新建类,并在AndroidManifest.xml中配置自己Application类因此Applicaiton就是程序的第一执行点。我们知道DexClassLoader加载的类是没有组件生命周期的,也就是说即使DexClassLoader通过对dex的 动态加载完成了对组件类的加载, 当系统启动

7、该组件时,还会出现加载类失败的异常。我已经在“Android APK加壳技术方案”中提出了一种使DexClassLoader加载组件类具有生命周期的方法。运行加固后的程序并通过Mat内存分析工具查看类加载情况:如上图所示,组件类的加载类已经被修改为com.secapk.wrapper.MyClassLoader类,可以得出结论,该方式和我提出方式基本相同,通过修改系统组件类ClassLoader来实现。(2)如何混淆native方法在so库函数对应关系?jni方法注册方式有两种:1、通过javah产生函数头,该种方式产生的方法具有固定的格式。该方式使逆向分析人员比较容易获取java层nativ

8、e方法对应的本地方法。2、在JNI_OnLoad方法中手动注册jni方法,不易查找对应关系。使用第二种方式可以实现混淆java层native方法和so函数的对应关系。1. #include 2. #include 3. 4. JNIEXPORT jstring JNICALL abcdefghijklmn( JNIEnv* env,jobject thiz ) 5. 6. return (*env)-NewStringUTF(env, Hello from JNI !); 7. 8. 9. JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void*

9、reserved) 10. 11. JNIEnv* env = NULL; 12. jint result = -1; 13. 14. if (*vm)-GetEnv(vm, (void*) &env, JNI_VERSION_1_4) != JNI_OK) 15. return JNI_ERR; 16. 17. JNINativeMethod gMethods = 18. stringFromJNI, ()Ljava/lang/String;, (void*)abcdefghijklmn , 19. ; 20. jclass clazz = (*env)-FindClass(env, com

10、/example/hellojni/HelloJni); 21. 22. if (clazz = NULL) 23. return JNI_ERR; 24. 25. if (*env)-RegisterNatives(env, clazz, gMethods, sizeof(gMethods) / sizeof(gMethods0) 0) 26. return JNI_ERR; 27. 28. /* success - return valid version number */ 29. result = JNI_VERSION_1_4; 30. return result; 31. 以上代码

11、中的字符串都是明文(比如“stringFromJNI”),如果这些文明字符串都换成密文的话,再通过运行时解密,相应的对应关系更不易看出。(3)如何使DexClassLoader加载加密的dex文件?虽然不了解梆梆加固是怎么做的,不过通过分析它的运行逻辑,我推测了一种可行的实现方案:了解该方案需要对 Android DexClassLoader的整个加载流程需要有清 晰的了解。首先推断assetsclasses.jar是一个加密的jar包。正常的DexClassLoader加载的流程如下:会有一个DexOpt产生odex过程但是梆梆加固后的应用DexClassLoader加载过程并没有该过程的l

12、og信息。推断加密的jar包里面含有odex文件,如果不是odex文件的话,DexClassLoader肯定会在运行时释放未加密的odex文件到目录,这样的话被保护的逻辑也就泄露了。DexClassLoader加载过程会在java层和C层产生不同的数据结构,java层并没有实质性的数据, 所有的数据都在c层,我们可用通过底层代码完成dex数据的解析。底层dex分析是可以支持byte数组的,解密 odex数据,传递过去就行了。这样java层就可以调用了。以下是大概伪代码实现步骤:1. int loadDex(char * dexFileName) 2. 3. char *dvm_lib_path = /system/lib/libdvm.so; 4. void * handle; 5. DvmGlobals gDvm; 6. handle = dlopen( dvm_lib_path, int mode); 1、读取dexFileName文件内容并解密到byte数组。2、调用dexFileParse函数解析byte数组为DexFiledalviklibdexDexFile.cDexFile* dexFileParse(const u1* data, size_t length, int flags)/dlsym(ha

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 办公文档 > 解决方案

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号