第三章
关键代码快速定位的方法有很多,基本思路就是通过Hook一些不变的函数,并打印函数栈信息。不变的函数指的是系统函数和一些没有经过混淆的路径固定的第三方库函数,如okhttp3等。本章介绍的定位思路不止可以应用于Java层函数,对于so层函数也是适用的,如通过Hook libc.so、libdl.so、libart.so、linker等系统函数库来定位。
关键代码快速定位
只要App应用程序想要调用系统函数,不管如何混淆,最终在调用时,系统函数的类名和方法名都是不变的。而在App应用程序的开发中,又不可避免地需要使用系统函数。因此,通过Hook一些系统函数来定位关键代码,是逆向分析中的基本操作。
集合的Hook
包括定位散列表HashMap、定位动态数组ArrayList和打印函数堆栈
Hook HashMap定位散列表
处理数据常用

打印函数栈
可以使用Log类的getStackTraceString方法
是通过制造异常的方式获取当前函数栈信息

具体如下

在任意想要打印函数栈的地方调用函数showStacks

Hook ArrayList定位动态数组
ArrayList在开发中也很常用

组件与事件的Hook
Toast定位提示
hook这个函数

根据打印的栈信息找到

可以看出App应用程序给的提示信息越多,关键代码越容易被定位,如在Windows逆向中就很喜欢通过对话框来定位关键代码。由此可见,逆向分析的思想是通用的。
Hook findViewById定位组件
通过组件id来获取组件,再进行点击事件的绑定或数据的获取等操作
通过SDK中的uiautomatorviewer来查看组件id,发现登录按钮的id为btn_login,接着使用Frida来获取登录按钮id对应的数值,btn_login是R类里面内部类id中的属性。

等于说是hook住了findViewById,当点击btn_login断下来

setOnClickListener定位按钮点击事件
一样的原理

常用类的Hook
包括定位用户输入、定位JSON数据、定位排序算法、定位字符转化、定位字符串操作和定位Base64编码
Hook TextUtils定位用户输入
从EditText组件中获取用户输入的数据后,通常需要判断是否为空。这时可能会使用到TextUtils的isEmpty方法

Hook JSONObject定位JSON数据
客户端与服务端进行数据交互时,通常会使用JSON数据作为中间数据进行交互。这时就会用到一些JSON解析相关的类,如JSONObject、Gson等。JSONObject这个类使用的相对较少,因为不是很好用。

上述代码中只Hook了一个重载方法,有需要的可以自行补全。从上述输出结果来看,通过Hook JSONObject类的put方法,定位到的是数据提交的地方。
HookCollections定位排序算法
sort

Hook String定位字符转换
String类的getBytes方法

StringBuilder定位字符串操作
Java中的字符串是只读的,对字符串进行修改、拼接等操作其实都会创建新的字符串来返回。
可以尝试Hook StringBuilder的toString方法来定位App应用程序中的关键字符串。

其他类的定位
Hook定位接口的实现类
有下面这样的类

实现类只有一个InterfaceDemo

先枚举所有已加载的类,筛选出路径以“com.xiaojianbang”开始的类,使用Java.use通过className获取Frida包装以后的类clazz,再通过Java反射机制提供的方法getInterfaces获取该类实现的所有接口。对这些接口进行遍历,如果其中包含名为“com.xiaojianbang.app.TestAbstract”的接口,则该className就是需要寻找的实现类。

Hook定位抽象类的实现类


上述代码先枚举所有已加载的类,筛选出路径以“com.xiaojianbang”开始的类,使用Java.use通过className获取Frida包装以后的类clazz,再通过Java反射机制提供的方法getSuperclass获取其父类resultClass。如果父类名为“com.xiaojianbang.app.TestAbstract”,则该className就是需要寻找的实现类。
