2

プロセスのメモリで null で終わる文字列のすべてのインスタンスを検索しようとしています。割り当てられたすべてのメモリ領域を 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 に答える