当前位置: 首页 > news >正文

Android5.1.1 - APK签名校验分析和修改源码绕过签名校验

Android5.1.1 - APK签名校验分析和修改源码绕过签名校验


作者:寻禹@阿里聚安全


APK签名校验分析

找到PackageParser类,该类在文件“frameworks/base/core/java/android/content/pm/PackageParser.java”中。PackageParser类的collectCertificates方法会对APK进行签名校验,在该方法会遍历APK中的所有文件,并对每个文件进行校验。下面是该方法的部分源码:

APK是一个ZIP格式的文件所以使用ZIP相关的类进行读写。上面代码中调用了loadCertificates方法,这个方法返回一个二维数组,如果APK中的文件签名校验失败那么loadCertificates方法会返回一个空数组(可能是null,可能是数组长度为0),按照上面代码的逻辑如果数组为空则会抛出异常。

loadCertificates方法的代码见下:

上面代码中is是JarFile.JarFileInputStream类的对象。loadCertificates方法中调用了readFullyIgnoringContents方法,在readFullyIgnoringContents方法中会调用JarFile.JarFileInputStream.read方法读取APK中一项的数据,在read方法中会校验读取到的数据项的签名,如果签名校验失败,则会抛出SecurityException类型的异常,即签名校验失败。

JarFile类在“libcore/luni/src/main/java/java/util/jar/JarFile.java”文件中。

上面代码中调用了StrictJarFile.getCertificateChains方法,下面是它的代码:

上面代码中isSigned的值是这么来的:

当证书读取成功,并且当前APK经过了签名,则isSigned为true。

回到StrictJarFile.getCertificateChains方法中,当isSigned为true时会调用JarVerifier.getCertificateChains方法,下面是它的代码:

下面是类成员变量verifiedEntries的声明:


verifiedEntries是一个键值对,键是APK中经过了签名的文件名,如:classes.dex文件,值是证书数组。如果向已经签过名的APK中新添加一个文件然后安装这个APK,当程序逻辑执行到JarVerifier.getCertificateChains方法中时,在verifiedEntries变量中无法找到新添加的文件名(因为这个新文件是在APK签名之后添加),那么JarVerifier.getCertificateChains方法将返回null。


绕过签名校验

源码修改点一

找到PackageParser.loadCertificates方法,下面是部分源码:

将上面代码catch块中的throw语句替换为:return null;

下面是修改后的代码:

代码修改完后,当APK中文件签名校验失败时不会抛出异常,APK还会继续安装。

源码修改点二

找到PackageParser.collectCertificates方法,找到代码中调用loadCertificates方法的地方:

将上面的throw语句替换为:continue;

修改后的代码:

代码修改完后,当遇到APK中没有经过签名的文件时不会抛出异常,APK还会继续安装。


作者:寻禹@阿里聚安全,更多Android技术文章,请访问阿里聚安全博客


阿里聚安全由阿里巴巴移动安全部出品,面向企业和开发者提供企业安全解决方案,全面覆盖移动安全、数据风控、内容安全、实人认证等维度,并在业界率先提出“以业务为中心的安全”,赋能生态,与行业共享阿里巴巴集团多年沉淀的专业安全能力。


相关文章:

  • Web标准制定过程
  • 文本管理工具及正则表达式的元数据总结
  • Linux面试题
  • HDU 5813 Elegant Construction 构造
  • 详解 ML2 Core Plugin(I) - 每天5分钟玩转 OpenStack(71)
  • IOS 压力测试-UI AutoMonkey
  • 将 Measurements 和 Units 应用到物理学
  • LeetCode 92 Reverse Linked List II(翻转链表II)(Linked List)(*)
  • 代理设计模式
  • 3.《Spring学习笔记-MVC》系列文章,讲解返回json数据的文章共有3篇,分别为:...
  • Linux 第九天: (08月11日) 练习和作业
  • 原生js库,持续更新中……
  • MongoDB工具简要说明
  • apk签名
  • Java中创建对象的5种方式
  • [LeetCode] Wiggle Sort
  • 【140天】尚学堂高淇Java300集视频精华笔记(86-87)
  • EOS是什么
  • ES学习笔记(12)--Symbol
  • Github访问慢解决办法
  • IP路由与转发
  • JavaScript设计模式之工厂模式
  • JS基础之数据类型、对象、原型、原型链、继承
  • leetcode讲解--894. All Possible Full Binary Trees
  • maven工程打包jar以及java jar命令的classpath使用
  • Spring技术内幕笔记(2):Spring MVC 与 Web
  • vue-router的history模式发布配置
  • Vue实战(四)登录/注册页的实现
  • 不上全站https的网站你们就等着被恶心死吧
  • 给Prometheus造假数据的方法
  • 深度学习在携程攻略社区的应用
  • 使用putty远程连接linux
  • 事件委托的小应用
  • 我看到的前端
  • 我与Jetbrains的这些年
  • 用quicker-worker.js轻松跑一个大数据遍历
  • 中文输入法与React文本输入框的问题与解决方案
  • 蚂蚁金服CTO程立:真正的技术革命才刚刚开始
  • 新年再起“裁员潮”,“钢铁侠”马斯克要一举裁掉SpaceX 600余名员工 ...
  • ​​快速排序(四)——挖坑法,前后指针法与非递归
  • ​【C语言】长篇详解,字符系列篇3-----strstr,strtok,strerror字符串函数的使用【图文详解​】
  • ​Linux Ubuntu环境下使用docker构建spark运行环境(超级详细)
  • ​linux启动进程的方式
  • ​MPV,汽车产品里一个特殊品类的进化过程
  • # Apache SeaTunnel 究竟是什么?
  • #我与Java虚拟机的故事#连载18:JAVA成长之路
  • (4)(4.6) Triducer
  • (剑指Offer)面试题41:和为s的连续正数序列
  • (原创)攻击方式学习之(4) - 拒绝服务(DOS/DDOS/DRDOS)
  • .bat批处理(三):变量声明、设置、拼接、截取
  • .NET 跨平台图形库 SkiaSharp 基础应用
  • .net2005怎么读string形的xml,不是xml文件。
  • .NetCore部署微服务(二)
  • @select 怎么写存储过程_你知道select语句和update语句分别是怎么执行的吗?
  • [Android]Android开发入门之HelloWorld