当前位置: 首页 > news >正文

安卓逆向(Bundle)

android.os.Bundle 是 Android 中一个非常常用的类,用于在不同组件之间传递数据。你可以把它想象成一个容器,它可以存储各种数据(如字符串、整数、布尔值等),并且可以通过键(key)来访问这些数据。

作用

Bundle 主要用于以下几种场景:

  1. 传递数据到另一个 Activity 或 Fragment
  2. 保存和恢复应用的状态

基本示例

1. Activity 之间传递数据

如果你要从一个 Activity 向另一个 Activity 传递数据,通常会用到 IntentBundle

Activity A 中创建并传递数据:

Intent intent = new Intent(ActivityA.this, ActivityB.class);

// 创建一个 Bundle
Bundle bundle = new Bundle();
bundle.putString("key", "Hello from Activity A");
bundle.putInt("number", 100);

// 把 Bundle 添加到 Intent 中
intent.putExtras(bundle);

// 启动 ActivityB
startActivity(intent);

Activity B 中获取数据:

// 从 Intent 获取 Bundle
Bundle bundle = getIntent().getExtras();
if (bundle != null) {
    String message = bundle.getString("key");
    int number = bundle.getInt("number");
    // 使用获取到的数据
}

ActivityA.java 示例:

package com.example.myapp;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;

public class ActivityA extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_a);

        // 启动 ActivityB
        Intent intent = new Intent(ActivityA.this, ActivityB.class);
        startActivity(intent);
    }
}

1. 编写 Frida 脚本

假设你要 hook MainActivity 中的 onCreate() 方法,并打印出 Bundle 中的内容:

Java.perform(function () {
    // 获取 MainActivity 类
    var MainActivity = Java.use('com.example.app.MainActivity');

    // Hook onCreate 方法,捕捉传入的 Bundle
    MainActivity.onCreate.overload('android.os.Bundle').implementation = function (bundle) {
        console.log('onCreate called');

        // 打印 Bundle 中的所有键值对
        if (bundle != null) {
            var keys = bundle.keySet();  // 获取所有的键
            var iterator = keys.iterator();

            while (iterator.hasNext()) {
                var key = iterator.next();
                var value = bundle.get(key);  // 获取每个键对应的值
                console.log('Key: ' + key + ', Value: ' + value);
            }
        }

        // 调用原始的 onCreate 方法
        this.onCreate(bundle);
    };
});

bundle.keySet() 方法

  • 作用:返回 Bundle 中所有键的集合(即数据的字段名),这个集合是一个 Set<String>
  • 返回类型Set<String>,表示 Bundle 中的所有键。
  • 用法:你可以通过 keySet() 获取 Bundle 中的所有键,然后逐一访问每个键对应的值。

假设有一个 Bundle,存储了多个键值对:

Bundle bundle = new Bundle();
bundle.putString("name", "John");
bundle.putInt("age", 25);
bundle.putBoolean("isStudent", true);

你可以使用 keySet() 来获取所有的键:

Set<String> keys = bundle.keySet();
for (String key : keys) {
    Log.d("Bundle", "Key: " + key + ", Value: " + bundle.get(key));
}

这段代码会输出:

Key: name, Value: John
Key: age, Value: 25
Key: isStudent, Value: true

追踪数据流向:Activity A 到 Activity B

Activity AActivity B 传递数据时,通常会使用 Intent 来启动 Activity B。你可以通过 hook Activity A 启动 Activity B 时传递的 Intent 来追踪数据。

假设在 Activity A 中,你使用如下代码传递数据:

Intent intent = new Intent(ActivityA.this, ActivityB.class);
intent.putExtra("username", "john_doe");
startActivity(intent);

使用 Frida hook Intent.putExtra()Intent.getExtras() 方法后,Frida 会显示 username 和它的值 john_doe

检查 Activity 启动过程

你可以在 Activity 的生命周期中捕获 Intent 数据,例如在 onCreate()onNewIntent() 中。通过 Frida 你可以 hook 这些生命周期方法,并打印出 Intent 的内容。

Java.perform(function() {
    var Activity = Java.use("android.app.Activity");

    // Hook onCreate 方法
    Activity.onCreate.overload('android.os.Bundle').implementation = function(savedInstanceState) {
        var intent = this.getIntent();  // 获取启动当前 Activity 的 Intent
        var extras = intent.getExtras();
        if (extras != null) {
            var keys = extras.keySet();
            keys.forEach(function(key) {
                var value = extras.get(key);
                console.log("[+] onCreate - key: " + key + ", value: " + value);
            });
        }
        this.onCreate(savedInstanceState);  // 调用原始方法
    };
});

相关文章:

  • 把 CSV 文件摄入到 Elasticsearch 中 - CSVES
  • PAT乙级真题 — 1084 外观数列(java)
  • 一口井深7米,一只蜗牛从井底往上爬每天爬3米掉下去1米,问几天能爬上井口?
  • CEF132 编译指南 Linux 篇 - 获取 CEF 源代码:源码同步详解(五)
  • 代码随想录算法训练营Day47
  • 爱彼(Audemars Piguet):瑞士制表艺术的巅峰之作(中英双语)
  • 使用Charles进行mock请求
  • 如何调整 Nginx工作进程数以提升性能
  • 华为ensp IPSEC隧道两端经过nat配置实验!
  • 【kafka系列】Exactly Once语义
  • DeepSeek进阶开发与应用2:DeepSeek中的自定义层与复杂模型构建
  • 【AI】Docker中快速部署Ollama并安装DeepSeek-R1模型: 一步步指南
  • SpringBoot教程(三十二) SpringBoot集成Skywalking链路跟踪
  • 如何优雅地使用全局标志位
  • servlet中的ServletContext
  • 【D2】神经网络初步学习
  • dfs深度优先搜索—邻接矩阵 + 邻接矩阵-递归版 + 邻接表
  • 基于Flask的茶叶销售数据可视化分析系统设计与实现
  • 一. vue2和vue3的Proxy底层源码详细拆解
  • Kepware的OPC UA配置深入介绍
  • 中国-拉共体论坛第四届部长级会议北京宣言
  • 学者的“好运气”:读本尼迪克特·安德森《椰壳碗外的人生》
  • 秦洪看盘|预期改善,或迎来新的增量资金
  • 商务部新闻发言人就中美日内瓦经贸会谈联合声明发表谈话
  • 美国“贸易战”前线的本土受害者:安静的洛杉矶港和准备关门的小公司
  • 为证明我爸是我爸,我将奶奶告上法庭