Android逆向技术高阶大法

原文链接 Android逆向技术高阶大法

安卓应用是一个客户端,与传统软件类似,需要把软件打包,然后通过某种渠道(应用市场)分发给用户,这是常规的发布方式,它的更新节奏很慢,从你在应用市场上更新后,到用户真正的执行升级,这中间很慢的,而且很多用户根本不会升级新版本,这对于互联网来说是极不友好的。传统的互联网,用户刷新一下网页后,就能看得到更新了,但对于客户端,这行不通,要想实现小时级别的发布和分钟级别的问题修复,正规的发布渠道是做不到的。于是各路大神和专家开始研究客户端的前端化,也就是运用各种技术能让发布,特别是一些问题修复性的小规模发布可以更快的传递到用户手中。

这与正向方法不一样,谷歌或者水果针对 应用市场有明确 的流程的,这是常规发布也即是正向方式。今天我们来聊一聊非正向方法,非常规方式,来实现小模块的发布和热修复。

核心技术原理

任何一项技术都离不开编程语言和操作系统上的支持,对于插件化技术来说,最为核心的原理就是Java支持反射,这是一种运行时修改代码的技术,另外就是动态代理,这是插件化可行的根本技术支撑。

说到底,Java仍是一种解释型语言,它的核心是JVM,即也虚拟机,我们所熟悉的Java编程语言,本质上是套在JVM上的一层语法规则,换了一种语言规则也是可行的。就好比Kotlin,Scala和Groovy它们的语法与Java相差很大,但它们编译过后的字节码是完全符合JVM规范的,可以直接运行在JVM之上。

其他的纯解释型语言,如Python和JavaScript,它们在运行时可以动态的加载一段源码,这即是动态化,可以实现真正的插件化,运行时直接加载运行一段代码。Java略变态一些,但它本质上是JVM,而JVM通过反射和动态代理,在一定程度上支持了类似的动态化,就是通过ClassLoader来动态加载一些编译好的Class。

此为插件化的核心原理。

动态代理机制,可以读这几篇文章:

  • 动态代理大揭秘,带你彻底弄清楚动态代理
  • 动态代理
  • Java的动态代理(dynamic proxy)
  • java动态代理实现与原理详细分析
  • 小白也能看懂的插件化DroidPlugin原理(一)-- 动态代理

Hook大法

有了核心原理,才有可行的方案。Hook主要研究三方面内容,一是研究ClassLoader,因为不同的dex分属于不同的层级,它们的ClassLoader不一样,反射的第一步就是要能加载到想要的Class,这个要靠找到合适的ClassLoader;二是动态代理机制,hook的核心原理就是用动态代理机制,创建一个Mock对象用以替换掉原来的,所以接口Interface是关键,原系统设计中必须使用大量接口,并且是以标准方式使用的(没有强制向下转型downcast),这样你创建出来的动态代理去替换才是安全的;三就是学习安卓系统核心组件 的流程,以找到最佳的hook地点。

其实,第3条才是对大部分人最为有益的。

具体如何做hook,可以参考以下文章:

  • Android 插件化原理解析——Service的插件化
  • Android 插件化原理解析——Hook机制之AMS&PMS
  • 探索Android开源框架 - 10. 插件化原理
  • 小白也能看懂的插件化DroidPlugin原理(二)-- 反射机制和Hook入门

由于安卓版本升级的原因,上面这几个文章都失效了,例子行不通了。但是这几遍对于原理解释的还是相当清楚的。

以下文章对于新版本也是适用的。

  • 基于Android9.0的Hook Activity 的启动(插件化)
  • Android Hook Activity 的几种姿势
  • Activity插件化原理第一种方案:Hook Instrumentation
  • Activity插件化原理第二种方案:Hook IActivityManager
  • 拦截Activity的启动流程绕过AndroidManifest检测

需要注意的是,hook这件事情,最基础的技术很简单,就通过反射来替换对象,把系统中的对象替换为仿造的,仿造有三种方式,一是直接创建,这需要类是比较简单的情况,并不需要开放出来,通过反射一切皆可创建;二是继续,这个对于复杂对象也能仿造,如Instrumentation,但是需要类是开放出来的;三是接口,通过动态代理 创建仿造对象(也即代理 )。核心技术就这些。其他的,全是对于系统代码的理解,找到可行的关键点来进行hook。

另外就是,谷歌对逆向方法限制越来越严了,反射系统的东西,会有限制,有时仅是打印日志,但指不定哪天就不给反射了。

Accessing hidden field Landroid/app/ActivityManager;->IActivityManagerSingleton:Landroid/util/Singleton; (light greylist, reflection)

