转载:实用FRIDA进阶:内存漫游、hook anywhere、抓包:https://www.anquanke.com/post/id/197657
frida github 地址:https://github.com/frida/frida
objection github:https://github.com/sensepost/objection
objection pypi:https://pypi.org/project/objection/
本章中我们进一步介绍,大家在学习和工作中使用 Frida 的实际高频场景,比如:
- 动态查看 安卓应用程序 在当前内存中的状态,
- 指哪儿就能 hook 哪儿,
- 比如 脱壳,
- 还有使用 Frida 来自动化获取参数、返回值等数据,
- 主动调用 API 获取签名结果 sign 等。。。
最后介绍一些经常遇到的高频问题解决思路,希望可以切实地帮助到读者。
Objection 简单使用
Frida hook工具 --- objection 使用:https://blog.csdn.net/wang_624/article/details/115601098
更多命令行参数可以查看 cli.py 文件得到:https://github.com/sensepost/objection/blob/e7eb1d9b769edf6a98870c75a6d2a6123b7346fd/objection/console/cli.py
使用命令
pip install objection # 安装
objection --help # 查看帮助
help frida # 不知道当前命令的作用 进入objection后就在命令前加 help 会有提示
objection -g 包名 explore # 注入进程,如果objection没有找到进程,会以spwan方式启动进程
objection -N -h 192.168.1.3 -p 9999 -g 包名 explore # 指定ip和端口的连接
# spawn启动前就Hook
objection -N -h 192.168.1.3 -p 9999 -g 包名 explore --startup-command "android hooking watch class '包名.类名'"
# spawn启动前就Hook 打印参数、返回值、函数调用栈
objection -N -h 192.168.1.3 -p 9999 -g 包名 explore --startup-command "android hooking watch class_method '包名.类名.方法' --dump-args --dump-return --dump-backtrace"
android hooking list classes # 列出内存中所有的类
android hooking search classes 包名 # 在内存中所有已加载的类中搜索包含特定关键词的类
android hooking list class_methods 包名.类名 # 列出类的所有方法
android hooking watch class 包名.类名 # hook类的所有方法
android hooking watch class_method 包名.类名.方法 # 默认会Hook方法的所有重载
# 如果只需hook其中一个重载函数 指定参数类型 多个参数用逗号分隔
android hooking watch class_method 包名.类名.方法 "参数1,参数2"
# hook方法的参数、返回值和调用栈(–dump-args: 显示参数; --dump-return: 显示返回值; --dump-backtrace: 显示堆栈)
android hooking watch class_method 包名.类名.方法 --dump-args --dump-return --dump-backtrace
jobs list # 查看 hook 的任务有多少个
jobs kill jobid # 把正在 hook 的任务关闭
android heap search instances 包名.类名 --fresh # 搜索堆中的实例
android heap execute 地址(hashcode的地址) 方法名 # 调用实例的方法
memory list modules # 枚举内存中所有模块
memory list exports 文件名.so # 枚举模块中所有导出函数
android hooking search classes okhttp3
android hooking watch class okhttp3.OkHttpClient --dump-args --dump-return
android hooking watch class_method okhttp3.OkHttpClient.newCall --dump-args --dump-backtrace --dump-return
启动
adb forward tcp:27042 tcp:27042
frida -U -l js_okhttp.js -F com.cdsb.newsreader --no-pause
frida -U -l okhttp_poker.js -F com.cdsb.newsreader --no-pause
frida -U -l okhttp_poker.js -F com.huanqiu.news --no-pause
frida -U -l frida_hook_js.js -f com.huanqiu.news --no-pause
objection -g com.app.name explore -P ~/objection/plugins
objection -g com.cdsb.newsreader explore -P objection_plugins
python r0capture.py -U -f com.cdsb.newsreader -v
python r0capture.py -U com.cdsb.newsreader -v -p cdsb.pcap
objection 下所有命令 简单说明
( :https://www.cnblogs.com/ningskyer/articles/14611822.html )
! # 执行操作系统的命令(注意:不是在所连接device上执行命令)
android # 执行指定的 Android 命令
clipboard
monitor
deoptimize # Force the VM to execute everything in the interpreter
heap
evaluate # 在 Java 类中执行 JavaScript 脚本。
execute # 在 Java 类中执行 方法。android heap execute 实例ID 实例方法
print
search
instances # 在当前Android heap上搜索类的实例。android heap search instances 类名
hooking
generate
class # A generic hook manager for Classes
simple # Simple hooks for each Class method
get
current_activity # 获取当前 前景(foregrounded) activity
list
activities # 列出已经登记的 Activities
class_loaders # 列出已经登记的 class loaders
class_methods # 列出一个类上的可用的方法
classes # 列出当前载入的所有类
receivers # 列出已经登记的 BroadcastReceivers
services # 列出已经登记的 Services
search
classes 关键字 # 搜索与名称匹配的Java类
methods 关键字 # 搜索与名称匹配的Java方法
set
return_value # 设置一个方法的返回值。只支持布尔返回
watch
class # Watches for invocations of all methods in a class
class_method # Watches for invocations of a specific class method
intent
launch_activity # 使用Intent启动Activity类
launch_service # Launch a Service class using an Intent
keystore
clear # 清除 Android KeyStore
list # 列出 Android KeyStore 中的条目
watch # 监视 Android KeyStore 的使用
proxy
set # 为应用程序设置代理
root
disable # 试图禁用 root 检测
simulate # 试图模拟已经 root 的环境
shell_exec # 执行shell命令
sslpinning
disable # 尝试禁用 SSL pinning 在各种 Java libraries/classes
ui
FLAG_SECURE # Control FLAG_SECURE of the current Activity
screenshot # 在当前 Activity 进行截图
cd # 改变当前工作目录
commands
clear # 清除当前会话命令的历史记录
history # 列出当前会话命令历史记录
save # 将在此会话中运行的所有惟一命令保存到一个文件中
env # 打印环境信息
evaluate # 执行 JavaScript。( Evaluate JavaScript within the agent )
exit # 退出
file
cat # 打印文件内容
download # 下载一个文件
http
start # Start's an HTTP server in the current working directory
status # Get the status of the HTTP server
stop # Stop's a running HTTP server
upload # 上传一个文件
frida # 获取关于 frida 环境的信息
import # 从完整路径导入 frida 脚本并运行
ios 执行指定的 ios 命令
bundles
cookies
heap
hooking
info
jailbreak
keychain
monitor
nsurlcredentialstorage
nsuserdefaults
pasteboard
plist
sslpinning
ui
jobs
kill # 结束一个任务。这个操作不会写在卸载或者退出当前脚本
list # 列出当前所有的任务
ls # 列出当前工作目录下的文件
memory
dump
all 文件名 # Dump 当前进程的整个内存
from_base 起始地址 字节数 文件 # 将(x)个字节的内存从基址转储到文件
list
exports # List the exports of a module. (列出模块的导出)
modules # List loaded modules in the current process. (列出当前进程中已加载的模块)
search # 搜索模块。用法:memory search "<pattern eg: 41 41 41 ?? 41>" (--string) (--offsets-only)
write # 将原始字节写入内存地址。小心使用!
ping # ping agent
plugin
load # 载入插接
pwd # 打印当前工作目录
reconnect # 重新连接 device
rm # 从 device 上删除文件
sqlite # sqlite 数据库命令
connect # 连接到SQLite数据库文件
ui
alert # 显示警报消息,可选地指定要显示的消息。(目前iOS崩溃)
1. 内存漫游
Frida 只是提供了各种 API 供我们调用,在此基础之上可以实现具体的功能,比如禁用证书绑定之类的脚本,就是使用 Frida 的各种 API 来组合编写而成。于是有大佬将各种常见、常用的功能整合进一个工具,供我们直接在命令行中使用,这个工具便是objection。objection 功能强大,命令众多,而且不用写一行代码,便可实现诸如内存搜索、类和模块搜索、方法hook打印参数返回值调用栈等常用功能,是一个非常方便的,逆向必备、内存漫游神器。
安装命令:pip3 install objection
objection 的界面及命令如图所示。
objection 是基于 frida 的命令行 hook 工具,可以让你不写代码, 敲几句命令就可以对 java 函数的高颗粒度 hook, 还支持 RPC 调用。
objection 目前只支持 Java层的 hook,但是 objection 有提供插件接口,可以自己写 frida 脚本去定义接口,
比如葫芦娃大佬的脱壳插件,实名推荐: https://github.com/hluwa/FRIDA-DEXDump
官方仓库: https://github.com/sensepost/objection
1.1 获取基本信息
首先介绍几个基本操作:
- 键入命令之后,回车执行;
- help: 不知道当前命令的效果是什么,在当前命令前加 help 比如:help env,回车之后会出现当前命令的解释信息;
- 按空格: 不知道输入什么就按空格,会有提示出来,上下选择之后再按空格选中,又会有新的提示出来;
- jobs: 作业系统很好用,建议一定要掌握,可以同时运行 多项 ( hook ) 作业;
简单使用
- 启动 Frida-server,并转发端口 ( adb forward tcp:27042 tcp:27042 )
- 附加需要调试的 app,进入交互界面 ( objection -g [packageName] explore )
连接逍遥模拟器,需要先进入模拟器所在目录,使用目录中 adb.exe 命令执行:adb.exe connect 127.0.0.1:21503
可以使用该 env 命令枚举与所讨论的应用程序相关的其他有趣目录:env
可以使用以下 file download 命令从远程文件系统中下载文件:file download [file] [outfile]
com.opera.mini.native on (samsung: 6.0.1) [usb] # file download fhash.dat fhash.dat
Downloading /data/user/0/com.opera.mini.native/cache/fhash.dat to fhash.dat
可以列出 app 具有的所有avtivity:android hooking list activities
com.opera.mini.native on (samsung: 6.0.1) [usb] # android hooking list activities
com.facebook.ads.AudienceNetworkActivity
com.google.android.gms.ads.AdActivity
com.google.android.gms.auth.api.signin.internal.SignInHubActivity
com.google.android.gms.common.api.GoogleApiActivity
com.opera.android.AssistActivity
com.opera.android.MiniActivity
com.opera.android.ads.AdmobIntentInterceptor
com.opera.mini.android.Browser
Found 8 classes
启动指定 avtivity:android intent launch_activity [class_activity]
com.opera.mini.native on (samsung: 6.0.1) [usb] # android intent launch_activity
com.facebook.ads.AudienceNetworkActivity
Launching Activity: com.facebook.ads.AudienceNetworkActivity...
RPC 调用命令:curl -s "http://127.0.0.1:8888/rpc/invoke/androidHookingListActivities"
$ curl -s "http://127.0.0.1:8888/rpc/invoke/androidHookingListActivities"
["com.reddit.frontpage.StartActivity","com.reddit.frontpage.IntroductionActivity", ... snip ...]
- RPC调用执行脚本:`url -X POST -H "Content-Type: text/javascript" http://127.0.0.1:8888/script/runonce -d "@script.js"`
$ cat script.js
{
send(Frida.version);
}
[{"payload":"12.8.0","type":"send"}]
RPC WIKI:https://github.com/sensepost/objection/wiki/API
API 介绍
以下只是写了一部分指令和功能, 详细的功能需要合理运用 空格 和 help
Memory 指令
memory list modules //枚举当前进程模块
memory list exports [lib_name] //查看指定模块的导出函数
memory list exports libart.so --json /root/libart.json //将结果保存到json文件中
memory search --string --offsets-only //搜索内存
android heap 指令
//堆内存中搜索指定类的实例, 可以获取该类的实例id
search instances search instances com.xx.xx.class
//直接调用指定实例下的方法
android heap execute [ins_id] [func_name]
//自定义frida脚本, 执行实例的方法
android heap execute [ins_id]
android 指令
android root disable //尝试关闭app的root检测
android root simulate //尝试模拟root环境
android ui screenshot [image.png] //截图
android ui FLAG_SECURE false //设置FLAG_SECURE权限
内存漫游
android hooking list classes //列出内存中所有的类
//在内存中所有已加载的类中搜索包含特定关键词的类
android hooking search classes [search_name]
//在内存中所有已加载的方法中搜索包含特定关键词的方法
android hooking search methods [search_name]
//直接生成hook代码
android hooking generate simple [class_name]
hook 方式
/*
hook指定方法, 如果有重载会hook所有重载,如果有疑问可以看
--dump-args : 打印参数
--dump-backtrace : 打印调用栈
--dump-return : 打印返回值
*/
android hooking watch class_method com.xxx.xxx.methodName --dump-args --dump-backtrace --dump-return
//hook指定类, 会打印该类下的所有调用
android hooking watch class com.xxx.xxx
//设置返回值(只支持bool类型)
android hooking set return_value com.xxx.xxx.methodName false
Spawn 方式 Hook
objection -g packageName explore --startup-command '[obejection_command]'
activity 和 service 操作
android hooking list activities //枚举activity
android intent launch_activity [activity_class] //启动activity
android hooking list services //枚举services
android intent launch_service [services_class] //启动services
任务管理器
jobs list // 查看任务列表
jobs kill [task_id] // 关闭任务
关闭 app 的 ssl 校验
android sslpinning disable
监控系统剪贴板
// 获取Android剪贴板服务上的句柄并每5秒轮询一次用于数据。
// 如果发现新数据,与之前的调查不同,则该数据将被转储到屏幕上。
help android clipboard
执行命令行
help android shell_exec [command]
插件编写 : objection pluging:https://github.com/sensepost/objection/wiki/Plugins
不写一行代码探索应用行为 --- 使用 objection
From:https://www.y4f.net/77651.html
这里拿 XCTF 的三个题目做演示,分别是mobile进阶区的第3题、第8题和第17题。
示例:以安卓 内置应用 "设置" 演示基本用法
在手机上启动 frida-server,并且点击启动 "设置" 图标,手机进入设置的界面,首先查看一下 "设置" 应用的包名。
# frida-ps -U|grep -i setting
7107 com.android.settings
13370 com.google.android.settings.intelligence
再使用 objection 注入 "设置" 应用。
# objection -g com.android.settings explore
启动 objection之后,会出现提示它的 logo,这时候不知道输入啥命令的话,可以按下空格,有提示的命令及其功能出来;
再按空格选中,又会有新的提示命令出来,这时候按回车就可以执行该命令,
见下图 2-2 执行的应用环境信息命令 env 和 frida-server 版本信息命令。
1.2 提取内存信息
1.2.1 查看内存中加载的库( memory list modules )
运行命令 memory list modules,效果如下图2-3所示。内存中加载的库
1.2.2 查看库的导出函数 ( memory list exports libssl.so )
运行命令 memory list exports libssl.so,效果如下图2-4所示。 libssl.so 库的导出函数
1.2.3 将结果保存到 json文件中
当结果太多,终端无法全部显示的时候,可以将结果导出到文件中,然后使用其他软件查看内容,见下图2-5。
# memory list exports libart.so --json /root/libart.json
Writing exports as json to /root/libart.json...
Wrote exports to: /root/libart.json
使用 json 格式保存的 libart.so 的导出函数
1.2.4 提取整个(或部分)内存( memory dump all from_base )
命令是 memory dump all from_base,这部分内容与下文脱壳部分有重叠,我们在脱壳部分介绍用法。
1.2.5 搜索整个内存( memory search --string --offsets-only )
命令是 memory search --string --offsets-only,这部分也与下文脱壳部分有重叠,我们在脱壳部分详细介绍用法。
1.3 内存堆 (heap) 上的搜索与执行
1.3.1 在堆 (heap)上搜索实例
我们查看AOSP源码关于设置里显示系统设置的部分,发现存在着 DisplaySettings类,可以在堆上搜索是否存在着该类的实例。
首先在手机上点击进入 "显示" 设置,然后运行命令:android heap search instances com.android.settings.DisplaySettings
并得到相应的实例地址:
1.3.2 调用实例的方法
查看源码得知 com.android.settings.DisplaySettings类 有一个 getPreferenceScreenResId()方法,这样就可以直接调用该实例的 getPreferenceScreenResId()方法,
(后文也会介绍在objection中直接打印类的所有方法的命令)
用 excute
命令:android heap execute 0x2526 getPreferenceScreenResId
Handle 0x2526 is to class com.android.settings.DisplaySettings
Executing method: getPreferenceScreenResId()
2132082764
可见结果被直接打印了出来。
1.3.3 在实例上执行 js 代码
也可以在找到的实例上直接编写 js 脚本,输入android heap evaluate 0x2526 命令后,会进入一个迷你编辑器环境,
- 输入 console.log("evaluate result:"+clazz.getPreferenceScreenResId()) 这串脚本,
- 按ESC退出编辑器,然后按回车,即会开始执行这串脚本,输出结果。
# android heap evaluate 0x2526
(The handle at `0x2526` will be available as the `clazz` variable.)
console.log("evaluate result:"+clazz.getPreferenceScreenResId())
JavaScript capture complete. Evaluating...
Handle 0x2526 is to class com.android.settings.DisplaySettings
evaluate result:2132082764
这个功能其实非常厉害,可以即时编写、出结果、即时调试自己的代码,不用再:编写→注入→操作→看结果→再调整,而是直接出结果。