Przypisanie bajtu/znaku zczytanego z ds:segment do zmiennej w TASM.

0

Ponownie mam problem, googlowałem ale nie ogarniam. Mam tak zadeklarowaną zmienną w kodzie ASM TSR'a pisanego pod TASM:
alfa dd 0
i taki kod (fragment):

        push    word ptr ss:[bp+2]      ;CS
        pop     ax
        sub     ax,2A4Fh                ;AX-???=DS
        mov     es,ax                   ;ES=CS
        mov     ds,ax                   ;DS=DS
        mov     esi,04E44h
        mov     alfa,esi
        cmp     byte ptr ds:[esi-28h],48h
        jne     EndOfTSR
        cmp     byte ptr ds:[esi-27h],61h
        jne     EndOfTSR
        cmp     byte ptr ds:[esi-26h],76h
        jne     EndOfTSR
        cmp     byte ptr ds:[esi-25h],65h
        jne     EndOfTSR
        mov     esi,0BA91h
        mov     al,byte ptr ds:[alfa+0]
        mov     byte ptr ds:[esi+0],al

I pod adres ds:0BA91 trafia 44h, a ja chciałbym aby trafił tam bajt/znak, ktory jest pod adresem ds:[alfa+0]. Czyli bajt zczytany z adresu ds:4E44. Czyli jeżeli będzie tam przykładowo zczytany znak ASCII 5 to ma trafić w docelowe miejsce bajt 35h itp. Docelowo to ma być później jeżeli pomożecie mi ogarnąc - pętla i ma zapisywać jeszcze inne znaki. Przykładowo alfa+1 do esi+1, alfa+2, do esi+2 i tak dalej. Z gory dziękuję ze wszelkie przykładowe kody i wyjaśnienia. Do tej pory nie musiałem używać takich zmiennych, a więc mam z tym problem.

2

Co prawda już dawno nie używałem TASMa (wolę NASM) ale to będzie coś w stylu:

mov ebx, dword ptr [alfa]
mov al, byte ptr [ebx]
mov byte ptr [0BA91h], al
1

Wydaje mi się ze nie możesz w ten sposób "indeksować" za pomocą zmiennej. Musisz wartość ds:[alfa] wczytać do rejestru którym możesz indeksować (np. bx) i dopiero odwołac się do ds:[rejestr]

0

@Azarien: dziękuję. Tak jak poniżej zadziałało. Bo przez odwołanie się bezpośrednio przez mov byte ptr [0BA91h], al powodowało błąd kompilacji.

        mov     esi,0BA91h
        mov     ebx, dword ptr [alfa+0]
        mov     al, byte ptr [ebx]
        mov     byte ptr ds:[esi+0],al

Mam jednak pytanie, zanim ogarnę pętlę i będę zwiększał esi. Powtórzyłem dla próby powyższy kod jeszcze siedem razy, bo w sumie ma zastępować osiem znaków. I całość się kompiluje, ale gra uruchomiona po załadowaniu tego TSR'a wywala błąd Can't allocate heap chwilę po załadowaniu i mignięciu ekranu z doxcheckiem, wychodząc do DOS'a. Jak to można poprawić i co jest właściwie nie tak? Prosil bym o doradzenie. TSR jest oczywiście kompilowany i uruchamiany z pliku .com.

        mov     esi,0BA91h

        mov     ebx, dword ptr [alfa+0]
        mov     al, byte ptr [ebx]
        mov     byte ptr ds:[esi+0],al
 
        mov     ebx, dword ptr [alfa+1]
        mov     al, byte ptr [ebx]
        mov     byte ptr ds:[esi+1],al

        mov     ebx, dword ptr [alfa+2]
        mov     al, byte ptr [ebx]
        mov     byte ptr ds:[esi+2],al

        mov     ebx, dword ptr [alfa+3]
        mov     al, byte ptr [ebx]
        mov     byte ptr ds:[esi+3],al

        mov     ebx, dword ptr [alfa+4]
        mov     al, byte ptr [ebx]
        mov     byte ptr ds:[esi+4],al

        mov     ebx, dword ptr [alfa+5]
        mov     al, byte ptr [ebx]
        mov     byte ptr ds:[esi+5],al

        mov     ebx, dword ptr [alfa+6]
        mov     al, byte ptr [ebx]
        mov     byte ptr ds:[esi+6],al

        mov     ebx, dword ptr [alfa+7]
        mov     al, byte ptr [ebx]
        mov     byte ptr ds:[esi+7],al

