慢 memory/signature 扫描仪
slow memory/signature scanner
我有以下字节数组:
?? ?? 00 00 ?? ?? 00 00 ?? ?? 00 00 ?? ?? 00 00 F1 FF FF ?? 00 00 00 0? 00 00 00 ?? 00 00 00 0? 00 00 00 0? 00 00 00 00 ?? ?? 47
我已经实现了一个 java 代码来查找模式以检索其地址。但是,我的方法非常慢,需要几分钟才能找到匹配的模式。我的代码的工作方式如下 (我正在使用 jna 库):
1- dump/retrieve 2048 字节。
2-在2048字节中使用boyer-moore算法搜索模式
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;
}
有人可以推荐一种 faster/effiecient 的实现方式吗?
每次越过 Java/Native 障碍时,都会有一些延迟。您构建代码的方式会导致多次不必要的读取。
您在循环中每次都创建了一个 new Memory()
对象。这在 Java 方面有一些小的开销(创建一个新对象并为其分配堆内存,但您也分配了相同大小的本机内存,您永远不会使用!您可以通过以下方式显着改进您的代码一次分配单个对象,然后重复将本机内存读入同一对象的 Java 端内存。(您也可以将 IntByReference()
初始化从循环中拉出,这是另一个本机 4 字节每次迭代都在浪费分配。)
另一方面,通过发送到搜索函数的格式化字符串将内存块转换为字符数组会产生开销。我不确定您是如何编写 search()
函数的,但我知道 dump()
的输出将需要对十六进制字符串中的字符进行更多操作并处理回车符 returns,并且可能比简单的字节数字比较效率低。我强烈建议从检索到的内存中读取 byte[]
数组,然后 运行 针对这些字节的算法。
最后,您选择 2048 作为阅读尺寸有什么原因吗?如果您一次可以抓取更大的块,那么您的 Java/Native 读取次数会更少。我建议至少 4096,通常的内存页大小,或 4096 的倍数。
我有以下字节数组:
?? ?? 00 00 ?? ?? 00 00 ?? ?? 00 00 ?? ?? 00 00 F1 FF FF ?? 00 00 00 0? 00 00 00 ?? 00 00 00 0? 00 00 00 0? 00 00 00 00 ?? ?? 47
我已经实现了一个 java 代码来查找模式以检索其地址。但是,我的方法非常慢,需要几分钟才能找到匹配的模式。我的代码的工作方式如下 (我正在使用 jna 库):
1- dump/retrieve 2048 字节。
2-在2048字节中使用boyer-moore算法搜索模式
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;
}
有人可以推荐一种 faster/effiecient 的实现方式吗?
每次越过 Java/Native 障碍时,都会有一些延迟。您构建代码的方式会导致多次不必要的读取。
您在循环中每次都创建了一个 new Memory()
对象。这在 Java 方面有一些小的开销(创建一个新对象并为其分配堆内存,但您也分配了相同大小的本机内存,您永远不会使用!您可以通过以下方式显着改进您的代码一次分配单个对象,然后重复将本机内存读入同一对象的 Java 端内存。(您也可以将 IntByReference()
初始化从循环中拉出,这是另一个本机 4 字节每次迭代都在浪费分配。)
另一方面,通过发送到搜索函数的格式化字符串将内存块转换为字符数组会产生开销。我不确定您是如何编写 search()
函数的,但我知道 dump()
的输出将需要对十六进制字符串中的字符进行更多操作并处理回车符 returns,并且可能比简单的字节数字比较效率低。我强烈建议从检索到的内存中读取 byte[]
数组,然后 运行 针对这些字节的算法。
最后,您选择 2048 作为阅读尺寸有什么原因吗?如果您一次可以抓取更大的块,那么您的 Java/Native 读取次数会更少。我建议至少 4096,通常的内存页大小,或 4096 的倍数。