frida入门总结
一、Frida概述
Frida是一款轻量级HOOK框架,可用于多平台上,例如android、windows、ios等。
frida分为两部分,服务端运行在目标机上,通过注入进程的方式来实现劫持应用函数,另一部分运行在系统机器上。
frida上层接口支持js、python、c等。
Frida官方github地址为:frida官方github地址
PS:虽然百度一下会发现frida教程有不少,但是涉及到native层的教程基本很少,然后对每一句Hook代码解释一下的更是少之又少,所以我还是厚着脸皮从自己的角度写了这一篇!!!
二、Frida安装
1 、安装python3.7并配置好环境变量(官方推荐python3以上版本至少为3.7),python安装包官方下载地址:https://www.python.org/downloads/。
2 、安装frida模块,命令为pip install frida(配置了多个python版本环境的可以使用命令python -m pip install frida防止用pip install frida命令报错)。

3、安装frida-tools模块,命令同上,pip install frida-tools或者python -m pip install frida-tools。

4、下载运行在目标机上的frida-sever端,官方下载地址:https://github.com/frida/frida/releases,下载时要选择对应的版本下载,例如我的机器为arm32为架构,就选择frida-server-12.8.14-android-arm.xz下载。(可以在adb使用命令cat /proc/cpuinfo查询)


5、将第四步下载好的文件解压,然后通过命令adb push 你的电脑是存放位置 /data/local/tmp将文件传输到手机中,然后通过adb shell进入手机端,给文件赋权777,并于root权限启动。


6、做完以上几步后,新开一个命令行输入命令frida-ps -U查看手机进程,如果出现以下结果,则frida安装成功。

三、Frida Hook Java层
1、编写一个小demo用来hook,该demo关键部分代码如下:

2、现在我们将该apk安装好,运行看一下未Hook前的显示字符串!!!

3、现在来编写Hook的Python脚本,脚本代码如下:
import frida #导入frida模块
import sys #导入sys模块
jscode = """ #从此处开始定义用来Hook的javascript代码
Java.perform(function(){
var MainActivity = Java.use('com.example.testfrida.MainActivity'); //获得MainActivity类
MainActivity.testFrida.implementation = function(){ //Hook testFrida函数,用js自己实现
send('Statr! Hook!'); //发送信息,用于回调python中的函数
return 'Change String!' //劫持返回值,修改为我们想要返回的字符串
}
});
"""
def on_message(message,data): #js中执行send函数后要回调的函数
print(message)
process = frida.get_remote_device().attach('com.example.testfrida') #得到设备并劫持进程com.example.testfrida(该开始用get_usb_device函数用来获取设备,但是一直报错找不到设备,改用get_remote_device函数即可解决这个问题)
script = process.create_script(jscode) #创建js脚本
script.on('message',on_message) #加载回调函数,也就是js中执行send函数规定要执行的python函数
script.load() #加载脚本
sys.stdin.read()
4、现在python脚本编写完毕,我们来执行该脚本,首先手机端执行frida,然后通过命令adb forward tcp:27043 tcp:27043和adb forward tcp:27042 tcp:27042来转发这两个端口,接着在手机上运行该应用程序,在命令行中执行脚本,最后点击应用的按钮,即可看到字符串已经被替换成我们要替换的了!!!




四、Frida Hook Native层
4.1、Hook native层返回值为int类型的demo
1、还是先写一个小demo,下面贴一下关键代码(很简单c语言代码就不再解释了,至于native层函数怎么编写,由于本篇主要不是讲怎么编写so函数,就不过多叙述了,实在不会的可以看一下我的一篇博客,我觉得写得还是挺详细的,博客编写native层函数链接:https://www.cnblogs.com/aWxvdmVseXc0/p/11564809.html)和未Hook前截图:

代码:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_example_fridaso_FridaSoDefine */
#ifndef _Included_com_example_fridaso_FridaSoDefine
#define _Included_com_example_fridaso_FridaSoDefine
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_example_fridaso_FridaSoDefine
* Method: FridaSo
* Signature: (II)I
*/
JNIEXPORT jint JNICALL Java_com_example_fridaso_FridaSoDefine_FridaSo(JNIEnv *env, jclass obj, jint a, jint b)
{
int c;
c = a + b;
return c;
}
#ifdef __cplusplus
}
#endif
#endif


2、接下来我们来写python hook脚本,我们需要hook native层这个函数,达到返回值修改为0的效果。写到这里需要说明一下关于so文件当中的函数,分为导出函数和未导出函数两种,导出函数打开IDA后能够在导出表中找到的函数就是导出函数,未导出函数则在导出表中寻找不到,一般来说静态编写的native函数都能在导出表中寻找到,而动态加载的则无法在导出表中发现!!!

