浅谈Android Hook技术

2019-04-04 约 3031 字 预计阅读 7 分钟

声明:本文 【浅谈Android Hook技术】 由作者 adrain 于 2017-03-15 06:50:00 首发 先知社区 曾经 浏览数 4595 次

感谢 adrain 的辛苦付出!

前言

xposed框架

xposed,主页:http://repo.xposed.info/module/de.robv.android.xposed.installer

是个开源的框架,在github上有源码的,直接下载apk后安装激活就可以使用,很多地方有这方面的教程,针对不同的手机架构,有大牛做了针对性的修改。可以在论坛中进行搜索

通过替换/system/bin/app_process程序控制zygote进程,使得app_process在启动过程中会加载XposedBridge.jar这个jar包,从而完成对Zygote进程及其创建的Dalvik虚拟机的劫持。

Xposed在开机的时候完成对所有的Hook Function的劫持,在原Function执行的前后加上自定义代码。

很多人将这个框架用在对android的私有化定制上面,其实在android安全测试方面这个框架提供了很大的便利,xposed主要是对方法的hook,在以往的重打包技术中,需要对smali代码的进行修改,修改起来比较麻烦。

利用xposed框架可以很容易的获取到android应用中的信息,比如加密私钥、salt值等等,不需要饭编译获取密钥转换算法、不需要了解密钥保存机制,直接hook函数,获取输入输出就可以。

原理

在Android系统中,应用程序进程都是由Zygote进程孵化出来的,而Zygote进程是由Init进程启动的。Zygote进程在启动时会创建一个Dalvik虚拟机实例,每当它孵化一个新的应用程序进程时,都会将这个Dalvik虚拟机实例复制到新的应用程序进程里面去,从而使得每一个应用程序进程都有一个独立的Dalvik虚拟机实例。这也是Xposed选择替换app_process的原因。

Zygote进程在启动的过程中,除了会创建一个Dalvik虚拟机实例之外,还会将Java运行时库加载到进程中来,以及注册一些Android核心类的JNI方法来前面创建的Dalvik虚拟机实例中去。注意,一个应用程序进程被Zygote进程孵化出来的时候,不仅会获得Zygote进程中的Dalvik虚拟机实例拷贝,还会与Zygote一起共享Java运行时库。这也就是可以将XposedBridge这个jar包加载到每一个Android应用程序中的原因。XposedBridge有一个私有的Native(JNI)方法hookMethodNative,这个方法也在app_process中使用。这个函数提供一个方法对象利用Java的Reflection机制来对内置方法覆写。有能力的可以针对xposed的源码进行分析,不得不说,作者对于android的机制和java的了解已经相当深入了。

简单实例

很简单的一个android登入代码:

很简单的就是判断下用户输入的用户名和密码是正确,这里做个简单的演示,将用户输入的用户名和密码信息hook出来不管正确与否

简单说下xposed模块的开发,首先需要的是导入api,具体的可以参考:https://github.com/rovo89/XposedBridge/wiki/Using-the-Xposed-Framework-API

在manifest中定义

声明这个是xposed模块,名称为hook test 并且使用api版本号是82

下面创建运行时候的hook代码:

看代码中的注释,主要是三个方法的调用,handleLoadPackage,主要是获取到android包的相关信息,这里由于只是对logintest进行hook,做下简单的判断。

findAndHookMethod 是主要的hook入口,里面几个参数分别为包名,classloader,hook的函数名,参数类型(这个比较容易出错,比如list类型写为List.class),回调函数

回调函数中比较重要的:beforeHookedMethod和afterHookedMethod,一个是在函数运行前劫持掉,一个是hook后放行,实例中对用户输入的字段进行劫持打印,后面将参数之改为正确登入用户名和密码,这样在app中输入任何字符都能登入成功

frida Hook框架

Frida是一款基于python + javascript 的hook框架,通杀android\ios\linux\win\osx等各平台,由于是基于脚本的交互,因此相比xposed和substrace cydia更加便捷,本文重点介绍Frida在android下面的使用。

Frida的官网为:http://www.frida.re/

安装

安装Frida非常简单,在pc端直接执行

pip install frida

即可

在Android设备需要导入frida的服务端,需要root你的手机

运行

设备上运行frida-server:

电脑上运行adb forward tcp转发:

27042端口用于与frida-server通信,之后的每个端口对应每个注入的进程。

运行如下命令验证是否成功安装:

$ frida-ps-R

正常情况应该输出进程列表如下:

Hook模块的编写

hook的主要模块是js编写的,利用javascript的api与server进行通信

下面结合一个真实例子进行简单的介绍,首先是测试代码:

反编译获取app中的核心函数

对于上面的js代码,其实就是调用app中的某个函数,比如sign值生成函数,加密解密函数,不需要自己单独的去分析算法流程,分析key值在哪,直接调用app的相应函数,让app帮我们完成这些工作。

这里我们分析的app是友宝,这是一款饮料售货机,当时抓包看到提货的时候是只有个订单id的,猜想是不是遍历订单的id,支付成功但是没有取货的订单会不会响应请求,自己掉货出来。

下面对友宝的订单进行分析过程

1.抓取支付订单成功链接

分析:
sign是校验值,主要是防止订单伪造的,orderid是产生的支付订单id,这个主要是防止伪造用

2.反编译友宝app

找到morder/shipping所在的包为:com/ub/main/d/e.class

其中localStringBuffer存储的就是url中的参数信息,该请求查找到的代码在a()

生成签名的函数在com/ub/main/d/e.class中的b函数

最后加上sign值,发送请求

3.可以反编译出他的sign计算方法,也可以直接调用b函数来产生sign值,后来发现app会自动取时间戳,我们就不需要给他array型的参数

直接调用a函数,把orderId给他,让他直接return一个值出来就好了,就有了上面的js代码

\4. 自动化的批量处理

看代码

构造了一个类,后面直接fuzz uid就可以了,提取里面的sign值拼接到post数据中去。

可以产生的post请求和抓到的数据包的请求是完全一样的,但是并没有测试成功,分析原因有可能是订单id和用户的id有所绑定。

不过学习到了怎样通过frida对app进行分析。

复杂参数的hook

如果遇到函数的参数类型是数组、map、ArrayList类型的,首先目标MyClass类的fun1函数,声明如下:

解决方法:

用Xposed自身提供的XposedHelpers的findClass方法加载每一个类,然后再将得到的类传递给hook函数作参数!

具体实现可参考链接,大牛讲的很清楚。

参考链接

https://xianzhi.aliyun.com/forum/read/611.html

http://www.freebuf.com/articles/terminal/56453.html

http://bbs.pediy.com/showthread.php?t=202147&page=2

关键词:[‘技术文章’, ‘技术文章’]


author

旭达网络

旭达网络技术博客,曾记录各种技术问题,一贴搞定.
本文采用知识共享署名 4.0 国际许可协议进行许可。

We notice you're using an adblocker. If you like our webite please keep us running by whitelisting this site in your ad blocker. We’re serving quality, related ads only. Thank you!

I've whitelisted your website.

Not now