Natomiast tylko takie coś jak poniżej się kompiluje i nie zawiesza gry:

        mov     ebx, dword ptr [alfa+0]
        mov     al, byte ptr [ebx]
        mov     byte ptr ds:[esi+0],al
 
        mov     ebx, dword ptr [alfa+1]
        mov     al, byte ptr [ebx]
        mov     byte ptr ds:[esi+1],al

        mov     ebx, dword ptr [alfa+2]
        mov     al, byte ptr [ebx]
        mov     byte ptr ds:[esi+2],al

Jednak pod adres alfa+0 trafia właściwy znak (wpisałem "abc") czyli "a". Jednak pod pozostałe dwa trafiają znaki o kodach ASCII (hex) 71 i 13. Jak to ogarnąć żeby było ok? Z góry dzięki za przykład kodu. Najbardziej interesuje mnie jak prawidłowo zrobić to pętlą od 0 do 7 włącznie tak żeby z alfa+iterator_pętliodczytane prawidlowe znaki trafiły do esi+iterator_pętli.

1

Tak nie wolno robić:

mov  ebx, dword ptr [alfa+1]

Tzn nie możesz indeksować przez zmienna+cośtam
Musisz tutaj użyć rejestru bx jak tak chcesz zrobić, tzn np.

mov bx, ds:[alfa]
mov eax, dword ptr ds:[bx+3]
mov ebx, eax

Napisalem ci już o tym wczesniej i Azarien tez o tym napisal...

0

Kurde zamotałem się. Najlepiej dla takiego laika jak ja trafiają przykłady, bo najpierw żeby w ogóle uniknąć błędów kompilacji robiłem taką pętlę:

        mov     esi,0BA91h
        mov     di, 0
aloop:
        mov     ebx, dword ptr [alfa+di]
        mov     al, byte ptr [ebx]
        mov     byte ptr ds:[esi+edi],al
        inc     di
        cmp     di, 3
        jnz	aloop 

I zapisywało same pierwszy znak i później pod dwa kolejne bajty bajty same zera, nie wspominając o zamuleniu gry przy reagowaniu na klawiaturę (kontroluję przerwanie 16h). Natomiast taki kod jak poniżej zapisywał pod czwarty bajt znak o kodzie ASCII 0.

        mov     esi,0BA91h
        mov     ebx,ds:[alfa]
        mov     eax,dword ptr ds:[bx+3]
        mov     ebx,eax
        mov     al,byte ptr [ebx]
        mov     byte ptr ds:[esi+3],al

Pomijając to że kompilator czepiał się kiedy przypisywałem ds:[alfa] do bx. Musiałem dać ebx, ponieważ to zmienna typu dd i chyba dlatego. Prosił bym o ostateczny przykład pętli od 0 do 7 włącznie, ktora wpisze co należy i skompiluje się dla zmiennej typu dd pod TASM'em. Sorry, że tak marudzę, ale do tej pory w TASMie operowałem tylko na starych i gotowych kodach, podmieniając stałe i dokonując nieznaczych zmian. A pętle i operacja na zmiennych by wszystko działałało bez błędów, dla kogoś mającego styczności głownie tylko z Delphi stanowi problem. Dziękuję za wyrozumiałość :)

