admin管理员组

文章数量:1637860

转载:实用FRIDA进阶:内存漫游、hook anywhere、抓包:https://www.anquanke/post/id/197657

frida github 地址:https://github/frida/frida
objection github:https://github/sensepost/objection
objection pypi:https://pypi/project/objection/

本章中我们进一步介绍,大家在学习和工作中使用 Frida 的实际高频场景,比如:

  • 动态查看 安卓应用程序 在当前内存中的状态
  • 指哪儿就能 hook 哪儿
  • 比如 脱壳,
  • 还有使用 Frida 来自动化获取参数、返回值等数据,
  • 主动调用 API 获取签名结果 sign 等。。。

最后介绍一些经常遇到的高频问题解决思路,希望可以切实地帮助到读者。

Objection 简单使用

Frida hook工具 --- objection 使用:https://blog.csdn/wang_624/article/details/115601098

更多命令行参数可以查看 cli.py 文件得到https://github/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://wwwblogs/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 来组合编写而成。于是有大佬将各种常见、常用的功能整合进一个工具,供我们直接在命令行中使用,这个工具便是objectionobjection 功能强大,命令众多,而且不用写一行代码,便可实现诸如内存搜索、类和模块搜索、方法hook打印参数返回值调用栈等常用功能,是一个非常方便的,逆向必备、内存漫游神器。

安装命令:pip3 install objection

objection 的界面及命令如图所示。

objection 是基于 frida 的命令行 hook 工具,可以让你不写代码, 敲几句命令就可以对 java 函数的高颗粒度 hook, 还支持 RPC 调用

objection 目前只支持 Java层的 hook,但是 objection 有提供插件接口,可以自己写 frida 脚本去定义接口,

比如葫芦娃大佬的脱壳插件,实名推荐: https://github/hluwa/FRIDA-DEXDump

官方仓库: https://github/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.gmsmon.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/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/sensepost/objection/wiki/Plugins

不写一行代码探索应用行为 --- 使用 objection

From:https://www.y4f/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

这个功能其实非常厉害,可以即时编写、出结果、即时调试自己的代码,不用再:编写→注入→操作→看结果→再调整,而是直接出结果。

1.4 启动 activity

本文标签: 进阶内存fridahookobjection