2011-08-18 131 views
2

我試圖搜索一個以null結尾的字符串進程的內存的所有實例。我enumed所有VirtualQueryEx的alloced內存區域,然後我用ReadProcessMemory讀給一個字節數組,並使用該算法中搜索(我發現這裏的作者聲稱是最快的)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; 
     } 
    } 

它的工作原理,但它太慢了。有沒有一種方法可以將內存映射到進程或以某種方式在其內存中更快地搜索?

回答

3

從外部過程中,你幾乎有正確的方法。但是,如果你正在尋找一個字符串,你可能不關心某些區域(例如,可執行內存),所以你可以從搜索區域中排除它們。很有可能你只對PAGE_READONLYPAGE_READWRITE感興趣。

您應該使用ReadProcessMemory()儘可能以較大的塊讀取內存。主要的瓶頸將是磁盤IO(來自交換),對於這一點你可以做的並不多。多線程會加速它,因爲那樣你會在處理先前的讀取時「緩衝讀取」。

如果您確實需要速度,正確的做法不是像現在這樣通過外部過程。您應該注入一個DLL,以便您可以直接訪問進程的虛擬內存空間。

在你的搜索算法中,你也可以做一些小技巧。例如,如果您知道字符串始終以4字節對齊方式分配,那麼您可以只搜索這些字符。您將獲得的最大提速是來自多線程和/或DLL注入。

+0

如何排除這些區域?順便提一下,這些都是動態字符串。它們在可執行程序執行後分配。此外,我正在閱讀大塊(作爲我正在尋找的當前內存區域的大小)。 – blez

+0

在VirtualQueryEx中,檢查MEMORY_BASIC_INFORMATION結構並查看Protect成員。 –

+0

這做了一個小的加速。該字符串不對齊,我不想注入一個DLL,導致最激進的病毒檢測到它。多線程是我唯一的希望嗎? – blez

相關問題