Jak ustalić właściwy DS dla gry DOS'owej i dopasować kod trainera TSR?

0

Cześć. Na wstepie wybaczcie, że się rozpisałem okropnie nawet jak na "moje standardy". Ale w wolnej chwili nadal męczyłem się z TSR'ami i "polskim Warcraftem". Swoje problemy opisuje poniżej.

Niestety @_13th_Dragon i @msm nie mogli mi pomóc (może teraz znajdą chwilę, bo wspomnę o nich w komentarzu :)), a jeśli nie to proszę innych o odpowiedź. Także jakoś udało mi się napisać na bazie tutoriala i kodu źródlowego autorstwa beanusa, który był zamieszczony w zinie BadIdea #1 napisać to co wklejam poniżej.

Kod działa prawidłowo, gra jest oszukiwana pod DOSBox'em zarówno w wersji CD jak i spatchowanej przeze mnie NOCD. Problem małem początkowo ze skorzystaniem z rejestru 32 bitowego, aby modyfikować pamięć pod adresem o wartości większej niż $FFFF. Poza tym teraz chciałbym się dowiedzieć jak w tym trainerze dopasować dwie rzeczy (kod poniżej).

Jak coś pod adresu http://olesio.eu/dos_asm.rar można pobrać moje "środowisko do działań z TASM'em pod DOS'em i potrzebnymi narzędziami (pliki *.asm kompilują się po naciśnięciu entera na nich pod NC, a po F4 otwierają się w skonfigurowanym Asm Edit). Natomiast z pod adresu: http://olesio.eu/polanie można pobrać wspomianą grę w wersji dyskietkowej (do niej trainer pisany na rejestracj 16 bitowych działa ok i jestem z kodu zadowolony), wersję z obrazem CD i wersję NOCD, z dołączonymi DOSBox'ami i trainerami.

Kod poniższego trainera jest też w mojej paczce DOS_ASM w pliku C:\ASM\polcd_t.asm. Ok. I teraz co mi spędza sen z powiek ;) Po pierwsze czy da się instrukcje po porównaniu, czyli te...

        mov     ds:[esi],eax
        mov     eax,0C9h
        mov     esi,1A7FDBh
        mov     ds:[esi],eax
        mov     eax,08Dh
        mov     esi,1A7FDCh
        mov     ds:[esi],eax
        mov     eax,082h
        mov     esi,1A7FDDh
        mov     ds:[esi],eax

Napisac jakoś bardziej elegancko? Zapis pojedycznego bajtu C9h pod 1A7FDBh niestety nie skutkuje zmianą w działaniu gry. Natomiast próba zapisu po instrukcji mov esi,1A7FDAh i porównaniu na przykład w sposób esi+1 też nie skutkuje zmianą w grze. Także czy można te patchowanie w pamięci zrobić jakoś bardziej elegancko pod względem zapisu? Prosił bym o przykład kodu.

Druga sprawa. Jak ustalać właściwy ds dla obszaru jaki mamy zmieniać? Teraz w kodzie jest tak, jak widzicie - czyli:

        mov     ax,word ptr ss:[bp+4]
        sub     ax,05F3h

W ax ląduje codesection gry (CS). Jednak wartość 05F3h ustaliłem trochę lamerską techniką. Mianowicie w kodzie patchującym pamięć gry, bez sprawdzania wartości zapisałem unikalny ciąg bajtów pod adresem gdzie ustaliłem koniecznośc zmian. Konkratnie 3a 9e 3a 9e. Później wyszukiwałem go w procesie DOSBox'a z uruchomioną grą i załadowanym TSR'em przy użyciu Cheat Engine. Następnie wyszukiwałem opcodów instrukcji w miejscu które trzeba patchowac, a które ustalilem debuggerem DOSBox'a, czyli bajty opcodów 89 C1 8D 82. Początkowo bez odejmowania czegokolwiek od ax różnica wyniosła o ile pamiętam $1680. Później odjąłem od ax jeden. Sprawdzilem różnice pod Cheat Engine i na podstawie obliczeń Kalkulatorem Windows w wyszła mi ta liczba do odjęcia jako prawidlowa. No właśnie, ale w czasach powstanie tej gry, gdy na topie był chyba Windows 95, a pod nim chyba tylko GameHack, to nie wiem czy tak łatwo było te różnice ustalić.

