Android逆向学习之Frida逆向与抓包实战学习笔记(持续更新中)

news2024/11/29 8:36:45

学习资料:《安卓Frida逆向与抓包实战》陈佳林/著

文章目录

  • 基础环境
  • 第三章 Frida逆向入门之Java层hook
    • 3.1 frida基础
      • 3.1.3frida基础知识
        • frida存在两种操作模式
        • frida操作App的方式有两种
      • 3.1.4Frida IDE配置
    • 3.2 frida脚本入门
      • 3.2.1 frida脚本的概念
      • 3.2.2 Java层hook基础
        • 1.hook初探
        • 2.重载函数的hook
      • 3.2.3 Java层主动调用
        • 1. 主动调用例1
        • 2. 主动调用例2
  • 第四章 Objection快速入门
    • 4.2 Objection的安装与使用
      • 4.2.1 objection安装
      • 4.2.2 objection使用
        • 1. 注入进程进入REPL
        • 2. 常用命令:

基础环境

  1. 安装Android Studio并配置好adb
  2. 一台root的真机或者安卓虚拟机

第三章 Frida逆向入门之Java层hook

3.1 frida基础

3.1.3frida基础知识

frida存在两种操作模式

  1. CLI(命令行模式)
    通过命令行将js代码注入进程
  2. RPC模式
    通过python将js代码注入进进程,本质上还是使用js代码进行hook

frida操作App的方式有两种

  1. spwan模式
    将启动app的权利交由frida控制,即使目标App已启动,也会被
    frida重新启动.通过-f参数可以指定以spwan模式操作app
  2. attach模式
    app已经启动,frida通过ptrace注入程序从而执行hook.frida默认是attach模式操作app

3.1.4Frida IDE配置

  1. 安装node和npm环境
  2. git下载frida-agent-example仓库
git clone https://github.com/oleavr/frida-agent-example.git 下载frida-agent-example仓库
cd frida-agent-example/
npm install

使用vscode打开,在frida-agent-example文件夹内创建文件夹即可写脚本
在这里插入图片描述

3.2 frida脚本入门

3.2.1 frida脚本的概念

示例:

setTimeout(function(){
    Java.perform(function(){
        console.log("hello,world")
    })
})

代码分析:
1. 调用setTimeout方法将匿名函数注册到js运行库中
2. 在函数中调用Java.perform方法,将匿名函数注册到App的java运行库中,并执行函数

在手机上运行frida-server之后,可以使用frid-ps -U命令查看运行的进程
请添加图片描述
然后可以使用frida -U -l test0.js android.process.media将脚本注入进程,可以发现注入后打印了helloworld
请添加图片描述

在上面的参数中,-U指定usb设备,-l指定注入脚本所在路径,最后的androdi.process.media则是设备上正在运行的进程名

3.2.2 Java层hook基础

1.hook初探

android studio项目代码

package com.example.hooktest1;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import java.util.Locale;

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        int x=0,y=0;
        while(true){
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            fun(x,y);
            x++;y++;
        }
    }
    void fun(int x,int y)
    {
        Log.d("sum=",String.valueOf(x+y));
    }
}

运行结果: android studio控制台会持续输出x+y,并且x和y逐次自增
请添加图片描述

hook脚本代码:

function main(){
    console.log("Script loaded success")
    //Java.perform是frida的api函数,可以将其中的脚本注入到java运行库,参数是一个匿名函数
    //函数的主体内容是监控和修改java函数逻辑的主题内容,任何针对java层的操作都必须在这个api函数中
    Java.perform(function(){
        console.log("Inside java perform!")
        //java.use获取hook函数所在类的类名
        var Mainactivity=Java.use('com.example.hooktest1.MainActivity')
        console.log("Java.use.success!")
        //通过.连接函数名,比如这里的函数名是fun,表示想hookfun函数
        //implementation表示实现该函数,也就是hook掉,这里可以写自己的函数
        Mainactivity.fun.implementation=function(x,y)
        {
            console.log("x=",x,"y=",y,"x+y=",x+y)   //打印参数,这里应该是函数原本没有被修改时的参数,即函数正常执行时的参数情况
            var retvalue=this.fun(666,66)           //再次调用原函数并且传递原本的参数fun,即重新执行原函数,在这里就可以修改参数
            return retvalue      //返回函数返回值,返回值最好不要修改类型,否则可能出错
        }
    })
}
//参数是要被执行的函数,例如传入main,表示frida注入app后立刻执行main
//setTimeout可以指定frida注入app多久之后执行函数,用于延时注入
setImmediate(main)

