Często czasy NOP
służą do wyrównania adresów instrukcji. Zazwyczaj występuje to na przykład podczas pisania Shellcode w celu wykorzystania luki w zabezpieczeniach polegającej na przepełnieniu bufora lub sformatowaniu łańcucha .
Załóżmy, że masz względny skok do 100 bajtów do przodu i dokonaj pewnych modyfikacji kodu. Możliwe, że twoje modyfikacje zepsują adres celu skoku i jako taki będziesz musiał również zmienić wyżej wspomniany skok względny. Tutaj możesz dodać NOP
s, aby przesunąć adres docelowy do przodu. Jeśli masz wiele NOP
s między adresem docelowym a instrukcją skoku, możesz usunąć NOP
s, aby wyciągnąć adres docelowy do tyłu.
Nie stanowiłoby to problemu, jeśli pracujesz z asemblerem obsługującym etykiety. Możesz po prostu zrobić JXX someLabel
(gdzie JXX to jakiś skok warunkowy), a asembler zastąpi someLabel
adres tej etykiety. Jeśli jednak po prostu ręcznie zmodyfikujesz zmontowany kod maszynowy (rzeczywiste kody operacyjne) (jak to czasami bywa przy pisaniu kodu powłoki), musisz również ręcznie zmienić instrukcję skoku. Możesz go zmodyfikować lub przenieść docelowy adres kodu za pomocą NOP
s.
Innym przypadkiem użycia NOP
instrukcji może być coś, co nazywa się zaprzęgiem NOP . W istocie chodzi o stworzenie wystarczająco dużej tablicy instrukcji, które nie powodują żadnych skutków ubocznych (takich jakNOP
lub zwiększanie, a następnie zmniejszanie rejestru), ale zwiększ wskaźnik instrukcji. Jest to przydatne na przykład, gdy chcemy przejść do określonego fragmentu kodu, którego adres nie jest znany. Sztuczka polega na tym, aby umieścić wspomniane sanki NOP przed kodem docelowym, a następnie wskoczyć gdzieś na te sanki. Mamy nadzieję, że wykonanie będzie kontynuowane z tablicy, która nie wywołuje żadnych skutków ubocznych, i przesuwa dalej instrukcje według instrukcji, aż trafi na pożądany fragment kodu. Technikę tę stosuje się powszechnie we wspomnianych exploitach przepełnienia bufora, a zwłaszcza w celu przeciwdziałania środkom bezpieczeństwa, takim jak ASLR .
Jeszcze innym szczególnym zastosowaniem NOP
instrukcji jest modyfikowanie kodu jakiegoś programu. Na przykład można zastąpić części skoków warunkowych na NOP
s i jako takie ominąć warunek. Jest to często stosowana metoda podczas „ łamania ” ochrony oprogramowania przed kopiowaniem. Najprościej chodzi tylko o usunięcie konstrukcji kodu asemblera dla if(genuineCopy) ...
wiersza kodu i zastąpienie instrukcji NOP
s i .. Voilà! Nie dokonuje się żadnych kontroli i działa nieoryginalna kopia!
Zauważ, że w zasadzie oba przykłady kodu powłoki i crackowania robią to samo; modyfikować istniejący kod bez aktualizacji względnych adresów operacji opartych na względnym adresowaniu.