Prośba o pomoc z przerobieniem kodu TSR'a do gry "Polanie".

0

Cześc. Pisałem w tej sprawie do @msm, ale nie ma On chyba póki co czasu mi odpisać na prywatną wiadomość. Dlatego zwracam się z prośbą o pomoc na forum. Rzadko o coś proszę. A tutaj sprawa jest niełatwa, ponieważ nie dośc, że dotyczy czasów DOS'a to jeszcze ASM'a i pisania TSR'ów. I oczywiście wiem, że łamanie zabezpieczeń gier jest niezgodne z prawem. Ale tutaj moim celem jest gra, którą już legalnie będzie ciężko kupić, a poza tym była dołaczona z TSR crackiem i słowami z instrukcji za darmo do pisma CD-Action za pewne dość dawno temu. Chodzi o nawet fajną polską strategię "Polanie".

Otoż na http://olesio.eu/dos_asm.rar umieściłem DOSBox wraz konfiguracją, uruchamiającym batchem i odpowiednimi narzędziami, jak i samą grą. Pod F2 mamy oczywiście menu. Pliki *.asm są w NC skojarzone przy naciśnięciu entera z plikiem make_com.bat w C:\TASM. Natomiast po naciśnięciu F4 na plikach *.asm wywoływany jest skonfigurowany już Asm Edit. Jednak chyba najłatwiej edytować pliki źródeł pod jakimś wygodnym Windowsowym edytorem, a tylko kompilować pod DOSBoxem w drugim oknie po naciśnięciu entera na zapisanym pliku *.asm z nowym kodem. W katalogu C:\ASM są źródła. W pliku crack11.asm TSR do wersji 1.1 Polan, którą fartownie znalezłem na chomikuj, dzięki czemu mogłem zrobić patcha do bardziej dostępnej na sieci wersji 1.3 (źródło w pliku crack13.asm).

Oba te TSR'y działają ok i się unloadują. W katalogu C:\POLANIE mamy samą grę. Plik polanie1.exe to wersja 1.1, a polanie3.exe to wersja 1.3. Dzięki lamerskiej "analizie" pod Cheat Engine ustaliłem, że aby oryginalny crack z wersji 1.1 działał i omijał docs check również w wersji 1.3, należy dokonać porównania i patchować podstawiając w pamięci pod rejestr di adres o zaledwie sześć bajtów mniejszy.

Kombinowałem samodzielnie, ale o asmie mam nikłe pojęcia, a o TSR'ach w ogóle. Kod plików crack*.asm w oryginale powstał dzięki dołączonemu Sourcerowi z dekompilacji oryginalnego cracka (jest on zawarty w pliku orgcrack.com w C:\POLANIE). Jedyne co w nim zmieniłem to zanopowałem wkurzające czekanie na dowolny klawisz (tekst musiał zostać, ale o tym napiszę za chwilę poniżej). W samym kodzie przearanżowałem jedynie układ tekstu w instrukcjach z db.

Co chce osiągnąć? Mamy poniższy kod. Dodałem stałą [?] data_7f. I teraz chciałbym, aby kod ten działał tak, że jeżeli porównanie po instrukcji mov di,data_7e się nie powiedzie, to pod di, zostanie podstawiony adres ze stałej data_7f i wtedy zostanie wykonane porównanie. W przypadku stawierdzenia pomyślnej wartości pod adresami ze stałych data_7e lub data_7f ma nastapić podstawienie pod di prawidłowej stałej (data_7e lub data_7f) i nastąpić patchowanie w pamięci poniżej. Po czym zdjęcie ze stosu i zakonczenie, tak aby nie powodowało to problemów.

Z czym mam problem? Otóż moje wszelkie kombinacje z kodem, sprawiały albo zamrażanie się DOSBoxa (pomagało tylko Ctrl+F9 lub wyjście przez zamnięcie okienka po minimalizacji przez Alt+Enter). Innym razem patch nie działal ani na wersji 1.1 ani na 1.3 gry albo powodował, że się ona wcale nie uruchomiła po załadowaniu TSR'a (albo jakiś błąd albo dźwięk w tle i czarny ekran z tekstami jak po wyłaczeniu NC). A ja chciałbym z Waszą pomocą zrobić TSR uniwersalny obsługujący jednocześnie obie wersje gry.

Dodatkowo zmniejszenie lub zwiększenie długości tekstu po instrukcjach db powoduje, że TSR się albo nie unloaduje po ponownym uruchomieniu albo też zamraża DOSBox'a. To też przydało by się poprawić. Jeżeli wiecie jak. Docelowo chciałbym tekst zmodyfikować i w kod wstawić tekst z pliku C:\ASM\tc.asc - z użyciem instrukcji db i móc go wyświetlić bez problemów, zachowując możliwośc unloadowania. Dodatkowo tak napisać kod aby instrukcja jne loc_2 nie generowała błędu kompilacji (za pewne przez skok dalszy niż $FF instrukcji niżej, z czym też miałem problem).