插件化原理

学习一门技术最好的方式就是去研读优秀的开源库的源码,对于插件化,现在有很多比较成熟 的开源框架存在了,可以挑几个比较有代表性的来研究 一下。

DroidPlugin

这个基于动态代理创建的插件方法,较为流行,里面有大量的hook技术,网络上也有很多解析此框架的文章,可以帮助理解。

它用了大量的hook,优点就是插件本身可以是正常的apk,无太多的限制,就用常规的app开发方式开发就好,这是它的最大优势,因为对插件无限制,所以框架本身就需要做大量的hook,是学习hook技法的良好例子。

DL : Apk动态加载框架

这个是以静态代理为基础创建的插件框架,并没有大量的hook,可以参看它的解析文章。

任大神的框架适配性较好,基本上是纯软件层的技术(静态代理),没怎么hook。当然缺点也相当明显,就是对于插件的开发要求很苛刻,必须实现框架本身自定义的一坨东西,与安卓标准的app开发差异较大,且越来越大,并且对于打包和开发过程并无工具支持,在实际应用过程中较为麻烦。退一步讲,并未有真正达到插化的目的,它对插件的限制较大。

现在已经基本没人用了,不过这属于开山之作。

Qigsaw

这个与其他插件框架的最大差别在于,它最接近于官方的东西(App bundle),它的重点在于项目模块化和打包上面,对于常规理解上的『插件』所做的事情特别少,hook特别少,安装和加载插件的过程比较很简单,接近原生,核心在于它的打包过程。这里有详细的介绍。

另外,包建强的书《Android插件化开发指南》也可以读一读的,书的好处在于,它毕竟是一个整体,从基础的技术原理到hook原理都有讲,还是相当不错的。不过书比较旧了 ,要结合作者的勘误,以及网上的文章一起来消化理解。

热修复原理

除了插件化,另外一个大厂热衷的技术便是热修复,这也是大厂头部应用的标配技术。其实插件化,也能实现热修复,比如某个插件,一般是厂里的一个业务,出问题了,紧急打包发布一个修复的版本,然后更新插件。不过,这略显笨重,相当于用牛刀去杀鸡了,总之就是效率不高。

真正的热修复技术讲究效率,且要小巧,针对 点对点式的修复。它的核心原理就是替换,用反射去替换类(修改dex classloader中的dex顺序),以及对方法的替换(侵入虚拟机中的method表,进行替换),还分冷生效(类替换一般是冷生效,也即下次启动时生效)和热生效(方法替换一般是热的,下次调用此方法时就生效了,因为它并不涉及classloader,无需要重新加载类),还有插桩式的,在代码中直接插桩,先检查有没有patch,有patch就先运行patch(这个思路最简单,适配性也好,但实行难度大,需要对现有代码进行插桩)。

这几篇文章有比较详细的讨论。

  • Android热修复技术原理详解
  • Android热修复技术,你会怎么选?
  • 探索Android开源框架 - 11. 热修复原理

具体的热修复工具

xposed派系

也即原生的Xposed和Xposed framework
以及大阿里的衍生版本dexposed。

针对 方法可以热生效的hook,当年Dalvik时代,这个东西还是相当牛逼的,时过境迁虽然Art上无法用了,但不妨用来学习。

Andfix

原产自支付宝的与Xposed类似的方法级的hook工具,支持Dalvik与Art,值得使用和学习。

AndroidMethodHook

可以用来学习sophix,sophix是大阿里的东西,把andfix以及dexposed商业化了,不再开源免费用了。这个项目比较接近它们,可以用来学习。

Tinker

微信出品的Tinker,核心技术还是用dex替换实现的class替换,冷生效。

它的重点在于补丁dex的差量生成,以及发布平台,还做成了收费平台,变成一种服务。所以,你看核心技术是由目标平台(安卓)决定的,原理大家也都懂,各家也都大差不差的,也都有开源现成的方案可以用,但这远远不够,整个链路是值得深挖的,这也是能产生商业价值的地方。

HotFix

安卓App热补丁动态修复技术介绍

Nuwa

安卓热更新之Nuwa实现步骤

Robust

Android热更新方案Robust开源,新增自动化补丁工具

这个与Nuwa一样,都用了代码插桩,当然插桩过程,是用了字节码工具(如ASM),进行编译时自动化处理,最终字节码(APK)是受影响的,但源码层面是无感知的。

瓶颈在哪里

插件化这项技术,它的成本特别高,但收益有限,需要庞大的研发体系来支持,并且只有长期投入,才能产出一些价值。因此,现在来说只有头部大厂才真正玩得转。

技术本身并不是瓶颈

