Jak znaleźć strukturę danych, która reprezentuje mój układ Saper w pamięci?

94

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?

KingNestor
źródło
27
Co za wspaniały pomysł na zadanie dla uczniów. To trochę jak laboratorium anatomiczne z trałowcem jako kotem.
ojblass
3
dla naszych międzynarodowych czytelników, którzy mogą być zdezorientowani, Saper jest amerykańską wersją szczęśliwej gry o znajdowaniu kwiatów, która jest dostarczana z systemem Windows Vista. microsoft.blognewschannel.com/index.php/archives/2006/09/28/…
Kip
16
Szczęśliwa gra o znajdowaniu kwiatów? O_o Polityczna poprawność posunęła się za daleko.
Eugene
10
Cóż, wersja trałowca jest domyślną wersją przynajmniej w szwedzkiej wersji Vista. Przypuszczam, że domyślnie wybierają wersję happy-flowers w miejscach, w których miny faktycznie rozbijają dzieci na kawałki.
JesperE
1
Więc ... po prostu kliknięcie na kilka przypadkowych kwadratów, aby zobaczyć, czy są to miny, nie jest w tym pomocne, co?
Smandoli

Odpowiedzi:

125

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:

  • Po uruchomieniu gry
  • Po kliknięciu radosna buźka
  • Po kliknięciu Game-> New lub wciśnięciu F2
  • Kiedy zmienisz poziom trudności

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.

.text:0100225D                 mov     [ebp+WndClass.lpfnWndProc], offset mainWndProc
.text:01002264                 mov     [ebp+WndClass.cbClsExtra], edi
.text:01002267                 mov     [ebp+WndClass.cbWndExtra], edi
.text:0100226A                 mov     [ebp+WndClass.hInstance], ecx
.text:0100226D                 mov     [ebp+WndClass.hIcon], eax

.text:01002292                 call    ds:RegisterClassW

Naciśnij Enter na nazwie funkcji (użyj „N”, aby zmienić jej nazwę na lepszą)

Teraz spójrz na

.text:01001BCF                 mov     edx, [ebp+Msg]

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

.text:01001D5B                 sub     eax, 111h
.text:01001D60                 jz      short loc_1001DBC

Kliknij prawym klawiszem myszy na 111h i użyj "Stała symboliczna" -> "Użyj standardowej stałej symbolicznej", wpisz WM_ i Enter. Teraz powinieneś

.text:01001D5B                 sub     eax, WM_COMMAND
.text:01001D60                 jz      short loc_1001DBC

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

... odbiera wiadomość WM_COMMAND lub WM_SYSCOMMAND. Najniższe słowo parametru wParam zawiera identyfikator akceleratora.

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.

.text:01001DBC HandleWM_COMMAND:                       ; CODE XREF: mainWndProc+197j
.text:01001DBC                 movzx   eax, word ptr [ebp+wParam]
.text:01001DC0                 mov     ecx, 210h
.text:01001DC5                 cmp     eax, ecx
.text:01001DC7                 jg      loc_1001EDC
.text:01001DC7
.text:01001DCD                 jz      loc_1001ED2
.text:01001DCD
.text:01001DD3                 cmp     eax, 1FEh
.text:01001DD8                 jz      loc_1001EC8

Użyj menu kontekstowego lub skrótu klawiaturowego „H”, aby wyświetlić wartości dziesiętne i możesz zobaczyć nasz skok

.text:01001DBC HandleWM_COMMAND:                       ; CODE XREF: mainWndProc+197j
.text:01001DBC                 movzx   eax, word ptr [ebp+wParam]
.text:01001DC0                 mov     ecx, 528
.text:01001DC5                 cmp     eax, ecx
.text:01001DC7                 jg      loc_1001EDC
.text:01001DC7
.text:01001DCD                 jz      loc_1001ED2
.text:01001DCD
.text:01001DD3                 cmp     eax, 510
.text:01001DD8                 jz      loc_1001EC8 ; here is our jump

