Frida 通过 C 语言将 QuickJS 注入到目标进程中,获取完整的内存操作权限,达到在程序运行时实时地插入额外代码和数据的目的。官方将调用代码封装为 python 库,当然你也可以直接通过其他的语言调用 Frida 中的 C 语言代码进行操作。

Frida安装和启动

电脑端 Frida 安装

  • Frida 支持 python2 和 python3 版本,演示所使用的版本为 python3.8
pip install frida-tools
  • 如果在安装中卡住,需要在 Frida 的 pypi 页面下载对应系统的 egg 文件,对应页面地址为:https://pypi.org/project/frida/#files ,并将该文件放置到个人文件夹路径下,例如 C:\Users\当前用户名 ,再重新使用命令安装。
  • 安装完毕后可以通过命令frida --version 来查看安装的版本,确认是否安装成功。

手机端 Frida-server 安装

  • 本次示例使用 Android App 作为目标程序,所以需要电脑端安装 SDK 环境,以便能够连接手机进行调试操作,还需在手机端准备一个 Frida-server,下载地址为:https://github.com/frida/frida/releases,下载匹配手机 CPU 架构和本地 Frida 版本的包。
  • 下载之后解压文件,使用adb push 命令将文件推送到手机端,建议放置在/data/local/tmp 文件夹中,并修改该文件的权限为 755,以便之后进行启动。

确认环境运行正常

  • 通过 Frida 提供的一些小工具,对 Frida 的安装运行环境做简单的确认。
  • 首先准备一个 Android 模拟器或者真机,将上一步中提到的 Frida-server 推送到手机端中,在本示例中将放置在手机的/data/local/tmp 文件夹内,并将文件命名为frida-server
  • 通过adb shell 命令连接手机,运行/data/local/tmp/frida-server & ,将 Frida-server 放在系统后台自动运行。
  • 在本地电脑终端中运行frida-ps -U ,结果如下展示手机中的进程信息,说明环境已经准备完毕。
  PID  Name
-----  --------------------------------------------------1313  adbd12621  android.process.acore18037  android.process.media14455  com.android.defcontainer11656  com.android.deskclock...

示例

目标应用介绍

  • 因为 Hook 需要通过分析源码中的逻辑来实现,所以先展示一下目标应用的源码部分,方便分析其中的逻辑,找到 Hook 时要修改的方法和变量。
  • 代码是简单的猜黑白游戏,通过按下黑或白按钮,与电脑结果进行对比,结果相同加 1 分,结果不同分数清零,当满 100 分时打出胜利提示语。具体代码如下:
package com.example.target_frida;import androidx.appcompat.app.AppCompatActivity;import android.annotation.SuppressLint;import android.os.Bundle;import android.view.View;import android.widget.Button;import android.widget.TextView;public class MainActivity extends AppCompatActivity implements View.OnClickListener {TextView winCountView;TextView battleInfoTextView;int winCount = 0;@SuppressLint("SetTextI18n")@Overridepublic void onClick(View view) {if (winCount > 100) {return;}if (view.getId() == R.id.tvButtonBlack) {if (!getCPUResult()) {winCount++;winCountView.setText(winCount + "");battleInfoTextView.setText("Right!");} else {winCount = 0;winCountView.setText(winCount + "");battleInfoTextView.setText("Wrong! Clean All!");}} else if (view.getId() == R.id.tvButtonWhite) {if (getCPUResult()) {winCount++;winCountView.setText(winCount + "");battleInfoTextView.setText("Right!");} else {winCount = 0;winCountView.setText(winCount + "");battleInfoTextView.setText("Wrong! Clean All!");}}if (winCount >= 100) {battleInfoTextView.setText("Win 100 times!!!");}}@SuppressLint("SetTextI18n")@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);winCountView = findViewById(R.id.winCount);winCountView.setText(winCount + "");battleInfoTextView = findViewById(R.id.battleInfo);battleInfoTextView.setText("猜黑白!!!");Button buttonBlack = (Button) findViewById(R.id.tvButtonBlack);Button buttonWhite = (Button) findViewById(R.id.tvButtonWhite);buttonBlack.setOnClickListener(this);buttonWhite.setOnClickListener(this);}public boolean getCPUResult() {//true为白,false为黑return Math.random() > 0.5;}
}