1
mov ecx, 0
petla:
	mov	ebx, ecx
	mov	eax, dword ptr ds:[alfa+ebx]
	mov	ebx, eax
	mov	al, byte ptr ds:[ebx]
	mov	byte ptr ds:[esi],al
	inc	esi
	inc	ecx
	cmp	ecx, 8
jb petla

Jakoś tak bym to napisał.
Albo w ogóle tak:

mov ecx, 0
mov edi, offset alfa
petla:
	mov	ebx, dword ptr ds:[edi]
	mov	al, byte ptr ds:[ebx]
	mov	byte ptr ds:[esi],al
	inc	esi
	inc	edi
	inc	ecx
	cmp	ecx, 8
jb petla

Nie przypiszesz zmiennej dd do rejestru 16 bitowego (bx) bo dd ma 32 bity ;)

0

Niestety @Shalom, pętlę albo wpisują tylko pierwszy znak albo "wykrzaczają" grę. Mam do Ciebie ogromną prośbę i ewentualnie do innych zainteresowanych, jeżeli znaleźli by chwilę cierpliwości. Do tego posta dołaczyłem archiwum. Wystarczy je rozpakować. Następnie uruchomić plik l2.bat. Pokaże się okno DosBOX'a i w tle jego Deubbger, na ktory możemy się przełaczyć kombinacją lewy Alt+Pause Break, a powrócić do tego co jest uruchomione wciskając w nim F5. Poleceniem z c.bat w zamontowanych katalogach uruchamiamy kompilację pliku 5.asm pod dołaczonym TASM'em. Pauza jest dla pewności żeby zobaczyć czy nie było błędów kompilacji i/lub linkowania. A następnie grę. I teraz kod 5.asm jest w "wariancie" z drugą pętlą. Raz powodowała on wywalenie gry. Teraz tylko debugger w tle co widać "sypie wyjątkami" o dostepie do nieprawidlowego bloku pamięci.

Generalnie ten TSR patch ma działać docelowo tak, ż w pamięci podmieni wszystkie prawidłowe kody 555-XXXX na to co wpisaliśmy. Póki co robi tylko to, że podmienia w pamięci ostatni prawidlowy kod doxchecka (555-0724), ktory jest jednocześnie jakimś cheatem, ale pozwala na uruchomienie gry bez intra. Teraz skompilowany 5.com działa tak, że wpisuje w miejsce kodu 555-0724 pierwszy znak pobrany z miejsca gdzie jest nasz kod, a poźnej reszte wypełnia znakami ASCII o kodzie 0.

Sprawdzić co się zapisało do pamięci mozna wydając w debuggerze następujące polecenie: memdumpbin 0:0 1000000. Plik wynikowy zapisze się w podkatalogu DOSBOX pod nazwą MEMDUMP.BIN i będzie to zrzut binarki. Inaczej niestety pod DosBOX'owym debuggerem wyszukiwać się nie da. Wyszukać w zrzucie wystarczy wystąpień ciągu 555-. Kod cheatowy 555-0724 jest normalnie ostatni za wszystkimi. na razie chcę skutecznie ogarnąc tylko jego podmianę na to co wpisane. Można też wydać identycznie polecenie ale memdump... wtedy zrobi nam się plik MEMDUMP.TXT, ale jego przeszukuje się ciężej bo trzeba wpisywać opcody. Co wygodniej robi się pod HIEW'em na zrzucie binarnym.

Jestem ciekaw, o ile znajdziesz chwilę czasu @Shalom, o co bardzo Cię proszę. Zeby wymodzić prawidlowy kod dla TASM'a. Czy to specyfika gry jest taka, że nie można ogarnac tego i są czasem zwiechy przy innych rozwiązaniach pętli. Ponieważ z tego co wiem, gra czyta cały czas stan klawiszy. A dojśc gdzie jest w kodzie porównanie sprawdzania kodów, pomimo iż sciv.exe nie jest spakowany, nie udalo mi się. Bo dusiłem palec w debuggerze na F10 i nie doszedłem do wczytywania danych po podaniu kodu 555-0724. Dlatego kombinuje z takim TSR'em żeby się czegoś nauczyć, a i lubię grzebać w oldskoolowych grach:)