Przepraszam za rozpisanie się. Jakby co dołaczam sam kod oryginalnego TSR'a wzbogacony o stałą data_7f i liczę na Waszą pomoć i wskazówki. Tych, którzy piszą/pisali w asm i znają trochę TASM oraz pamiętają coś z DOS'a. Ja googlowałem za kursami ASM, ale znalazłem bardzo pobieżnie kursy z przykładami, których nie mam czasu całych studiować, chociaż to co doczytałem na nic konkretnego mnie nie naprowadziło.

Ja chętnie pomagam w problemach z Delphi / Pascalem, kiedy umiem, ale tutaj bez pomocy doświadczonych za wiele nie wskóram. A że lubie ogólny OldSkool i stare gry oraz te dawne czasy, to postanowiłem pokombinować :) Z góry dziękuję za pomoc w skutecznej modyfikacji kodu. A DOSBox'a z narzędziami oraz grą dołączyłem po to, aby ułatwić Wam kompilowanie kodu pod DOS'em i testowanie go z tą grą.

data_7e		equ	398h
data_7f		equ	392h

seg_a		segment	byte public
		assume	cs:seg_a, ds:seg_a

		org	100h

crack		proc	far

start:
		jmp	real_start
data_1		db	'POLANIE crack by JdA/RoR/BoB 1996', 0Dh, 0Ah
		db	'=================================', 0Dh, 0Ah, 0Dh, 0Ah
		db	'Crack installed in memory. '
		db	'Run program again to uninstall.', 0Dh, 0Ah, 0Dh, 0Ah
		db	0Dh, 0Ah, 'Notes:', 0Dh, 0Ah
		db	'------', 0Dh, 0Ah
		db	'This is an old-school TSR crack. '
		db	'Enjoy and read NFO for more details...', 0Dh, 0Ah
		db	'Press any key to continue...', 0Dh, 0Ah, '$'
data_2		db	'POLANIE crack succesfully uninstalled.', 0Dh, 0Ah, '$'
data_3		db	0, 0
data_4		dw	0
data_5		dw	0, 0

crack		endp

int_10h_entry	proc	far
		cmp	ax,13h
		jne	loc_2
		pop	word ptr cs:data_3
		pop	cs:data_4
		push	cs:data_4
		push	word ptr cs:data_3
		push	es
		push	di
		push	bx
		push	ax
		push	dx
		mov	ax,cs:data_4
		sub	ax,3E7h
		mov	es,ax
		mov	di,data_7e
		cmp	word ptr es:[di],568Ah
		jne	loc_1
		mov	byte ptr es:[di],8Ah
		mov	byte ptr es:[di+1],0D0h
		mov	byte ptr es:[di+2],80h
		mov	byte ptr es:[di+3],0EAh
		mov	byte ptr es:[di+4],64h
		mov	byte ptr es:[di+5],88h
		mov	byte ptr es:[di+6],56h
		mov	byte ptr es:[di+7],0FEh
		mov	byte ptr es:[di+8],0B6h
		mov	byte ptr es:[di+9],0
		mov	byte ptr es:[di+0Ah],0EBh
		mov	byte ptr es:[di+0Bh],27h
loc_1:
		pop	dx
		pop	ax
		pop	bx
		pop	di
		pop	es
loc_2:
		jmp	dword ptr cs:data_5

real_start:
		push	cs
		pop	ds
		mov	ax,3510h
		int	21h
		mov	ax,234h
		cmp	ax,bx
		je	loc_3
		mov	word ptr data_5,bx
		mov	word ptr data_5+2,es
		mov	dx,offset int_10h_entry
		mov	ax,2510h
		int	21h
		mov	ax,3
		int	10h
		mov	dx,offset data_1
		mov	ah,9
		int	21h
		mov	dx,2AAh
		int	27h
loc_3:
		mov	dx,es:[bx-4]
		mov	ds,es:[bx-2]
		mov	ax,2510h
		int	21h
		mov	ah,49h
		int	21h
		push	cs
		pop	ds
		mov	ax,3
		int	10h
		mov	dx,offset data_2
		mov	ah,9
		int	21h
		mov	ax,4C00h
		int	21h
int_10h_entry	endp

seg_a		ends

		end	start

No chyba, że ktoś wie na przykłąd jak coś działającego identycznie jak opisałem napisać w Turbo Pascalu i ma jakieś kody z dawnych czasów oraz wskazówki to chętnie spojrzę. Bo na necie są różne TSR'y w TP, ale nie można ich kompletnie unloadować (to może nie aż taki problem), ale nie wiem jak szukać, porównać i spatchować pod TP pamięć o takim samym adresie jak robi to ten TSR. Wiadomo pod Windowsem nie ma z tym problemu :)

1
start:
                jmp        real_start

W tym miejscu możesz zrobić sprawdzanie wersji gry dowolnym sposobem, i skakać w zależności od wersji do real_start_11 albo real_start_11.

int_10h_entry        proc        far

Wtedy takie procedury byłyby dwie, zupełnie niezależne. A jako TSR zostawałaby tylko jedna z nich.

0

