《Android应用逆向——分析反编译代码之大神器》
在之前的一篇文章中,我们提到一个思路,使用 apktool 解包目标APK,然后在感兴趣的JAVA包里使用脚本批量注入日志,随后重新打包APK,安装运行后,函数的执行流程就通过logcat打印了出来,目标APP点击某个按钮后执行了哪些函数一目了然。
回顾一下大致思路:
public class InjectLog {
public static void PrintCaller()
{
Thread cur_thread = Thread.currentThread();
StackTraceElement stack[] = cur_thread.getStackTrace();
Log.d("InjectLog", stack[3].toString() + "[" + cur_thread.getId() + "]");
}
}
我们写了这样一段JAVA代码,用于输出调用者的函数名。
然后我们又写了一行JAVA代码:
InjectLog.PrintCaller();
反编译为smali代码:
invoke-static {}, Lcom/hook/tools/InjectLog;->PrintCaller()V
然后把这句smali代码,批量注入到目标APP的smali代码中,让目标APP的每个函数都会调用这行代码,就能实现观测目标APP函数执行流程的效果。
这个思路行之有效,被转到52pojie论坛中,很多同学使用了都说好。不过之前的文章中我们只是讲了思路,注入脚本也写的很潦草很随意,对于各种异常情况没有做处理,比如有的APK反编译的smali代码,没有.prologue标记,导致注入失败,并且存在重复执行脚本会导致重复注入多行代码的情况。于是这一章,我们完善了一下这个注入脚本,修复这些问题,并放到Github上,大家一起来完善,也可以提 issues 反馈问题,使得这个工具可用性越来越好。同时,本章我们也通过一个小小的案例,来回顾一下这个工具的具体用法。
项目地址:https://github.com/encoderlee/android_tools
需要先安装 Python3
用法示例:
1.先用 apktool 解包 apk 到目录 f:\alipay_10.1.30
2.执行 inject_log.py -c 目标是 apktool 解包出的文件夹根目录
inject_log.py -c f:\alipay_10.1.30\
这一步作用其实是把 InjectLog.smali 拷贝到 f:\alipay_10.1.30\smali\com\hook\tools\ 中,InjectLog.smali 就是 InjectLog.PrintCaller()函数的实现,对于每个apk项目,这个步骤只需做一次
3.注入代码:
① 只对一个 smali 文件注入代码
inject_log.py f:\alipay_10.1.30\smali_classes5\com\alipay\mobile\payee\ui\PayeeQRActivity.smali
② 对一个目录下的所有 smali 文件注入代码,不递归子目录
inject_log.py f:\alipay_10.1.30\smali_classes5\com\alipay\mobile\payee\ui\
② 对一个目录及它所有子目录下的所有 smali 文件注入代码,递归子目录
inject_log.py -r f:\alipay_10.1.30\smali_classes5\com\alipay\mobile\payee\ui\
小技巧:
可以把 inject_log.py 放到一个目录中,把这个目录添加到 PATH 环境变量中
接下来在任意位置,按住【shift】键,点击鼠标右键,就可以在此位置打开CMD窗口
然后就可以直接对当前目录执行注入脚本工作了:
inject_log.py -c ./
inject_log.py -r ./
先缩小范围,确定关键代码在某几个包中,再小范围批量注入代码,不要一上来就对整个APK全部注入代码,那样运行起来会卡死奔溃的
注入代码前,最好先用 git 跟踪 apktool 解包出的整个项目文件夹,这样清除注入的日志也方便
git chekout .
《Android逆向小技巧①:从Activity下手找到切入点,逆向分析支付宝APP》
上一篇文章,我们通过 adb 获取了 Activity 名,并通过【Android Device Monitor】获取 resource-id ,找到了关键代码的大致位置。
在支付宝的收款二维码界面点击【设置金额】后来到了第二个界面,通过 adb 获取到了 Activity 名为:
com.alipay.mobile.payee.ui.PayeeQRSetMoneyActivity
于是我们将目光锁定到了 com.alipay.mobile.payee.ui 这个JAVA包,使用日志注入工具对该包下的所有 smali 注入代码。
在首次注入代码前,我们需要到 apktool 解包出的根目录里执行:
inject_log.py -c f:\alipay_10.1.30\
此举作用在于往目标APK中放入一个文件 smali\com\hook\tools\InjectLog.smali 该文件是 InjectLog.PrintCaller() 函数的实现,没有这个文件的话,调用 InjectLog.PrintCaller() 会出错的。
然后我们找到 com.alipay.mobile.payee.ui 所在的 smali 文件目录:
f:\alipay_10.1.30\smali_classes5\com\alipay\mobile\payee\ui
使用日志注入工具注入代码:
inject_log.py -r f:\alipay_10.1.30\smali_classes5\com\alipay\mobile\payee\ui
随后用 apktool 重打包并安装运行,在 Android Studio 中打开 logcat ,过滤 tag 为 InjectLog,查看日志输出。
so easy !
我们可以看到在 PayeeQRSetMoneyActivity 界面 onClick 点击 确定 按钮后,执行了几个函数,后面到了
PayeeQRActivity.onActivityResult() 的时候,其实 确定 按钮的功能代码已经执行完了,得到了二维码结果并返回了上一个界面PayeeQRActivity。这样一来,大大的进一步缩小了重点关注的范围,只需要在这几个函数上研究反编译的JAVA代码,很快就能找到关键点。
果然,很快就找到了关键实现代码:
ConsultSetAmountReq localConsultSetAmountReq = new ConsultSetAmountReq();
localConsultSetAmountReq.amount = this.g;
localConsultSetAmountReq.desc = this.c.getUbbStr();
localConsultSetAmountReq.sessionId = this.h;
new RpcRunner(new cs(this), new cr(this)).start(new Object[] { localConsultSetAmountReq });
构造一个 ConsultSetAmountReq 对象,分别赋值 amount 金额,desc 备注,sessionid,然后放入RpcRunner中向服务器发送请求。接下来,继续深入分析他是怎么发的请求,或者止步于此,直接使用Xposed注入模块到支付宝进程中,调用这段代码就能实现相同的效果。
另外,关于有的APK使用 apktool 解包或打包出错。重新打包后的微信、支付宝等APK,签名验证不通过而无法登陆该怎么办,在后续文章中我们将一一道来。
日志注入工具更新内容:
2019年05月31日
输出函数名的时候增加了序号,方便观察,以免同名函数反复调用的时候扰乱视觉
本文由encoderlee发表于CSDN博客: https://blog.csdn.net/CharlesSimonyi/article/details/90691417 转载请注明出处