Prowadzi to do fragmentu kodu, który wywołuje pewne procenty i kończy działanie wndProc.

.text:01001EC8 loc_1001EC8:                            ; CODE XREF: mainWndProc+20Fj
.text:01001EC8                 call    sub_100367A     ; startNewGame ?
.text:01001EC8
.text:01001ECD                 jmp     callDefAndExit  ; default

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

.text:0100367A sub_100367A     proc near               ; CODE XREF: sub_100140C+CAp
.text:0100367A                                         ; sub_1001B49+33j ...
.text:0100367A                 mov     eax, dword_10056AC
.text:0100367F                 mov     ecx, uValue
.text:01003685                 push    ebx
.text:01003686                 push    esi
.text:01003687                 push    edi
.text:01003688                 xor     edi, edi
.text:0100368A                 cmp     eax, dword_1005334
.text:01003690                 mov     dword_1005164, edi
.text:01003696                 jnz     short loc_10036A4
.text:01003696
.text:01003698                 cmp     ecx, dword_1005338
.text:0100369E                 jnz     short loc_10036A4

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.

.text:0100367A startNewGame    proc near               ; CODE XREF: handleButtonPress+CAp
.text:0100367A                                         ; sub_1001B49+33j ...
.text:0100367A                 mov     eax, newMineFieldWidth
.text:0100367F                 mov     ecx, newMineFieldHeight
.text:01003685                 push    ebx
.text:01003686                 push    esi
.text:01003687                 push    edi
.text:01003688                 xor     edi, edi
.text:0100368A                 cmp     eax, currentMineFieldWidth
.text:01003690                 mov     dword_1005164, edi
.text:01003696                 jnz     short loc_10036A4
.text:01003696
.text:01003698                 cmp     ecx, currentMineFieldHeight
.text:0100369E                 jnz     short loc_10036A4

Nieco później nowe wartości zastępują aktualny i wywoływany jest podprogram

.text:010036A7                 mov     currentMineFieldWidth, eax
.text:010036AC                 mov     currentMineFieldHeight, ecx
.text:010036B2                 call    sub_1002ED5

A kiedy to zobaczyłem

.text:01002ED5 sub_1002ED5     proc near               ; CODE XREF: sub_1002B14:loc_1002B1Ep
.text:01002ED5                                         ; sub_100367A+38p
.text:01002ED5                 mov     eax, 360h
.text:01002ED5
.text:01002EDA
.text:01002EDA loc_1002EDA:                            ; CODE XREF: sub_1002ED5+Dj
.text:01002EDA                 dec     eax
.text:01002EDB                 mov     byte ptr dword_1005340[eax], 0Fh
.text:01002EE2                 jnz     short loc_1002EDA

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

.text:01002EE4                 mov     ecx, currentMineFieldWidth
.text:01002EEA                 mov     edx, currentMineFieldHeight
.text:01002EF0                 lea     eax, [ecx+2]
.text:01002EF3                 test    eax, eax
.text:01002EF5                 push    esi
.text:01002EF6                 jz      short loc_1002F11    ; 
.text:01002EF6
.text:01002EF8                 mov     esi, edx
.text:01002EFA                 shl     esi, 5
.text:01002EFD                 lea     esi, dword_1005360[esi]
.text:01002EFD
.text:01002F03 draws top and bottom borders
.text:01002F03 
.text:01002F03 loc_1002F03:                            ; CODE XREF: sub_1002ED5+3Aj
.text:01002F03                 dec     eax
.text:01002F04                 mov     byte ptr MineField?[eax], 10h ; top border
.text:01002F0B                 mov     byte ptr [esi+eax], 10h       ; bottom border
.text:01002F0F                 jnz     short loc_1002F03
.text:01002F0F
.text:01002F11
.text:01002F11 loc_1002F11:                            ; CODE XREF: sub_1002ED5+21j
.text:01002F11                 lea     esi, [edx+2]
.text:01002F14                 test    esi, esi
.text:01002F16                 jz      short loc_1002F39

