【Android】Frida Hook 文件读写操作

这篇具有很好参考价值的文章主要介绍了【Android】Frida Hook 文件读写操作。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

在挖掘客户端漏洞的时候,通常会关注应用对什么文件进行了读写操作,当我们能控制被读的文件或观测到敏感写入的文件,通常可以造成一定危害。本文详细介绍了如何通过frida监控文件读写操作。

相关知识

1. 读写相关调用api

在Linux系统下,文件的创建、读取、追加、写入和删除等操作涉及到以下系统调用:

  • open:打开文件,用于创建和打开文件。
  • fopen: 打开文件
  • read:从文件中读取数据。
  • write:向文件中写入数据。
  • lseek:移动文件指针。
  • close:关闭文件。
  • unlink:删除文件。

2. Interceptor.attach

在Frida中,**Interceptor.attach()**是一个用于拦截函数调用的函数。它可以让我们在目标进程中拦截任意函数调用,并在函数调用前或函数调用后执行自定义的JavaScript代码。

Interceptor.attach()函数的语法如下:

Interceptor.attach(target, callbacks)

其中,target参数指定要拦截的函数,可以是函数名或函数地址。callbacks参数是一个回调函数对象,用于定义拦截函数调用时要执行的代码。回调函数对象可以包含以下函数:

  • onEnter(args):在函数调用之前执行的回调函数,args参数是一个数组,包含了函数调用时的参数。
  • onLeave(retval):在函数调用之后执行的回调函数,retval参数是函数调用的返回值。

3. Interceptor

在Frida中,Interceptor对象是一个用于拦截函数调用和修改函数实现的工具集。除了**Interceptor.attach()**函数外,Interceptor对象还提供了以下几个常用的方法:

  • Interceptor.replace(target, replacement):用于替换函数实现。target参数指定要替换的函数,可以是函数名或函数地址;replacement参数是一个JavaScript函数,用于替换原函数的实现。替换函数的参数和返回值需要和原函数保持一致。以下是一个使用Interceptor.replace()函数替换strcmp()函数实现的示例:
// Replace the implementation of strcmp() 
function Interceptor.replace(
	Module.findExportByName("libc.so", "strcmp"), 
	new NativeCallback(function (str1, str2) {   
		console.log("strcmp() called with arguments: " + Memory.readUtf8String(str1) + ", " + Memory.readUtf8String(str2));   
		return 0; 
	}, 'int', ['pointer', 'pointer'])); 
  • Interceptor.attachOnce(target, callbacks):用于一次性拦截函数调用。与Interceptor.attach()函数不同,Interceptor.attachOnce()函数只会拦截一次函数调用,然后自动解除拦截。这个方法的参数和Interceptor.attach()函数相同。

  • Interceptor.detachAll():用于解除所有拦截器。这个方法会解除所有通过Interceptor.attach()和Interceptor.attachOnce()函数添加的拦截器。

  • Interceptor.flush():用于刷新所有修改过的函数实现。在修改函数实现后,需要调用Interceptor.flush()函数来刷新目标进程中的函数缓存。这样做可以确保修改后的函数实现能够生效。

4. Module.findExportByName()

Module.findExportByName()是一个用于查找指定模块中导出函数地址的函数。它可以通过模块名称和函数名来查找函数地址,并返回一个指向函数地址的NativePointer对象。

Module.findExportByName()函数的语法如下:

Module.findExportByName(moduleName, symbolName)

其中,moduleName参数是要查找的模块名称,可以是模块文件名或模块名称字符串;symbolName参数是要查找的函数名称,可以是函数名字符串或函数地址。需要注意的是,如果moduleName是模块文件名,则需要包含文件路径信息,并且路径分隔符需要使用反斜杠(\)转义。

如果第一个参数是NULL,则表示在全局进行搜索函数。

以下是一个使用Module.findExportByName()函数查找libc.so模块中的printf()函数地址的示例:

var printfAddr = Module.findExportByName("libc.so", "printf");
console.log("printf() address: " + printfAddr);

在上述示例中,我们使用Module.findExportByName()函数查找libc.so模块中的printf()函数地址,并将结果输出到控制台。

需要注意的是,Module.findExportByName()函数只能在已经加载的模块中查找函数地址。如果要查找未加载的模块中的函数地址,可以使用Module.load()函数动态加载模块,并使用Module.getExportByName()函数查找函数地址。

监控文件读写的Frida脚本

基于上述相关知识,写出下列frida脚本

function hook_file_read() {

    // Hook open、fopen、read函数
    Interceptor.attach(Module.findExportByName(null, "open"), {
        onEnter: function (args) {
            var path = Memory.readUtf8String(args[0]);
            this.path = path;
        },
        onLeave: function (retval) {
            if (retval > 0) {
                console.log("[open] path: " + this.path);


            }
        }
    });

    Interceptor.attach(Module.findExportByName(null, "fopen"), {
        onEnter: function (args) {
            var path = Memory.readUtf8String(args[0]);
            this.path = path;
        },
        onLeave: function (retval) {
            if (retval != 0) {
                console.log("[fopen] path: " + this.path);

            }
        }
    });

    Interceptor.attach(Module.findExportByName(null, "read"), {
        onEnter: function (args) {
            this.fd = args[0].toInt32();
            this.buf = args[1];
            this.size = args[2].toInt32();
        },
        onLeave: function (retval) {
            if (retval > 0 && this.fd > 0) {
                var data = Memory.readByteArray(this.buf, retval >>> 0);
                console.log("[read] fd: " + this.fd + ", size: " + retval + ", data: " + data);
            }
        }
    });
    // 3. Hook the write system call
    Interceptor.attach(Module.findExportByName(null, "write"), {
        onEnter: function (args) {
            // Get the file descriptor and buffer address
            var fd = args[0].toInt32();
            var buf = args[1];

            // Log the write call
            console.log("[write] fd: " + fd + ", buf: " + buf);
        }
    });

    // 4. Hook the lseek system call
    Interceptor.attach(Module.findExportByName(null, "lseek"), {
        onEnter: function (args) {
            // Get the file descriptor and offset
            var fd = args[0].toInt32();
            var off = args[1].toInt32();

            // Log the lseek call
            console.log("[lseek] fd: " + fd + ", offset: " + off);
        }
    });

    // 5. Hook the close system call
    Interceptor.attach(Module.findExportByName(null, "close"), {
        onEnter: function (args) {
            // Get the file descriptor
            var fd = args[0].toInt32();

            // Log the close call
            console.log("[close] fd: " + fd);
        }
    });

    // 6. Hook the unlink system call
    Interceptor.attach(Module.findExportByName(null, "unlink"), {
        onEnter: function (args) {
            // Get the file path
            var path = Memory.readUtf8String(args[0]);

            // Log the unlink call
            console.log("[unlink] path: " + path);
        }
    });


}

// 调用hook_file_read函数
setImmediate(hook_file_read);

运行实例:
【Android】Frida Hook 文件读写操作

后话

Interceptor.attach非常强大,主要还是看挖掘思路,往往能起到非常好的辅助效果。文章来源地址https://www.toymoban.com/news/detail-481824.html

