吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 36072|回复: 98
收起左侧

[Android 原创] frida入门总结

    [复制链接]
windy_ll 发表于 2020-3-11 16:33
本帖最后由 windy_ll 于 2022-3-28 21:31 编辑

一、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:27043adb 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

    免费评分

    参与人数 39威望 +2 吾爱币 +135 热心值 +36 收起 理由
    全场最佳赵山河 + 1 + 1 谢谢@Thanks!
    我是小窝 + 1 + 1 热心回复!
    RikkaTi + 1 谢谢@Thanks!
    tianexe + 1 用心讨论,共获提升!
    liushuaijie123 + 2 + 1 热心回复!
    superzhangxue + 1 + 1 热心回复!
    1024liu + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
    fisherpau + 1 + 1 谢谢@Thanks!
    h3nimm + 1 我很赞同!
    ai474427793 + 1 + 1 我很赞同!
    xbugger + 1 谢谢@Thanks!
    hu968574 + 1 + 1 我很赞同!
    hk520590 + 1 + 1 我很赞同!
    Ytest + 1 + 1 谢谢@Thanks!
    小刀十九块 + 1 + 1 我很赞同!
    疯火戏猪猴 + 2 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
    duguyue + 1 + 1 用心讨论,共获提升!
    xin_taozi + 1 谢谢@Thanks!
    qtfreet00 + 2 + 100 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
    七个涨停一倍 + 1 + 1 鼓励转贴优秀软件安全工具和文档!
    破解的味道 + 1 谢谢@Thanks!
    小火锅King + 1 + 1 热心回复!
    smile5 + 1 谢谢@Thanks!
    风清扬方丈 + 1 + 1 这就是入门?太高级了,我选择放弃,感谢大佬分享,一脸懵逼进,一脸懵逼出
    女萝岩 + 1 + 1 我很赞同!
    红烧排骨 + 1 热心回复!
    冰雪冬樱250 + 1 + 1 用心讨论,共获提升!
    笙若 + 1 + 1 谢谢@Thanks!
    风绕柳絮轻敲雪 + 3 + 1 我很赞同!
    13071326738 + 1 + 1 谢谢@Thanks!
    asq56747277 + 1 + 1 谢谢@Thanks!
    nws0507 + 1 谢谢@Thanks!
    tail88 + 1 谢谢@Thanks!
    z5487693 + 1 + 1 开热点给评分!感谢分享
    夜步城 + 1 + 1 已经处理,感谢您对吾爱破解论坛的支持!
    Pholhx + 1 + 1 谢谢@Thanks!
    逍遥一仙 + 3 + 1 用心讨论,共获提升!
    CWHY + 1 大佬就是大佬!!!
    ForUsContribute + 1 + 1 感谢大佬

    查看全部评分

    本帖被以下淘专辑推荐:

    发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

    cheanchun 发表于 2021-3-15 09:31
    吾爱字节 发表于 2020-3-11 19:34
    Frida有点不适合需要一直运行的情况 可能后面还是需要xposed

    完全不需要,frida就足够了
     楼主| windy_ll 发表于 2020-7-26 12:02
    sqw637 发表于 2020-7-26 10:32
    首先感谢楼主的分享,我想问下这个frida一定要用root的手机吗,现在大多数手机都不支持root了。

    可以用模拟器,服务端用安卓x86或安卓x64即可
    CWHY 发表于 2020-3-11 16:41
    zgrm1000 发表于 2020-3-11 16:43
    感谢大佬,一直想学,没有看到合适的,您的说明我要好好看看学习
    HelloWang 发表于 2020-3-11 17:07
    好巧哦,我们最近刚开始学咯。 微信图片_20200311170656.png
    夜步城 发表于 2020-3-11 17:09
    支持楼主 ,来学习一下
    z5487693 发表于 2020-3-11 17:17
    牛皮!!感谢分享
    刘爱学 发表于 2020-3-11 17:35
    感谢分享,,
    asq56747277 发表于 2020-3-11 17:45
    学习了,辛苦了
    13071326738 发表于 2020-3-11 18:11
    很有用,刚好可以学学
    吾爱字节 发表于 2020-3-11 19:34
    Frida有点不适合需要一直运行的情况 可能后面还是需要xposed
    您需要登录后才可以回帖 登录 | 注册[Register]

    本版积分规则

    返回列表

    RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

    GMT+8, 2024-12-19 04:20

    Powered by Discuz!

    Copyright © 2001-2020, Tencent Cloud.

    快速回复 返回顶部 返回列表