Reszta podprogramu rysuje lewą i prawą granicę

.text:01002F18                 mov     eax, esi
.text:01002F1A                 shl     eax, 5
.text:01002F1D                 lea     edx, MineField?[eax]
.text:01002F23                 lea     eax, (MineField?+1)[eax+ecx]
.text:01002F23
.text:01002F2A
.text:01002F2A loc_1002F2A:                            ; CODE XREF: sub_1002ED5+62j
.text:01002F2A                 sub     edx, 20h
.text:01002F2D                 sub     eax, 20h
.text:01002F30                 dec     esi
.text:01002F31                 mov     byte ptr [edx], 10h
.text:01002F34                 mov     byte ptr [eax], 10h
.text:01002F37                 jnz     short loc_1002F2A
.text:01002F37
.text:01002F39
.text:01002F39 loc_1002F39:                            ; CODE XREF: sub_1002ED5+41j
.text:01002F39                 pop     esi
.text:01002F3A                 retn

Inteligentne użycie poleceń WinDBG może zapewnić fajny zrzut pola minowego (niestandardowy rozmiar 9x9). Sprawdź granice!

0:000> db /c 20 01005340 L360
01005340  10 10 10 10 10 10 10 10-10 10 10 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f  ................................
01005360  10 0f 0f 0f 0f 0f 0f 0f-0f 0f 10 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f  ................................
01005380  10 0f 0f 0f 0f 0f 0f 0f-0f 0f 10 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f  ................................
010053a0  10 0f 0f 0f 0f 0f 0f 0f-0f 0f 10 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f  ................................
010053c0  10 0f 0f 0f 0f 0f 0f 0f-0f 0f 10 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f  ................................
010053e0  10 0f 0f 0f 0f 0f 0f 0f-0f 0f 10 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f  ................................
01005400  10 0f 0f 0f 0f 0f 0f 0f-0f 0f 10 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f  ................................
01005420  10 0f 0f 0f 0f 0f 0f 0f-0f 0f 10 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f  ................................
01005440  10 0f 0f 0f 0f 0f 0f 0f-0f 0f 10 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f  ................................
01005460  10 0f 0f 0f 0f 0f 0f 0f-0f 0f 10 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f  ................................
01005480  10 10 10 10 10 10 10 10-10 10 10 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f  ................................
010054a0  0f 0f 0f 0f 0f 0f 0f 0f-0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f  ................................
010054c0  0f 0f 0f 0f 0f 0f 0f 0f-0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f  ................................
010054e0  0f 0f 0f 0f 0f 0f 0f 0f-0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f  ................................

Hmm, wygląda na to, że potrzebuję kolejnego wpisu do zamknięcia tematu

Stanislav
źródło
1
@Stanislav, dobra odpowiedź Stanislav. Jeśli w ogóle możesz to rozwinąć, zrób to. Te długie, pouczające odpowiedzi są najlepsze. Może trochę więcej na temat tego, jak skupiłeś się na strukturze danych pola minowego?
KingNestor
@Stanislav, zaakceptowałem twoją odpowiedź, ponieważ kończyła się nagroda za 250 rep. Gratulacje!
KingNestor
1
@Stanislav, zredagowałem twoją wieloczęściową odpowiedź w jedną odpowiedź. Nie osiągnąłeś limitu rozmiaru Twojej pojedynczej odpowiedzi i myślę, że zazwyczaj lepiej jest mieć jedną odpowiedź niż opublikować kilka. Możesz edytować swoją oryginalną odpowiedź (tę) i uzupełniać ją według własnego uznania.
mmcdole
2
Również epicka odpowiedź Stanislav. Wielkie dzięki za twoją ciężką pracę!
mmcdole
15

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.

http://www.freeimagehosting.net/uploads/fcc1991162.png

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.