这项技术的可行性是由Java决定的,因此一直是可行的。但每年的Android版本,都会对核心组件进行不同程度的强化和升级,这会导致之前的一些方案可能一下子就失效了。另外,手机厂商可能也会做一些修改,不过一般都比较小。

安卓 版本升级,会对插件化有影响,甚至会让现有方案全部失效,但这个还真不是这项技术的瓶颈。因为安卓 升级较慢,正常一年一个版本,但是对核心组件大变化,通常几年才有一次,这个速度对比三方技术的演进还是相当慢的。前面说了这项技术头部大厂最为受益,因此他们会有专门的专家级别的人物在研究,谷歌出了政策,很快就会对策出来,一般用不了多久,插件化技术大拿们就能给出针对 新版本的解决方案。

由于开源和技术分享,很快便会在业界普及。因此,单就技术本身,绝不是瓶颈,并且由于开源的发展,核心业务本身都是开源的,大家都能很快使用最先进的技术。

网络和平台能力才是瓶颈

插件化这个事情,想要真正的用好,光有核心业务还是不够的。核心业务现在都有现成的开源库,拿过来就可以用,但这远远不够。

就从一个插件从开发人员手中到用户手中,并成功安装生效,这一过程拆来看需要多少东西吧:

  1. 插件的开发,需要一些辅助工具。理想的情况下,一个插件模块的开发,应该与常规应用开发是一样的,但毕竟它的构建目标是一个插件,而非标准的app,所以你需要针对核心业务插件框架适用的一些开发工具。这个一般开源框架中都有提供,但不见得有那么好。
  2. 构建和打包。如果是一个合格的插件化框架,一定会有怎么构建 打包的配套设施。
  3. 测试和调试。这里面的难点在于,如何能尽可能的模拟真实的流程,并且能方便的来实施测试和验证结果
  4. 发布上线控制。一些细节就是如何精准推送,如何做灰度发布,以及发现问题后如何快速回滚(你看,这哪一项涉及插件化技术)
  5. 下载。客户端的一个最大的问题就是,客户端在客户那里,我们发布的东西都在服务器上,如何能让插件顺利的送达到用户手中。别小看这个,网络问题永远是出错误原因里面最多的一个,而且容易被测试忽略,因为研发人员自己的网络环境一般简单且稳定。(一个最简单的测试就是,当你在电梯里,地铁里,高铁时,厕所里,山上,河里,村里,手机里面的应用还有几个能正常联网的?)
  6. 安装和生效。这个也是插件化的核心业务,框架都会支持的。难点在于校验,就是客户端拿到的插件是不是符合预期的,文件有没有损坏,有没被篡改。
  7. 降级。这个通常插件化框架不会提供。降级的意思就是如果插件安装更新失败了,你怎么办?能否回滚,如果这个插件彻底废了,有没有H5页面可以用?

我们粗略来看,就能分出上面7个步骤,其实还有更细的。上面这些里,插件化开源框架一定能解决的是2和6,1和3会在一定程度上支持。而其他的只有靠自己了,当然 也可能会有一些开源软件可以用,但它们并不纯是为了插件化而做的。这些东西都属于研发效率平台,甚至是涉及软件流程,基本上都属于商业公司的核心业务机密了,基本上是不可能开源的,而且不同的公司文化制度流程都不一样,即使开源给你了,也不一定用得上。但这恰恰又是最能体现一个公司结合技术实力的地方,小公司或者综合能力差的公司,即使有现成的插件化框架方案给你,你也用不好,因为配套设施不行。再次佐证,插件化这东西只有头部大厂才能玩得转,并产生正收益。

这些才是真正的瓶颈。

这是逆向工程技术

插件化需要用到大量的反射和动态代理技术去hook安卓系统,从而实现官方并不直接支持的特性,这属于逆向工程,与官方倡导的方向并不一致。

而且,只有在国内圈子里面才比较流行,国外的一些大厂和专家似乎并不愿意花时间和精力搞这些事情。很难简单的用好与坏来评价,只能说文化不同。

逆向工程技术局限性较大,很难长久发展, 一旦官方把某个关键地方堵住(不能说是漏洞,而一些关键的对象和接口),很多插件框架可能就废掉了,当然了道高一尺,魔高一丈,总还是能找到可以hook的地方,仍总感觉怪怪的。

常规的技术,如编程范式(函数式编程,Reactive,RxJava),编程语言,平台框架和轮子(如Picasso,如OkHttp),这些是纯正的技术,不受制于任何平台,不但能长久发展,更能反过来推动官方进步(如OkHttp已被谷歌内置为安卓内部作为HTTP协议的实现)。

