Android 中的那些 Hacker技术

日常君
·
·
IPFS

Android 中的那些 Hacker 技术

本文的主要内容将以反编译 apk,修改 apk 为主。同时也会介绍如何针对系统 framework 的反编译。最后我们以微信 app 为 demo,来一场综合应用,看如何反编译它,并绕过 APP 的签名校验,dex 哈希校验,加入自动增加微信信运动步数的功能。

1.什么是反编译?为什么要反编译?

简单的来说就是一种逆向的过程,将二进制的 apk 还原成为我们能够理解的 “ 汇编 ” 形式。通常在我们的开发阶段,都避免不了对竞品的分析,或者有些疑难 bug 只在特定的手机上才出现。这都需要我们通过逆向去分析。

2.相关工具整理及介绍

Apktool:用于反编译和重打包。

dex2smali:将 dex 文件转为 jar 等格式。

jd-gui:查看 jar 文件的工具。

jadx:比较综合的一款反编译工具,将dex文件转换为java的效果比较好,然后再将 java 文件拖入 studio 中分析。

vdexExtractor:用于从 O 上的 vdex 文件中提取出 dex 文件。

dextra:用于从 odex 文件中提取出 dex 文件。

apktool_AndResGuard:如果 apk 被 AndResGuard 处理过,用 apktool 会出现 “ No resource found ” 等错误,则可以用这款改进版的 apktool。

SigKill:通过 hook PackageManagerService,达到可以一键绕过 APP 签名验证的效果。重点推荐,赶紧去点 Start 和 Fork 吧

3.先来看看如何反编译出手机系统的 framework 源码

首先通过 adb pull 拿出 framework:


然后通过 grep 确定 framework 所在的文件:


再通过 vdexExtractor 提取出 dex 文件:


一般来说是没问题的,but 总有刁民喜欢乱搞。这不,用 OPPO 8.1 的手机就失败了。现在肿么办?喜欢看热闹的你是不是感到很惊喜!那就来手动提取吧。 因为 vdex 里面其实包含了完整的 dex 文件。简单看下 vdex 的header定义: 


可以看到第 3 个的 4 字节起表示这个 vdex 里面有多少个 dex 文件。 我们会根据这个信息来决定提取多少个 dex 文件。

现在先用 vim -b 打开 vdex 文件,并在末行模式下输入 %!xxd 切换到 16 进制模式显示:

 这时看到了我们熟悉的 dex.037,我们就是要将从这里开始的数据提取出来。但是我们一共要提取几个,从上面的vdex格式我们知道第 9 - 12 字节就是我们要提取的数量。

0100 0000,转成 10 进制为 1,也就是说这个 vdex 一共只包含了 1 个 dex。

接下来就用 dd 大法抠出 dex 文件:


参数解释:if 为输入文件,of 为输出文件,bs 可以为固定的 1, skip 为跳过的字节数,count 为要扣出来的字节长度。 按照 dex 的格式,第 32 字节开始的 4 个字节为 dex 长度,所以也就是 bc9b a200 这 4 个字节,拼成 16 进制为 0x00a29bbc,转成 10 进制也就是 10656700。

现在我们有了 dex 文件,接下来的就简单了。可以转成 jar 用 jd-gui 看。但是我个人比较喜欢转成 Java 放到 studio 中看,因为 studio 更强大,也更好操作。

于是用 jadx 将上一步生成的 out.dex 转换为 java 文件:


最后将 java 文件 copy 到 studio:


现在我们就能在熟悉的 studio 中查看 framework 各部分的代码。 分析这些厂商到底加入了什么代码导致我们的 APP 发生一些奇奇怪怪的问题!

总结:通过上面的学习我们知道了如何反编译出系统 framework,并导入到 studio 中进行分析。

4.那我们又如何反编译 apk 呢?

我们下载一个最新版的微信 apk 6.6.7,来看一下 apk 里面到到底包含了哪些内容 

通过 apktool 反编译 apk: 


