2011-08-18 3 views
2

null로 끝나는 문자열의 모든 인스턴스를 프로세스 메모리로 검색하려고합니다. 나는 그때 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; 
     } 
    } 

그것은 작동하지만 enumed 너무 느립니다. 프로세스를 메모리 맵핑하는 방법이 있습니까? 아니면 어떻게하면 더 빨리 메모리를 검색 할 수 있습니까?

답변

3

외부 프로세스를 통해 올바른 접근 방식을 취할 수 있습니다. 그러나 문자열을 찾는 경우 특정 영역 (예 : 실행 가능 메모리)을 신경 쓰지 않아도되므로 검색 영역에서 제외시킬 수 있습니다. 대부분 PAGE_READONLYPAGE_READWRITE에만 관심이있을 것입니다.

ReadProcessMemory()를 사용하여 가능한 한 큰 블록으로 메모리를 읽어야합니다. 주 병목 현상은 디스크 입출력 (스와핑)에서 발생하며 실제로 그렇게 할 수있는 일은별로 없습니다. 멀티 스레딩을 사용하면 이전 읽기를 처리하는 동안 '버퍼링'이되므로 속도가 빨라집니다.

속도가 정말로 필요한 경우 올바른 방법은 현재 수행중인 것처럼 외부 프로세스를 사용하지 않는 것입니다. 프로세스의 가상 메모리 공간에 직접 액세스 할 수 있도록 DLL을 삽입해야합니다.

검색 알고리즘에서 약간의 트릭을 수행 할 수도 있습니다. 예를 들어, 문자열이 항상 4 바이트 정렬로 할당된다면 그 문자열 만 검색 할 수 있습니다. 가장 빠른 속도는 멀티 스레딩 및/또는 DLL 주입입니다.

+0

어떻게 해당 지역을 제외 할 수 있습니까? 그런데 그것은 동적 문자열입니다. 실행 파일 실행 후에 할당됩니다. 또한 큰 블록 (현재 검색중인 메모리 영역의 크기)으로 읽는 중입니다. – blez

+0

VirtualQueryEx에서 MEMORY_BASIC_INFORMATION 구조를 확인하고 보호 멤버를 확인하십시오. –

+0

작은 속도 향상. 문자열이 정렬되어 있지 않고 dll을 주입하고 싶지 않으므로 대부분의 바이러스 백신이이를 감지합니다. 멀티 스레드가 내 유일한 희망입니까? – blez

관련 문제