代码如下:(跟上面hook java层重复的代码不在注释详讲了!!!)
import frida
import sys
jscode = """
Java.perform(function(){
//下面这一句代码是指定要Hook的so文件名和要Hook的函数名,函数名就是上面IDA导出表中显示的那个函数名
Interceptor.attach(Module.findExportByName("libfridaso.so","Java_com_example_fridaso_FridaSoDefine_FridaSo"),{
//onEnter: function(args)顾名思义就是进入该函数前要执行的代码,其中args是传入的参数,一般so层函数第一个参数都是JniEnv,第二个参数是jclass,从第三个参数开始才是我们java层传入的参数
onEnter: function(args) {
send("Hook start");
send("args[2]=" + args[2]); //打印我们java层第一个传入的参数
send("args[3]=" + args[3]); //打印我们java层传入的第二个参数
},
onLeave: function(retval){ //onLeave: function(retval)是该函数执行结束要执行的代码,其中retval参数即是返回值
send("return:"+retval); //打印返回值
retval.replace(0); //替换返回值为0
}
});
});
"""
def printMessage(message,data):
if message['type'] == 'send':
print('[*] {0}'.format(message['payload']))
else:
print(message)
process = frida.get_remote_device().attach('com.example.fridaso')
script = process.create_script(jscode)
script.on('message',printMessage)
script.load()
sys.stdin.read()
3、最后在手机端执行frida-server,转发端口,开启应用,执行脚本,点击按钮,即可看到返回值已经被修改成了0,效果图如下:


4.2、Hook native层返回值为String类型的demo
1、上面已经写了怎么Hook修改native层函数返回值为int类型的情况,使用replace()函数直接修改即可,但是返回情况为字符串则不一样,在c语言中,返回值为字符串其实是返回了一个char *(字符串指针),所以简单的替换是无法取效果的,具体怎么修改返回值,接着看下面,下面还是贴上demo的关键代码和未Hook前截图:

代码如下:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_example_fridasostring_fridaSoString */
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_example_fridasostring_fridaSoString */
#ifndef _Included_com_example_fridasostring_fridaSoString
#define _Included_com_example_fridasostring_fridaSoString
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_example_fridasostring_fridaSoString
* Method: FridaSo
* Signature: (Ljava/lang/String;)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_example_fridasostring_fridaSoString_FridaSo(JNIEnv *env, jclass obj, jstring str)
{
return str;
}
#ifdef __cplusplus
}
#endif
#endif
未Hook前运行截图:

2、接下来是python Hook脚本(只解释与上面有差异的代码),Hook的函数具体函数名还是使用IDA去寻找

python代码:
import frida
import sys
jscode = """
Java.perform(function(){
Interceptor.attach(Module.findExportByName("libfridaso.so","Java_com_example_fridasostring_fridaSoString_FridaSo"),{
onEnter: function(args) {
send("Hook start");
send("args[2]=" + args[2]);
},
onLeave: function(retval){
send("return:"+retval);
var env = Java.vm.getEnv(); //获取env对象,也就是native函数的第一个参数
var jstrings = env.newStringUtf("tamper"); //因为返回的是字符串指针,使用我们需要构造一个newStringUtf对象,用来代替这个指针
retval.replace(jstrings); //替换返回值
}
});
});
"""
def printMessage(message,data):
if message['type'] == 'send':
print('[*] {0}'.format(message['payload']))
else:
print(message)
process = frida.get_remote_device().attach('com.example.fridasostring')
script = process.create_script(jscode)
script.on('message',printMessage)
script.load()
sys.stdin.read()
3、运行脚本后,点击按钮,我们可以看到字符串已经被替换成了tamper,如下所示:


4、关于为导出函数的Hook,大体上差不多,差别在于需要通过ida找到偏移值计算地址,而不是像导出函数这么方便罢了,但原理都是差不多的,就不在细说了!!!
五、相关附件
python Hook代码已经demo下载链接:https://pan.baidu.com/s/1ZCIeJXzeTpQ8uJ9Ew5nnGQ
提取码:z94i
frida入门总结的更多相关文章
- 从三道题目入门frida
偶然从看雪看到了一篇入门frida的题目,正好苦于没练手的东西,直接上手一波 1.第一题jadx打开,也没有壳和混淆,整体非常清晰,判断的逻辑也很简单 发现其实就是两个输入框,一个用户名一个密码,先拼 ...
- 在iOS应用程序中使用Frida绕过越狱检测
阿里聚安全在之前的三篇博客中介绍了利用Frida攻击Android应用程序,整个过程仿佛让开发者开启上帝视角,在本篇博客中,我们将会介绍在iOS应用程序中使用Frida绕过越狱检测.即使 ...
- 爬虫工程师的unidbg入门教程
现在很多的app使用了so加密,以后会越来越多.爬虫工程师可能会直接逆向app,看java代码,完成java层的算法破解,但是如果遇到so该怎么办呢?可能你会直接破解so,但是真的会有很多爬虫工程师会 ...
- Angular2入门系列教程7-HTTP(一)-使用Angular2自带的http进行网络请求
上一篇:Angular2入门系列教程6-路由(二)-使用多层级路由并在在路由中传递复杂参数 感觉这篇不是很好写,因为涉及到网络请求,如果采用真实的网络请求,这个例子大家拿到手估计还要自己写一个web ...
- ABP入门系列(1)——学习Abp框架之实操演练
作为.Net工地搬砖长工一名,一直致力于挖坑(Bug)填坑(Debug),但技术却不见长进.也曾热情于新技术的学习,憧憬过成为技术大拿.从前端到后端,从bootstrap到javascript,从py ...
- Oracle分析函数入门
一.Oracle分析函数入门 分析函数是什么?分析函数是Oracle专门用于解决复杂报表统计需求的功能强大的函数,它可以在数据中进行分组然后计算基于组的某种统计值,并且每一组的每一行都可以返回一个统计 ...
- Angular2入门系列教程6-路由(二)-使用多层级路由并在在路由中传递复杂参数
上一篇:Angular2入门系列教程5-路由(一)-使用简单的路由并在在路由中传递参数 之前介绍了简单的路由以及传参,这篇文章我们将要学习复杂一些的路由以及传递其他附加参数.一个好的路由系统可以使我们 ...
- Angular2入门系列教程5-路由(一)-使用简单的路由并在在路由中传递参数
上一篇:Angular2入门系列教程-服务 上一篇文章我们将Angular2的数据服务分离出来,学习了Angular2的依赖注入,这篇文章我们将要学习Angualr2的路由 为了编写样式方便,我们这篇 ...
- Angular2入门系列教程4-服务
上一篇文章 Angular2入门系列教程-多个组件,主从关系 在编程中,我们通常会将数据提供单独分离出来,以免在编写程序的过程中反复复制粘贴数据请求的代码 Angular2中提供了依赖注入的概念,使得 ...
随机推荐
- 吴裕雄--天生自然 HADOOP大数据分布式处理:添加主机和服务器的域名映射
- OpenCV 特征点检测
#include <stdio.h> #include <iostream> #include "opencv2/core/core.hpp" #inclu ...
- 解决scoped 下confirm 样式问题
- 在mysql中生成数据库和数据表
#创建数据库CREATE DATABASE s4day65 DEFAULT CHARSET utf8; #班级表 CREATE TABLE class (id INT NOT NULL AUTO_IN ...
- deeplearning.ai 序列模型 Week 1 RNN(Recurrent Neural Network)
1. Notations 循环序列模型的输入和输出都是时间序列.$x^{(i)<t>}$表示第$i$个输入样本的第$t$个元素,$T_x^{(i)}$表示输入的第$i$个样本的元素个数:$ ...
- Alfresco的安装配置(Centos6系统中安装)
Alfresco是一款开源的企业内容管理系统(ECMS),为企业提供了日常的文档管理.协同工作.工作记录管理.知识管理.网络内容管理.图片管理等多种功能. Alfresco是目前应用最广泛的开源企业知 ...
- Java IO: FileOutputStream
原文链接 作者: Jakob Jenkov 译者: 李璟(jlee381344197@gmail.com) FileOutputStream可以往文件里写入字节流,它是OutputStream的子类, ...
- MyBatis学习笔记一:MyBatis最简单的环境搭建
MyBatis的最简单环境的搭建,使用xml配置,用来理解后面的复杂配置做基础 1.环境目录树(导入mybatis-3.4.1.jar包即可,这里是为后面的环境最准备使用了web项目,如果只是做 my ...
- python开发之Pandas
正确的对DataFrame reverse运算 data.reindex(index=data.index[::-]) or simply: data.iloc[::-] will reverse y ...
- 吴裕雄--天生自然 R语言开发学习:功效分析(续一)
#----------------------------------------# # R in Action (2nd ed): Chapter 10 # # Power analysis # # ...