IP = 0
, wskazuje na instrukcję mov eax, 10
b8
mov eax, LICZBA
, pobiera jeszcze 4 bajty stanowiące liczbę
IP = 5
, wskazuje na bajt b9
czyli instrukcję mov ecx, LICZBA
, itd.
eax
i ecx
, co to jest? Procesor ma wbudowany w siebie szereg rejestrów. Każdy rejestr to jednostka pamiętająca pewną liczbę bitów. Można powiedzieć w uproszczeniu, że eax
i ecx
przypominają zmienne z języka C.
32-bit | EAX | ECX | EDX | EBX | EDI | ESI | ||||||||||||||||||
16-bit | AX | CX | DX | BX | DI | SI | ||||||||||||||||||
8-bit | AH | AL | CH | CL | DH | DL | BH | BL |
AX | b15 | b14 | b13 | b12 | b11 | b10 | b09 | b08 | b07 | b06 | b05 | b04 | b03 | b02 | b01 | b00 |
AH | b15 | b14 | b13 | b12 | b11 | b10 | b09 | b08 | ||||||||
AL | b07 | b06 | b05 | b04 | b03 | b02 | b01 | b00 | ||||||||
123410 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 0 | 1 | 0 | 0 | 1 | 0 |
mov CEL, ŹRÓDŁO
- przekopiuj wartość ze ŹRÓDŁA do CEL u np. mov eax, ecx
skopiuje zawartość ecx
do eax
add CEL, WARTOŚĆ
- dodaj do CELu WARTOŚĆ np. add eax, 1
doda 1 do eax
sub CEL, WARTOŚĆ
- jw. ale odejmowanie
div REJESTR
- dzieli zawartość eax
przez REJESTR. Wynik zapisany będzie w eax
, reszta z dzielenia w edx
ale UWAGA!, rejestr edx
musi być wcześniej wyzerowany!
mul REJESTR
- mnoży eax
przez REJESTR
cmp CEL, WARTOŚĆ
- porównanie CELu z WARTOŚCIĄ np. cmp eax, ecx
porówna rejestr eax
z ecx
; po takim porównaniu ustawione zostaną flagi
j?? ETYKIETA
- jest to skok warunkowy do ETYKIETY; znaki zapytania to odpowiednie litery, których należy użyć do określonej funkcjonalności:
je
- jump-if-equal, skocz jeśli porównane wartości są równe
jne
- jump-if-not-equal, skocz jeśli nie są równe
jl
oraz jle
- jump-if-less oraz jump-if-less-or-equal, skocz jeśli CEL jest mniejszy od WARTOŚCI (jle
= jeśli mniejszy lub równy)
jg
oraz jge
- jump-if-greater oraz jump-if-greater-or-equal, skocz jeśli CEL jest większy od WARTOŚCI (jle
= jeśli większy lub równy)
C:
Asembler:
Warto zauważyć, że w C programista pisze if() myśląc przy jakim warunku wykonać kod, natomiast w asemblerze programista myśli przy jakim warunku przeskoczyć kod :)
C:
Asembler:
Instrukcja jmp
to bezwarunkowy skok - zawsze skacze do podanej etykiety, niezależnie od rejestru stanów.
Używany kompilator na zajęciach: http://flatassembler.net/download.php
Przykładowy kod: http://www.cs.put.poznan.pl/tzok/example.asm
Komentarz:
cinvoke NAZWA, ARGUMENT1, ARGUMENT2, ...
db
, koniecznie zakończone zerem. Znak nowej linii to 13, 10
(zobacz przykład powyżej, zmienna format_out
)
dd
mov eax, [n]
oznacza "zawartość zmiennej n wpisz do rejestru eax"
Używany debuger na zajęciach: http://www.ollydbg.de/odbg110.zip
Debugowanie to proces kontrolowanego uruchomienia aplikacji. Oznacza to tyle, że można wykonywać program instrukcja po instrukcji obserwując dokładnie jak zmieniają się wartości w rejestrach i flagi stanu.
Po włączeniu OllyDbg wczytujemy nasz skompilowany program przez opcję File->Open
Legenda:
Aby przejść jedną instrukcję do przodu, naciskamy F8. Po każdym kroku zmienione rejestry oraz flagi zapalają się na czerwono.
eax
trafia wartość 10
eax
znajduje się wartość o 1 mniejsza
[start + 1]
, czyli co to oznacza? Spójrz na sam początek tej strony gdzie znajduje się przykład jak wygląda instrukcja mov eax, LICZBA
; są to bajty b8 ?? ?? ?? ??
gdzie znaki zapytania oznaczają liczbę. A zatem zapis pod adres [start + 1]
nadpisuje te cztery bajty!
sub
ustawia flagę ZF
jeśli po jej wykonaniu wynikiem będzie zero. Natomiast instrukcja mov
nie zmienia żadnych flag. Dlatego sekwencja: sub
, mov
, jnz start
to prosta pętla, która będzie wracać do punktu startu dopóki w eax
nie znajdzie się zero.
eax
:
6a
oznacza umieść na stosie wartość o wielkości 1-bajta, natomiast 68
to umieść na stosie wartość o wielkości 4-bajtów
jecxz ETYKIETA
- skocz do etykiety jeśli ecx
jest równe 0 (nie potrzeba wykonywać insturkcji cmp
)
cmov?? CEL, WARTOŚĆ
- działa jak instrukcja mov
, ale działa warunkowo; pod znaki zapytania należy wstawić końcówki jak w insturkcjach skoku np. cmovz
albo cmovle