Hook 需求分析

  • 由于正常情况下,连赢 100 次的概率几乎为零,如果想要达到胜利条件,Hook 就是一个比较好的方式。
  • 首先分析一下源码,想要达到连赢 100 次的情况,可以有两种解决办法:一种是通过修改用来记录连赢次数的变量winCount ,将连赢记录改成 99,这样只需要再赢一次就可以获得胜利;还有一种是通过修改getCPUResult 方法的返回值,让其固定返回一种可能性,这样只需要选择对应的颜色就可以连续获胜。接下来通过实现第一个方案,看看使用 Frida 如何达到想要的效果。

第一种实现:修改结果变量中保存的值

  • 首先展示修改代码,然后再进行逐步讲解:
import timeimport frida, sysdate_str = time.strftime('%m-%d %H:%M:%S')def on_message(message, data):if message['type'] == 'send':print(f"[{date_str}] {message['payload']}")else:print(f"[{date_str}] {message}")def run_all():# Java.perform方法:当 js 附加到目标的进程中时被执行,运行其中定义的函数# Java.choose方法:通过完整类名,获取它的实例,从而对实例中的数据进行修改# 通过 key:value 结构定义了两个函数:# onMatch 对应的函数在命中一个实例的时候被调用,传入函数中的参数 instance 就是被命中的实例# onComplete 函数会在所有实例遍历完毕之后被调用,可以做一些后续处理操作jscode = """Java.perform(function () {Java.choose("com.example.target_frida.MainActivity",{onMatch:function(instance){console.log("winCount value is "+instance.winCount.value);instance.winCount.value=99;console.log("winCount value is "+instance.winCount.value);},onComplete:function(){console.log("Complete!!!")}});});"""# attach目标App进程target_app = 'com.example.target_frida'process = frida.get_usb_device().attach(target_app)# 将JS代码注入进程,并附加监听方法,用来获取返回的日志信息script = process.create_script(jscode)script.on('message', on_message)# 打印起始日志print(f'[{date_str}] Start Frida on {target_app}')# 加载注入的JS代码逻辑script.load()# 使用系统输入语句阻止函数运行完毕自动退出sys.stdin.read()if __name__ == '__main__':run_all()
  • 代码中的 python 语句已经添加了注释,Hook 的核心逻辑,JS 语句作为字符串保存在 jscode 变量中。
  • 梳理一下整个 JS 语句的流程:通过Java.choose 函数获取com.example.target_frida.MainActivity 类的实例。在获取到实例时,首先使用console.log 语句将当前实例中的 winCount 变量值(使用 winCount.value)打印到日志中,之后直接通过赋值语句把变量值改为 99,再次输出日志确认修改无误,修改逻辑就完成了。
  • 在手机端启动 Frida-server 和被测 App,电脑端运行脚本,可以看到在命令行中输出如下内容:
[04-15 18:19:57] Start Frida on com.example.target_fridawinCount value is 0winCount value is 99Complete!!!
  • 这时在 App 中选择一个颜色点击,只要选中正确的颜色,就可以成功达到预期的 100 次连胜目标,如果没能选中正确的颜色导致清零,可以再重复运行脚本修改一次数值,在这种情况下要达到预期的场景就很容易。

总结

第二个方案以及其他更多的可能性,就留给读者自行探索,在这里送上 Frida 官方 JavaScript API 链接:https://frida.re/docs/javascript-api/ ,可以通过这个链接找到你所需要的 JS 函数。

通过示例可以看到 Frida 实现 Hook 功能的强大能力,它可以定位到类的实例,并且对实例中的数据进行直接的修改,达到场景构建的目的。

更多技术文章