将脚本注入进程frida -U -l test0.js com.example.hooktest1
可以看到注入之后命令台会输出js脚本函数的内容
请添加图片描述
再看看android studio命令台,可以发现控制台一直在输出sum=: 732
说明脚本中调用this.fun(666,66)成功
请添加图片描述

2.重载函数的hook

略微修改代码:

package com.example.hooktest1;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import java.util.Locale;
public class MainActivity extends AppCompatActivity {
    private String total="hello";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        int x=0,y=0;
        while(true){
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            fun(x,y);
            x++;y++;
            Log.d("hooktest:",fun("HelloWorld!"));
        }
    }
    void fun(int x,int y)
    {
        Log.d("sum=",String.valueOf(x+y));
    }
    String fun(String s){
        return s.toLowerCase();
    }

程序运行结果:
请添加图片描述

hook脚本:

//定位重载函数,使用overload即可,overload内指定重载函数参数类型,如果函数有返回值要注意返回
 function main(){
    console.log("Loaded sucess!")
    Java.perform(function(){
        console.log("Inside java perform")
        var activity=Java.use("com.example.hooktest1.MainActivity")
        console.log("定位activity成功")
        activity.fun.overload('java.lang.String').implementation=function(x){
            console.log("hook fun string=",x)
            return x
        }
        activity.fun.overload('int','int').implementation=function(x,y){
            console.log("x=",x,"y=",y)
           var ret= this.fun(66,55)
           return ret;
        }
    })
 }
 setImmediate(main)

hook结果
请添加图片描述

控制台:
请添加图片描述

3.2.3 Java层主动调用

上述实现的是被动调用:即随着app正常逻辑执行函数
主动调用则是可以直接调用关键函数,不需要app去执行该函数
这里又分两种情况:

  1. 类函数(静态方法) 直接使用Java.use找到函数所在类即可
  2. 实例方法(动态方法) 使用Java.choose这个api函数在java堆中寻找指定类实例

1. 主动调用例1

程序代码:
添加了secret和staticSecret两个方法

package com.example.hooktest1;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import java.util.Locale;

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        int x=0,y=0;
        while(true){
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            fun(x,y);
            x++;y++;
            Log.d("hooktest:",fun("HelloWorld!"));
        }
    }
    void fun(int x,int y)
    {
        Log.d("sum=",String.valueOf(x+y));
    }
    String fun(String s){
        return s.toLowerCase();
    }
    void secret(){
        Log.d("this is secret","find secret func!");
    }
    static void staticSecret(){
        Log.d("this is staticSecret","Find static!");
    }
}

程序执行结果:
请添加图片描述

hook脚本:

function main(){
    Java.perform(function(){
        console.log("Inside java perform")
        var MainActivity=Java.use("com.example.hooktest1.MainActivity")
            
        MainActivity.staticSecret()
        //动态函数主动调用
        //java.choose先从内存中寻找类的实例对象,然后再调用实例对象的函数
        Java.choose('com.example.hooktest1.MainActivity',{
            onMatch: function(instance){
                console.log("instance found",instance)
                instance.secret()
            },
            onComplete: function(){
                console.log('search Complete')
            }
        })

    })
}
setImmediate(main)

hook结果
可以看到成功打印了实例对象所在类及其地址
请添加图片描述

控制台可以看见成功调用了secret和staticSecret这两个函数
请添加图片描述

