Próbuję nauczyć się inżynierii odwrotnej, używając Minesweepera jako przykładowej aplikacji. Znalazłem ten artykuł MSDN na temat prostego polecenia WinDbg, które ujawnia wszystkie miny, ale jest stare, nie zostało wyjaśnione szczegółowo i naprawdę nie jest tym, czego szukam.
Mam dezasembler IDA Pro i debugger WinDbg i załadowałem winmine.exe do obu z nich. Czy ktoś może udzielić kilku praktycznych wskazówek dla któregokolwiek z tych programów w zakresie znajdowania lokalizacji struktury danych reprezentującej pole minowe?
W WinDbg mogę ustawiać punkty przerwania, ale trudno mi sobie wyobrazić, w którym momencie ustawić punkt przerwania iw jakiej lokalizacji pamięci. Podobnie, kiedy przeglądam kod statyczny w IDA Pro, nie jestem pewien, od czego zacząć, aby znaleźć funkcję lub strukturę danych reprezentującą pole minowe.
Czy w Stackoverflow są jacyś inżynierowie ds. Zwrotów, którzy mogą wskazać mi właściwy kierunek?
źródło
Odpowiedzi:
Część 1 z 3
Jeśli poważnie podchodzisz do inżynierii odwrotnej - zapomnij o trenerach i oszukujących silnikach.
Dobry inżynier odwrotny powinien najpierw zapoznać się z systemem operacyjnym, podstawowymi funkcjami API, ogólną strukturą programu (czym jest pętla uruchamiania, struktury Windowsa, procedury obsługi zdarzeń), format pliku (PE). Pomocne mogą być klasyki Petzolda „Programowanie Windows” (www.amazon.com/exec/obidos/ISBN=157231995X), a także MSDN online.
Najpierw zastanów się, gdzie można wywołać procedurę inicjalizacji pola minowego. Pomyślałem o następującym:
Postanowiłem sprawdzić komendę akceleratora F2.
Aby znaleźć kod obsługi akceleratora, należy znaleźć procedurę obsługi komunikatów okna (WndProc). Można go prześledzić za pomocą wywołań CreateWindowEx i RegisterClass.
Czytać:
Otwórz IDA, okno importu, znajdź "CreateWindow *", przejdź do niego i użyj polecenia "Skocz odnośnik do operandu (X)", aby zobaczyć, gdzie jest wywoływany. Powinien być tylko jeden telefon.
Teraz spójrz powyżej na funkcję RegisterClass i jej parametr WndClass.lpfnWndProc. W moim przypadku nazwałem już funkcję mainWndProc.
Naciśnij Enter na nazwie funkcji (użyj „N”, aby zmienić jej nazwę na lepszą)
Teraz spójrz na
Jest to id wiadomości, która w przypadku naciśnięcia klawisza F2 powinna zawierać wartość WM_COMMAND. Masz znaleźć porównanie do 111 godzin. Można to zrobić, śledząc w dół edx w IDA lub ustawiając warunkowy punkt przerwania w WinDbg i naciskając klawisz F2 w grze.
Tak czy inaczej prowadzi do czegoś takiego
Kliknij prawym klawiszem myszy na 111h i użyj "Stała symboliczna" -> "Użyj standardowej stałej symbolicznej", wpisz WM_ i Enter. Teraz powinieneś
Jest to łatwy sposób na znalezienie wartości identyfikatora wiadomości.
Aby zrozumieć obsługę akceleratora, sprawdź:
Na jedną odpowiedź to sporo tekstu. Jeśli jesteś zainteresowany, mogę napisać jeszcze kilka postów. Długopisy, krótkie pole minowe zapisane jako tablica bajtów [24x36], 0x0F pokazuje, że bajt nie jest używany (gra mniejsze pole), 0x10 - puste pole, 0x80 - moje.
Część 2 z 3
Ok, przejdźmy do przycisku F2.
Zgodnie z funkcją wndProc przy użyciu akceleratorów klawiatury po naciśnięciu przycisku F2
Ok, już znaleźliśmy, gdzie przetwarzany jest WM_COMMAND, ale jak określić odpowiednią wartość parametru wParam? Tutaj do gry wkracza haker zasobów . Nakarm go binarnymi i pokaże ci wszystko. Jak dla mnie stół akceleratorów.
tekst alternatywny http://files.getdropbox.com/u/1478671/2009-07-29_161532.jpg
Jak widać, przycisk F2 odpowiada 510 w wParam.
Wróćmy teraz do kodu, który obsługuje WM_COMMAND. Porównuje wParam z różnymi stałymi.
Użyj menu kontekstowego lub skrótu klawiaturowego „H”, aby wyświetlić wartości dziesiętne i możesz zobaczyć nasz skok
Prowadzi to do fragmentu kodu, który wywołuje pewne procenty i kończy działanie wndProc.
Czy to jest funkcja, która inicjuje nową grę? Dowiedz się w ostatniej części! Bądźcie czujni.
Część 3 z 3
Przyjrzyjmy się pierwszej części tej funkcji
Istnieją dwie wartości (dword_10056AC, uValue) wczytywane do rejestrów eax i ecx i porównywane z kolejnymi dwoma wartościami (dword_1005164, dword_1005338).
Spójrz na rzeczywiste wartości za pomocą WinDBG ('bp 01003696'; on break 'p eax; p ecx') - wydawały mi się wymiarami pola minowego. Gra z niestandardowym rozmiarem pola minowego pokazała, że pierwsza para to nowe wymiary, a druga - aktualne wymiary. Ustalmy nowe nazwy.
Nieco później nowe wartości zastępują aktualny i wywoływany jest podprogram
A kiedy to zobaczyłem
Byłem całkowicie pewien, że znalazłem tablicę minową. Przyczyna cyklu, który inicjuje tablicę długości 360h bajtów (dword_1005340) z 0xF.
Dlaczego 360h = 864? Poniżej znajduje się kilka wskazówek, które zajmują 32 bajty, a 864 można podzielić przez 32, więc tablica może pomieścić 27 * 32 komórek (chociaż interfejs użytkownika pozwala na maksymalnie 24 * 30 pól, istnieje jedno bajtowe wypełnienie wokół tablicy dla granic).
Poniższy kod generuje górną i dolną granicę pola minowego (0x10 bajtów). Mam nadzieję, że w tym bałaganie widać iterację pętli;) Musiałem użyć kartki i długopisu
Reszta podprogramu rysuje lewą i prawą granicę
Inteligentne użycie poleceń WinDBG może zapewnić fajny zrzut pola minowego (niestandardowy rozmiar 9x9). Sprawdź granice!
Hmm, wygląda na to, że potrzebuję kolejnego wpisu do zamknięcia tematu
źródło
Wygląda na to, że próbujesz zdemontować źródło, ale musisz spojrzeć na przestrzeń pamięci uruchomionego programu. Edytor heksadecymalny HxD ma funkcję, która pozwala właśnie na to.
Gdy znajdziesz się w przestrzeni pamięci, chodzi o robienie migawek pamięci podczas majstrowania przy tablicy. Wyodrębnij, co się zmienia, od tego, co nie. Kiedy myślisz, że masz uchwyt, w którym znajduje się struktura danych w pamięci szesnastkowej, spróbuj edytować ją, gdy jest w pamięci i zobacz, czy w rezultacie zmieni się tablica.
Proces, którego potrzebujesz, przypomina budowanie „trenera” do gry wideo. Zwykle polegają one na znalezieniu w pamięci miejsc, takich jak zdrowie i amunicja, i ich zmianie w locie. Możesz znaleźć dobre samouczki na temat tworzenia trenerów gier.
źródło
Sprawdź ten artykuł dotyczący projektu kodu, jest nieco bardziej szczegółowy niż wspomniany wpis na blogu.
http://www.codeproject.com/KB/trace/minememoryreader.aspx
Edytować
A ten artykuł, choć nie dotyczy bezpośrednio trałowca, zawiera dobry przewodnik krok po kroku dotyczący polowania w pamięci za pomocą WinDbg:
http://www.codingthewheel.com/archives/extracting-hidden-text-with-windbg
Edytuj 2
Ponownie, nie chodzi o trałowiec, ale na pewno dało mi to trochę do myślenia podczas debugowania pamięci, jest tutaj mnóstwo samouczków:
http://memoryhacking.com/forums/index.php
Pobierz również CheatEngine (wspomniany przez Nicka D.) i zapoznaj się z samouczkiem, który zawiera.
źródło
Dokładnie!
Cóż, możesz poszukać procedur, takich jak random (), które zostaną wywołane podczas tworzenia tabeli min. Ta książka bardzo mi pomogła, kiedy eksperymentowałem z inżynierią odwrotną. :)
Ogólnie rzecz biorąc, dobrymi miejscami do ustawiania punktów przerwania są wywołania skrzynek komunikatów, wywołania odtwarzania dźwięku, liczniki czasu i inne procedury API win32.
BTW, teraz skanuję trałowiec za pomocą OllyDbg .
Aktualizacja: nemo przypomniał mi świetne narzędzie, Cheat Engine autorstwa Erica „Dark Byte” Heijnen.
Cheat Engine (CE) to świetne narzędzie do oglądania i modyfikowania przestrzeni pamięci innych procesów. Poza tym podstawowym udogodnieniem, CE ma więcej specjalnych funkcji, takich jak przeglądanie zdemontowanej pamięci procesu i wstrzykiwanie kodu do innych procesów.
( prawdziwą wartością tego projektu jest to, że możesz pobrać kod źródłowy -Delphi- i zobaczyć, jak te mechanizmy zostały zaimplementowane - robiłem to wiele lat temu: o)
źródło
Całkiem niezły artykuł na ten temat można znaleźć na Uninformed . Obejmuje odwracanie Saper (jako wprowadzenie do inżynierii odwrotnej aplikacji Win32) z bardzo dużą ilością szczegółów i jest całkiem niezłym źródłem.
źródło
Ta witryna może być bardziej pomocna:
http://www.subversity.net/reversing/hacking-minesweeper
Ogólny sposób na zrobienie tego jest następujący:
W odpowiedzi na Bounty
Cóż, po drugim czytaniu wygląda na to, że wolisz przewodnik dotyczący korzystania z debuggera, takiego jak WinDBG, zamiast zwykłego pytania o inżynierię wsteczną. Pokazałem Ci już stronę internetową, która podaje wartości, których musisz szukać, więc pytanie brzmi, jak tego szukasz?
W tym przykładzie używam Notatnika, ponieważ nie mam zainstalowanego programu Minesweeper. Ale idea jest taka sama.
Ty pisz
Naciśnij „?”, A następnie „s”, aby wyświetlić pomoc.
Po znalezieniu żądanego wzoru pamięci możesz nacisnąć alt + 5, aby wywołać przeglądarkę pamięci i uzyskać ładny ekran.
WinDBG wymaga trochę przyzwyczajenia się, ale jest tak dobry, jak każdy inny debugger.
źródło
Dobrym punktem do rozpoczęcia śledzenia w debugerze byłoby przesunięcie wskaźnika myszy w górę. Więc znajdź procedurę okna głównego (myślę, że narzędzia takie jak spyxx mogą sprawdzać właściwości okna, a adres obsługi zdarzeń jest jednym z nich). Włam się do niego i sprawdź, gdzie obsługuje zdarzenia myszy - będzie przełącznik, jeśli możesz go rozpoznać w asemblerze (spójrz na wartość WM_XXX dla myszy w górę w windows.h).
Umieść tam punkt przerwania i zacznij wkraczać. Gdzieś pomiędzy momentem zwolnienia przycisku myszy a aktualizacją ekranu, ofiara uzyska dostęp do poszukiwanej infrastruktury.
Bądź cierpliwy, spróbuj zidentyfikować, co jest robione w danym momencie, ale nie zawracaj sobie głowy zagłębianiem się w kod, który podejrzewasz, że jest nieinteresujący dla twojego obecnego celu. Może to zająć kilka uruchomień w debugerze, aby to naprawić.
Znajomość normalnego przepływu pracy aplikacji win32 również pomaga.
źródło
Miny prawdopodobnie będą przechowywane w jakiejś dwuwymiarowej tablicy. Oznacza to, że jest to tablica wskaźników lub pojedyncza tablica wartości logicznych w stylu C.
Za każdym razem, gdy formularz odbiera zdarzenie myszy do góry, odwołuje się do tej struktury danych. Indeks zostanie obliczony za pomocą współrzędnych myszy, prawdopodobnie przy użyciu dzielenia liczb całkowitych. Oznacza to, że prawdopodobnie powinieneś poszukać
cmp
instrukcji lub podobnej, w której jeden z operandów jest obliczany za pomocą przesunięcia, ax
gdziex
jest wynikiem obliczenia obejmującego dzielenie liczb całkowitych. Przesunięcie będzie wówczas wskaźnikiem do początku struktury danych.źródło
Dość rozsądne jest założenie, że informacje o minach są rozmieszczone w pamięci w sposób ciągły przynajmniej dla wierszy (tj. Jest to tablica 2D lub tablica tablic). Dlatego spróbuję otworzyć kilka sąsiednich komórek w tym samym rzędzie, robiąc zrzuty pamięci z procesu, a następnie porównując je i szukając wszelkich powtarzających się zmian w tym samym regionie pamięci (tj. 1 bajt zmieniony w pierwszym kroku, następny bajt zmieniony na dokładnie tę samą wartość w następnym kroku itp.).
Istnieje również możliwość, że jest to spakowana tablica bitowa (3 bity na minę powinny wystarczyć do zarejestrowania wszystkich możliwych stanów - zamknięte / otwarte, moje / brak, oflagowane / nieoznaczone), więc też na to zwróciłbym uwagę ( wzory byłyby również powtarzalne, choć trudniejsze do wykrycia). Ale nie jest to wygodna struktura i nie sądzę, aby użycie pamięci było wąskim gardłem dla Saper, więc jest mało prawdopodobne, aby tego rodzaju rzeczy zostały użyte.
źródło
Chociaż nie jest to „narzędzie inżynierii wstecznej”, a raczej zabawka, której mógłby użyć nawet taki idiota, jak ja, sprawdź Cheat Engine . Ułatwia to nieco śledzenie, które części pamięci uległy zmianie, kiedy, a nawet ma możliwości śledzenia zmienionych części pamięci za pomocą wskaźników (chociaż prawdopodobnie nie potrzebujesz tego). Dołączony jest ładny interaktywny samouczek.
źródło