@Azarien: dziękuję bardzo za odpowiedź. Ale czy mógłbym Ciebie prosić jednak o konkretne przerobienie kodu, z mojego pierwszego posta według Twoich zaleceń i wklejenie go tutaj? Zawsze możesz go przetestować pod DOSBoxem z plikami jakie zamieściłem. Ponieważ zrobiłem tak, jak poniżej żeby się tylko kompilowało, ale TSR nie pokazuje żadnych tekstów i w ogóle nie działa na żadnej z wersji gry. Wiem, że to co zrobiłem poniżej jest inaczej niż pisałeś, ale opisanego przez Ciebie sposobu nie umiem zastosować. Mam komunikaty o zbyt dalekich jumpach przy próbie przeniesienia części kodu porównania z procedury obsługi przerwania 10h. A nie wiem czy można jakoś zrobić jumpy jakiekolwiek (w tym warunkowe) ale nie takie short jak pod Windows, ale więćej niż chyba 256 instrukcji niżej lub wyżej.

Poza tym, w jaki sposób mogę zrobić sprawdzenie wersji gry w pamięci przez porównanie na początku uruchomienia loadera, skoro to porównanie jest w procedurze obsługi przerwania 10h i chyba tylko tam zadziała prawidłowo tą metodą, zastosowaną w oryginalnym kodzie. Nie wiem jak to wszystko zdublować żeby działało prawidłowo i wyświetlało tekst powitalny. Doceniam Twoją odpowiedź, ale niestety się zamotałem i nie umiem tego wdrożyć, tak aby loader działał. A przy okazji, masz jeszcze pojęcia co zrobić aby tekst powitalny loadera ze wszystkimi znakami (w tym entery CRLF), poza znakiem dolara kończącym tekst nie musiały być długości dokładnie 255 znaków? Tylko więcej lub mniej niż ta ilość. Ponieważ teraz dokładnie ma taką długość i przy wszelkich zmianach dzieją się wspomniane w pierwszym postcie wątku "cyrki" z niemożliwością unloadowania albo zamrożeniami DOSBoxa.

data_7e		equ	398h
data_7f		equ	392h

seg_a		segment	byte public
		assume	cs:seg_a, ds:seg_a

		org	100h

crack		proc	far

start:

		jmp	real_start11
data_1		db	'POLANIE crack by JdA/RoR/BoB 1996', 0Dh, 0Ah
		db	'=================================', 0Dh, 0Ah, 0Dh, 0Ah
		db	'Crack installed in memory. '
		db	'Run program again to uninstall.', 0Dh, 0Ah, 0Dh, 0Ah
		db	0Dh, 0Ah, 'Notes:', 0Dh, 0Ah
		db	'------', 0Dh, 0Ah
		db	'This is an old-school TSR crack. '
		db	'Enjoy and read NFO for more details...', 0Dh, 0Ah
		db	'Press any key to continue...', 0Dh, 0Ah, '$'
data_2		db	'POLANIE crack succesfully uninstalled.', 0Dh, 0Ah, '$'
data_3		db	0, 0
data_4		dw	0
data_5		dw	0, 0

crack		endp

int_10h_entry	proc	far
		cmp	ax,13h
		jne	loc_2
		pop	word ptr cs:data_3
		pop	cs:data_4
		push	cs:data_4
		push	word ptr cs:data_3
		push	es
		push	di
		push	bx
		push	ax
		push	dx
		mov	ax,cs:data_4
		sub	ax,3E7h
		mov	es,ax
		mov	di,data_7e
		cmp	word ptr es:[di],568Ah
		jne	loc_1
		mov	byte ptr es:[di],8Ah
		mov	byte ptr es:[di+1],0D0h
		mov	byte ptr es:[di+2],80h
		mov	byte ptr es:[di+3],0EAh
		mov	byte ptr es:[di+4],64h
		mov	byte ptr es:[di+5],88h
		mov	byte ptr es:[di+6],56h
		mov	byte ptr es:[di+7],0FEh
		mov	byte ptr es:[di+8],0B6h
		mov	byte ptr es:[di+9],0
		mov	byte ptr es:[di+0Ah],0EBh
		mov	byte ptr es:[di+0Bh],27h
loc_1:
		pop	dx
		pop	ax
		pop	bx
		pop	di
		pop	es
loc_2:

;aaa
;		jmp	dword ptr cs:data_5
		jmp	real_start13

real_start11:
		push	cs
		pop	ds
		mov	ax,3510h
		int	21h
		mov	ax,234h
		cmp	ax,bx
		je	loc_3
		mov	word ptr data_5,bx
		mov	word ptr data_5+2,es
		mov	dx,offset int_10h_entry
		mov	ax,2510h
		int	21h
		mov	ax,3
		int	10h
		mov	dx,offset data_1
		mov	ah,9
		int	21h
		mov	dx,2AAh
		int	27h
loc_3:
		mov	dx,es:[bx-4]
		mov	ds,es:[bx-2]
		mov	ax,2510h
		int	21h
		mov	ah,49h
		int	21h
		push	cs
		pop	ds
		mov	ax,3
		int	10h
		mov	dx,offset data_2
		mov	ah,9
		int	21h
		mov	ax,4C00h
		int	21h
int_10h_entry	endp