综合来说,除非你需要专门研究插件化,并能得到收益之外(对业务,对公司,对个人),对于插件化技术,了解一下就够了,而且这东西并不能真正的提升软件质量(它带来的问题比它解决的要多很多)。不如把时间花在业务上面,花在编程范式,花在编程语言,花在流行的框架和轮子上面,这更能提升软件质量,且是终生受益的。毕竟,假如代码质量够好,发出去的版本都可控,都能达到预期,也就没必要折腾插件化了(即使是对大厂头部应用来说,版本的发布仍主要是靠正常的apk发布,插件迭代一般用在正常版本来不及时使用比如电商的双11期间)。

**研发工具(如Instant Run),调试工具(如获取 一些运行时的信息,在线调试),测试工具(如Mock),不侵入源码式编程(动态插桩,AOP和依赖注入)**才是反射和动态代理以及Hook的最终归宿,是值得我们深入研究和学习的方向。

参考资料

  • 动态注入技术(hook技术)
  • Android插件化原理解析——Hook机制之动态代理
  • 插件化知识详细分解及原理 之代理,hook,反射
  • 盘点Android常用Hook技术
  • 理解 Android Hook 技术以及简单实战
  • Android Hook技术防范漫谈
  • Android插件化——高手必备的Hook技术
  • Android Hook 机制之简单实战
  • 字节跳动开源 Android PLT hook 方案 bhook

原创不易,打赏点赞在看收藏分享 总要有一个吧

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/87982.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Docker 容器监控之CAdvisor+InfluxDB+Granfana

是什么 一句话:CAdvisor监控收集InfluxDB存储数据Granfana展示图表 CAdvisor InfluxDB Granfana 总结 容器编排CIG CIG CAdvisorInfluxDBGranfana 1、新建目录 2、新建docker-compose.yml文件 version: 3.1volumes:grafana_data: {}services:influxdb:image: t…

C语言实现八种功能的通讯录(添加、删除、查找、修改、显示、排序、退出、清空)

通讯录功能概要及前提说明 此通讯录利用C语言完成,可以实现八种功能的通讯录(添加、删除、查找、修改、显示、排序、退出、清空) 代码由三部分组成,为什么要写成三部分而不写成一部分可以参考我以前的博客,如下&…

【PMP/软考】软件需求的三个主要层次:业务需求、用户需求和功能需求解释及实例解析

简述 当进行需求分析时,通常着重考虑三个主要层次:业务需求、用户需求和功能需求。业务需求关注项目与组织战略目标的一致性,用户需求明确最终用户的期望,而功能需求定义具体的系统功能和特性。这三个层次为项目管理和软件工程提…