注意:调用这两个函数输出的结果是在android studio控制台,不在frida控制台,frida控制台输出的是js脚本中的内容.

2. 主动调用例2

略微修改上述程序代码,增加了两个私有变量,尝试hook变量值

package com.example.hooktest1;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import java.util.Locale;

public class MainActivity extends AppCompatActivity {
    private String total="hello";
    private int count=0;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        int x=0,y=0;
        while(true){
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            fun(x,y);
            x++;y++;
            Log.d("hooktest:",fun("HelloWorld!"));
        }
    }
    void fun(int x,int y)
    {
        Log.d("sum=",String.valueOf(x+y));
    }
    String fun(String s){
        return s.toLowerCase();
    }
    void secret(){
        total+="call"+count;
        count++;
        Log.d("this is secret","find secret func!");
    }
    static void staticSecret(){
        Log.d("this is staticSecret","Find static!");
    }
}

程序运行结果:
请添加图片描述

hook脚本:

//调用secret函数,需要控制台手动进行,
function callSecretFunc(){
    Java.perform(function(){
        Java.choose('com.example.hooktest1.MainActivity',{
            onMatch:function(instance){
                instance.secret()
            },
            onComplete:function(){

            }
        })
})
}

//获取total的值
function getTotalValue(){
    Java.perform(function(){
        Java.choose('com.example.hooktest1.MainActivity',{
            onMatch:function(instance){
                console.log("find instance=",instance)
                console.log("totalAddr=",instance.total)//获取类变量的值要使用.value,total本身是一个引用类型
                console.log("total=",instance.total.value)
            },
            onComplete:function(){
                console.log("search end")
            }
        })
    })
}
setImmediate(getTotalValue)

hook结果
可以看到程序先调用了getTotalValue函数,输出了total的值
然后我们在frida控制台调用callSecretFunc()脚本函数来调用secret函数修改total的值
再次调用getTotalValue输出total的值发现成功修改
请添加图片描述

总结:

  1. 获取类中的实例变量要用.value才可以得到他的值,如果直接打印得不到值(可以得到变量有关信息,因为total本身是一个引用类型)
  2. frida控制台中我们可以反复调用脚本的函数来达到反复调用程序函数的目的

第四章 Objection快速入门

4.2 Objection的安装与使用

4.2.1 objection安装

pip install -U objection

注意:由于frida更新较快,需要保证objection版本的发布时间在frida之后.最新的objection版本为1.11.0,对应的frida版本最大为14.2.14,frida-tools为9.2.2

4.2.2 objection使用

1. 注入进程进入REPL

objection默认通过USB连接设备,不需要像frida使用-U参数指定usb
以’设置’应用演示注入进程命令:objection -g com.android.settings explore
成功注入会显示如下信息:
请添加图片描述

这样就成功进入了objection的REPL界面,可以输入exit退出

2. 常用命令:

空格键可以提示输入命令
请添加图片描述

  1. help 如果不知道当前命令是什么效果,可以在命令前跟help,会输出命令的解释信息
    请添加图片描述

  2. jobs命令
    jobs list 显示当前作业
    jobs kill 删除作业
    请添加图片描述

  3. frida命令
    查看frida信息
    请添加图片描述

  4. 内存漫游相关命令
    (1)android hooking list classes
    打印内存中的所有类
    请添加图片描述

    (2)android hooking search classes key
    搜索包含关键词key的所有类
    请添加图片描述

    (3)android hooking search methods key
    搜索包含关键词key的所有方法
    请添加图片描述

    (4)android hooking list class_methods classname
    查看名为classname的类的所有方法
    请添加图片描述

    (5)android hooking list activities(services receivers providers)
    打印四大组件,列出进程所有的activity活动(service receiver provider)
    请添加图片描述

  5. hook相关命令
    android hooking watch class_method methodName
    对指定方法进行hook
    请添加图片描述

持续更新中…

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/576441.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

续---初识HTML!!!(结束篇)