int_10h_entry13	proc	far
		cmp	ax,13h
		jne	loc_2a
		pop	word ptr cs:data_3
		pop	cs:data_4
		push	cs:data_4
		push	word ptr cs:data_3
		push	es
		push	di
		push	bx
		push	ax
		push	dx
		mov	ax,cs:data_4
		sub	ax,3E7h
		mov	es,ax
		mov	di,data_7f
		cmp	word ptr es:[di],568Ah
		jne	loc_1a
		mov	byte ptr es:[di],8Ah
		mov	byte ptr es:[di+1],0D0h
		mov	byte ptr es:[di+2],80h
		mov	byte ptr es:[di+3],0EAh
		mov	byte ptr es:[di+4],64h
		mov	byte ptr es:[di+5],88h
		mov	byte ptr es:[di+6],56h
		mov	byte ptr es:[di+7],0FEh
		mov	byte ptr es:[di+8],0B6h
		mov	byte ptr es:[di+9],0
		mov	byte ptr es:[di+0Ah],0EBh
		mov	byte ptr es:[di+0Bh],27h
loc_1a:
		pop	dx
		pop	ax
		pop	bx
		pop	di
		pop	es
loc_2a:
		jmp	dword ptr cs:data_5

real_start13:
		push	cs
		pop	ds
		mov	ax,3510h
		int	21h
		mov	ax,234h
		cmp	ax,bx
		je	loc_3a
		mov	word ptr data_5,bx
		mov	word ptr data_5+2,es
		mov	dx,offset int_10h_entry13
		mov	ax,2510h
		int	21h
		mov	ax,3
		int	10h
		mov	dx,offset data_1
		mov	ah,9
		int	21h
		mov	dx,2AAh
		int	27h
loc_3a:
		mov	dx,es:[bx-4]
		mov	ds,es:[bx-2]
		mov	ax,2510h
		int	21h
		mov	ah,49h
		int	21h
		push	cs
		pop	ds
		mov	ax,3
		int	10h
		mov	dx,offset data_2
		mov	ah,9
		int	21h
		mov	ax,4C00h
		int	21h
int_10h_entry13	endp

seg_a		ends

		end	start
1

Na kod spojrzę, jeśli czas pozwoli, ale tak na szybko mogę podpowiedzieć nt. zbyt długich jumpów.
Ograniczenie jest do ±128 bajtów w obie strony (tak żeby offset się mieścił w jednym bajcie), ale dotyczy tylko skoków warunkowych. żeby to ominąć, można zrobić coś tego typu:

zamiast

      jne zadaleko
      bla bla bla
      ...
zadaleko:

zrobić

      jne niedaleko
      jmp here
niedaleko:
      jmp zadaleko
here:
      bla bla bla
      ...
zadaleko:

dzięki czemu kod działa tak samo, a nie ma dalekich skoków warunkowych.

0

Ponownie dziękuję za odpowiedź. Jednak dla mnie takie "rozbijnie" tych skoków taką metodą może być tutaj klopotliwe aby w tym kodzie czegoś jeszcze bardziej nie skopać. Fajnie jak znajdziesz czas aby móc dopasować kod tak aby działał i był uniwersalny, bo ja sam nie bardzo dam raczej radę. Nie jest mi oczywiście bardzo śpieszno. A i mógłbym też "puscić" w świat te dwa TSR'y bez czekania na dowolny klawisz do wersji 1.1 oraz 1.3 tej gry. Jednak wolę mieć dopracowane rozwiązanie i wtedy podzielić się z szerszym gronem, podsyłając poprawioną grę na przykład do ludzi (człowieka [?]) od serwisu Stara Polska Szkoła, ktory coś teraz leży, ale mam nadzieję, że nie padł ostatecznie. Chyba był i jest on dość znanym i dobrym źródłem dla starych polskich gier zebranych w jednym miejscu.

2

Disclaimer: jestem zbyt młody, żebym kiedykolwiek wcześniej miał do czynienia z TSR, więc to, co piszę może być głupotą.

Dodatkowo zmniejszenie lub zwiększenie długości tekstu po instrukcjach db powoduje, że TSR się albo nie unloaduje po ponownym uruchomieniu albo też zamraża DOSBox'a. To też przydało by się poprawić. Jeżeli wiecie jak.

mov	dx, 2AAh
int	27h

Przy TSR trzeba oznaczyć ile pamięci ma zostać zachowane. Oznacza się go przez dx przy wywołaniu int 27h: offset ostatniego bajtu + 1 (licząc od segmentu w cs). Przy pierwotnej kompilacji zapewne została tam wstawiona stała (2aah) i to może być powodem tego, że dzieją się cuda przy zmianie długości twojego źródła. Wstaw tam zwykłe odejmowanie etykiet, żeby wyliczało się to przy kompilacji.

0

Niezbyt rozumiem czemu dzielisz to na dwie niezależne obsługi. Przecież różnice są tak małe że da się to obsłużyć paroma dodatkowymi instrukcjami. Jeżeli tak zrobisz to nie musisz na początku decydować 11 czy 13.

0