基于改进莱维飞行和混沌映射的粒子群优化BP神经网络预测股票价格研究(Matlab代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…

[架构之路-223]:数据管理能力成熟度评估模型DCMM简介

目录 一、背景 二、评估依据 三、评估内容 四、主要适用对象 五、能力等级 六、不同层次的文件: 一、背景 信息技术与经济社会的交汇融合引发了数据爆发式增长。数据蕴含着重要的价值,已成为国家基础性战略资源,正日益对全球生产、流通…

更适合程序员体质的PPT制作工具——Slidev

Slidev简介 Slidev是什么 Slidev是一款基于Vue.js的现代化幻灯片制作工具,它可以帮助用户快速、高效地制作出美观、专业的幻灯片。 目前市面上有很多功能丰富的、通用的、所见即所得的幻灯片制作工具,例如 微软 PowerPoint 或 苹果 Keynote. 它们在制…

tp8 Editor.md

Editor.md - 开源在线 Markdown 编辑器 放于public文件夹下 html代码&#xff1a; <div class"layui-col-md12" id"content"><textarea name"content" placeholder"详情" class"layui-textarea">{notempty nam…

buuctf web [极客大挑战 2019]Upload

上传头像&#xff0c;上传一下&#xff0c;看看能不能成功 抓包&#xff0c;抓取上传时的数据,看看限制条件 改两个地方&#xff0c;符合上传图片的要求&#xff0c;上传试试 一句话木马的<?被扳了 改一下木马的格式 <script language"php">eval($_POST[cm…

Tomcat 开启远程调试

Tomcat 部署的 war包工程开启远程调试 Linux服务器下&#xff0c;编辑Tomcat bin 目录下的 startup.sh 文件 vim startup.sh在第一行加入&#xff1a;(不换行&#xff0c;在同一行) declare -x CATALINA_OPTS"-server -Xdebug -Xnoagent -Djava.compilerNONE -Xrunjdwp:…

Redis 集群搭建教程

一、介绍 Redis 集群有着高可用、易扩展、更好的性能等优势&#xff0c;本文主要是实战搭建一个三主三从的 Redis 集群。 正常来说&#xff0c;搭建 Redis 集群需要 6 台服务器。为了简单一点&#xff0c;本文通过一台服务器&#xff0c;6 个端口&#xff0c;搭建一个 Redis …

孜然单授权系统V1.0[免费使用]

您还在为授权系统用哪家而发愁&#xff1f;孜然单授权系统为您解决苦恼&#xff0c;本系统永久免费。 是的&#xff0c;还是那个孜然&#xff0c;消失了一年不是跑路了是没有空&#xff0c;但是这些都是无关紧要的&#xff0c;为大家带来的孜然单授权系统至上我最高的诚意&…

数据安全态势管理:什么是事实,什么是虚构?

考虑到组织存储大量数据的日益复杂的云环境&#xff0c;数据安全态势管理 ( DSPM )的兴起并不令人意外。使组织能够全面了解云数据资产和敏感数据的安全状况的流程对于当今的安全团队来说非常有价值。 尽管 DSPM 的重要性日益凸显&#xff0c;但人们对于它能为企业做什么和不能…

序列化对象(ObjectOutputStream,ObjectInputStream)

1、对象序列化 作用&#xff1a;以 内存 为基准&#xff0c;把内存中的对象存储到磁盘文件中去&#xff0c;称为对象序列化使用到的流是对象字节输出流&#xff1a;ObjectOutputStream package com.csdn.d7_serializable; import java.io.*; public class ObjectOutputStreamDe…

电脑开机慢问题的简单处理

电脑用久了&#xff0c;开机时间要10-20分钟特别慢&#xff0c;一下介绍两种简单有效处理方式&#xff0c;这两种方式经测试不会影响原系统软件的使用&#xff1a; 方式一&#xff1a;禁用非必要启动项【效果不是很明显】 利用360里面的优化加速禁用启动项【禁用启动项还有其…

大数据Flink(八十九):Temporal Join(快照 Join)

文章目录 Temporal Join(快照 Join) Temporal Join(快照 Join) Temporal Join 定义(支持 Batch\Streaming):Temporal Join 在离线的概念中其实是没有类似的 Join 概念的,但是离线中常常会维护一种表叫做 拉链快照表,使用一个明细表去 join 这个 拉链快照表 的 join …

【LeetCode-简单题】501. 二叉搜索树中的众数

文章目录 题目方法一&#xff1a;暴力哈希方法二&#xff1a;利用二叉搜索树的特性&#xff08;递归双指针&#xff09; 题目 方法一&#xff1a;暴力哈希 这是针对于普通二叉树的解法 统计number出现次数 然后将次数最大的众数集 取出来 Map<Integer , Integer > map …

Mysql备份恢复、与日志管理

Mysql日志管理、备份与恢复 一、Mysql日志管理1.1、日志分类1.1.1、错误日志1.1.2 、通用查询日志1.1.3、 二进制日志1.1.4 、慢查询日志1.1.5 、配置日志 1.2、日志的查询 二、备份与恢复2.1、 数据备份的必要性2.2 、造成数据丢失的原因2.3、 数据库备份的分类2.3.1、 物理备…

mysql-4:SQL的解析顺序

SQL语句的解析顺序 文章目录 SQL语句的解析顺序编写顺序与解析顺序解析顺序关键字FROMONOUTER JOINWHEREGROUP BYHAVINGSELECTDISTINCTORDER BYLIMIT 解析流程流程分析流程说明WHERE条件解析顺序 编写顺序与解析顺序 编写顺序 SELECT DISTINCT < select_list > FROM &l…

Linux C/C++下收集指定域名的子域名信息(类似dnsmap实现)

我们知道dnsmap是一个工具&#xff0c;主要用于收集指定域名的子域名信息。它对于渗透测试人员在基础结构安全评估的信息收集和枚举阶段非常有用&#xff0c;可以帮助他们发现目标公司的IP网络地址段、域名等信息。 dnsmap的操作原理 dnsmap&#xff08;DNS Mapping&#xff…

AMEYA360:瑞萨电子整合Reality AI工具与e² studio IDE,扩大其在AIoT领域的卓越地位

全球半导体解决方案供应商瑞萨电21日宣布已在其Reality AI Tools?和e2 studio集成开发环境间建立接口&#xff0c;使设计人员能够在两个程序间无缝共享数据、项目及AI代码模块。实时数据处理模块已集成至瑞萨MCU软件开发工具套件&#xff08;注&#xff09;&#xff0c;以方便…