内存/签名扫描程序速度较慢



我有以下字节数组:

?? ?? 00 00 ?? ?? 00 00 ?? ?? 00 00 ?? ?? 00 00 F1 FF FF FF FF?? 00

00 00 0? 00 00 00 ?? 00 00 00 0? 00 00 00 00 00 ?? ?? 47我已经实现了一个 java 代码,它可以找到模式来检索其地址。但是,我的方法非常慢,需要几分钟才能找到匹配的模式。我的代码的工作方式如下(我正在使用 jna 库(:

1- 转储/检索 2048 字节。

2-使用Boyer-Moore算法在2048字节中搜索模式。

3-检索接下来的2048字节并应用Boyer-Moore算法(重复直到找到匹配的模式(

3-找到模式后,给我地址。

代码片段:

public void setTimeAddress() {
String pattern;
for (long i = 0x01000000; i <= 0x040000000; i += 2048) {
pattern = readMemory(process, i, 2048).dump();
if (search(pattern.toCharArray())) {
address = i - shift;
System.out.println(address);
break;
}
}
}
private Memory readMemory(Pointer process, long address, int bytesToRead) {
IntByReference read = new IntByReference(0);
Memory output = new Memory(bytesToRead);
kernel32.ReadProcessMemory(process, address, output, bytesToRead, read);
return output;
}

有人可以推荐一种更快/有效的方法来实现这一点吗?

每次越过Java/Native障碍时,都会产生一些延迟。 您构建代码的方式是执行多个不必要的读取。

每次在循环中创建一个new Memory()对象。 这在 Java 端有一些小开销(创建一个新对象并为其分配堆内存,但您也分配了相同大小的本机内存,您永远不会使用! 您可以通过分配单个对象一次,然后将本机内存重复读取到同一对象的 Java 端内存中来显著改进代码。 (您也可以将IntByReference()初始化从循环中拉出,这是您每次迭代浪费的另一个本机 4 字节分配。

另一方面,通过发送到搜索函数的格式化字符串将内存块转换为字符数组会产生开销。 我不确定您是如何编写search()函数的,但我知道dump()的输出将需要对十六进制字符串中的字符进行更多操作并处理回车符,并且可能不如简单的字节数字比较效率低。 我强烈建议从检索到的内存中读取byte[]数组,然后针对这些字节运行算法。

最后,您选择2048年作为阅读大小有什么原因吗? 如果你一次可以抓取更大的块,你的Java/本机读取就会更少。 我建议至少 4096,通常的内存页面大小,或 4096 的倍数。

最新更新