Ponownie dziękuję za nowe odpowiedzi. Przede wszystkim @Rev: Twoja porada okazała się dla mnie bardzo pomocna, teraz kod TSR'a jest taki, jak poniżej i działa tak jak chciałem. Jednak w swojej lamerskości nie bardzo umiem odjąć etykiet, tak aby kod był uniwersalny i żebym nie musiał sprawdzać ile zajmuje mój TSR względem oryginalnego i dodawać tę wartość do dx przed instrukcją int 27h. Możesz mi jednak podać przykład jak zastosować Twoją poradę "Wstaw tam zwykłe odejmowanie etykiet, żeby wyliczało się to przy kompilacji."? Ponieważ oczywiście mogę tam wstawić jakąś większą liczbę z kosmosu i TSR będzie działał, ale chciałbym aby się mógl też prawidłowo unloadować jeżeli ktoś kiedy zechciał by go użyć na wiekowej maczynie albo pod pradziwym DOS'em.

@_13th_Dragon: niestety zrobiłem, jak zrobiłem poprzednio. Wynika to z małej wiedzy o ASM'ie i pisaniu pod TASM, a także zawiłościach DOS'a. Teraz już poprawiłem kod, tak jak to widać poniżej, ale proszę tylko jeszcze Was o krótki przykładowy fragment kodu jaki pownienem zastosować poradę Użytkownika @Rev o odejmowaniu etykiet.

data_7e		equ	398h
data_7f		equ	392h

seg_a		segment	byte public
		assume	cs:seg_a, ds:seg_a


		org	100h

crack		proc	far

start:
		jmp	real_start
data_1		db	'POLANIE crack by JdA/RoR/BoB 1996', 0Dh, 0Ah
		db	'=================================', 0Dh, 0Ah, 0Dh, 0Ah
		db	'Crack installed in memory. '
		db	'Run program again to uninstall.', 0Dh, 0Ah, 0Dh, 0Ah
		db	0Dh, 0Ah, 'Notes:', 0Dh, 0Ah
		db	'------', 0Dh, 0Ah
		db	'This is an old-school TSR crack. '
		db	'Enjoy and read NFO for more details...', 0Dh, 0Ah
		db	'Press any key to continue...', 0Dh, 0Ah, '$'
data_2		db	'POLANIE crack succesfully uninstalled.', 0Dh, 0Ah, '$'
data_3		db	0, 0
data_4		dw	0
data_5		dw	0, 0

crack		endp

;ŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰ
;
;                       External Entry Point
;
;ŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰ

int_10h_entry	proc	far
		cmp	ax,13h
		jne	loc_2
		pop	word ptr cs:data_3
		pop	cs:data_4
		push	cs:data_4
		push	word ptr cs:data_3
		push	es
		push	di
		push	bx
		push	ax
		push	dx
		mov	ax,cs:data_4
		sub	ax,3E7h
		mov	es,ax
		mov	di,data_7e
		cmp	word ptr es:[di],568Ah
		je	patch
		mov	di,data_7f
		cmp	word ptr es:[di],568Ah
		je	patch
		jmp	loc_1