使用Frida 实现 Hook 功能相关推荐

  1. Frida Android hook

    From:https://eternalsakura13.com/2020/07/04/frida/ 目录 1.r0ysue 大佬 2.Frida 环境 2.1 pyenv 2.2 frida 安装 ...

  2. 安卓逆向_24( 一 ) --- Hook 框架 frida( Hook Java层 和 so层) )

    From:Hook 神器家族的 Frida 工具使用详解:https://blog.csdn.net/FlyPigYe/article/details/90258758 详解 Hook 框架 frid ...

  3. 纯C#实现Hook功能

    纯C#实现Hook功能 发布一个自己写的用于Hook .Net方法的类库,代码量不大,完全的C#代码实现,是一个比较有趣的功能,分享出来希望能和大家共同探讨 安装:Install-Package Do ...

  4. 转载:使用 Frida 来 hook 加固的 Android 应用的 java 层

    Android 加固应用Hook方式 --- Frida:https://github.com/xiaokanghub/Android 转载:使用 frida 来 hook 加固的 Android 应 ...

  5. Android逆向之旅---破解某支付软件防Xposed等框架Hook功能检测机制

    一.情景介绍 最近想写几个某支付软件的插件,大家现在都知道现在插件大部分都是基于Xposed的hook功能,包括之前写了很多的某社交软件的插件,所以不多说就直接用Jadx打开支付软件之后然后找到想要h ...

  6. Android中破解某支付软件防Xposed的hook功能检测机制过程分析

    一.情景介绍 最近想写几个某支付软件的插件,大家现在都知道现在插件大部分都是基于Xposed的hook功能,包括之前写了很多的某社交软件的插件,所以不多说就直接用Jadx打开支付软件之后然后找到想要h ...

  7. Frida模板Hook

    JAVA层HOOK: # -*- coding: utf-8 -*- """ Spyder EditorThis is a temporary script file.J ...

  8. 使用VirtualXposed的hook功能定位收集mac地址的代码位置

    引言 公司的app被应用商店下架了,原因是违规收集用户mac地址信息.我明明已经把第三方SDK初始化推迟到用户同意协议后,怎么还会有违规收集的问题呢?我认为是第三方SDK在初始化前收集了用户的mac地 ...

  9. 什么是HOOK功能?

    HOOK API是一个永恒的话题,如果没有HOOK,许多技术将很难实现,也许根本不能实现.这里所说的API,是广义上的API,它包括DOS下的中断,WINDOWS里的API.中断服务.IFS和NDIS ...

最新文章

  1. [NC15034]德玛西亚万岁
  2. 如何正确清理Excel互操作对象?
  3. 洛谷P6097:【模板】子集卷积(FWT)
  4. 【树链剖分】染色(luogu 2486/金牌导航 树链剖分-3)
  5. 2016第11届四川省高校计算机(软件)院长论坛纪要(旁听)
  6. windows 服务中托管asp.net core
  7. 使用Navicat管理MySQL用户
  8. 连续性的设计——改善产品的体验
  9. ARM常用汇编指令讲解
  10. 新计算机是飞行模式怎么开,win10自己打开飞行模式,怎么处理
  11. pg事务:隔离级别历史与SSI
  12. 代码审计[java安全编程]
  13. 个人看法(设计思想)
  14. WPF学习之深入浅出话属性
  15. 紫罗兰永恒花园rust简谱_【Sincerely】简谱 自制 高清
  16. 一个模仿布卡那样的划动手势看在线漫画的简单应用DEMO
  17. w ndows10故障如何重新进入,天正建筑T20常见问题
  18. 记录中招勒索病毒及其解决过程
  19. 【Python数据结构系列】☀️《树与二叉树-基础知识》——知识点讲解+代码实现☀️
  20. 前端复杂表格一键导出看这篇就够了(附源码)

热门文章

  1. 【数值分析】学习笔记1——范数与条件数
  2. AIOC极速卸载Corona
  3. java设计博客_JAVA课程设计——团队博客
  4. HTML5+CSS3+JS小实例:旋转的圣诞树
  5. utu2440 gdbserver 搭建
  6. nextSibling
  7. TrueTpye字体和postscript字体
  8. nextSibling的兼容问题
  9. Reflections 详细介绍
  10. CC00060.kafka——|Hadoopkafka.V45|——|kafka.v45|日志存储概述|