app逆向-frida安装调试

一、前言

frida是一款基于python + javascript 的hook框架,可运行在android ios linux winosx等各平台,主要使用动态二进制插桩技术

官方网站:https://frida.re/docs/home/
api地址:https://frida.re/docs/javascript-api/

二、安装

需要准备的

  • 一台root好的安卓手机
  • frida-server:运行在手机上,安卓6使用frida-server-12.8.10,安卓8以上新版本
  • frida-tools:python模块 提供cli工具命令跟frida-server交互pip install frida-tools
  • frida:python模块 pip install frida

1、先搭建python环境

Python环境安装脚本,版本必须对应上不然会报错

安卓6:

pip install frida==12.8.0
pip install frida-tools==5.3.0
pip install objection==1.8.4

安卓8以上:

pip install frida
pip install frida-tools
pip install objection

2、配置frida-server

frida-server下载地址:https://github.com/frida/frida/releases,需要查看手机架构下载对应的安装包

先查看手机架构命令如下

adb shell getprop ro.product.cpu.abi

效果
在这里插入图片描述
那么对应的frida-server
在这里插入图片描述
下载好后,将 frida-server 解压 push 到手机,增加执行权限并且运行起来

adb push frida-server /data/local/tmp/
adb shell
su
cd /data/local/tmp
## 确定手机当前目录是root权限
chmod 777 frida-server
./frida-server&

端口转发到电脑

adb forward tcp:27043 tcp:27043
adb forward tcp:27042 tcp:27042

检测frida是否运行成功

frida-ps -U

效果
在这里插入图片描述

三、hook调试,hook java类

启动方式

  • attach 进程名:app启动后再hook,不能hook app启动阶段
  • spawm 进程名:重启app,适合hook app 启动阶段

app已经启动了,访问成员变量,固定写法如下:

def on_message(message, data):
    if message['type'] == 'send':
        print("[*] {0}".format(message['payload']))
    else:
        print(message)

jscode = '''
	Java.perform(
		function(){
			console.log('hook住了')
			var MainActivity = Java.use('类名')
			MainActivity.onClick.implementation = function(参数){
				# 执行原有逻辑
				this.onClick(v)
				# 实现自己的逻辑
				console.log('打印' + this.m.value)
			}
		}
	)
'''
# app已经启动了
process = frida.get_usb_device(-1).attach('这里写软件的包名/进程名')
script = process.create_script(jscode)
script.on('message', on_message)
print('[*] Hook Start Running')
script.load()
# 守护进程
sys.stdin.read()

app启动阶段,访问成员变量,固定写法如下:

def on_message(message, data):
    if message['type'] == 'send':
        print("[*] {0}".format(message['payload']))
    else:
        print(message)

jscode = '''
	Java.perform(
		function(){
			console.log('hook住了')
			var MainActivity = Java.use('类名')
			MainActivity.onClick.implementation = function(参数){
				# 执行原有逻辑
				this.onClick(v)
				# 实现自己的逻辑
				console.log('打印' + this.m.value)
			}
		}
	)
'''
# app启动阶段
device = frida.get_usb_device(-1)
pid = device.spawn(["这里写软件的包名/进程名"])
process = device.attach(pid)
script = process.create_script(jscode)
script.on('message', on_message)
print('[*] Hook Start Running')
script.load()
device.resume(pid)
sys.stdin.read()

匿名类,内部类访问外部类,固定写法如下:

def on_message(message, data):
    if message['type'] == 'send':
        print("[*] {0}".format(message['payload']))
    else:
        print(message)

jscode = '''
	Java.perform(
		function(){
			console.log('hook住了')
			# 匿名类 类名$xxx
			var MainActivity = Java.use('类名$xxx')
			MainActivity.onClick.implementation = function(参数){
				# 内部类访问外部类
				console.log(this.this$0.value.m.value)
				# 执行原有逻辑
				this.onClick(v)
				# 实现自己的逻辑
				console.log('打印' + this.m.value)
			}
		}
	)
'''
# app已经启动了
process = frida.get_usb_device(-1).attach('这里写软件的包名/进程名')
script = process.create_script(jscode)
script.on('message', on_message)
print('[*] Hook Start Running')
script.load()
# 守护进程
sys.stdin.read()
### 使用 Frida 实现反调试技术 #### 反调试概述 在逆向工程过程中,目标程序通常会集成各种形式的防调试机制以阻止分析人员深入了解其运行逻辑。这些保护措施可能包括但不限于检测是否附加了调试器、检查进程状态以及监控特定事件的发生等[^1]。 #### 基于Frida实现反调试的具体方法 ##### 1. 阻断常见的调试接口调用 许多移动应用程序会在启动初期执行一系列用于确认环境安全性的验证过程。如果发现有外部工具试图干预,则立即终止自身或其他异常行为作为响应。为了绕过此类限制,可以采用拦截并修改敏感函数返回值的方式: ```javascript Interceptor.attach(Module.findExportByName(null, 'isDebuggerPresent'), { onEnter: function (args) { this.return_value = false; // 修改默认判断结果为未被调试 }, onLeave: function (retval) { retval.replace(this.return_value); // 替换原始输出 } }); ``` 此段脚本展示了怎样利用 `Interceptor` API 来挂钩 Windows 平台下的标准库函数 `IsDebuggerPresent()` ,从而欺骗目标认为当前不存在任何调试活动正在进行中[^4]。 ##### 2. 处理动态加载模块中的隐藏逻辑 对于那些采用了复杂加载策略的应用来说,仅仅依靠静态分析往往难以获得完整的代码路径覆盖度。此时借助像 Frida 这样的注入框架能够实现在内存层面实时跟踪新引入的对象及其关联的操作流。特别是针对经过高度优化甚至加密处理后的二进制文件而言,这种方法尤为有效[^3]。 例如,在面对 Flutter 应用时,由于其独特的编译方式使得传统的字节码解析变得不再适用;而通过上述手段则可以在不解密的前提下获取到更多关于内部组件交互的信息[^2]。 ##### 3. 绕过基于时间戳或计数器的时间差攻击防御 部分软件可能会记录下每次重要操作之间所耗费的实际秒数,并据此推算是否存在人为延缓现象——这通常是手动单步追踪留下的痕迹之一。对此类情况可以通过调整系统时钟读取函数的行为来达到目的: ```javascript var orig_gettime = new NativeFunction(Module.findBaseAddress('libc.so').add(0x7f8), 'int', ['pointer']); function fake_gettime(buffer){ var result = orig_gettime(buffer); Memory.writeUtime(buffer.add(Process.pointerSize), Date.now() / 1e3 | 0); // 设置固定的时间点 return result; } Interceptor.replace(orig_gettime.address, Interceptor.createCallback(fake_gettime)); ``` 这段 JavaScript 脚本实现了对 Linux 系统上常用的 `gettimeofday()` 函数替换,确保无论何时查询都能得到一致的结果,进而规避因时间间隔不正常引发的安全警报。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我是花臂不花

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值