续———初识HTML!!! 一、表单 1.表单的作用 关于表单的作用:表单最大的作用就是收集用户的信息,用户填写表单,点击提交数据给服务器。 2.如何画出表单? 在HTML中我们采用form标签来画一个…

2023 (ICPC) Jiangxi Provincial Contest -- Official Contest

A. Drill Wood to Make Fire 输出即可 #include<bits/stdc.h> #define int long long #define x first #define y second using namespace std; const int N1100; typedef pair<int,int>pii;int m,n; int a[N][N];void solve() {int s,v,n;cin>>n>>s&…

Kali-linux Arpspoof工具

Arpspoof是一个非常好的ARP欺骗的源代码程序。它的运行不会影响整个网络的通信&#xff0c;该工具通过替换传输中的数据从而达到对目标的欺骗。本节将介绍Arpspoof工具的 使用。 9.8.1 URL流量操纵攻击 URL流量操作非常类似于中间人攻击&#xff0c;通过目标主机将路由流量注…

腾讯T4大牛整理的SpringBoot文档,覆盖你认知中的所有操作

SpringBoot目前的使用已经很普遍了&#xff0c;实际的项目中&#xff0c;我们需要集成各种的插件支持&#xff0c;不仅如此&#xff0c;还有很多可能我们平时不知道&#xff0c;但是很方便的操作。pdf里面的东西还是比较全面的。 1、关于文档 2、获得帮助 3、第一 步 4、使…

【Docker】Docker最近这么火,它到底是什么

前言 Docker 是一个开源的应用容器引擎&#xff0c;让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux或Windows操作系统的机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。 &#x1f4d5;作者简介&#xff1a;热…

RMP软件管理、YUM源、磁盘管理。

1、RPM软件管理 1> 通过rpm安装vsftpd软件。 去官网找到xsftpdx86的链接。 2> 查询vsftpd软件包的信息。 3> 卸载软件包vsftpd。 2、YUM软件管理 1> 挂载本地光盘&#xff0c;配置yum源为rhel.repo。 2> 通过yum来安装traceroute。 3> 使用yum查询ifconfig命…

详解如何使用LAMP架构搭建论坛

文章目录 1.LAMP概述2.编译安装Apache httpd服务1.关闭防火墙&#xff0c;将安装Apache所需软件包传到/opt目录下2.安装环境依赖包 3.配置软件模块4.编译及安装5.优化配置文件路径&#xff0c;并把httpd服务的可执行程序文件放入路径环境变量的目录中便于系统识别6.添加httpd系…

位图,布隆过滤器,哈希分割

文章目录 &#x1f680;位图&#x1f4a1;概念&#x1f4a1;接口操作 &#x1f680;布隆过滤器&#x1f4a1;思想&#x1f4a1;实现代码&#x1f4a1;实际应用 &#x1f680;哈希分割 &#x1f680;位图 学习位图前&#xff0c;我们先来看一道题 用哈希表存储每个整数&#…

github在线编程

github在线编程 文章目录 github在线编程两种区别演示项目 Ruoyi-VueGitHub Codespaces 演示github 访问项目使用 GitHubCodeSpace 打开该项目查看运行环境安装运行环境初始化myql数据安装 redis运行前端运行后端前后端运行成功测试安装相关插件 GitPod 演示 说明: 目前总结 gi…

路径规划算法:基于果蝇优化的路径规划算法- 附代码

路径规划算法&#xff1a;基于果蝇优化的路径规划算法- 附代码 文章目录 路径规划算法&#xff1a;基于果蝇优化的路径规划算法- 附代码1.算法原理1.1 环境设定1.2 约束条件1.3 适应度函数 2.算法结果3.MATLAB代码4.参考文献 摘要&#xff1a;本文主要介绍利用智能优化算法果蝇…

聚类算法学习笔记(一)

