安卓Dex壳技术探讨(1)

最近在研究安卓平台的加壳技术,以前以为只有原生层的代码才可以加壳,看了看网上的资料,才发现原来Java层也可以加壳,虽然与传统的壳有些区别,但就最终的效果来说,反静态分析的目的还是达到了的。

目前安卓市场上的大多数apk的保护方式都是对Java层进行代码混淆,将关键数据放在原生层,再用传统加壳手段对so文件进行加壳,这种方式的缺陷是Java层的代码安全完全依赖于代码混淆,实际上只要熟悉smali语法,代码混淆的意义就没有想象的那么大,对于那些资深的C/C++逆向工程师来说,逆向smali可比在一堆汇编代码里面按图索骥轻松多了。

传统的PE文件是怎么加壳的

看雪对PE文件的壳解释的很详尽,就不多作阐述了,大致原理是对源PE文件加密或压缩后,将数据嵌入外壳程序里面,外壳程序执行后将源PE文件解密加载,然后跳到源PE文件的入口(OEP)执行。静态分析加壳的程序,就只能看到外壳程序和加密的源PE文件。如果要获得源PE文件(脱壳),就只能运行外壳,让其将源PE文件解密,然后找到OEP,将解密后的PE文件从内存里dump下来,重建输入表,生成脱壳后的PE文件。软件安全工程师可以在壳上采用反调试(Anti-debug)和复杂化控制流等技术来阻止破解者寻找OEP。

可以看出,一个传统的“壳”需要具备以下特点:

1、源程序压缩或加密后内嵌在外壳程序内部;

2、外壳程序先于源程序运行,对源程序解密;

3、解密后的数据必须存放在内存中;

4、源程序加载后要能正常运行;

最为关键的是第3点,需要明白的是,只要投入足够的时间,壳最终是肯定会被破解的,壳的意义实际上在于增加破解成本,尽可能地拖延破解时间,要做到这一点,就必须把与破解者的对抗的关键点放到分析外壳程序的解密逻辑的困难性上,如果破解者有办法绕过分析外壳程序的步骤,直接拿到解密后的源程序,那么这个壳就是无效的。解密后的数据如果留在了文件系统里,破解者就能直接获取到源程序。为什么要单独把这个问题提出来说呢,传统的壳加载源程序,只要解密过后,重定位到OEP就可以了,安卓加载可执行文件却需要使用类加载器DexClassLoader,原型如下:

public DexClassLoader (String dexPath, String optimizedDirectory, String libraryPath, ClassLoader loader)

其中第一个参数dexPath是代表的一个路径,也就是说,DexClassLoader只能加载存放在文件系统里的可执行文件。问题就出来了,刚刚说,我们不能把解密后的源程序放在文件系统上,但是要用DexClassLoader 加载安卓可执行文件dex的话就必须先把它存放在文件系统上,这是对Dex文件进行加壳最大的难点。

为了解决这个问题,我想到了两个办法,第一个办法是减少暴露在文件系统里的时间,在DexClassLoader装载完源程序后,立即将其从文件系统中删除,这样破解者就必须动态调试,在源程序被删除之前断下来才能获得源程序。但是这种办法还是很不安全,我们需要一种彻底不在文件系统留下任何痕迹的方法。先回过头来看DexClassLoader,它虽然只提供路径作为参数,但其加载过程最终肯定有一个步骤是将文件转化成输入流,然后映射到内存,也就是说,DexClassLoader 最终还是要从内存中加载源程序。在网上查了资料,最终在http://www.strazzere.com/papers/DexEducation-PracticingSafeDex.pdf里找到了答案,原来安卓4.0以下的版本确实不支持内存加载Dex,4.0以上的版本实际上是提供了一个以byte数组为参数的接口openDexFile来从内存中加载类的,只不过这个接口并没有开放给SDK,因此需要利用Java反射机制来调用。细节等以后再说,本篇文章先讲讲怎么实现第一种方法。

将源APK嵌入外壳Dex中

我们知道Apk是安卓的安装包,本质是一个zip,需要安装后才能运行,APK里面的classes.dex才是真正的可执行文件,为什么要嵌入APK而不是classes.dex呢?因为classes.dex里并不包含资源文件,如果只加载classes.dex的话,运行后是没有任何资源的。