Niestety dosowy Soft-ICE i jednoczęsnie gra w wersji NOCD nie chcą działać pod VMWare WorkStaton ani DOSBox'em z postawionym DOS'em. A maszyny z Windows 95 nie stawiałem jeszcze. Zaś Debugger DOSBox'a nie ma polecenia w stylu s. Można tylko zrobić memdumpbin o wielkości $1000000 i przeszukać go na przykład pod HIEW'em. Z pod tego co widzę pod DOSBox'owym Debuggerem to po założeniu bpint na 33h mamy CS=160,a DS=168, ale odejmowanie 8 czy dodawanie albo próba zapisu pod samo ax, zawierające CS skutkuje właśnie tym przesunietym "na plus" (dalej) zmienionym ciągiem bajtów, o $1680.

O ile wiem to właśnie jedna wartość więcej w CS czy DS to chyba 16 ($10) bajtów - opcodów instrukcji. Także pewnie stąd ta różnica. Ale włąsnie jak takie rzeczy ustalać. Bo w kodzie w pliku gods_trn.asm zawartym w moim środowisku ASM'owym mamy ;DS=CS-1DB6h i według tego co opisano w pliku beanus01.txt (katalog C:\ASM), to faktycznie jak uruchomię grę GODS i we właściwej fazie gry wejdę do debuggera, to różnica między CS, a DS tyle właśnie wynosi. A tutaj w przypadku Polan CD próba dodania do CS 8 albo $1680 powodowała zapiś odpowiednich wartości jeszcze gdzie indziej i to po kilka razy czasami, co wynikało z CHeat Engine. Może mi to ktoś wyjaśnić jak takie rzeczy ustalać nie po omacku ale przy użyciu DOSBox'owego Debuggera?

A oto kod całego trainera, jeśli ktoś chciałby pomóc bez ściągania mojego "środowiska" ASM:

.model tiny
.code
.386
org 100h
Start:
        jmp  RealStart
OldProc dd 0
TrainerProc:
        push    bp
        mov     bp,sp
        pusha
        push    es
        push    ds
        mov     ax,word ptr ss:[bp+4]
        sub     ax,05F3h
        mov     ds,ax
        mov     eax,089h
        mov     esi,1A7FDAh
        cmp     dword ptr ds:[esi], 0828DC189h
        jne     EndOfTrainer
        mov     ds:[esi],eax
        mov     eax,0C9h
        mov     esi,1A7FDBh
        mov     ds:[esi],eax
        mov     eax,08Dh
        mov     esi,1A7FDCh
        mov     ds:[esi],eax
        mov     eax,082h
        mov     esi,1A7FDDh
        mov     ds:[esi],eax
EndOfTrainer:
        pop  ds
        pop  es
        popa
        pop  bp
        jmp  dword ptr cs:[OldProc]
RealStart:
	mov  ax,3
        int  10h
        mov  ah,9
        mov  dx,offset LogoText
        int  21h
        mov  si,81h
        mov  ax,3533h
        int  21h
        cmp  bx,offset TrainerProc
        jne  InstallNow
        mov  dx,word ptr es:[OldProc]
        mov  ax,word ptr es:[OldProc +2]
        mov  ds,ax
        mov  ax,2533h
        int  21h
        mov  ah,49h
        int  21h
        mov  ax,cs
        mov  ds,ax
        mov  ah,9
        mov  dx,offset UninstalledText
        int  21h
        mov  ax,4c02h
        int  21h
InstallNow:
        mov  ax,word ptr ds:[2ch]
        mov  es,ax
        mov  ah,49h
        int  21h
        mov  ax,3533h
        int  21h
        mov  word ptr cs:[OldProc],bx
        mov  word ptr cs:[OldProc +2],es
        mov  ax,2533h
        mov  dx,offset TrainerProc
        int  21h
        mov  ah,9
        mov  dx,offset InstalledText
        int  21h
        mov  dx,offset RealStart
        int  27h