Zauważyłem też, że gra wolno reaguje na klawisze i nawet jak od razu chcemy nacisnąc Enter to zamula całośc kiedy tak napisany TSR jest w pamięci. Oczywiście credits dla Ciebie będzie i innych którzy mi dopomogą w ogarnięciu calości. Moze też jest inny sposob i TSR'a można zrobić inaczej, ale wolał bym na bazie tego kodu, bo to tej pory się sprawdzał :)

A i próbowałem zrobić sprawdznie jaki klawisz wciśnięto i czy jest to Enter. Według opisu przerwania 16h, który wygooglowałem i tego co patrzylem pod debuggerem w EAX siedzi kod klawisza. Ale takie sprawdzanie po ustaleniu cs nie powodowalo zapisu czegokolwiek w pamięci nowego tam gdzie był doxcheckowy kod dla cheatu. A takim kodem sprawdzal klawisze beanus w trainerze do gry Gofs, tylko ona korzystała z przerwania 09h.

in      al,60h
cmp     al,13
jne EndOfTSR
0

Jeśli to jest TSR, to na 85% jest on 16-bitowy. W kodzie jest straszna mieszanina adresowania 16- i 32-bitowego. To się co prawda skompiluje, ale jest strasznie błędogenne.
Proponuję ograniczyć się z 32-bitowością do samych danych, ale nie używać 32-bitowych rejestrów do adresowania.

czyli zamiast:

mov        ebx, dword ptr ds:[edi]

pisać:

mov        ebx, dword ptr ds:[di]

okej że kopiujesz dworda do ebx, ale nie ok że do adresowania używasz 32-bitowego edi.

0

@Azarien: niestety robiłem jak umiałem i żeby się kompilowało, po Twoich zmianach nadal tlink wymaga paremetru /3 dla skompilowania 32 bit. Wiem, że TSR będzie raczej 16 bit. Ale po zmianach tak jak doradziłeś czyli jest jak poniżej nadal są zamrożenia w grze przy reakcji na klawisze. Do tego dalej pod pierwszy bajt docelowy wpisywane jest tylko pierwszy znak, a dalej same ASCII o kodzie zero.

        mov     esi,0BA91h
        mov     ecx, 0
        mov     edi, offset alfa
petla:
        mov     ebx, dword ptr ds:[di]
        mov     al, byte ptr ds:[ebx]
        mov     byte ptr ds:[si],al
        inc     esi
        inc     edi
        inc     ecx
        cmp     ecx, 8
        jb      petla

@Shalom: no jeśli znajdziesz chwilę i się pobawisz, to pewnie ze swoją lepszą umiejętnością do kodzenia i znajomością ASM'a, także za pewne pod DOS. Wskórasz więcej. Czekam na info. Jeszcze raz dziękuję za cierpliwość :)

0

Ok, poradziłem sobie. Trochę na okolo, ale działa. Gra się nie wywala (przez to sprawdznie czy ostatni kod - cheat którego nie zmieniamy zaczyna się od 5 (35h). Ponieważ inaczej, po starcie gry wywaliła by ona komunikat o błedzie. Dlatego nadpisane są inne obrazki. Mam nadzieję, że kod się komuś przyda na przyszłośc do podobnego modzenia z grami. Wersję Polską można za to łatwiej "złamać", bo kody są jawnie w rozpakowanych plikach, co wystarczy podmienić. Zresztą jeżeli grę chcemy uruchamiać z takim TSR'ami to raczej z pod DosBOx'a, a nie SCUMMVM. Ponieważ ten drugi emulator wiadomo uruchamia gry po swojemu, a twórcy są przeciwni łamania zabezpieczeń w grach, które i tak już często legalnie zdobyć nie mozemy, a poza tym są to imo abandonware i tyle :)