具体内嵌APK的方法参考了这篇博客:http://blog.csdn.net/androidsecurity/article/details/8678399。博主的做法是将APK加密后,添加到外壳的classes.dex尾部,然后加上APK的文件长度,最后修改classes.dex的dex文件头。这部分很简单,博主也提供了源代码,所以就不阐述了。

需要一提的是,如果把内嵌了源APK的外壳classes.dex直接放入外壳APK中,放进手机安装的话会出错,原因是这样破坏了APK签名,需要把外壳APK中的META-INF文件夹删掉,然后用signapk.jar重新签名,我的signapk.jar的下载地址如下:http://www.uzzf.com/soft/60860.html

在外壳中剥离源APK

外壳程序运行后,通过getApplicationInfo().sourceDir就能获取到外壳自身的APK地址,将其以文件形式打开后,输入到一个ZipInputStream流里,然后遍历zip找到classes.dex,将其输入到一个byte数组,利用byte数组的长度-4得到内嵌的源APK文件的长度,最后调用System.arraycopy将源apk拷贝出来,解密后,输出到文件系统里就可以了。读取壳自身apk的代码如下:

1         ByteArrayOutputStream dexByteArrayOutputStream = new ByteArrayOutputStream();
2         ZipInputStream localZipInputStream = new ZipInputStream(
3                 new BufferedInputStream(new FileInputStream(
4                         this.getApplicationInfo().sourceDir)));

利用DexClassLoader动态加载源APK

安卓是允许在不安装apk的情况下调用apk的可执行文件的,要实现这个,就得利用DexClassLoader,这是安卓专用的类加载器,它以APK路径作为参数,找到APK中的classes.dex文件,将里面的类加载进来,这样我们就可以调用源APK中的代码了。需要注意的是,直接用DexClassLoader加载进来的安卓组件类是死的,不具有生命周期,跟普通的类没有区别,也就是说我们不能直接像普通调用安卓组件的方式去调用DexClassLoader加载进来的组件。网上找了一会儿,在http://blog.csdn.net/singwhatiwanna/article/details/22597587上找到了一种解决办法,该博主是将源APK中的组件与调用APK的组件的生命周期绑定在一起,相当于将源APK的生命周期模拟了出来,这种调用技术可用于实现APK插件化,但是存在很多限制,最有效的解决方案其实是360提出的Proxy/Delegate框架:http://blogs.360.cn/blog/proxydelegate-application/这种解决方案是将调用APK的Application动态替换为源APK的Application(Proxy与Delegate),将其运用在Dex文件加壳上的话,这样就相当于替换了应用程序运行环境,运行中的外壳就完全变成了源程序,这时候只要调用源程序的Application.onCreate(),源程序就启动了。此外,需要在源程序的Application.onCreate()里加入启动MainActivity的代码,否则MainActivity是不会主动启动的。

未完待续……

时间: 2024-08-10 19:16:48

安卓Dex壳技术探讨(1)的相关文章

安卓 dex 通用脱壳技术研究(一)

注:以下4篇博文中,部分图片引用自DexHunter作者zyqqyz在slide.pptx中的图片,版本归原作者所有: 0x01 背景介绍 安卓 APP 的保护一般分为下列几个方面: JAVA/C代码混淆 dex文件加壳 .so文件加壳 反动态调试技术 其中混淆和加壳是为了防止对应用的静态分析:代码混淆会增加攻击者的时间成本, 但并不能从根本上解决应用被逆向的问题:而加壳技术一旦被破解,其优势更是荡然无存:反调试用来对抗对APP的动态分析: 昨天看雪zyqqyz同学发了一个Android应用程序

安卓推送技术方案实现探讨

背景介绍 随着苹果产品的风靡,推送技术在国内也越来越热门.推送最开始用于邮件系统.随着iPhone 和 Android 手机的风靡,逐渐在手机上也越来越常见.不少手机客户端也时常推送一些消息. 推送技术的应用 推送技术在手机上的应用主要有两块:广告推送.SNS信息推送. l  广告推送:给目前有一定安装量但没有盈利模式的手机应用开发者带来了一定希望,但要注意推送的频度和内容选中,不然会因为推送的东西用户不感兴趣造成打扰. l  SNS信息推送:主要用于QQ空间.人人网.微博和天涯论坛等web2.

