Frida之文件操作

Frida之文件操作

首页角色扮演无情剑客更新时间:2024-04-21

在前面的文章中介绍了数据库的操作,这篇文章主要介绍文件的操作。

当你在使用程序的时候,可以动态修改程序的文件操作,其实是很恐怖的,比如,本来是往文件中写入100元钱,但是经过动态修改后变成了0元,据此可以脑洞大开一下。 @[toc]

基础概念Linux下文件描述符

一个Linux进程启动后,会在内核空间创建一个PCB进程控制块,PCB是一个进程的私有财产。这个PCB中有一个已打开文件描述符表,记录着所有该进程打开的文件描述符以及对应的file结构体地址。

默认情况下,启动一个Linux进程后,会打开三个文件,分别是标准输入、标准输出、标准错误分别使用了0、1 、2号文件描述符。

当该进程使用函数open打开一个新的文件时,一般会在内核空间申请一个file结构体,并且把3号文件描述符对应的file指针指向file结构体。

v-node table entry是虚拟文件系统对应的文件节点,i-node是磁盘文件系统对应的文件节点。通过这两个节点就能找到最终的磁盘文件。 举个例子:

#include <unistd.h>#include <fcntl.h>#include <stdio.h>int main(int argc,char *argv[]){ int fd = open("./1.c",O_RDWR); printf("fd=%d\n",fd);}

程序运行结果是: fd=3

每一个进程只有一个process table entry,一般情况下默认使用 fd 0、fd1、fd2,新打开的文件1.c将使用fd 3,后续的文件描述符的值以此类推。

文件描述符含义0标准输入1标准输出2标准错误输出

JavaScript Promise对象

ECMAscript 6 原生提供了 Promise 对象。Promise 对象代表了未来将要发生的事件,用来传递异步操作的消息。

var myFirstPromise = new Promise(function(resolve, reject){ //当异步代码执行成功时,我们才会调用resolve(...), 当异步代码失败时就会调用reject(...) //在本例中,我们使用setTimeout(...)来模拟异步代码,实际编码时可能是XHR请求或是HTML5的一些API方法. setTimeout(function(){ resolve("欢迎关注我的微信公众号:无情剑客!"); //代码正常执行! }, 250);});myFirstPromise.then(function(successMessage){ //successMessage的值是上面调用resolve(...)方法传入的值. //successMessage参数不一定非要是字符串类型,这里只是举个例子 document.write("Yay! " successMessage);});

Promise简化了对error的处理,上面的代码我们也可以这样写:

promise.then(onFulfilled).catch(onRejected)

更多Promise的内容,后续会专门介绍。

Android Activity生命周期

为了在 Activity 生命周期的各个阶段之间导航转换,Activity 类提供六个核心回调:onCreate()、onStart()、onResume()、onPause()、onStop() 和 onDestroy()。当 Activity 进入新状态时,系统会调用其中每个回调。

文件和流文件File

import frida,sysdef on_message(message, data): if message['type'] == 'send': print(" {0}".format(message['payload'])) else: print(message)passsession = frida.get_usb_device().attach("com.lingpao.lpcf622b")jscode = """if(Java.available){ Java.perform(function(){ var Activity = Java.use('android.app.Activity'); Activity.onResume.implementation = function () { send('onResume() got called! '); var file = new File('/data/data/com.lingpao.lpcf622b/files/chat/test.txt', 'wb'); file.write('hello world'); file.flush(); file.close(); this.onResume(); }; });}"""script = session.create_script(jscode)script.on("message", on_message)print(' Start attach')script.load()sys.stdin.read()输入流InputStream

All methods are fully asynchronous and return Promise objects.

在类Unix系统中,获取输入流的方式:

在Windwos平台下,获取输入流的方式:

Android是基于Linux系统的,所以属于类Unix系统,具体代码示例,在前面的文章中对Intercepter进行了介绍,这里对open函数进行替换,对打开的文件读取输入流。

var openPtr = Module.getExportByName(null, 'open');var open = new NativeFunction(openPtr, 'int', ['pointer', 'int']);Interceptor.replace(openPtr, new NativeCallback(function (pathPtr, flags) { var path = pathPtr.readUtf8String(); console.log('Opening "' path '"'); var fd = open(pathPtr, flags); if (fd > 0){ var input = new UnixInputStream(fd); var promise = input.read(1000); promise.then(function(result){ console.log(' burning' hexdump(result,{lenght:1000})); }).catch(function(error){ console.log(' fail:' error); }); } console.log('Got fd: ' fd); return fd;}, 'int', ['pointer', 'int']));

运行结果如下。

输出流OutputStream

All methods are fully asynchronous and return Promise objects.

在类Unix系统中,获取输出流的方式:

在Windwos平台下,获取输出流的方式:

具体使用,可参考InputStream的使用。

输入输出流

输入和输出都是相对的。高中物理讲过火车上的人,以车做参考系,人是静止的,但是如果以树做参考系人是运动的,那末输入输出的参考系是什么?

内存。往内存中写就是输入,从内存中向文件中写就是输出。

写在最后

预告一下,下篇Frida的文章说网络,网络的本质其实还是文件。

公众号

更多Frida相关的内容,欢饮关注我的微信公众号:无情剑客。

查看全文
大家还看了
也许喜欢
更多游戏

Copyright © 2024 妖气游戏网 www.17u1u.com All Rights Reserved