TSR_IRQ equ 16h
.model tiny
.code
.386
org 100h
Start:
        jmp  RealStart
OldProc dd 0
MyMarker db 'LARRY2_ENGVER_CRACK_BY_OLESIO'
My_Marker_Length equ $ - offset MyMarker
TSRProc:
        push    bp
        mov     bp,sp
        add     bp,2
        pusha
        push    es
        push    ds
        push    word ptr ss:[bp+2]      ;CS
        pop     ax
        sub     ax,2A4Fh                ;AX-???=DS
        mov     es,ax                   ;ES=CS
        mov     ds,ax                   ;DS=DS
        mov     esi,04E44h
        cmp     byte ptr ds:[esi-28h],48h
        jne     EndOfTSR
        cmp     byte ptr ds:[esi-27h],61h
        jne     EndOfTSR
        cmp     byte ptr ds:[esi-26h],76h
        jne     EndOfTSR
        cmp     byte ptr ds:[esi-25h],65h
        jne     EndOfTSR
        mov     al, byte ptr ds:[esi+0]
        mov     chr0, al
        mov     al, byte ptr ds:[esi+1]
        mov     chr1, al
        mov     al, byte ptr ds:[esi+2]
        mov     chr2, al
        mov     al, byte ptr ds:[esi+3]
        mov     chr3, al
        mov     al, byte ptr ds:[esi+4]
        mov     chr4, al
        mov     al, byte ptr ds:[esi+5]
        mov     chr5, al
        mov     al, byte ptr ds:[esi+6]
        mov     chr6, al
        mov     al, byte ptr ds:[esi+7]
        mov     chr7, al
        mov     al,0
        mov     esi,0BA0Ah
        cmp     byte ptr ds:[esi+87h],35h
        jne     EndOfTSR
PatchLoop:
        mov     bl,chr0
        mov     byte ptr ds:[esi+0],bl
        mov     bl,chr1
        mov     byte ptr ds:[esi+1],bl
        mov     bl,chr2
        mov     byte ptr ds:[esi+2],bl
        mov     bl,chr3
        mov     byte ptr ds:[esi+3],bl
        mov     bl,chr4
        mov     byte ptr ds:[esi+4],bl
        mov     bl,chr5
        mov     byte ptr ds:[esi+5],bl
        mov     bl,chr6
        mov     byte ptr ds:[esi+6],bl
        mov     bl,chr7
        mov     byte ptr ds:[esi+7],bl
        add     esi,9
        add     al,1
        cmp     al,14
        jbe     PatchLoop
EndOfTSR:
        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  ah,35h
        mov  al,TSR_IRQ
        int  21h
        mov  si,offset MyMarker
        mov  di,si
        mov  cx,My_Marker_Length
        cld
        repe cmpsb
        jne  InstallNow
        mov  dx,word ptr es:[OldProc]
        mov  ax,word ptr es:[OldProc +2]
        mov  ds,ax
        mov  ah,25h
        mov  al,TSR_IRQ
        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  ah,35h
        mov  al,TSR_IRQ
        int  21h
        mov  word ptr cs:[OldProc],bx
        mov  word ptr cs:[OldProc+2],es
        mov  ah,25h
        mov  al,TSR_IRQ
        mov  dx,offset TSRProc
        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 '           Leisure Suit Larry Goes Looking for Love version 1.002.000'
                db 13,10
                db '           For English language version of game - TSR crack by olesio'
                db 13,10
                db '           Adapted from source code of Gods trainer by beanus & CoxoC'
                db 13,10,13,10,'$'
InstalledText   db '                     Crack has been installed in memory.',13,10,13,10,'$'
UninstalledText db '                     Crack has been removed from memory.',13,10,13,10,'$'
chr0 db 0
chr1 db 0
chr2 db 0
chr3 db 0
chr4 db 0
chr5 db 0
chr6 db 0
chr7 db 0
end Start

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