As a known problem, Memory.readByteArray causes memory leaks when performing large memory reads.
“Memory.readByteArray()” Memory is not automatically freed · Issue #1997 · frida/frida (github.com)
I have come up with the following method to improve search speed and eliminate memory leaks.
1)Allocate memory for reading in advance.
2)Call mach_vm_read_overwrite.
3)Compress the read binary data with LZ4 using compression_encode_buffer.
4)Convert read result to ArrayBuffer with ArrayBuffer.wrap
By adopting this method, the memory read speed is increased by about 200% compared to Memory.readByteArray.
The code fragment is as follows.
const COMPRESSION_LZ4 = 0x100;
var mach_task_selfPtr = Module.findExportByName(null, "mach_task_self");
var mach_vm_read_overwritePtr = Module.findExportByName(
null,
"mach_vm_read_overwrite"
);
var mach_task_self = new NativeFunction(mach_task_selfPtr, "pointer", []);
var mach_vm_read_overwrite = new NativeFunction(
mach_vm_read_overwritePtr,
"int",
["pointer", "long", "int", "pointer", "pointer"]
);
var compression_encode_bufferPtr = Module.findExportByName(
null,
"compression_encode_buffer"
);
compression_encode_buffer = new NativeFunction(
compression_encode_bufferPtr,
"int",
["pointer", "int", "pointer", "int", "pointer", "int"]
);
var g_Buffer = Memory.alloc(1048576);
var g_dstBuffer = Memory.alloc(1048576);
var g_Task = mach_task_self();
function ReadProcessMemory(address, size) {
var size_out = Memory.alloc(8);
mach_vm_read_overwrite(g_Task, address, size, g_Buffer, size_out);
if (size_out.readUInt() == 0) {
return false;
} else {
var compress_size = compression_encode_buffer(
g_dstBuffer,
size,
g_Buffer,
size,
ptr(0),
COMPRESSION_LZ4
);
var ret = ArrayBuffer.wrap(g_dstBuffer, compress_size);
return ret;
}
}
How to expand lz4 on the python side is implemented in the following project.
frida-ceserver
I hope this information will be of some help.