Assembler

0

Pomoże ktos z analizą poniższego kodu?
Wartości pocztakopwe rejestrów:

EAX 00000000
EBX 00410000
ECX 23450090
EDX FEDC0000
EBP 00900000
ESP 00100000
ESI  00300000
EDI 00000000
Kod:
MOV [ESP-4], EAX
CALL EBX
:00400000
NOP
------
:00410000, 
ADD CX, 0BBBBh
SHR CX, 1
OR EAX, [ESP]
JZ 00410000
JMP EAX
:004F0000
NOP

Chodzi mi o analizę działania. W krokach co się dzieje. Sporo rozumiem i umiem sam zrobić ale trudność sprawia mi stos, który chyba nie do końca rozumiem. Miłoby było gdyby ktoś rozpisał pomocnicze obliczenia. Nie chodzi mi o same suche wyniki. Chcę się tego nauczyć i zrozumiec :)

0

Chodzi o to że powstaje mi pętla nieskończona a chyba nie powinno tak być...

0

Ty masz ten kod przeanalizować rozpisując to co się dzieje na kartce? Bo bezpośrednia zmiana wartości rejestru ESP jest błędem i skończyłoby się to w normalnym programie jakimś SIGSEGV. Jeśli to ma być tylko analiza "przyjmijmy, że" to mogłoby wyglądać to mniej więcej tak:

EAX 00000000
EBX 00410000
ECX 23450090
EDX FEDC0000
EBP 00900000
ESP 00100000
ESI  00300000
EDI 00000000
Kod:
MOV [ESP-4], EAX  ; na szczyt stosu program wrzuca null-byte'y
CALL EBX ; w miejsce null-byte'ów na stosie wrzuca adres powrotu z funkcji, której aktualny adres posiada rejestr EBX (adresem powrotu jest adres kolejnej instrukcji, czyli NOP) i wywołuje funkcje
:00400000
NOP
------
:00410000,  ; patrząc po wartościach rejestrów - to jest funkcja, której nastąpi wywołanie
ADD CX, 0BBBBh ; do dolnych 16-bitów rejestru ECX dodaje wartość hex 0xBBBB
SHR CX, 1 ; SHR to instrukcja przesuwająca bity w prawo odnosząc się do wartości unsigned, czyli to jest po prostu podzielenie dolnych 16-bitów rejestru ECX przez 2^1
OR EAX, [ESP] ; tu następuje operacja logiczna OR wartości w rejestrze EAX z wartością na szczycie stosu, czyli adresem powrotu z tej funkcji
JZ 00410000  ; jeśli poprzednia operacja OR dała wynik 0 to skocz ponownie na początek funkcji, czyli mamy do czynienia z pętlą
JMP EAX ; w przeciwnym wypadku skocz w miejsce, w które wskazuje wartość w rejestrze EAX
:004F0000
NOP

I teraz stos będzie wyglądał tak (przed wykonaniem instrukcji CALL EBX):

######################################################################
WARTOŚĆ EAX (0)
######################################################################
ADRES POWROTU main (przyjmując, że ta pierwsza funkcja to funkcja main) <---- ESP
######################################################################

Po wykonaniu instrukcji CALL EBX:

######################################################################
ADRES POWROTU FUNKCJI (ADRES INSTRUKCJI NOP) <---- ESP
######################################################################
ADRES POWROTU main (przyjmując, że ta pierwsza funkcja to funkcja main)
######################################################################

Więc skoro szczytem stosu jest adres powrotu funkcji, czyli adres kolejnej instrukcji będącej za CALL EBX to ta instrukcja OR EAX, [ESP] da wynik większy od 0, ponieważ EAX przechowuje wartość 0 --> http://www.ee.surrey.ac.uk/Projects/CAL/digital-logic/gatesfunc/#orgate

W EAX po wykonaniu tej operacji będzie adres instrukcji spod labela :00400000, czyli NOP. Ta instrukcja jest bezpośrednio przed pętlą zatem procesor wykona instrukcję, która tak naprawdę nie robi nic (NOP == No OPeration) zatem znów jesteśmy w pętli. Pętla nie zmienia wartości, na którą wskazuje rejestr ESP i z tego powodu zawsze wykonywana jest taka operacja --> ADRES POWROTU Z FUNKCJI, KTÓREJ ADRES PRZECHOWYWANY JEST W EBX or ADRES POWROTU Z FUNKCJI, KTÓREJ ADRES PRZECHOWYWANY JEST W EBX, a z tego z kolei wynika, że znów wartość tej operacji nie jest zerowa i znów następuje skok do tego adresu powrotu, znów wykonana jest instrukcja NOP i znów jesteśmy w pętli ponownie - ta sytuacja będzie się powtarzać i dlatego występuje w tym kodzie infinite loop.

1 użytkowników online, w tym zalogowanych: 0, gości: 1