Android逆向之hook框架frida篇
来源:互联网 发布:软件服务合同模板 编辑:程序博客网 时间:2024/06/04 23:25
前言
Frida是一款基于python + javascript 的hook框架,通杀android\ios\linux\win\osx等各平台,由于是基于脚本的交互,因此相比xposed和substrace cydia更加便捷,本文重点介绍Frida在android下面的使用。Frida的官网为:http://www.frida.re/
安装和搭建Frida环境
首先要保证你的android手机已经root。通过pip安装frida:
pip install frida
下载frida-server:
frida_server的下载地址:https://github.com/frida/frida/releases
到android手机上并且运行
adb push frida-server /data/local/tmp/
adb shell
su
cd /data/local/tmp/
chmod 777 frida-server
./frida-server
转发android TCP端口到本地:
adb forward tcp:27042 tcp:27042
adb forward tcp:27043 tcp:27043
测试frida环境,如果出现android手机的进程列表说明搭建成功:
frida-ps -R
PID Name2700 acceleratord
2713 adbd
2798 agnsscontrol
2799 agnsslog
2195 akmd09911
8078 android.process.acore
31283 android.process.media
2185 atcmdserver
4939 chargelogcat
2796 chr_logd
22856 com.android.browser
7912 com.android.contacts
22417 com.android.gallery3d
....
得到android手机当前最前端Activity所在的进程
其中get_front_app.py的内容如下:
import fridardev = frida.get_remote_device()front_app = rdev.get_frontmost_application()print front_app
枚举android手机所有的进程
enum_process.py内容如下:
import fridardev = frida.get_remote_device()processes = rdev.enumerate_processes()for process in processes: print process
枚举某个进程加载的所有模块以及模块中的导出函数
import fridardev = frida.get_remote_device()session = rdev.attach("com.tencent.mm") #如果存在两个一样的进程名可以采用rdev.attach(pid)的方式modules = session.enumerate_modules()for module in modules: print module export_funcs = module.enumerate_exports() print "\tfunc_name\tRVA" for export_func in export_funcs: print "\t%s\t%s"%(export_func.name,hex(export_func.relative_address))
hook android的native函数
import fridaimport sysrdev = frida.get_remote_device()session = rdev.attach("com.tencent.mm")scr = """Interceptor.attach(Module.findExportByName("libc.so" , "open"), { onEnter: function(args) { send("open("+Memory.readCString(args[0])+","+args[1]+")"); }, onLeave:function(retval){ }});"""script = session.create_script(scr)def on_message(message ,data): print messagescript.on("message" , on_message)script.load()sys.stdin.read()
hook android的java层函数
如下代码为hook微信(测试版本为6.3.13,不同版本由于混淆名字的随机生成的原因或者代码改动导致类名不一样)
com.tencent.mm.sdk.platformtools.ay类的随机数生成函数,让微信猜拳随机(type=2),而摇色子总是为6点(type=5)
import fridaimport sysrdev = frida.get_remote_device()session = rdev.attach("com.tencent.mm")scr = """Java.perform(function () {var ay = Java.use("com.tencent.mm.sdk.platformtools.ay");ay.pu.implementation = function(){ var type = arguments[0]; send("type="+type); if (type == 2) { return this.pu(type); } else { return 5; }};});"""script = session.create_script(scr)def on_message(message ,data): print messagescript.on("message" , on_message)script.load()sys.stdin.read()
通过frida向android进程注入dex
import frida, sys, optparse, redef on_message(message, data): if message['type'] == 'send': print("[*] {0}".format(message['payload'])) else: print(message)jscode = """Java.perform(function () { var currentApplication = Java.use("android.app.ActivityThread").currentApplication(); var context = currentApplication.getApplicationContext(); var pkgName = context.getPackageName(); var dexPath = "%s"; var entryClass = "%s"; Java.openClassFile(dexPath).load(); console.log("inject " + dexPath +" to " + pkgName + " successfully!") Java.use(entryClass).%s("%s"); console.log("call entry successfully!")});"""def checkRequiredArguments(opts, parser): missing_options = [] for option in parser.option_list: if re.match(r'^\[REQUIRED\]', option.help) and eval('opts.' + option.dest) == None: missing_options.extend(option._long_opts) if len(missing_options) > 0: parser.error('Missing REQUIRED parameters: ' + str(missing_options))if __name__ == "__main__": usage = "usage: python %prog [options] arg\n\n" \ "example: python %prog -p com.android.launcher " \ "-f /data/local/tmp/test.apk " \ "-e com.parker.test.DexMain/main " \ "\"hello fridex!\"" parser = optparse.OptionParser(usage) parser.add_option("-p", "--package", dest="pkg", type="string", help="[REQUIRED]package name of the app to be injected.") parser.add_option("-f", "--file", dest="dexPath", type="string", help="[REQUIRED]path of the dex") parser.add_option("-e", "--entry", dest="entry", type="string", help="[REQUIRED]the entry function Name.") (options, args) = parser.parse_args() checkRequiredArguments(options, parser) if len(args) == 0: arg = "" else: arg = args[0] pkgName = options.pkg dexPath = options.dexPath entry = options.entry.split("/") if len(entry) > 1: entryClass = entry[0] entryFunction = entry[1] else: entryClass = entry[0] entryFunction = "main" process = frida.get_usb_device().attach(pkgName) jscode = jscode%(dexPath, entryClass, entryFunction, arg) script = process.create_script(jscode) script.on('message', on_message) print('[*] Running fridex') script.load() sys.stdin.read()
通过注入抛出异常代码实现跟踪程序调用栈
在<<Android 软件安全与逆向分析>>这本书中第八章有介绍通过重打包写入异常代码进行栈跟踪,但是这样比较麻烦,使用frida注入更方便。
frida的相关资源
https://github.com/dweinstein/awesome-frida
http://jaq.alibaba.com/community/art/show?articleid=816
https://koz.io/using-frida-on-android-without-root/
- Android逆向之hook框架frida篇
- android平台HOOK框架汇总之Frida
- Android hook神器frida(一)
- 基于Frida的Android Hook神器AppMon
- Android中Frida框架篇-动态二进制插桩技术
- Frida hook app
- Android逆向分析之Xposed的hook技术
- Android逆向分析之Xposed的hook技术
- Android.Hook框架xposed篇
- Frida hook带handler的method
- Android逆向之旅---Native层的Hook神器Cydia Substrate使用详解
- Android逆向之旅---Native层的Hook神器Cydia Substrate使用详解
- Android逆向之Xposed不重启手机替换hook代码(并不是简单替换字符串)
- iOS 越狱开发那些事儿之六---Frida篇
- H5 Web App 的性能测试平台 : 使用 Frida 实现 AOP 拦截 hook Android 原生应用的方法
- 使用Frida渗透Android app
- Android Hook框架Xposed详解
- Android Hook 框架 Cydia_substrate 详解
- 关于maven-jdocbook-plugin插件org.jboss.highlight.XhtmlRendererFactory does not indentify an extern的一个小问题
- ffmpeg常用基本命令
- r+w+无法写入/读取文件:w+和r+的根本区别
- java 将当前日期转换为 24 小时制时间字符串
- OpenCL与CNN篇二:OpenCL基础API介绍
- Android逆向之hook框架frida篇
- Linux内核之inotify与epoll的具体例程实现
- 中文编程思想(续)
- 练习98
- 获取JPEGImageEncoder和JPEGCode这两个类
- KYLIN基于CDH入门实战(2)之kylin安装
- vim的快捷键集合,好全!
- 期望dp的水题
- 练习99