2016-04-12 6 views
5

Patrzę na kilka prostych środków anty-debug wymienione w tym artykule http://www.codeproject.com/Articles/30815/An-Anti-Reverse-Engineering-Guide#BpMemanty debug - oblicz zużycie pamięci funkcja detekcji przerwania int 3

I zostały wdrożone prostą kontrolę dla int 3 pułapki w sposób dana funkcja, aby funkcja testForInt3Breakpoints zwróciła wartość true, jeśli punkt przerwania jest ustawiony w dowolnym miejscu w obrębie thisIsADummyFunction. powyżej

int thisIsADummyFunction() 
{ 
    int i = rand(); 
    ++i; 
    return i; 
} 

bool testForInt3Breakpoints() 
{ 
    bool breakPointPresent = false; 
    unsigned char* memPtr = reinterpret_cast<unsigned char*>(thisIsADummyFunction); 

    auto size = 0x16; //this value determined by manual inspection of compiled code 

    for (size_t i = 0; i < size; i++) { 
     if (memPtr[ i ] == 0xCC) {   //see if byte equals int 3 instruction 
      breakPointPresent = true; 
      break;    
     } 
    } 
    return breakPointPresent; 
} 

Funkcja działa dobrze dla mnie, dla tej jednej konkretnej funkcji, ale chciałbym być w stanie monitorować wiele funkcji bez konieczności sprawdzania skompilowany kod za każdym razem.

Moje pytanie brzmi: czy istnieją metody uzyskiwania informacji o funkcji pamięci, aby wiedzieć, jaką pamięć monitorować?

rozumiem jest wieloplatformowym nie ogólny sposób, aby to zrobić w czasie wykonywania: How to get the length of a function in bytes?

ale używam na Windows x64 i Visual Studio 2015 i dość szczęśliwy dla konkretnych odpowiedzi na pomoście lub czegokolwiek, co mogłoby zautomatyzować proces w pewnym sensie.

+0

Twój kod generuje fałszywe alarmy.Jeśli naprawdę chciałeś sprawdzić opcodes 'int 3', musisz przeanalizować instrukcje. 0xCC może być częścią opcora innego niż "int 3" (na przykład wartość bezpośrednia). Poza tym debugger ma całą moc, by zmienić swój świat. Może zawieszać wątki, przeskakiwać kod lub ustawiać punkty przerwania inne niż przez wstrzykiwanie sekwencji 0xCC. To naprawdę bardzo naiwna próba odparcia ataków. – IInspectable

+0

Zamiast skanowania dla 0xCC, lepiej jest wygenerować skrót kodu, a następnie porównać pod kątem różnic. Ma to również zaletę wykrywania innych ataków polegających na modyfikacji kodu. –

+0

W skrócie, nie ma na to dobrego sposobu. Zobacz także: http://stackoverflow.com/questions/4156585/how-to-get-the-length-of-a-function-in-bytes –

Odpowiedz

0

Jak już wspomniano w komentarzach powyżej, nie ma dobrego rozwiązania dla tego konkretnego opisu problemu, szczególnie nie w połączeniu ze skanowaniem dla 0xCC jest to poprawny bajt, który pojawi się w kodzie prędzej czy później, nawet jeśli nie ma żadnych punktów przerwania zestaw.

Jak już wspomniano, lepszym rozwiązaniem byłoby zahartowanie całej sekcji kodu. Jednak ten ma następujące wady:

  • Hen-and-jajko Problem: Trzeba by uzyskać wartość hashed po kompilacji, ale faktycznie go używać wewnątrz kodu do porównania rzeczywistej hash z oczekiwaną.
  • W zależności od tego, jak często robisz kontrole i jak duża jest sekcja kodu (w tym kod biblioteki), może to mieć większy wpływ na wydajność. Dodatkowo, jeśli sprawdzisz, gdy aplikacja jest bezczynna, system Windows będzie musiał wyświetlać strony we wszystkich częściach kodu, nawet jeśli nie są one wykonywane w danej chwili, skutecznie blokując cały program w pamięci, nawet jeśli nie jest to wymagane.
  • Mogą pojawić się problemy z oprogramowaniem zabezpieczającym i innymi narzędziami, które wykonują niewielkie modyfikacje innych procesów. Niektóre narzędzia, takie jak to, zastępują/zawieszają część kodu bezpośrednio w pamięci, aby wykonać dodatkowe funkcje bezpieczeństwa.

Jeśli mimo to postanowił pójść tą drogą, można uzyskać granice sekcji kodu przy użyciu VirtualQuery ze wskaźnikiem nigdzie w kodzie (takich jak &main), a następnie odczytać je wszystkie i użyć algorytmu skrótu, takie jak Murmurhash (co jest dość szybkie), aby utworzyć skrót i porównać go z zapisaną wartością.

Aby rozwiązać problem z kurą i jajkiem, możesz na przykład uzyskać skrót od uruchomionej kopii programu (używając jakiegoś "tajnego" przełącznika wiersza poleceń lub czytając pamięć za pomocą innego programu, z którego można wykonać zadanie, aby wykonać to zadanie) i zapisać go w lokalizacji, która nie jest częścią hasha, takiej jak sekcja danych lub zasoby. Jeśli użyjesz tego drugiego, możesz nawet ustawić poprawny hasz w pliku bez rekompilacji go.

Powiązane problemy