一文了解安卓APP逆向分析与保护机制
本文由 网易云发布。
“知物由学”是网易云易盾打造的一个品牌栏目,词语出自汉·王充《论衡·实知》。人,能力有高下之分,学习才知道事物的道理,而后才有智慧,不去求问就不会知道。“知物由学”希望通过一篇篇技术干货、趋势解读、人物思考和沉淀给你带来收获的同时,也希望打开你的眼界,成就不一样的你。
以下为文章正文:
想知道Android App常见的保护方法及其对应的逆向分析方法吗?
网易云易盾资深安全工程师 钟亚平
3月17日,安卓巴士全球开发者论坛在重庆举办,网易资深安全工程师钟亚平出席交流活动,并做了《安卓APP逆向与保护》的演讲。在分享中,他介绍了 Android App常见保护方法及其对应的逆向分析方法,以及分析了常见的加固方案原理与对抗方法。
安卓APP安全包含很多内容,本次分享了混淆代码、整体Dex加固、拆分 Dex 加固、虚拟机加固等方面。事实上,这些内容也是国内近几年Android App安全保护的一种主要趋势。
一、混淆代码
Java代码是非常容易反编译的,作为一种跨平台的、解释型语言,Java 源代码被编译成中间“字节码”存储于class文件中。由于跨平台的需要,这些字节码带有许多的语义信息,很容易被反编译成Java源代码。为了很好地保护Java源代码,开发者往往会对编译好的class文件进行混淆处理。
混淆就是对发布出去的程序进行重新组织和处理,使得处理后的代码与处理前代码完成相同的功能,而混淆后的代码很难被反编译,即使反编译成功也很难得出程序的真正语义。ProGuard就是一个混淆代码的开源项目,能够对字节码进行混淆、缩减体积、优化等处理。
Proguard处理流程图如下所示,包含压缩、优化、混淆、预检四个主要环节:
压缩(Shrink):检测并移除代码中无用的类、字段、方法和特性(Attribute);
优化(Optimize):对字节码进行优化,移除无用的指令。优化代码,非入口节点类会加上private/static/final,没有用到的参数会被删除,一些方法可能会变成内联代码;
混淆(Obfuscate):使用a、b、c、d这样简短而无意义的名称,对类、字段和方法进行重命名;
预检(Preveirfy):在Java平台上对处理后的代码进行预检,确保加载的class文件是可执行的。
在分享中,钟亚平展示了利用Proguard,对Dex2jar进行反编译处理后的Apk效果示例:
Proguard处理后
Proguard混淆器不仅能够保护代码,而且能够精简编译后的程序大小,减少内存占用。
混淆代码逆向分析
如果想要反编译混淆代码,钟亚平分享了一个国外的工具DEGUADR,它能够通过统计的方式来解混淆。虽然这个工具的正确率达不到100%,但是能在一定程度上帮助反编译代码。
使用DEGUADR解混淆的示例:
com.xxxxx.common.util.CryptoUtil网站也提供了一种反编译服务,如下所示:
java.lang.String a(byte[]) -> encodeToString
java.lang.String a(byte[],boolean,java.lang.String) -> a
byte[] a(byte[],byte[]) -> encrypt
byte[] b(byte[]) -> getKey
byte[] b(byte[],byte[]) -> decrypt
byte[] d(java.lang.String) -> getKey
java.lang.String a(byte,char[]) -> a
java.lang.String a(java.io.File) -> getHash
java.lang.String a(java.lang.String) -> c
java.lang.String b(java.lang.String) -> encode
二、整体Dex加固
为了加强Android保护强度,随着安全技术的发展,又出现了新型的“加固技术”。DEX加固是对DEX文件进行加壳防护,防止被静态反编译工具破解而泄露源码,最刚开始出现的是整体加固技术方案。
整体加固技术的原理如上所示,包括替换application/classes.dex、解密/动态加载原classes.dex、调用原application相关方法、将原application对象/名称设置到系统内部相关变量四大环节。其中最为关键的一步就是解密/动态加载原classes.dex,通过加密编译好的最终dex源码文件,然后在一个新项目中用新项目的application启动来解密原项目代码并加载到内存中,再把当前进程替换为解密后的代码,能够很好地隐藏源码并防止直接性的反编译。
整体Dex加固逆向分析
整体Dex加固逆向分析有两种常用的方法。其一是在内存中暴力搜索 dex\n035,再 dump。以下是在32位系统中的效果示例:
另一种方法就是通过HookdvmDexFileOpenPartial(void* addr, int len, DvmDex**)。
三、拆分Dex加固
随着业务规模发展到一定程度,不断地加入新功能、添加新的类库,代码在急剧膨胀的同时,相应的apk包的大小也急剧增加,那么简单的整体加固方案就不能很好地满足安全需求,在整体加固方案之外又出现了拆分加固的技术方案。
但是如上所示,dex文件在加固时,针对中间缺失的一部分数据会以解密后的数据来替换,有的时候这种拆分替换也会导致数据不准确。那么到底应该拆分什么样的数据呢?就需要了解一下dex文件的数据结构。
Dex文件结构极为复杂,以下图示选取了其中较为重要的内容。事实上,dex文件是一个以class为核心组装起来的文件,其中最重要的是classdata和classcode两部分,有其特定的接口和指令数据,选取这两部分来拆分的话,即使拆分出来也不会泄露class数据和字节码数据,反编译出来也不完整,安全性较高。
拆分Dex加固逆向分析
对于dex拆分加固的逆向分析,如下所示,可以用classdata替换从而组装成新的dex文件,虽然和原来的dex文件不会完全一致,但也在一定程度上复原了被拆分数据的样子。
但要注意的是,这种方法仅适用于被拆分出去的数据变形一次性完成,也就是说,在有其他保护思路的情况下尽量避免使用,而且即使有需要也尽量选在用到这个类的时候才去恢复。
此外还有一个更底层一些的工具dexhunter,这个工具较为前卫,但同时也有一些局限性,譬如部分指令数据会被优化,形成的代码界面不是很美观等等。
四、虚拟机加固
虚拟机加固也属于dex拆分加固的一种,它是对字节做了一些变化处理。如下所示,这是一个正常安卓系统中的代码,在其中进行了虚拟机加固操作:
以add-int v0, v1, v2、sub-int v0, v1, v2、mul-int v0, v1, v2这三条指令进行替换,然后进行加固编译,这样子操作后,即使把替换后的数据恢复了,也不会以add-int v0, v1, v2、sub-int v0, v1, v2、mul-int v0, v1, v2这三条指令进行替换,然后进行加固编译,这样子操作后,即使把替换后的数据恢复了,也不会变形成为之前的字节码,安全系数较高。
虚拟机加固逆向分析—HOOK JNI 接口
这种方式下的逆向分析,一方面可以通过HOOK JNI 接口来实现,它有两种实现方式。
其一是类成员/静态变量操作相关接口,比如:
GetStaticDoubleFieldSetStaticDoubleField GetDoubleField SetDoubleField …
(byte, object, int,long…)
其二是反射调用类方法,比如:
CallVoidMethodACallBooleanMethodA CallShortMethodA CallObjectMethodA …
CallStaticVoidMethodACallStaticBooleanMethodA CallStaticShortMethodA CallStaticObjectMethodA …
(byte, int, long,double …)
CallObjectMethodA(JNIEnv* env, jobject object, jmethoID method, …)
通过HOOKJNI 接口实现虚拟机加固逆向分析
通过HOOK JNI 接口不用逆向底层,就可以了解APP大致的调用流程。但是对于复杂的调用过程,或者虚拟化方法数量较多的情况,这种逆向分析手段看起来会比较混乱;对于不需要返射到Java层执行的指令,如算术、逻辑运算等,则无法监控到。
虚拟机加固逆向分析—分析指令操作码映射
另一方面,也可以通过分析指令操作码映射来逆向分析。在同一加固版本,或者映射关系相同的情况下,可以采取以下所示的方法:
但在实际情况中,每次加固时的映射关系都是随机变化的,如下所示,这种情况下就无法直接建立映射关系。
不依赖于操作码的映射关系只与虚拟机结构有关,所以需要根据偏移关系建立映射关系,从而进行逆向分析。
以上就是此次《安卓APP逆向与保护》主题的全部分享内容。
安卓APP逆向保护作为开发工作中的重要内容,一直是网易云易盾致力于提供的应用服务。“后续,我们将在SO加密保护方面进行更加深入的研究。”钟亚平最后说道。
*本文作者:网易云易盾,来自FreeBuf.COM
相关阅读:大公司怎么做Android代码混淆的?
了解 网易云 :
网易云官网:https://www.163yun.com/
新用户大礼包:https://www.163yun.com/gift
网易云社区:https://sq.163yun.com/
一文了解安卓APP逆向分析与保护机制的更多相关文章
- 安卓动态逆向分析工具--Andbug&Androguard
工具使用方法: 转自: http://bbs.pediy.com/showthread.php?t=183412 https://testerhome.com/topics/3542 安装andbug ...
- 当前安卓App加固到底该如何做到防篡改?
安卓dalvik虚拟机要求dex文件在内存中以明文形式存在,那么任何加壳方法到头来到了内存还是明文存在,各种dump方法终究是可以获得它的.App究竟应该如何加固才能防止被篡改? 加固和 dump ...
- 20145307陈俊达_安卓逆向分析_Xposed的hook技术研究
20145307陈俊达_安卓逆向分析_Xposed的hook技术研究 引言 其实这份我早就想写了,xposed这个东西我在安卓SDK 4.4.4的时候就在玩了,root后安装架构,起初是为了实现一些屌 ...
- 20145307陈俊达_安卓逆向分析_dex2jar&jd-gui的使用
20145307陈俊达_安卓逆向分析_dex2jar&jd-gui的使用 引言 这次免考选择了四个项目,难度也是从简到难,最开始先写一个工具的使用 想要开发安卓首先要会编写代码,但是想要逆向分 ...
- 20145307陈俊达_安卓逆向分析_APKtools分析smail
20145307陈俊达_安卓逆向分析_APKtools分析smail 引言 真刺激呢!到了第二篇博客了,难度开始加大,之前是简单的dex2jar和有图形界面的jd-gui,现在来隆重介绍强大的反汇编工 ...
- 微信小程序、安卓APP、苹果APP对比分析
今天的话题主要是关于微信小程序.安卓APP.苹果APP对比分析.既然是对比分析肯定是将它们一个一个说明. 本篇不涉及技术话题,只讲解微信小程序.安卓APP.苹果APP它们各自的优缺点及其应用场景. 一 ...
- Android无需权限显示悬浮窗, 兼谈逆向分析app
前言 最近UC浏览器中文版出了一个快速搜索的功能, 在使用其他app的时候, 如果复制了一些内容, 屏幕顶部会弹一个窗口, 提示一些操作, 点击后跳转到UC, 显示这个悬浮窗不需要申请android. ...
- 安卓app测试之Monkey日志分析《转载》
安卓app测试之Monkey日志分析 链接:https://www.cnblogs.com/wuzm/p/10965762.html
- Soul Android app 悬浮view以及帖子中view的联动刷新逆向分析
Soul app是我司的竞品,对它的语音音乐播放同步联动的逻辑很感兴趣,于是就开启了一波逆向分析. 下面看代码,以及技术分析,直接步入正轨,哈哈. 我们根据https://github.com/xin ...
随机推荐
- 密码脱落 JAVA 蓝桥杯
密码脱落 X星球的考古学家发现了一批古代留下来的密码.这些密码是由A.B.C.D 四种植物的种子串成的序列.仔细分析发现,这些密码串当初应该是前后对称的(也就是我们说的镜像串).由于年代久远,其中许多 ...
- java中的异常以及 try catch finally以及finally的执行顺序
java中的 try.catch.finally及finally执行顺序详解: 1.首相简单介绍一下异常以及异常的运行情况: 在Java中异常的继承主要有两个: Error和Exception 这两个 ...
- Access数据库自动生成设计文档
在做Access数据库设计时,常常直接在access文件中建表,建字段,然后写设计文档时,又得重新再写一遍字段和表间关系.其实access数据库自己就支持自动生成数据库文档. 操作方法如下: 数据库工 ...
- C语言第二周作业----分支结构
一.PTA实验作业 题目1.7-1计算分段函数 本题目要求计算下列分段函数f(x)的值: 注:可在头文件中包含math.h,并调用sqrt函数求平方根,调用pow函数求幂. 1.实验代码 int ma ...
- 团队作业4——第一次项目冲刺(Alpha版本) Day 1
小队@JMUZJB-集美震惊部 一.Daily Scrum Meeting照片 二.Burndown Chart 燃尽图 三.项目进展 1.界面 屏幕开发中,原型设计完毕. 2.服务器 服务器由学校提 ...
- 团队作业7——第二次项目冲刺(Beta版本12.05-12.07)
1.当天站立式会议照片 本次会议内容:1:每个人汇报自己完成的工作.2:组长分配各自要完成的任务. 2.每个人的工作 黄进勇:项目整合,后台代码. 李勇:前台界面优化. 何忠鹏:数据库模块. 郑希彬: ...
- HTML5 canvas绘制雪花飘落
Canvas是HTML5新增的组件,它就像一块幕布,可以用JavaScript在上面绘制各种图表.动画等. 没有Canvas的年代,绘图只能借助Flash插件实现,页面不得不用JavaScript和F ...
- 17-TypeScript代理模式
在有些情况下,我们需要把客户端真正调用的类和方法隐藏起来,而通过暴露代理类给客户端.客户端调用代理类的方式就可以访问到真实类提供的功能. abstract class Called{ protecte ...
- java异常常见面试问题
java异常常见面试问题 一.java异常的理解 异常主要是处理编译期不能捕获的错误.出现问题时能继续顺利执行下去,而不导致程序终止,确保程序的健壮性. 处理过程:产生异常状态时,如果当前的conte ...
- 07_Python的控制判断循环语句1(if判断,for循环...)_Python编程之路
Python的数据类型在前几节我们都简单的一一介绍了,接下来我们就要讲到Python的控制判断循环语句 在现实编程中,我们往往要利用计算机帮我们做大量重复计算的工作,在这样的情况下,需要机器能对某个条 ...