Pytanie:
Widok ramki stosu funkcji IDA Pro
PSS
2013-06-19 07:00:31 UTC
view on stackexchange narkive permalink

IDA Pro wyświetla określony bufor lub dopełnienie powyżej (przy niższych adresach) zmiennych lokalnych w widoku ramki stosu. Na przykład:

Przykład 1.
Poniższy zrzut ekranu widoku ramki stosu przedstawia bufor 12-bajtowy (zawarty w czerwonym polu):

enter image description here

Przykład 2.
Poniższy zrzut ekranu przedstawiający inny widok ramki stosu pokazuje ponownie 12-bajtowy bufor:

enter image description here

Rozumiem, że IDA oznaczyło to jako db?; undefined , ponieważ nie mógł dowiedzieć się, jak został użyty. Zdaję sobie również sprawę, że IDA automatycznie oblicza rozmiar ramki stosu poprzez monitorowanie ESP. Przypuszczam, że może to mieć coś wspólnego z nieulotnym obszarem zapisu rejestru. Jednak w Przykładzie 1 wyraźnie widać Zapisane reg .: 0 , aw Przykładzie 2 widać Saved regs: 4 . Jestem zdziwiony i oto moje pytania:

Dlaczego IDA Pro wyświetla określony bufor lub dopełnienie powyżej (przy niższych adresach) zmiennych lokalnych w widoku ramki stosu? Czy to przypadek, że oba widoki pokazują dokładnie 12 bajtów bufora? Czy jest to coś szczególnego w stosunku do określonej konwencji powoływania lub zgodności?

Kompilator może dodawać wypełnienie stosu ze względu na wydajność (wyrównanie pamięci) lub z powodów związanych z zapobieganiem przepełnieniu, ale nie pokazują się one tak dobrze. Czy możesz pokazać zdemontowany kod funkcji?
Dodaj instrukcje prologu funkcji.
Trzy odpowiedzi:
Jason Geffner
2013-06-19 07:58:24 UTC
view on stackexchange narkive permalink

IDA śledzi wartość wskaźnika stosu (ESP) podczas statycznej analizy całej funkcji. Największa ujemna wartość ESP (w stosunku do początku funkcji) jest używana do określenia rozmiaru ramki stosu.

Jeśli chodzi o to, dlaczego wysłane przez Ciebie ramki stosu mają „niezdefiniowane” bajty na górze, dzieje się tak dlatego, że IDA nie mogła automatycznie określić, czy i jak te przesunięcia stosu były używane.

Dziękuję bardzo za odpowiedź. Zdaję sobie sprawę ze wszystkiego, o czym wspomniałeś. Jednak nie odpowiada na moje pytania. Wyjaśniłem swoje pytania. Mam nadzieję, że jest to trochę bardziej jasne i możesz mi w tym pomóc.
PSS
2013-06-19 19:27:56 UTC
view on stackexchange narkive permalink

Dziękuję bardzo za odpowiedzi i komentarze. Czytając Wasze komentarze i przygotowując się do aktualizacji pytania, znalazłem odpowiedź.

Muszę przyznać uznanie Igorowi Skochinskiemu, który poprosił mnie o dostarczenie instrukcji dotyczących prologu funkcji. Obie funkcje używają konwencji wywoływania cdecl. Jednak konwencja wywoływania nie ma nic wspólnego z tym buforem. Oto jak wygląda prolog:

  push ebpmov ebp, espsub esp, <size of local vars>push ebxpush esipush edi  

Ten bufor odzwierciedla trzy instrukcje push dla rejestrów EBX, ESI, EDI. Rejestry te są klasyfikowane jako Callee Saved Registers , a ten „bufor” nosi nazwę Non-Volatile Register Save Area .

Zgodnie z konwencją x86 (ma to również zastosowanie do x64), rejestry są podzielone na Zapisane rejestry dzwoniących i Zapisane rejestry Callee .

Rejestry zapisane dzwoniącego są również znane jako rejestry ulotne. Są to główne rejestry procesora, takie jak EAX, EDX i ECX. Funkcja wywołująca (Caller) jest odpowiedzialna za zapisywanie ulotnych rejestrów na zwykle stosie czasu wykonywania przed wykonaniem wywołania.

Zapisane rejestry wywoływane są znane jako rejestry nieulotne. Są to główne rejestry procesora, takie jak EBX, ESI, EDI, ESP i EBP. Konwencja zakłada, że ​​wartości w tych rejestrach zostaną zachowane przez funkcję wywoływaną. W przypadku, gdy którykolwiek z rejestrów nieulotnych ma być używany wewnątrz wywoływanego, odbiorca jest odpowiedzialny za zapisanie rejestrów na stosie wykonawczym. Ponadto odbiorca jest odpowiedzialny za przywrócenie tych rejestrów przed powrotem do funkcji wywołującej.

Sposób, w jaki używane są rejestry ulotne i nieulotne, jest raczej sterowany przez kompilator. Poniższy dokument x86 Assembly Guide bardziej szczegółowo opisuje zasady dzwoniącego i wywoływanego.

nomilk
2013-06-19 15:26:44 UTC
view on stackexchange narkive permalink

Zrzuty ekranu pokazują, że badasz szczegółowy widok stosu IDA.

IDA nadaje nazwę każdemu bajtowi, do którego dostęp jest bezpośrednio w funkcji, pozostałe bajty pozostają niezdefiniowane.

Konwencja telefoniczna? Podaj nam prolog i epilog tego podprogramu, abyśmy mogli zobaczyć, jak stos jest przydzielany i czyszczony.

Więc jeśli jest to ramka stosu normalnej aplikacji napisanej w języku wysokiego poziomu (nie jest to złośliwe oprogramowanie ani napisane w asemblerze ręcznym) i nie wywołując konkretnej konwencji, myślę, że możemy się zgodzić, że kompilator z jakiegoś powodu przydzielił więcej miejsca na stosie, niż potrzebuje ta funkcja.

Nie sądzę, aby wiedzieć dlaczego kompilator to zrobił, ale to twój wybór.

Dziękuję za wkład. Wiem, co to za konwencja przywoławcza. Ja o to nie pytam. Chciałbym wiedzieć, czy ten konkretny bufor dotyczy określonej konwencji wywoływania? Aktualizuję swoje pytanie, aby to wyjaśnić.
@PSS Nie widzę mojej odpowiedzi wyjaśniającej, czym jest konwencja wywoływania, ale jeśli jesteś na tyle uprzejmy, aby dostarczyć nam prolog i epilog do tego podprogramu, aby dowiedzieć się, czy chodzi o konwencję wywoływania, czy nie, możemy pomóc ty.
Udzieliłem już odpowiedzi. Dziękuję za wkład.


To pytanie i odpowiedź zostało automatycznie przetłumaczone z języka angielskiego.Oryginalna treść jest dostępna na stackexchange, za co dziękujemy za licencję cc by-sa 3.0, w ramach której jest rozpowszechniana.
Loading...