Fanatyk LEGO Island nie powiedział jeszcze ostatniego słowa.

  • Lacky@tech.pr0n.plOP
    link
    fedilink
    arrow-up
    3
    ·
    22 days ago

    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ść ;-) ).

    • naur@tech.pr0n.plM
      link
      fedilink
      Polski
      arrow-up
      1
      ·
      18 days ago

      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?

      • Lacky@tech.pr0n.plOP
        link
        fedilink
        arrow-up
        2
        ·
        17 days ago

        Kopiowałem budowę struktur z kodu źródłowego silnika AGS do osobnego pliku C. Potem budowałem to do samego obiektu (plik *.o). Potem w w samym GDB ładowałem to poleceniem add-symbol-file.

        • naur@tech.pr0n.plM
          link
          fedilink
          Polski
          arrow-up
          1
          ·
          edit-2
          15 days ago

          Fajna sztuczka. Ciekawe czy zadziałałoby to w C++. Tutaj trzeba by pewnie trafić z flagami kompilatora, żeby layout klas był taki sam.

          Nawiasem mówiąc, w C++ kolejność składowych klasy w wygenerowanej binarce jest gwarantowana tylko w obrębie tego samego poziomu dostępu (public/protected/private). Tak więc teoretycznie robiąc strukturę trzeba by deklarować pewnie wszystie pola/metody publiczne. W praktyce wątpię, czy który kolwiek kompilator to przestawia.