LogoText db 13,10,13,10
                db '          ________  _________  ____ _________ __________  ____ ________'
                db 13,10
                db '       E _\    __/_/      \  \/   /_    _   /_\__   /_  \/   /_   /   /_'
                db 13,10
                db '      H  \    /   /   /   /       _/   ____/   _    _/   \   _/__     _/'
                db 13,10
                db '     T   /________\______/___\/___\___/   /_________\___\____\/_______\spot'
                db 13,10,13,10
                db '           Polanie CD (v4.27) not decreasing milk - trainer by olesio'
                db 13,10
                db '           Adapted from source code of Gods trainer by beanus & CoxoC'
                db 13,10,13,10,'$'
InstalledText   db '                     Trainer has been installed in memory.',13,10,13,10,'$'
UninstalledText db '                     Trainer has been removed from memory.',13,10,13,10,'$'
end Start
0
        mov     eax,089h
        mov     esi,1A7FDAh
        cmp     dword ptr ds:[esi], 0828DC189h
        jne     EndOfTrainer
        mov     ds:[esi],eax
        mov     eax,0C9h
        mov     esi,1A7FDBh
        mov     ds:[esi],eax
        mov     eax,08Dh
        mov     esi,1A7FDCh
        mov     ds:[esi],eax
        mov     eax,082h
        mov     esi,1A7FDDh
        mov     ds:[esi],eax

możesz zamienić na:

        mov     eax,0828DC189h
        mov     esi,1A7FDAh
        cmp     dword ptr ds:[esi], eax
        jne     EndOfTrainer
        mov     ah,0C9h
        mov     ds:[esi], eax

Nie wiem czy zdajesz sobie sprawę że kod:

        mov     eax,082h
        mov     esi,1A7FDDh
        mov     ds:[esi],eax

wpisuje nie tylko 082h pod adres 1A7FDDh ale jeszcze 00h pod adresy 1A7FDEh, 1A7FDFh 1A7FE0h

0

Dziękuję za odpowiedź. Jednak pomijając już sposób porównania. Tylko taki kod jak poniżej (bardziej optymalny o 4 bajty w wielkości wynikowego pliku *.com) działa ok i nie psuje późniejszych bajtów, bo również je ustawia). Twój kod do zmiany niestety nie sprawiał zmian, nie pomagały zmiany eax na ah czy ah na al i tym podobne. Nie pmagało też zapis z rzutowaniem [?] przez mov byte ptr ds:.... A i dodam również, że końcowa instrukcja mov eax,082h i późniejsze ustawianie rejestru esi musi się dokonać. Późniejszą instrukcję zapisu już można usunąc. Inaczej pod ostatni bajt zapisze się także wspomniane przez Ciebie bajty 00. Co również miało miejsce oczywiście wcześniej w podanym powyżej kodzie.

Prawidłowy póki co kod - w sensie działania jak założyłem i bez zapisu zbędnych bajtów 00, które na szczęśćie i tak nie psują gry - wraz z całym moim "środowiskiem" ASM wrzuciłem ponownie na: http://olesio.eu/dos_asm.rar . Także jeśli chcesz to pobierz wraz z grą i przetestuj jak znajdziesz czas. Ja nic lepszego nie wykombinuję z moją nikłą znajomością ASM. Być może te "udziwnienia" w sposobie zapisu do pamięci gry, wynikają z tego, że muszę - ze względu na wartości - używać rejestrów 32 bitowych, a może i też fakt, że gra działa w trybie chronionym pod extenderem DOS4GW. Pozostaje tylko kwestia, jak można ustalić łatwiej właściwy segment cs do zapisu tych danych, niż wspomnianą w pierwszym moim postcie, w tym wątku - "lamerską metodą". Może @msm znajdzie chwilę, bo obiecał tutaj spojrzeć, to może coś jeszcze doradzi w kwestii optymalnego zapisywania do pamięci oraz tego cs.

        mov     esi,1A7FDAh
        cmp     dword ptr ds:[esi], 0828DC189h
        jne     EndOfTrainer
        mov     eax,089h
        mov     ds:[esi],eax
        mov     eax,0C9h
        mov     esi,1A7FDBh
        mov     ds:[esi],eax
        mov     eax,00129828Dh
        mov     esi,1A7FDCh
        mov     ds:[esi],eax
        mov     eax,082h
        mov     esi,1A7FDDh

1 użytkowników online, w tym zalogowanych: 0, gości: 1