Android 中的那些 Hacker技术
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:
![](https://assets.matters.news/embed/36bcc067-fd5d-43fc-82d8-81c0d99333b0.png)
然后通过 grep 确定 framework 所在的文件:
![](https://assets.matters.news/embed/0012ce74-faf4-46d1-a1dc-ab6260332c94.png)
再通过 vdexExtractor 提取出 dex 文件:
![](https://assets.matters.news/embed/95ff7a90-15d9-4fa9-9394-2c0c90b50494.png)
一般来说是没问题的,but 总有刁民喜欢乱搞。这不,用 OPPO 8.1 的手机就失败了。现在肿么办?喜欢看热闹的你是不是感到很惊喜!那就来手动提取吧。 因为 vdex 里面其实包含了完整的 dex 文件。简单看下 vdex 的header定义:
可以看到第 3 个的 4 字节起表示这个 vdex 里面有多少个 dex 文件。 我们会根据这个信息来决定提取多少个 dex 文件。
现在先用 vim -b 打开 vdex 文件,并在末行模式下输入 %!xxd 切换到 16 进制模式显示:
![](https://assets.matters.news/embed/a527fc1a-19b7-4047-a3bf-fd5f280a151f.png)
这时看到了我们熟悉的 dex.037,我们就是要将从这里开始的数据提取出来。但是我们一共要提取几个,从上面的vdex格式我们知道第 9 - 12 字节就是我们要提取的数量。
0100 0000,转成 10 进制为 1,也就是说这个 vdex 一共只包含了 1 个 dex。
接下来就用 dd 大法抠出 dex 文件:
![](https://assets.matters.news/embed/411b0ebc-9d04-4213-b60c-1e49c302f7ff.png)
参数解释: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 文件:
![](https://assets.matters.news/embed/8fef0400-2119-40ac-a149-aa8f7f5105f2.png)
最后将 java 文件 copy 到 studio:
![](https://assets.matters.news/embed/fb90de5b-4e68-4cc9-bc20-daed0ddb2345.png)
现在我们就能在熟悉的 studio 中查看 framework 各部分的代码。 分析这些厂商到底加入了什么代码导致我们的 APP 发生一些奇奇怪怪的问题!
总结:通过上面的学习我们知道了如何反编译出系统 framework,并导入到 studio 中进行分析。
4.那我们又如何反编译 apk 呢?
我们下载一个最新版的微信 apk 6.6.7,来看一下 apk 里面到到底包含了哪些内容
通过 apktool 反编译 apk:
这里特别说一下,从上面 apk 的图里可以看到微信 apk 被 AndResGuard 处理过,所以我们要用 apktool-2.3.2-yanchen.jar 进行反编译 / 重打包,如果用官方的 apktool 则会出现下面这样的错误:
![](https://assets.matters.news/embed/294be325-bfae-424c-8dba-3652efd23291.png)
下一步,移除微信中的保护:
现在完成了对微信 APK 的反编译,接下来就可以通过修改 smali 等来更改微信的功能了。但是在这之前,我们还有一些额外的事情要做,那就是去除微信的保护 (废话,不然搞毛)。这就要求我们要有一定的 smali 基础才行。smali 基本语法不是本次的重点,这里推荐一个入门的教程,大家稍作了解即可( smali教程,大概了解怎么调用函数,怎么传递参数,if-else怎么写就行了。)
那现在我们思考一下可能会存在哪些保护呢? 毫无疑问,首当其冲的就是签名校验,不仅在 Java 层有,native 层也有。但除了这其实还有 dex 文件 Hash 的校验。
先从一段简单的签名验证说起:
![](https://assets.matters.news/embed/65f6a4ed-0179-4329-b1f0-04bce33d4435.png)
其实一般的签名验证大致都是这样,会通过 PackageManager 获取签名,然后和预期的信息对比。如果不一致则会认为是非法客户端。
那我们如何绕过呢?
如果你的想法是将保存的信息修改或者将判断条件修改,那么恭喜你,入门了! 但是你怎么知道是哪些信息呢?怎么去找呢?如果是在 native 层的又如何去改呢?并且如果有的 APP 比较变态,重复写了几十处这样的代码,会好找吗?
当然说了这么说,其实只要用上面工具中提到的 SigKill 就都解决了。通过它可以自动搞定所有的签名校验,用法也很简单,只有三步,可以参考 github。
于是我们就很愉快的破掉了签名验证,那还剩下文件 hash 校验。那文件 hash 校验是怎么做的呢?其实也是读取 dex 文件的哈希和值,和预期的对比。这里就直接说微信是怎么做的吧。
![](https://assets.matters.news/embed/9b4f6ccf-40d1-4b79-b2b8-5ac6c62a6ccc.png)
可以看到微信将几个 dex 文件的 md5 保存在了 assets/secondary-program-dex-jars/metadata.txt 文件里面,这样我们只需要在打包后,重新计算出新 dex 的 md5,并更新到这个文件就可以了。 现在,我们终于移除了破解机制。可以搞它了。
开始添加自动增加运动步数功能
那你得要先知道在哪里添加吧。如何分析不是本次重点,这里就直接说结果吧。
运动是在 SportService 里面添加了一个 sensor listener:
opr 这个变量对应的文件是:
所以理论上我们只要在 k.smali 这个文件的 onSensorChanged ( ) 里面修改下数据就可以的。 下面是我们写的一段自动运动的 java 代码:
![](https://assets.matters.news/embed/d8378da0-899e-4f40-a370-c3e0f1ccd4c5.png)
![](https://assets.matters.news/embed/47a232fd-1ba1-4514-a446-651702e2c436.png)
![](https://assets.matters.news/embed/95ae5040-8794-4345-a6b9-bdaeffb66dea.png)
![](https://assets.matters.news/embed/f7748bba-e622-41af-a9c2-ee7519dae9c5.png)
代码解释: 上面的代码主要功能是每隔 10 - 15 分钟自动产生 500 - 1200 步。 一切都是随机的,是为了避免被检测出使用外挂。 这样即便是我们的手机放着不动也能自动增加运动步数了。
接下来在 Application 中插入去除签名验证的 smali 代码:
![](https://assets.matters.news/embed/8f4e667a-5e6b-4371-ab00-37eff1940e7f.png)
将上面的 java 代码编译为 smali 代码,并插入到 onSensorChanged 函数中:
![](https://assets.matters.news/embed/420963dc-74d0-4160-bd4b-9159fbe57e0d.png)
这段 smali 代码翻译为 java 代码也就是下面这样的:
![](https://assets.matters.news/embed/2579b549-8b1e-4895-a3ae-7207f0ab94da.png)
也就是说如果是真正的走路产生的运动我们会忽略掉,之有我们自己产生的才会处理。因为如果太频繁也会被检测到。
然后我们就重新打包:
![](https://assets.matters.news/embed/42232b8e-942a-4ee1-821b-cfa7b1504101.png)
计算新 dex 的 md5:
![](https://assets.matters.news/embed/9efd935f-c008-4b8b-9ea2-a9850d87572c.png)
更新 apk 中储存的 md5:
![](https://assets.matters.news/embed/b7b179be-bc08-4f02-854d-e55387dbb421.png)
然后重新签名安装运行,现在这个帐号初始的步数情况:
![](https://assets.matters.news/embed/a6fb348d-950a-43ac-a20d-0074fab1606c.png)
现在我们将手机静静的放一会,可以看到有如下 log 输入,说明成功了:
![](https://assets.matters.news/embed/1a37d796-c922-4e33-8814-02604134990a.png)
从上面的 log 中可以看到每 10 多分钟就有步数产生了,我们再来打开 APP 查看实际情况:
![](https://assets.matters.news/embed/6919a3d0-368e-4b7f-8475-d8ef19551aca.png)
恩,确实增加了。
然后睡个午觉起来,哈哈,已经霸占第一:
![](https://assets.matters.news/embed/ec03149d-c0c5-4a00-a334-390fe9e09240.png)
总结
通过上面的操作,我们知道了如何绕过一个 APP 的签名验证,并且向里面注入我们想要的功能。针对其他 APP 也是类型的操作手法。
特别申明:微信APP仅在本文中作为一个学习 demo 研究,并非针对该 APP。也请勿将您的修改传到网上或给他人使用!
![](https://assets.matters.news/embed/49bddf83-d845-4860-8e62-73668487d9b5.png)
![](https://assets.matters.news/embed/1c5dd0c4-23a8-4320-8c5f-2dfe04bbcdc0.png)
![](https://assets.matters.news/embed/9b7b7248-a4cb-4365-89b5-e7695d5f71f8.png)
![](https://assets.matters.news/embed/b5a623e7-ab92-476d-8867-e3903d2d714c.jpeg)
![](https://assets.matters.news/embed/b8feca3f-06ef-4737-a164-bfc6e7279839.png)
喜欢我的作品吗?别忘了给予支持与赞赏,让我知道在创作的路上有你陪伴,一起延续这份热忱!
![](https://imagedelivery.net/kDRCweMmqLnTPNlbum-pYA/prod/avatar/409c5dac-4004-4a10-8ad7-e635d81a9fd0.jpeg/public)
- 来自作者
- 相关推荐