到了这里,关于【Android】Frida Hook 文件读写操作的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • adb连接安卓模拟器或真机hook参数加密详细过程(frida)

    app逆向时,参数与函数的确定很关键,找到可疑的函数,不确定是否由该函数生成,该怎么解决?hook就应允而生了,首先是要求本地电脑和安卓模拟器(网易mumu模拟器支持多系统,该模拟器作为主流)或真机的连接,无论是网易mumu模拟器还是真机都要取得超级权限(root),

    2024年02月13日
    浏览(51)
  • C语言——文件操作(2)文件的读写操作

            之前,我讲解了文件的基本情况与读写模式,看到这篇博客的小伙伴们先参考这篇博客:  C语言——文件操作详解(1)_         接下来,我会继续讲解文件操作的第二大步:文件读/写操作。 目录         A.文件的顺序读写         一.字符输入输出函数 

    2024年02月09日
    浏览(26)
  • Android 文件读写

    Android的App可以读写的位置为: 一、内置data目录下对应app名称的目录; 二、扩展SD卡(包括虚拟的内置SD卡和外置SD卡); 一、先说说内置data目录下文件的读写。 内置data目录即内部存储,指的是应用内部独有的存储, 这部分存储的文件、数据,只能被应用自身访问到,其他

    2024年01月17日
    浏览(31)
  • c++文件操作 (1) -- 读写文件

    目录 为什么使用文件操作 文件输入流和输出流 -- 相对于内存而言 文件操作  1. 文件操作常用类以及头文件 2. 文件输入流(写文件操作)  1. 写文本文件  1)文件操作是使用对象来实现的  2)文件输出  3)打开文件  open函数 : 2. 读文本文件  3. 写二进制文件   4. 读二进制

    2024年01月25日
    浏览(34)
  • C语言文件操作(文件读写)

    本文主要介绍C语言中文件操作的相关内容(例:文件读、写等相关函数)。 在对计算机的使用中我们几乎离不开文件。例如常见的有word 文档,txt文本文件,图片文件、音频文件等。 文件是以计算机硬盘为载体存储在计算机上的信息集合。是数据源的一种,最主要的作用是保

    2024年02月02日
    浏览(30)
  • 【Android 】android13 新权限获取 读写文件权限

    android13 新权限获取 参考:Android 13(API 33)读写SD卡权限的调整适配 - Mr,Han - 博客园 android在 获取文件读写权限(尤其是音视频、图片等等资源)的权限获取逻辑更换了。 必须申请如下权限: 这段逻辑可以看上面的文件拷贝类的代码:

    2024年02月04日
    浏览(47)
  • android java读写yaml文件

    目录 申请读写权限: build.gradle中添加库引用: android java读写yaml文件 java修改yaml文件 YamlFile: 修改yaml文件方法2 Yaml: 删除值:     uses-permission android:name=\\\"android.permission.WRITE_EXTERNAL_STORAGE\\\" /     uses-permission android:name=\\\"android.permission.READ_EXTERNAL_STORAGE\\\" / 写文件可以参考下面的:

    2024年02月09日
    浏览(28)
  • Qt文件系统操作和文件的读写

    QIODevice:所有输入输出设备的基础类 QFile :用于文件操作和文件数据读写的类 QSaveFile :用于安全保存文件的类 QTemporaryFile :用于创建临时文件的类 QTcpSocket 和 QUdpSocket :分别实现了TCP和UDP的类 QSerialPort :实现串口通信的类 QBluetoothSocket :用于蓝牙通信的类 QProcess :用于启

    2024年02月12日
    浏览(35)
  • Qt——文件的读写操作

    文件的读写是很多应用程序具有的功能,甚至某些应用程序就是围绕着某一种格式文件的处理而开发的,所以文件读写是应用程序开发的一个基本功能。 Qt 提供了两种读写纯文本文件的基本方法: 用 QFile 类 的 IODevice 读写功能直接进行读写 利用 QFile 和 QTextStream 结合起来,

    2024年02月13日
    浏览(33)
  • 「Qt」文件读写操作

            我们知道 C 和 C++ 都提供了文件读写的类库,不过 Qt 也有一套自己的文件读写操作;本文主要介绍 Qt 中进行文件读写操作的类 —— QFile 。         一般的桌面应用程序,当我们想要打开一个文件时,通常会弹出一个文件对话框。在 Qt 中,文件对话框使用 QFileDial

    2024年02月12日
    浏览(27)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包