var fis = Java.use("java.io.FileInputStream");
var file = fis.$new("/data/local/file.txt");
var fileBytes = new Uint8Array(file.available());
var x;
while ((x = file.read()) != -1)
fileBytes.push(x);
我正在使用上面的代码,但它的读取速度约为100 kb / s,在我的情况下大约需要20秒。 >我也尝试了带有1,4,16kb缓冲区的ByteArrayOutputStream,但是结果没有什么不同。
我相信一个带有Inputfilestream并返回一个bytearray的本机Java函数将解决我的问题,但是我找不到任何。
如何使该过程更快?
我实际上正在尝试将其与具有
okio.ByteString
方法的.read()
一起使用,但无法从Frida中访问它。它是未定义的。#1 楼
您的代码运行缓慢的原因不是Frida,而是您的代码。在纯J2SE Java中执行时,您的代码也将很慢。简单的原因是,您正在使用无缓冲的
FileInputStream
逐字节读取文件,这是读取文件的最差方法。通常,IO操作可处理至少4096字节的块(文件系统中的典型块站点)。因此,简单的修改方法是将
FileInputStream
封装在BufferedInputStream
中:var fis = Java.use("java.io.FileInputStream");
var bis = Java.use("java.io.BufferedInputStream");
var file = bis.$new(fis.$new("/data/local/file.txt"));
...
但是,这不会占用大量时间的
read
调用。因此,以下代码读取字节块并进行处理。这应该快得多:
var fis = Java.use("java.io.FileInputStream");
var file = fis.$new("/data/local/file.txt");
var fileBytes = new Uint8Array(file.available());
const buffer = Java.array('byte', new Array(4096).fill(0));
var x;
while ((x = file.read(buffer)) != -1) {
for (int i = 0; i < x; i++) {
fileBytes.push(buffer[i]);
}
}
最快的方法是,如果您的应用程序包含直接将文件读取到文件的Java代码,字节数组。您必须执行更少的Frida JavaScript调用才能更快地获得结果。
因此,请检查您的应用程序是否包含像Apache公共IO之类的库。然后您可以直接执行
org.apache.commons.io.IOUtils.toByteArray(java.io.InputStream)
。#2 楼
不幸的是,使用缓冲区仍然对我没有帮助。我想做JS-> Java-> JS-> Java需要一些时间。我找到了以下解决方案:
var Files = Java.use("java.nio.file.Files");
var Paths = Java.use("java.nio.file.Paths");
var URI = Java.use("java.net.URI");
var fileBytes = Files.readAllBytes(Paths.get(URI.create("file:///sdcard/file.jpg")));
它确实用Java读取并返回了一个非常快的字节数组。
评论
实际上,我忘记了Files.readAllBytes是Java7函数,因此可以在Android上使用。但是,如何将其转换为Uint8Array?我认为逐字节转换它仍然是一个非常缓慢的操作。
–罗伯特
9小时前
@Robert我已经检查过,是的,新的Uint8Array(fileBytes)仍然很慢。 typeof fileBytes将其显示为一个对象,因此我不确定类型,甚至我们是否需要对其进行转换,因为转换后的类型看起来相同。我实际上是将此数组(不进行转换)传递给okio.ByteString,以便在Android应用程序中使用它,效果非常快
–卡格里
6小时前
评论
感谢您的回答,但是我之前已经尝试使用缓冲区,并且速度几乎相同。我没有尝试过Java.array,但它似乎也不起作用。我发布了对我有用的答案
–卡格里
9小时前