James McMahon
źródło
2
Cóż, ~ możesz ~ zlokalizować lokalizację pamięci poprzez statyczny demontaż. Możesz postępować zgodnie z instrukcjami asemblacji, szukając takich rzeczy, jak funkcje rand () wywoływane w celu wygenerowania pola minowego, a następnie prześledź stamtąd, aby zobaczyć, w jakim miejscu jest ono przechowywane w pamięci (i jak).
mmcdole
Oba podejścia są trudne. W przeszłości próbowałem rozmontowywać aplikacje i stwierdziłem, że jest to bardzo bolesne. Jak dokładnie rozpoznajesz funkcję rand ()?
James McMahon
Dziękuję za odpowiedź nemo.
KingNestor,
11

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.

Kirschstein
źródło
9

„W WinDbg mogę ustawić punkty przerwania, ale trudno mi sobie wyobrazić, w którym momencie ustawić punkt przerwania i w jakiej lokalizacji pamięci. Podobnie, gdy przeglądam kod statyczny w IDA Pro, nie jestem pewien, od czego zacząć aby znaleźć funkcję lub strukturę danych, która reprezentuje pole minowe. "

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)

Nick Dandoulakis
źródło
5

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.

mrduclaw
źródło
4

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:

  1. Jakoś zdobyć kod źródłowy.
  2. Zdemontuj i miej nadzieję, że pozostałe symbole mogą ci pomóc.
  3. Odgadnij typ danych i spróbuj nim manipulować i użyj skanera pamięci, aby ograniczyć możliwości.

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.

tekst alternatywny

Ty pisz

s <options> <memory start> <memory end> <pattern>

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.

tekst alternatywny

WinDBG wymaga trochę przyzwyczajenia się, ale jest tak dobry, jak każdy inny debugger.

Nieznany
źródło
1
„Jakoś zdobądź kod źródłowy” to głupie stwierdzenie, ponieważ Saper jest wysyłany bez źródła. A inżynieria odwrotna ze źródłem nie jest inżynierią wsteczną ... to analiza kodu źródłowego.
mrduclaw
@mrduclaw istnieją aplikacje, które mogą dekompilować assembler na język źródłowy. Nie ma terminu zwanego „analizą kodu źródłowego”.
Nieznane
1
@Unknown Istnieją aplikacje, które próbują zrekonstruować program w języku źródłowym z danego skompilowanego pliku binarnego. Ale nie można uzyskać „kodu źródłowego” z komentarzami autora i cytatami ze skompilowanego pliku binarnego. Jasne, niektóre z tych "dekompilatorów" wykonują lepszą robotę niż inne, ale nie dają Ci kodu napisanego przez autora (kod zoptymalizowany przez kompilator często bardzo różni się od kodu programisty). Czy nigdy nie przeprowadzałeś testów zapewniających jakość? Co robią narzędzia takie jak PREfast i Sparse? Statyczna analiza kodu źródłowego.
mrduclaw
Statyczna analiza kodu źródłowego w PREfast i Sparse różni się całkowicie od ręcznego odczytu zdekompilowanego kodu w celu zhakowania. Nie sądzę, żeby ktokolwiek pomylił te dwie różne idee ze sobą.
nieznane
@Unknown Idę dalej i zgadzam się, że nie należy mylić dezasemblacji za pomocą inżynierii wstecznej z przeglądaniem kodu źródłowego (zdekompilowanego lub w inny sposób, jeśli masz źródło, z którego wykonujesz analizę kodu źródłowego). To był cały mój punkt widzenia. Więc proszę, przestańcie mylić te dwie rzeczy. :)
mrduclaw
0

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.

Eugene
źródło
0

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ć cmpinstrukcji lub podobnej, w której jeden z operandów jest obliczany za pomocą przesunięcia, a xgdzie xjest wynikiem obliczenia obejmującego dzielenie liczb całkowitych. Przesunięcie będzie wówczas wskaźnikiem do początku struktury danych.

Jørgen Fogh
źródło
0

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.

Pavel Minaev
źródło
0

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.

Ivan Vučica
źródło