聚类算法学习笔记&#xff08;一&#xff09; 方法Euclidean Cluster [ 1 ] ^{[1]} [1]SuperVoxel [ 1 ] ^{[1]} [1]Depth Cluster [ 1 ] ^{[1]} [1]SLR: Scan-line Run [ 1 ] ^{[1]} [1]Range Image-based [ 2 ] ^{[2]} [2] 实验对比其他概念Cluster ToleranceKD-Tree Referce…

95后阿里P7晒出工资单:狠补了这个,真香....

最近一哥们跟我聊天装逼&#xff0c;说他最近从阿里跳槽了&#xff0c;我问他跳出来拿了多少&#xff1f;哥们表示很得意&#xff0c;说跳槽到新公司一个月后发了工资&#xff0c;月入5万多&#xff0c;表示很满足&#xff01;这样的高薪资着实让人羡慕&#xff0c;我猜这是税后…

Oracle Linux 9.2 发布 - Oracle 提供支持 RHEL 兼容发行版

Oracle Linux 9.2 发布 - Oracle 提供支持 RHEL 兼容发行版 Oracle Linux with Unbreakable Enterprise Kernel (UEK) & Red Hat compatible kernel (RHCK) 请访问原文链接&#xff1a;https://sysin.org/blog/oracle-linux-9/&#xff0c;查看最新版。原创作品&#xff…

数学建模的初阶-快速上手

目录 第一步&#xff1a;明确问题 第二步&#xff1a;选择建模方法 第三步&#xff1a;收集数据 第四步&#xff1a;构建数学模型 第五步&#xff1a;模型验证与评估 数学建模软件推荐 统计模型 (1) 线性回归模型 (2) 逻辑回归模型 (3) 时间序列模型 优化模型 (1) …

cuda编程学习——运行错误检测(四)

前言 参考资料&#xff1a; 高升博客 《CUDA C编程权威指南》 以及 CUDA官方文档 CUDA编程&#xff1a;基础与实践 樊哲勇 文章、讲解视频同步更新公众《AI知识物语》&#xff0c;B站&#xff1a;出门吃三碗饭 1:编写头文件erro.cuh 编写一个头文件&#xff08;error.cuh&…

LabVIEWCompactRIO 开发指南第六章38

LabVIEWCompactRIO 开发指南第六章38 了解数据如何在模块硬件组件和LabVIEW FPGA框图之间传输&#xff0c;可以帮助开发更好的程序并更快地进行调试。本节介绍不同的硬件体系结构&#xff0c;模拟和数字C系列I/O模块以及如何与每个模块通信。这些模块通常用于测量或控制信号&a…

10. python字典

文章目录 一、什么是字典二、访问键-值对三、添加、修改键-值对四、删除键-值对4.1 语句del4.2 方法pop() 五、创建空字典六、遍历字典6.1方法items()6.2方法keys()6.3方法values() 七、嵌套7.1 字典列表7.2 在字典中存储列表7.3 在字典中存储字典 一、什么是字典 #创建一个字…

canal server 标准化集群搭建(一)

1.背景 随这业务增加&#xff0c;数据同步服务 canal server 需求与日俱增&#xff0c;以往私搭乱建的 canal server 不符合运维标准化。 2.目的 规范 canal server 的部署&#xff0c;形成固定操作流程及文档 3. 环境版本 canal server&#xff1a; canal.deployer-1.1.…

电装光庭汽车电子(武汉)有限公司

电装光庭汽车电子&#xff08;武汉&#xff09;有限公司 &#xff08;汽车座舱显示系统&#xff0c;汽车电子产品及其材料和组件的开发&#xff0c;设计&#xff0c;制造&#xff0c;销售&#xff0c;批发&#xff0c;进出口&#xff09; 一、公司介绍 电装光庭汽车电子是一…

Android中使用kotlin进行xutils数据库版本升级

Android中使用kotlin进行xutils数据库版本升级 前言 最近的项目是一个很老的项目&#xff0c;数据库采用的是xutils中的数据库&#xff0c;之前的业务没有关于版本变更和数据库修改的业务&#xff0c;这次新需求数据库需要新加一张表&#xff0c;之前的表也需要修改字段&…