na adresie 12ff60. Przypuśćmy, że pod adresem 0xl2ff5c jest przechowywana wartość 0x12456098. Zrzut pamięci o adresie 0xl2ff5c będzie wyglądał następująco:
0x12ff5c 98 60 45 12
Dane są wyświetlane tak jakby od końca. Adres wskazuje bowiem na najmniej znaczący bajt w słowie.
Aby znaleźć wskaźnik this, należy sprawdzić, gdzie jest przechowywany rejestr ECX na początku funkcji.
Aby dostać się do ramki stosu kodu wywołującego, należy posłużyć się wartością adresil wskazywanego przez rejestr EBP. Jest to wskaźnik do poprzedniej ramki stosu. Jak w wypadku każdej ramki stosu parametry wywołania są przechowywane w pamięci powyżej wskazywanego adresu, a zmienne lokalne są przechowywane poniżej tego adresu. Jeśli weźmiemy wartość przechowywaną we wskazywanym adresie to uzyskamy wskaźnik do ramki stosu kolejnego kodu wywołującego. I tak możemy kontynuować przechodzenie stosu.
Opisana technika jest poprawna w architekturze x86. Przedstawiony kod nie został zoptymalizowany. Zoptymalizowany kod będzie wyglądał inaczej. Zamiast zmiennych lokalnych mogą być na przykład użyte wskaźniki.
160
jak to zrobić
Czasami będziemy mogli zobaczyć tylko część stosu. Może to mieć kilka przyczyn. Na przykład stos może być uszkodzony, co uniemożliwi śledzenie go. Jeśli wiemy, w jakiej lokalizacji jest błąd, to może nam się udać umieścić w tej lokalizacji punkt zatrzymania i dowiedzieć się z niego, przez jaki kod jest zapisywany stos. Na ogół jednak trzeba będzie przejść przez każdy wiersz kodu, aż do znalezienia przyczyny błędu. Jest to jeden z najgorszych błędów do znalezienia.
Innym problemem może być to, że poza stosem, weszliśmy w kod uruchomieniowy. W tym wypadku to, co ujrzymy na stosie, będzie tym, co właśnie debugujemy. W celu rozwiązania tego problemu, należy użyć innych technik usuwania błędów.
Trzeci problem może być spowodowany użyciem funkcji w języku maszynowym napisanej w konwencji niezrozumiałej dla debugera. (Okno „Cali stack” debugera wypełnia się za pomocą czynności omówionych w poprzedniej wskazówce.) Jeśli pojawi się kod maszynowy, który uniemożliwi debugerowi przeszukanie rejestru EBP w celu znalezienia ramki stosu, to debuger się podda.
Jeśli nie brakuje nam cierpliwości, to możemy spróbować ominąć kod maszynowy, aby móc kontynuować przechodzenie stosu. Przed rozpoczęciem należy zapisać sobie