2009-08-18 11 views
6

Rozważmy następujący kod x86 montaż:dereferencing etykietę w montażu x86

section .data 

foo: 
    mov ebx, [boo] 
    mov [goo], ebx 
goo: 
    mov eax, 2 
    mov eax, 3 
    ret 
boo: 
    mov eax, 4 
    mov eax, 5 
    ret 

Co dokładnie się dzieje? Kiedy wyodrębniam [boo] i mov do [goo] co dokładnie tam się poruszam? Tylko jedno polecenie? The ret również?


pytania uzupełniające:

  1. Czy dereferencing etykieta dać mi adres? Lub kod maszynowy dla pierwszego polecenia na etykiecie?
  2. Jeśli jest to kod maszynowy - w jaki sposób może to być więcej niż jedno polecenie? Czy wszystkie polecenia nie są w zasadzie 32-bitowe (nawet jeśli nie wszystkie bity są używane)?
  3. Dolna linia - czy eax ma wartość 3 lub 5 na końcu?

Odpowiedz

9

boo jest przesunięcie instrukcji mov eax, 3 wewnątrz sekcji .data. mov ebx, [boo] oznacza "pobranie czterech bajtów z przesunięciem wskazanym przez boo wewnątrz ebx". Podobnie, mov [goo], ebx przenosi zawartość ebx na offset wskazany przez goo.

Jednak kod jest często przeznaczony tylko do odczytu, więc nie powinno dziwić, że kod właśnie się zawiesza.

Oto jak instrukcje są kodowane w boo:

boo: 
b8 03 00 00 00   mov eax,0x3 
c3      ret 

Więc co masz w ebx jest właściwie 4/5 z instrukcją mov eax, 3.

+1

Wygląda to tak się dzieje do pracy, ponieważ nie są one w pełnym 32-bitowych i ilości ostatni bajt będzie zawsze wynosił 0. Ten kod zakończy się niepowodzeniem, jeśli spróbujesz czegoś takiego jak mov, eax 0xC000000 – Michael

+0

"przynieś cztery bajty" było tym, czego szukałem. dzięki! –

3

Pierwszy ruch jest kopiowany z przesunięcia odsunięcia względem rejestru segmentu [e] DS. Drugi mov zapisuje offset foo do lokalizacji danych względem rejestru DS. Jeśli CS i DS są przypadkowe, to można to zignorować. Zakładając, że CS i DS są przypadkowe, najprawdopodobniej natkniesz się na różne mechanizmy ochrony, które renderują sekcje kodu tylko do odczytu.

RE followups:

  1. Etykieta isnt jak odniesienie - dont dereference jako takie. Asembler zastępuje liczbę reprezentującą lokalizację w wynikowym kodzie. Możesz załadować adres lub adres podany w adresie. [I] wskazuje na dereferencje - w pierwszej odpowiedzi naprawiłem dezorientujący element, aby to uwzględnić. IOW robi [goo] ładuje rzeczy pod tym adresem.
  2. Zestaw instrukcji CISC podobnie jak x86 zawiera instrukcje o bardzo dużej długości - niektóre nawet nie są wielokrotnością długości słowa. RISC zazwyczaj starają się to zmienić, aby instrukcje dekodowania były prostsze.
  3. 3 - modyfikujesz tylko pierwsze 4 bajty z mov eax, 2 (które, z powodu małego kodowania endian, zostają zastąpione 4, ale potem zostają nadpisane przez następną instrukcję, która w ogóle nie została zmodyfikowana - 5 nigdy nie jest w obrazek jako kandydat (myślałem, że myślisz, że kod zostanie uporządkowany w sposób, w jaki zadałeś to pytanie [1], chociaż wyraźnie wiesz o wiele więcej, jak powinienem odgadnąć z twojego przedstawiciela: P)]).

Należy pamiętać, że wszystko to zakłada, że ​​CS = DS i DEP isnt intensywniejszej w.

Ponadto, jeśli uzywasz BX zamiast EBX, ten rodzaj rzeczy, które były oczekujących będzie wchodzić w grę (za pomocą xX zamiast ExX uzyskuje dostęp do niskich 2 bajtów rejestru [i xL uzyskuje dostęp do najniższego bajtu])

[1] Pamiętaj, że asembler jest czystym narzędziem do pisania opkodów - takich jak etykiety itp. Wszystko sprowadza się do liczby itp. z bardzo małą magią lub imponującymi przekształceniami kodu - nie ma tam zamknięć ani niczego głębszego z natury. (Jest to nieco upraszczając - kod może być przenoszone, a w wielu przypadkach fixups się zastosować do zwyczajów offsetu przez połączenie z łącznikiem i ładowarka)

+0

prawo - Byłem z RISC w umyśle ... dzięki za oczyszczenie tego punktu –

2

śledzić odpowiedzi:

  1. Daje kod maszynowy począwszy od adresu. Ile to zależy od długości twojego ładunku, w tym przypadku jest to 4 bajty.

  2. Może to być więcej niż jedno polecenie lub tylko fragment polecenia. W przypadku tej architektury (Intel x86) polecenia kodu maszynowego zawierają się w przedziale od 8 do 120 bitów.

  3. 3.