patch:
		mov	byte ptr es:[di],8Ah
		mov	byte ptr es:[di+1],0D0h
		mov	byte ptr es:[di+2],80h
		mov	byte ptr es:[di+3],0EAh
		mov	byte ptr es:[di+4],64h	; 'd'
		mov	byte ptr es:[di+5],88h
		mov	byte ptr es:[di+6],56h	; 'V'
		mov	byte ptr es:[di+7],0FEh
		mov	byte ptr es:[di+8],0B6h
		mov	byte ptr es:[di+9],0
		mov	byte ptr es:[di+0Ah],0EBh
		mov	byte ptr es:[di+0Bh],27h	; '''
loc_1:
		pop	dx
		pop	ax
		pop	bx
		pop	di
		pop	es
loc_2:
		jmp	dword ptr cs:data_5

;ŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰ
;
;                       External Entry Point
;
;ŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰ

real_start:
		push	cs
		pop	ds
		mov	ax,3510h
		int	21h
		mov	ax,234h
		cmp	ax,bx
		je	loc_3
		mov	word ptr data_5,bx
		mov	word ptr data_5+2,es
		mov	dx,offset int_10h_entry
		mov	ax,2510h
		int	21h
		mov	ax,3
		int	10h
		mov	dx,offset data_1
		mov	ah,9
		int	21h
		mov	dx,2B7h
		int	27h
loc_3:
		mov	dx,es:[bx-4]
		mov	ds,es:[bx-2]
		mov	ax,2510h
		int	21h
		mov	ah,49h
		int	21h
		push	cs
		pop	ds
		mov	ax,3
		int	10h
		mov	dx,offset data_2
		mov	ah,9
		int	21h
		mov	ax,4C00h
		int	21h
int_10h_entry	endp


seg_a		ends



		end	start
0

Sorry, że post pod postem, ale tak mi wyjątkowo wygodniej ;P Zostawiam poprzedni kod w postcie i jednocześnie jakby wyróżniam moje nowe "dokonania" w tym temacie ;) Otóż problem z ładowaniem oczywiście rozwiązałem tak:

		mov	dx, offset real_start
		int	27h

I działa ok jeżeli chodzi o ładowanie. Jednak chciałbym zrobić TSR, że tak to ujmę "DOS'owo idealny". Czyli chodzi mi również o to, aby móc go unloadować bez problemów. Czyli podejrzewam, że kwestia w poniższym fragmencie kodu: Czy da się jakoś te liczbę po ax wyliczyć dynamicznie? Czy muszę jednak raczej mozolnie dodając każdy znak tekstu do wyświetlenia - zwiększać odpowiednio to, co trafi do rejestru ax przed porównanie? Proszę o przykład kodu, jeżeli się da inaczej.

		mov	ax,234h
		cmp	ax,bx
		je	loc_3
0
olesio napisał(a):

krótki przykładowy fragment kodu jaki pownienem zastosować poradę Użytkownika @Rev o odejmowaniu etykiet.

Ładowanie adresu etykiety już użyłeś, np tu:
mov dx,offset int_10h_entry
Słabo mi się wierzy że nie znasz instrukcji:
sub
Więc jakoś niezbyt rozumiem jakiego przykładu potrzebujesz.

0

@_13th_Dragon: czytałem o add oraz sub, ale nie wiem jak tutaj i co od czego subnąc, aby było dobrze wedlug podpowiedzi @Rev. Jednak zastosowanie dx, offset real_start sprawia, że TSR działa ok i unloaduje się jak należy. Zresztą przykłady TSRów do cheatowania w grach autorstwa beanusa - kod pochodzi a arta w issue 0 słynnego crackzina "TAC". Pewnie to, że TSR do Polan po poprawkach i tak działa ok - nie znaczy, że na pewno do końca jest napisany jak powinien. Pozostaje nadal problem z prawidlowym unloadowaniem. Zauważyłem, że stała jaką ustawiam tsr_memorysize equ 394h powoduje, że porównanie w kodzie:

		mov	ax,tsr_memorysize
		cmp	ax,bx
		je	loc_3

Z nowym tekstem jaki ustawiłem do wyświetlanie przy załadowaniu i wyładowaniu powoduje, że w końcu TSR ładuje się i unloaduje jak należy. Jednak chciałym aby to co trafia do rejestru ax było obliczane głownie na podstawie całkowitej długości tesktu w zmiennych (stałych [?]) data_1 oraz data_2. Teraz obliczyłem tak, że skoro z tsr_memorysize equ 394h To jeśli długośc wszystkich wyświetlanych tekstów łącznie z kończącymi $ wynosi 847 bajtów to 394h czyli 916 - 847 = 69 czyli 45h. Także zacząłem kombinować tak, jak według porad w google liczy się długośc stringów, ale pod samym HIEW widzę już wierutne bzdury czyli wartości wielokrotnie większe niż wynosi długośc tych stringów. Jak więc zadeklarować prawidłową długośc i później ją dobrze podstawić oraz zsumować?

		mov ax, $ - data_1
		add ax, $ - data_2
		add ax, 45h
		cmp	ax,bx
		je	loc_3

A to dla przykładu kompletny source trainera TSR autorstwa beanusa i CoxoC'a, z którego wywnioskowałem, że powinienem przy int 27h zrobić tak, a nie inaczej. Wiem, mało umiem asma, ale pod DOS'a to już prawie nic ;/

.model tiny
.code
.386
org 100h
Start:
        jmp  StartTutaj
staraproc dd 0
znacznik db 'gODS trAiNER bY bEANUS & CoxoC'

NaszaProc:
        push    bp
        mov     bp,sp
        add     bp,2
        pusha
        push    es
        push    ds
        push    word ptr ss:[bp+2]      ;CS
        pop     ax
        sub     ax,2DB3h
        mov     es,ax                   ;ES=CS
        add     ax,0FFDh                ;DS=CS-1DB6h
        mov     ds,ax                   ;DS=DS procesu
        in      al,60h
        cmp     al,59                   ;F1 - zycia
        je      zycia
        cmp     al,60                   ;F2 - energia
        je      energia
        cmp     al,61                   ;F3 - zabij_sie
        je      zabij
        cmp     al,62                   ;F4 - kasa
        je      kasa
        cmp     al,63                   ;F5 - stuff
        je      help
        cmp     al,64                   ;F6 - stuff
        je      help1
        jmp     koniec_train
;-------

zycia:
        mov     di,093Fh
        mov     al,90h
        mov     cx,6
        rep     stosb
        jmp     koniec_train
;-------
energia:
        mov     di,4542h        ;STRZAL
        mov     al,90h
        mov     cx,5
        rep     stosb
        mov     di,0ACD3h       ;WEJSCIE NA POTWORA
        mov     cx,4
        rep     stosb
        mov     di,1BDDh        ;KOLCZUGA
        mov     cx,5
        rep     stosb
        mov     di,4C3Eh        ;SPADEK
        mov     cx,4
        rep     stosb
        mov     di,4D43h        ;SPADEK
        mov     cx,4
        rep     stosb
        mov     di,0dba0h
        mov     cx,5
        rep     stosb
JMP koniec_train
;-------

zabij:
        mov     si,192h
        mov     ax,0
        mov     ds:[si],ax
        JMP     koniec_train
;-------
kasa:
        mov     eax,01000000h
        mov     esi,3B5h
        mov     DS:[esi],EAX
        mov     si,194h
        mov     ax,65000
        mov     ds:[si],ax
        jmp     koniec_train
;ds:180h - zawartosc drugiej kieszeni
help:
        mov si,180h
        inc word ptr ds:[si]
        JMP koniec_train
help1:
        mov si,180h
        dec word ptr ds:[si]
        jmp koniec_train
koniec_train:
        pop  ds
        pop  es
        popa
        pop  bp
        jmp  dword ptr cs:[staraproc]
;--------- koniec

StartTutaj:
        mov  ah,9
        mov  dx,offset Logo
        int  21h
        mov  si,81h
        cld
Petla:
        lodsb
        cmp  al,'u'
        je   Rozinstaluj
        cmp  al,'U'
        je   Rozinstaluj
        cmp  al,0dh
        je   Instaluj
        jmp  Petla
Rozinstaluj:
        mov  ax,3509h
        int  21h
        cmp  bx,offset NaszaProc
        jne  NieMa
        mov  si,offset znacznik
        mov  di,si
        mov  cx,17
        cld
        repe cmpsb
        jnz  NieMa
        mov  dx,word ptr es:[staraproc]
        mov  ax,word ptr es:[staraproc +2]
        mov  ds,ax
        mov  ax,2509h
        int  21h
        mov  ah,49h
        int  21h
        mov  ax,cs
        mov  ds,ax
        mov  ah,9
        mov  dx,offset Uninst
        int  21h
        mov  ax,4c02h
        int  21h
NieMa:
        mov  ah,9
        mov  dx,offset Brak
        int  21h
        mov  ax,4c04h
        int  21h
Instaluj:
        mov  ax,word ptr ds:[2ch]
        mov  es,ax
        mov  ah,49h
        int  21h
        mov  ax,3509h
        int  21h
        mov  word ptr cs:[staraproc],bx
        mov  word ptr cs:[staraproc +2],es
        mov  ax,2509h
        mov  dx,offset NaszaProc
        int  21h
        mov  ah,9
        mov  dx,offset Napis
        int  21h
        mov  dx,offset StartTutaj
        int  27h

Logo   db 'gODS trAiNER bY bEANUS & CoxoC.',13,10
       db '     parametr /u - usuniecie programu z pamieci',13,10,'$'
Napis  db 'Program zainstalowany w pamieci.',13,10,'$'
Brak   db 'Program nie byl wczesniej instalowany w pamieci.',13,10,'$'
Uninst db 'Program usuniÓty z pamieci.',13,10,'$'
end Start
1

Tekstów chyba żadnych nie potrzebujesz w pamięci po zainstalowaniu, więc przenieś to co nie musi być w pamięci na sam koniec.
Na górze zostaw tylko niezbędne dane.
Przy takim podejściu nawet odejmować nic nie musisz,
rozmiarem będzie adres real_start.

Mogę coś chrzanić bo wciąż mam gorączkę prawie 38.

0

Bardzo Ci dziękuję @_13th_Dragon - Twoja podpowiedź rozwiązania bardzo pomogła, jak rownież wcześniejsza podpowiedź od Użytkownika @Rev. Ostateczny kod TSR'a po wszystkich poprawkach wklejam poniżej. Może da się coś jeszcze poprawić i wiem, że to zastosowanie instrukcji mov dx, offset real_start może i mało eleganckie, ale jest dzięki temu wszystko ok. Natomiast wartosć tsr_basememsize podejrzałem sobie pod starym, Borlandowskim "Turbo Debuggerem" w wersji 5.0, jaki został mi kiedyś na dysku. Ponieważ debuggera dołączonego dla DOSBoxa w osobnej wersji, praktycznie nie ogarniam.

Natomiast jestem ciekaw jak w czasach świetności DOS'a i tej gry w 1996 roku debuggowali ją crackerzy. Ponieważ próby uruchomienia tej gry pod DOSBoxem z prawidzym DOS'em na obrazie dysku i załadowanum Soft-Ice dla DOS'a nie udawały się. Ciągle brakowało pamięci EMS, a jak wiadomo Dosowy S-Ice nie uruchomi się z emm386. Także nawet nie kombinowałem z szukaniem takiego wynalazku co zwał się bodajże QEMM, który sporo pomagał mi w czasach jak miałem jeszcze 386, ale pewnie S-Ice by się z nim również nie uruchomił. Pewnie zdolne crackersy używały jakichś innych debuggerów.

Anyway, dziękuję raz jeszcze wszystkim odpowiadającym za pomoc. Teraz w wolnym czasie pora przejśc pare etapów, bo skupiałem się ostatnio na czymś innym. Na jakiejś usenetowej grupie ktoś w 1997 pisał, że crack który ma nie omija docs checka po bodajże piątej misji, ale mi się wydaje że ja grałem w Polan dawno temu na starym komuterze i wersji 1.1. I na 100% miałem ten sam TSR crack, a grę dało się przejść do końca. Jeżeli mnie pamięć nie myli, a wiadomo to było bardzo dawno temu.

Kompilacja, aby uniknąc zbędnej isntrukcji nop przy pomocy poniższych poleceń w takim batchu który jako parametr przyjąc musi samą nazwę pliku (na przykład pol_crk - koniecznie bez .asm). Ale najwygodniej pobrać zaktualizowane archiwum z całym źródłem, grą i niezbędnymi narzędziami z http://olesio.eu/dos_asm.rar - tam pliki *.asm kompiluje się z pod entera w NC. Są też oczywiście skonfigurowane narzędzia jak Asm Edit dostępny w NC pod F4 przy wybieraniu pliku *.asm.

@echo off
tasm %1.asm,%1 /w1/m/t
tlink %1,%1.com,%1.map /t

EDIT: poniżej ostateczna wersja kodu TSR'a, przy skoku do unloadowania jednak wystarczy porównanie: cmp bx,offset int_10h_entry i teraz wszystko działa ok.

data_ver11	equ	398h
data_ver13	equ	392h

seg_a		segment	byte public
		assume	cs:seg_a, ds:seg_a

		org	100h

crack		proc	far

start:
		jmp	main_code

data_3		db	0, 0
data_4		dw	0
data_5		dw	0, 0

crack		endp

int_10h_entry	proc	far
		cmp	ax,13h
		jne	loc_2
		pop	word ptr cs:data_3
		pop	cs:data_4
		push	cs:data_4
		push	word ptr cs:data_3
		push	es
		push	di
		push	bx
		push	ax
		push	dx
		mov	ax,cs:data_4
		sub	ax,3E7h
		mov	es,ax
		mov	di,data_ver11
		cmp	word ptr es:[di],568Ah
		je	patch_code
		mov	di,data_ver13
		cmp	word ptr es:[di],568Ah
		je	patch_code
		jmp	loc_1
patch_code:
		mov	byte ptr es:[di],8Ah
		mov	byte ptr es:[di+1],0D0h
		mov	byte ptr es:[di+2],80h
		mov	byte ptr es:[di+3],0EAh
		mov	byte ptr es:[di+4],64h
		mov	byte ptr es:[di+5],88h
		mov	byte ptr es:[di+6],56h
		mov	byte ptr es:[di+7],0FEh
		mov	byte ptr es:[di+8],0B6h
		mov	byte ptr es:[di+9],0h
		mov	byte ptr es:[di+0Ah],0EBh
		mov	byte ptr es:[di+0Bh],27h
loc_1:
		pop	dx
		pop	ax
		pop	bx
		pop	di
		pop	es
loc_2:
		jmp	dword ptr cs:data_5

main_code:
		push	cs
		pop	ds
		mov	ax,3510h
		int	21h
		cmp	bx,offset int_10h_entry
		je	unload_code
		mov	word ptr data_5,bx
		mov	word ptr data_5+2,es
		mov	dx,offset int_10h_entry
		mov	ax,2510h
		int	21h
		mov	ax,3
		int	10h
		mov	dx,offset logo_text
		mov	ah,9
		int	21h
		mov	dx,offset load_text
		mov	ah,9
		int	21h
		mov	dx, offset main_code
		int	27h
unload_code:
		mov	dx,es:[bx-4]
		mov	ds,es:[bx-2]
		mov	ax,2510h
		int	21h
		mov	ah,49h
		int	21h
		push	cs
		pop	ds
		mov	ax,3
		int	10h
		mov	dx,offset logo_text
		mov	ah,9
		int	21h
		mov	dx,offset unload_text
		mov	ah,9
		int	21h
		mov	ax,4C00h
		int	21h
int_10h_entry	endp

even_size	db	0Dh, 0Ah, '$'
logo_text	db	0Dh, 0Ah, 0Dh, 0Ah
		db 	'          ________  _________  ____ _________ __________  ____ ________'
		db	0Dh, 0Ah
		db 	'       E _\    __/_/      \  \/   /_    _   /_\__   /_  \/   /_   /   /_'
		db	0Dh, 0Ah
		db 	'      H  \    /   /   /   /       _/   ____/   _    _/   \   _/__     _/'
		db	0Dh, 0Ah
		db 	'     T   /________\______/___\/___\___/   /_________\___\____\/_______\spot'
		db	0Dh, 0Ah, 0Dh, 0Ah, '$'
load_text	db	0Dh, 0Ah
		db 	'     Original TSR crack for game POLANIE in version 1.1 by JdA/RoR/BoB 1996'
		db	0Dh, 0Ah, 0Dh, 0Ah
		db 	'            Adapted to work with game versions 1.1 and 1.3 by olesio'
		db	0Dh, 0Ah, 0Dh, 0Ah
		db 	'         Big thanks to _13th_Dragon and Rev from 4programmers.net/Forum'
		db	0Dh, 0Ah
		db 	'         for helping me to improve TSR code - now it works perfectly :)'
		db	0Dh, 0Ah, 0Dh, 0Ah
		db 	'               Crack installed in memory. Run again to uninstall.'
		db	0Dh, 0Ah, '$'
unload_text	db	0Dh, 0Ah
		db	'                     POLANIE crack succesfully uninstalled.', 0Dh, 0Ah, '$'

seg_a		ends

		end	start

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