2

我正在尝试在进程的内存中搜索以空字符结尾的字符串的所有实例。我用 VirtualQueryEx 枚举了所有分配的内存区域,然后我用 ReadProcessMemory 将它们读取到一个字节数组并使用这个算法进行搜索(我在这里找到了,作者声称是最快的)

    public static unsafe List<long> IndexesOf(byte[] Haystack, byte[] Needle) {
        List<long> Indexes = new List<long>();
        fixed (byte* H = Haystack) fixed (byte* N = Needle) {
            long i = 0;
            for (byte* hNext = H, hEnd = H + Haystack.LongLength; hNext < hEnd; i++, hNext++) {
                bool Found = true;
                for (byte* hInc = hNext, nInc = N, nEnd = N + Needle.LongLength; Found && nInc < nEnd; Found = *nInc == *hInc, nInc++, hInc++) ;
                if (Found) Indexes.Add(i);
            }
            return Indexes;
        }
    }

它有效,但它太慢了。有没有办法对进程进行内存映射或以某种方式在其内存中更快地搜索?

4

1 回答 1

3

从外部流程来看,您几乎拥有正确的方法。但是,如果您正在寻找一个字符串,您可能不关心某些区域(例如可执行内存),因此您可以将它们从搜索区域中排除。很可能您真的只对PAGE_READONLY和感兴趣PAGE_READWRITE

您应该使用 ReadProcessMemory() 以尽可能大的块读取内存。主要瓶颈将是磁盘 IO(来自交换),您对此无能为力。多线程它会加快它的速度,因为这样你将在处理前一个读取时“缓冲读取”。

如果您真的需要速度,那么正确的方法不是像您现在所做的那样通过外部过程。您应该注入一个 DLL,以便您可以直接访问进程的虚拟内存空间。

在你的搜索算法中,你也可以做一些小技巧。例如,如果您知道字符串始终以 4 字节对齐方式分配,那么您可以搜索它们。您将获得的最大加速来自多线程和/或 DLL 注入。

于 2011-08-18T11:37:18.410 回答