AndroidLinker与SO加壳技术之上篇

1. 前言 Android 系统安全愈发重要,像传统pc安全的可执行文件加固一样,应用加固是Android系统安全中非常重要的一环.目前Android 应用加固可以分为dex加固和Native加固,Native 加固的保护对象为 Native 层的 SO 文件,使用加壳.反调试.混淆.VM 等手段增加SO文件的反编译难度.目前最主流的 SO 文件保护方案还是加壳技术, 在SO文件加壳和脱壳的攻防技术领域,最重要的基础的便是对于 Linker 即装载链接机制的理解.对于非安全方向开发者,深刻理解系

android apk 防止反编译技术第一篇-加壳技术

做android framework方面的工作将近三年的时间了,现在公司让做一下android apk安全方面的研究,于是最近就在网上找大量的资料来学习.现在将最近学习成果做一下整理总结.学习的这些成果我会做成一个系列慢慢写出来与大家分享,共同进步.这篇主要讲apk的加壳技术,废话不多说了直接进入正题. 一.加壳技术原理 所谓apk的加壳技术和pc exe的加壳原理一样,就是在程序的外面再包裹上另外一段代码,保护里面的代码不被非法修改或反编译,在程序运行的时候优先取得程序的控制权做一些我们自己想

【腾讯Bugly干货分享】Android Linker 与 SO 加壳技术

本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/57e3a3bc42eb88da6d4be143 作者:王赛 1. 前言 Android 系统安全愈发重要,像传统pc安全的可执行文件加固一样,应用加固是Android系统安全中非常重要的一环.目前Android 应用加固可以分为dex加固和Native加固,Native 加固的保护对象为 Native 层的 SO 文件,使用加壳.反调试.混淆.VM 等手段增加SO文件的反编译难

七雄Q传封包辅助技术探讨回忆贴

前言 网页游戏2013年左右最火的类型最烧钱游戏,当年的我也掉坑了.为了边玩还满足码农精神我奋力的学习如何来做外挂.2013年我工作的第二个年头.多一半…介绍下游戏<七雄Q传>是北京游戏谷(北京漫游谷信息技术有限公司)研发的一款以春秋战国为时代背景的大型Q版社交SLG游戏, 这款游戏官方推出比肩爆款七雄争霸二代产品.七雄争霸不用说了当年月流水上亿 2013年7月左右开服到2017年2月闭服 这款游戏距今快7年了,算上封测 我也是删档测试的玩家,.(他们关服了我才敢写) 注册时间2013-1-2

AndroidLinker与SO加壳技术之下篇

点此查看上篇<AndroidLinker与SO加壳技术之上篇>2.4 链接 链接过程由 soinfo_link_image 函数完成,主要可以分为四个主要步骤: 1. 定位 dynamic section,由函数 phdr_table_get_dynamic_section 完成,该函数会遍历 program header,找到为类型为 PT_DYNAMIC 的 header, 从中获取的是 dynamic section 的信息,主要就是虚拟地址和项数. 2. 解析 dynamic sect

安卓刷量技术揭秘

安卓刷量技术揭秘(一) 工具篇 安卓刷量技术揭秘(二) 高级攻防技巧 可使用XPOSED来进行刷量

虚拟化及云环境下数据库审计技术探讨(下)

在上篇文章也介绍到大部分的虚拟化及云环境下的数据审计技术探讨 接下来我们来进入更深的层次研究 场景三:应用和数据库分别托管部署在完全独立的第三方云计算平台 场景四是场景三的一种延伸与扩大,场景四主要指目前主流的第三方云平台提供商如阿里云.亚马逊.腾讯云.华为云.百度云等等,底层的硬件.存储.网络等等都对用户不透明,上层的虚拟机具体在哪个物理硬件服务器上,连接哪个物理交换机,用户一概不知道,如下图所示: 因此要用传统方式配置镜像,基本上没有可能,云平台提供商并不会提供底层资源的控制权给云主机租户,