Przecież ludzie siedzą przy narzędziach do rewersu i starają się sami zrozumieć, nadając odpowiednie nazwy funkcjom. Jeśli coś zostało napisane z użyciem popularnych bibliotek, frameworku lub silnika, to ułatwia.
Tak, ludzie siedzą nad takimi grami, ale to wymaga ogromnego samozaparcia.
Stare gry mają chyba stosunkowo mało kodu opartego na zewnętrznych zależnościach.
Zdecydowana większość funkcji zawiera pewnie implementację “gameplayu”.
Popatrz chociażby na ten plik. Nie ma tam prawie wcale wywołań zewnętrznych API. Pomijając kilka odwołań do stringów, cała logika opiera się na żonglowaniu wartościami liczbowymi i flagami.
Jak rozpoznałbyś w tych regułach zachowanie określonego typu przeciwnika?
Na dodatek spora część gier jest oparta na customowej maszynie wirtualnej i kod trzeba analizować na dwóch “poziomach abstrakcji”. Wtedy nawet standardowy debugger ma ograniczoną użyteczność.
Uznałem, że skrypty i vm ułatwiają. Wymagają interfejsów, które są bardziej czytelne.
Oglądałem kiedyś jakąś sesję dekompilacji gry. Nie starano się tam dokładnie wszystkiego rozpracować. Rozpracowywano to co byli w stanie/co było potrzebne. To czego nie byli, oznaczali jako niewiadoma z sugestiami, że jakieś wartości powodują coś. Ale nie wiadomo z czego to wynika.
W przykładzie który podałeś ułatwieniem są entity. Trzeba śledzić wartości i patrzyć co powoduje zmiany podczas gry.
VM jest ułatwieniem, jeśli masz rozpracowane opcode’y i narzędzia do analizy.
Do tego czasu analiza jest moim zdaniem znacznie trudniejsza, bo widzisz funkcje, które przetwarzają jakiś strumień danych (w postaci wirtualnego kodu maszynowego).
Nie wiem, czy już kiedyś to wklejałem (wyszukiwarka niczego nie znalazła), ale widziałem ostatnio ciekawe rozwiązanie do RE gier dosowych.
Kolesie napisali w C# emulator i debugger trybu rzeczywistego x86 z możliwością przekierowania wywołań kodu do funkcji C#.
@lacky mógłby opowiadać, ale chyba zagląda tu raz na miesiąc.
Jakiś rozpieszczony ostatnio jesteś jeśli chodzi o re. Zdeterminowany człowiek będzie czytał deasm jak książkę, na poziomie abstrakcyjnych powtarzalnych bloków i idiomów. Bo chyba sam nie masz problemu ze zrozumieniem wygenerowanego asma z własnego kodu?
Już częściej ;-) Miałem ostatnie 1-2 miesiące mocno napięty grafik. Ciężko mi polecić cokolwiek konkretnego nakierowanego na RE w DOS. Chyba jedynie debugger wbudowany w Dosbox.
Nie uważam siebie za jakiś autorytet, ale coś skrótowo mogę napisać.
Zależy co chcesz wyciągnąć. Jeżeli pliki graficzne, to punktem zaczepienia jest poznanie jakich bibliotek używa dana gra. Jeżeli jest to SDL, to mniej więcej możesz ustalić jakie funkcje są używane do ładowania tekstur. Po załadowaniu do debuggera robisz na takiej breakpoint na funkcji SDL i wiesz, że “gdzieś pomiędzy tą funkcją i startem aplikacji jest ładowanie pliku tekstur, jego rozpakowanie/dekodowanie/parsowanie”. Dalej możesz zawęzić poszukiwania szukając syscalla otwierającego pliki itd. Gorzej jeżeli aplikacja ma np statycznie zlinkowanego SDL (jeżeli dobrze pamiętam, to jego licencja pozwala na coś takiego). Wtedy masz więcej roboty, żeby ustalić w którym miejscu jest kod gry, a gdzie jest SDL.
Dużo pomaga jeżeli gra działa na jakimś gotowym silniku, a jeżeli ten silnik jest open source to już całkiem bajka (nawet jeżeli sama gra nie ma otwartych źródeł). Miałem tak z jedną grą zrobioną na Adventure Game Studio. Potrzebowałem sobie dodać do ekwipunku postaci jakiś przedmiot. Pogrzebałem w źródłach silnika jak obsługiwany jest tam ekwipunek i wiedziałem już czego mniej więcej szukać. Pomógł też fakt, że plik wykonywalny nie był do końca wystripowany. Nie było pełnych symboli debuggowych, ale były nazwy funkcji z silnika AGS. To co musiałem zrobić to ustalić w pamięci adres struktury zawierającej informacje o postaci. Popatrzyłem jakie funkcje silnika korzystają z tej struktury i była tam funkcja odpowiedzialna za przemieszczanie. Dałem na niej breakpoint, sprowokowałem przemieszczenie i miałem z GDB informację gdzie jest interesująca mnie struktura. Ponieważ AGS był open source, to mogłem ręcznie stworzyć sobie symbole debuggowe do interesujących mnie struktur i edytować je w GDB jak człowiek, a nie jak to zwierze ręcznie liczyć offsety ;-). Potem ręcznie z debuggera wołałem funkcję silnika odpowiedzialną do dodanie przedmiotu. Jako argument potrzebne były właśnie ta struktura, której szukałem i ID przedmiotu. Identyfikator ustaliłem już metodą prób i błędów, ale nie zajęło to jeż jakoś długo, bo wiedziałem czego szukam.
Ilość użytych przez autorów zewnętrznych bibliotek mocno potrafi ułatwić RE. Nawet jeżeli wystripują wydanie gry z wszelkich symboli debuggowych, to muszą pozostać nazwy funkcji importowanych z tych zewnętrznych bibliotek. Te biblioteki często lubią udostępniać jakieś tutoriale, przykładowe kody źródłowe itp. Czasami patrzysz w taki przykład i w dekompilację gry i widzisz, że w tym miejscu było kopiuj-wklej przykładu z dokumentacji. Podobna była akcja u tego gościa co analizował silnik gry Trespasser, ale tam źródłem wiedzy była jakaś stara książka o grafice komputerowej. Widać było, że niektóre fragmenty silnika to było takie kopiuj-wklej z tej książki.
Próbowałem kiedyś bawić w RE jakieś gry na DOS, ale pamiętam, że jakoś mi nie szło i temat porzuciłem. Może warto do niego wrócić, bo wtedy chyba robiłem to mocno po partyzancku. Być może teraz by mi poszło lepiej. Tamta gra używała jakiegoś extendera i miałem z nim jakiś problem, ale już nie pamiętam o co dokładnie poszło. Z tamtych czasów zrobiłem sobie kopię dokumentacji formatu LX (Linear eXecutable), której używał ten extender, a musiałem się naszukać, żeby ją znaleźć. Co prawda nie gra, ale natrafiłem kiedyś na stary elektrozłom, którego firmware działał na systemie operacyjnym “bytebos” (https://web.archive.org/web/19990208011926/http://www.bytebos.com/). Co się naszukałem jakieś konkretnej dokumentacji do tego wynalazku to moje (też zrobiłem sobie kopię na przyszłość ;-) ).
W jaki sposób tworzyłeś pliki symboli do binarek? Przygotowałeś pliki .c ze strukturami i skompilikowałeś do obiektu, czy jest jakiś inny sposób na generowanie takich DWARFów/PDB bez oryginalnej wersji?
Przecież ludzie siedzą przy narzędziach do rewersu i starają się sami zrozumieć, nadając odpowiednie nazwy funkcjom. Jeśli coś zostało napisane z użyciem popularnych bibliotek, frameworku lub silnika, to ułatwia.
Tak, ludzie siedzą nad takimi grami, ale to wymaga ogromnego samozaparcia.
Stare gry mają chyba stosunkowo mało kodu opartego na zewnętrznych zależnościach.
Zdecydowana większość funkcji zawiera pewnie implementację “gameplayu”.
Popatrz chociażby na ten plik. Nie ma tam prawie wcale wywołań zewnętrznych API. Pomijając kilka odwołań do stringów, cała logika opiera się na żonglowaniu wartościami liczbowymi i flagami.
Jak rozpoznałbyś w tych regułach zachowanie określonego typu przeciwnika?
Na dodatek spora część gier jest oparta na customowej maszynie wirtualnej i kod trzeba analizować na dwóch “poziomach abstrakcji”. Wtedy nawet standardowy debugger ma ograniczoną użyteczność.
Uznałem, że skrypty i vm ułatwiają. Wymagają interfejsów, które są bardziej czytelne.
Oglądałem kiedyś jakąś sesję dekompilacji gry. Nie starano się tam dokładnie wszystkiego rozpracować. Rozpracowywano to co byli w stanie/co było potrzebne. To czego nie byli, oznaczali jako niewiadoma z sugestiami, że jakieś wartości powodują coś. Ale nie wiadomo z czego to wynika.
W przykładzie który podałeś ułatwieniem są entity. Trzeba śledzić wartości i patrzyć co powoduje zmiany podczas gry.
VM jest ułatwieniem, jeśli masz rozpracowane opcode’y i narzędzia do analizy.
Do tego czasu analiza jest moim zdaniem znacznie trudniejsza, bo widzisz funkcje, które przetwarzają jakiś strumień danych (w postaci wirtualnego kodu maszynowego).
Nie wiem, czy już kiedyś to wklejałem (wyszukiwarka niczego nie znalazła), ale widziałem ostatnio ciekawe rozwiązanie do RE gier dosowych.
Kolesie napisali w C# emulator i debugger trybu rzeczywistego x86 z możliwością przekierowania wywołań kodu do funkcji C#.
@lacky mógłby opowiadać, ale chyba zagląda tu raz na miesiąc.
Jakiś rozpieszczony ostatnio jesteś jeśli chodzi o re. Zdeterminowany człowiek będzie czytał deasm jak książkę, na poziomie abstrakcyjnych powtarzalnych bloków i idiomów. Bo chyba sam nie masz problemu ze zrozumieniem wygenerowanego asma z własnego kodu?
Już częściej ;-) Miałem ostatnie 1-2 miesiące mocno napięty grafik. Ciężko mi polecić cokolwiek konkretnego nakierowanego na RE w DOS. Chyba jedynie debugger wbudowany w Dosbox.
Raczej chodziło o to byś opowiedział coś o RE w grach.
Nie uważam siebie za jakiś autorytet, ale coś skrótowo mogę napisać.
Zależy co chcesz wyciągnąć. Jeżeli pliki graficzne, to punktem zaczepienia jest poznanie jakich bibliotek używa dana gra. Jeżeli jest to SDL, to mniej więcej możesz ustalić jakie funkcje są używane do ładowania tekstur. Po załadowaniu do debuggera robisz na takiej breakpoint na funkcji SDL i wiesz, że “gdzieś pomiędzy tą funkcją i startem aplikacji jest ładowanie pliku tekstur, jego rozpakowanie/dekodowanie/parsowanie”. Dalej możesz zawęzić poszukiwania szukając syscalla otwierającego pliki itd. Gorzej jeżeli aplikacja ma np statycznie zlinkowanego SDL (jeżeli dobrze pamiętam, to jego licencja pozwala na coś takiego). Wtedy masz więcej roboty, żeby ustalić w którym miejscu jest kod gry, a gdzie jest SDL.
Dużo pomaga jeżeli gra działa na jakimś gotowym silniku, a jeżeli ten silnik jest open source to już całkiem bajka (nawet jeżeli sama gra nie ma otwartych źródeł). Miałem tak z jedną grą zrobioną na Adventure Game Studio. Potrzebowałem sobie dodać do ekwipunku postaci jakiś przedmiot. Pogrzebałem w źródłach silnika jak obsługiwany jest tam ekwipunek i wiedziałem już czego mniej więcej szukać. Pomógł też fakt, że plik wykonywalny nie był do końca wystripowany. Nie było pełnych symboli debuggowych, ale były nazwy funkcji z silnika AGS. To co musiałem zrobić to ustalić w pamięci adres struktury zawierającej informacje o postaci. Popatrzyłem jakie funkcje silnika korzystają z tej struktury i była tam funkcja odpowiedzialna za przemieszczanie. Dałem na niej breakpoint, sprowokowałem przemieszczenie i miałem z GDB informację gdzie jest interesująca mnie struktura. Ponieważ AGS był open source, to mogłem ręcznie stworzyć sobie symbole debuggowe do interesujących mnie struktur i edytować je w GDB jak człowiek, a nie jak to zwierze ręcznie liczyć offsety ;-). Potem ręcznie z debuggera wołałem funkcję silnika odpowiedzialną do dodanie przedmiotu. Jako argument potrzebne były właśnie ta struktura, której szukałem i ID przedmiotu. Identyfikator ustaliłem już metodą prób i błędów, ale nie zajęło to jeż jakoś długo, bo wiedziałem czego szukam.
Ilość użytych przez autorów zewnętrznych bibliotek mocno potrafi ułatwić RE. Nawet jeżeli wystripują wydanie gry z wszelkich symboli debuggowych, to muszą pozostać nazwy funkcji importowanych z tych zewnętrznych bibliotek. Te biblioteki często lubią udostępniać jakieś tutoriale, przykładowe kody źródłowe itp. Czasami patrzysz w taki przykład i w dekompilację gry i widzisz, że w tym miejscu było kopiuj-wklej przykładu z dokumentacji. Podobna była akcja u tego gościa co analizował silnik gry Trespasser, ale tam źródłem wiedzy była jakaś stara książka o grafice komputerowej. Widać było, że niektóre fragmenty silnika to było takie kopiuj-wklej z tej książki.
Próbowałem kiedyś bawić w RE jakieś gry na DOS, ale pamiętam, że jakoś mi nie szło i temat porzuciłem. Może warto do niego wrócić, bo wtedy chyba robiłem to mocno po partyzancku. Być może teraz by mi poszło lepiej. Tamta gra używała jakiegoś extendera i miałem z nim jakiś problem, ale już nie pamiętam o co dokładnie poszło. Z tamtych czasów zrobiłem sobie kopię dokumentacji formatu LX (Linear eXecutable), której używał ten extender, a musiałem się naszukać, żeby ją znaleźć. Co prawda nie gra, ale natrafiłem kiedyś na stary elektrozłom, którego firmware działał na systemie operacyjnym “bytebos” (https://web.archive.org/web/19990208011926/http://www.bytebos.com/). Co się naszukałem jakieś konkretnej dokumentacji do tego wynalazku to moje (też zrobiłem sobie kopię na przyszłość ;-) ).
W jaki sposób tworzyłeś pliki symboli do binarek? Przygotowałeś pliki .c ze strukturami i skompilikowałeś do obiektu, czy jest jakiś inny sposób na generowanie takich DWARFów/PDB bez oryginalnej wersji?