这里特别说一下,从上面 apk 的图里可以看到微信 apk 被 AndResGuard 处理过,所以我们要用 apktool-2.3.2-yanchen.jar 进行反编译 / 重打包,如果用官方的 apktool 则会出现下面这样的错误:


下一步,移除微信中的保护:

现在完成了对微信 APK 的反编译,接下来就可以通过修改 smali 等来更改微信的功能了。但是在这之前,我们还有一些额外的事情要做,那就是去除微信的保护 (废话,不然搞毛)。这就要求我们要有一定的 smali 基础才行。smali 基本语法不是本次的重点,这里推荐一个入门的教程,大家稍作了解即可( smali教程,大概了解怎么调用函数,怎么传递参数,if-else怎么写就行了。)

那现在我们思考一下可能会存在哪些保护呢? 毫无疑问,首当其冲的就是签名校验,不仅在 Java 层有,native 层也有。但除了这其实还有 dex 文件 Hash 的校验。

先从一段简单的签名验证说起:


其实一般的签名验证大致都是这样,会通过 PackageManager 获取签名,然后和预期的信息对比。如果不一致则会认为是非法客户端。

那我们如何绕过呢?

如果你的想法是将保存的信息修改或者将判断条件修改,那么恭喜你,入门了! 但是你怎么知道是哪些信息呢?怎么去找呢?如果是在 native 层的又如何去改呢?并且如果有的 APP 比较变态,重复写了几十处这样的代码,会好找吗?

当然说了这么说,其实只要用上面工具中提到的 SigKill 就都解决了。通过它可以自动搞定所有的签名校验,用法也很简单,只有三步,可以参考 github。

于是我们就很愉快的破掉了签名验证,那还剩下文件 hash 校验。那文件 hash 校验是怎么做的呢?其实也是读取 dex 文件的哈希和值,和预期的对比。这里就直接说微信是怎么做的吧。


可以看到微信将几个 dex 文件的 md5 保存在了 assets/secondary-program-dex-jars/metadata.txt 文件里面,这样我们只需要在打包后,重新计算出新 dex 的 md5,并更新到这个文件就可以了。 现在,我们终于移除了破解机制。可以搞它了。

开始添加自动增加运动步数功能

那你得要先知道在哪里添加吧。如何分析不是本次重点,这里就直接说结果吧。

运动是在 SportService 里面添加了一个 sensor listener: 

opr 这个变量对应的文件是: 


所以理论上我们只要在 k.smali 这个文件的 onSensorChanged ( ) 里面修改下数据就可以的。 下面是我们写的一段自动运动的 java 代码:





代码解释: 上面的代码主要功能是每隔 10 - 15 分钟自动产生 500 - 1200 步。 一切都是随机的,是为了避免被检测出使用外挂。 这样即便是我们的手机放着不动也能自动增加运动步数了。

接下来在 Application 中插入去除签名验证的 smali 代码:


将上面的 java 代码编译为 smali 代码,并插入到 onSensorChanged 函数中:


这段 smali 代码翻译为 java 代码也就是下面这样的:


也就是说如果是真正的走路产生的运动我们会忽略掉,之有我们自己产生的才会处理。因为如果太频繁也会被检测到。

然后我们就重新打包:


计算新 dex 的 md5:


更新 apk 中储存的 md5:


然后重新签名安装运行,现在这个帐号初始的步数情况:


现在我们将手机静静的放一会,可以看到有如下 log 输入,说明成功了:


从上面的 log 中可以看到每 10 多分钟就有步数产生了,我们再来打开 APP 查看实际情况:


恩,确实增加了。

然后睡个午觉起来,哈哈,已经霸占第一


总结

通过上面的操作,我们知道了如何绕过一个 APP 的签名验证,并且向里面注入我们想要的功能。针对其他 APP 也是类型的操作手法。

特别申明:微信APP仅在本文中作为一个学习 demo 研究,并非针对该 APP。也请勿将您的修改传到网上或给他人使用!







CC BY-NC-ND 2.0 授权

喜欢我的作品吗?别忘了给予支持与赞赏,让我知道在创作的路上有你陪伴,一起延续这份热忱!