"No creas de nosotros cuentos que otros cuenten." Eskorbuto

miércoles, 2 de octubre de 2019

DOS cracking series V ~ Dandole al DOSBox debugger para arreglar un bug en un juego MS-DOS

Y con esta ya son cinco las entradas que llevamos de oldschool cracking. Decir que no soy ningun experto y hacia años (decadas ya joder :/) que no cacharreaba con DOS a bajo nivel, por lo que cualquier correccion o comentario es bienvenido, yo aprendo.

01. Cracking de un juego DOS con IDA (analisis estatico)
02. Cracking de un juego DOS con DOSBox debugger (analisis dinamico)
03. Haciendo un cargador (loader) para crackear un juego DOS en tiempo de ejecucion (I)
04. Haciendo un cargador (loader) para crackear un juego DOS en tiempo de ejecucion (II)
05. esta entrada que estas leyendo.

Bien, comencemos. California Games (1987) [1] tiene un bug en la parte donde se introduce el nombre del jugador/es. El bug hace que solo se pueda introducir un nombre con un teclado de los de 84/85 teclas, si tienes un teclado extendido de 101/102 teclas el juego no detecta nada.

¿Que implica esto? que no podemos jugar a California Games en EGA/VGA, unicamente si usamos DOSBox en CGA y Tandy (machine=cga o machine=tandy) funcionara, ya que en estas dos DOSBox emula un teclado no extendido que si soporta el juego. Comentar que no es problema de DOSBox, el bug tambien existe en un DOS real.

Ante esta situacion nos asaltan dos preguntas: ¿por que? y ¿conseguiremos de alguna manera jugar en EGA/VGA? Bien, para resolverlo vamos a darle al debugger.

Lo que podemos observar es que tenemos un problema con el teclado. Comenzaremos usando los comandos:
INTHAND [intNum]          - Set code view to interrupt handler.
INTVEC [filename] - Writes interrupt vector table to file.
Vamos a inspeccionar la interrupcion de teclado del DOS.
INTHAND 16
y el debugger nos muestra el codigo que se ejecuta cuando se llama a la INT 16. A continuacion la parte relevante:
CS:6D5F 0AE4    or   ah,ah      ; ¿nos llaman para INT 16 funcion 0?
CS:6D61 740B je 6D6E ; SI: Saltamos a nuestra rutina de teclado a gestionar funcion 0
CS:6D63 FECC dec ah ; ¿funcion 1?
CS:6D65 7438 je 6D9F ; SI: Saltamos a nuestra rutina funcion 1
CS:6D67 FECC dec ah ; ¿funcion 2?
CS:6D69 7445 je 6DB0 ; SI: Saltamos a nuestra rutina funcion 2
Bien, ese codigo no se corresponde con la INT 16 del DOS, el juego ha capturado la INT 16 y redirige las funciones 0, 1 y 2 a su propia rutina de manejo de teclado.

Si quisieramos ver que interrupciones esta capturando el programa, podriamos volcar a un archivo el vector de interrupciones con DOSBox recien iniciado y volcarlo de nuevo en el punto del programa que queramos.
INTVEC orig
INTVEC juego
y el debugger nos responde con
DEBUG: Interrupt vector table written to ORIG.
DEBUG: Interrupt vector table written to JUEGO.
y si comparamos ambos archivos (son archivos de texto) los punteros que no coincidan seran las interrupciones que el juego ha capturado. Si lo hacemos veremos que el juego captura unas cuantas, entre ellas la INT 16
valor del puntero original -> F000:E9EC
valor del puntero a la rutina para la INT 16 del juego -> CS:6D57
Bien, si continuamos la ejecucion y volvemos a activar el debugger (ALT+PAUSA) en el punto donde el juego te pide tu nombre veremos que el juego llama a la INT 21/8 para leer caracteres del teclado, y el bug esta en que el juego asume que el DOS acabara llamando a INT 16/0. Con un teclado no extendido es asi y todo va bien, pero con un teclado extendido no, si nos fijamos en el valor de AX que muestra el debugger veremos que el DOS acaba llamando a INT 16 con AH=10h , que el juego no redirige, con lo cual no ocurre nada.

Comentar que podemos caer justo en la llamada a INT 21/8 poniendo un breakpoint de interrupcion con el comando:
BPINT 21 8
Y al llegar a la parte de introducir nombres el debugger nos deja aqui:
CS:9830 B608  mov  dh,08
(...)
CS:9841 92 xchg dx,ax
CS:9842 CD21 int 21 ; llamamos a INT 21/8
Para que funcione con teclado extendido (es decir, poder jugar en dosbox con EGA/VGA), el fix que se me ocurrio fue modificar la parte de codigo donde se llama a INT 21/8 para que llame a INT 16/0.
CS:9830 30F6  xor  dh,dh  ; ESTA LINEA ES EL CRACK
(...)
CS:9841 92 xchg dx,ax ; INT 16/0
CS:9842 CD16 int 16 ; ESTA LINEA ES EL CRACK
Para aplicar el fix abrimos CALGAMES.EXE con nuestro editor hexadecimal favorito y sustituimos:
b6 08 a1 5c 5e 0a e4 75 08 c7 06 5c 5e ff ff eb 05 92 cd 21
por
30 f6 a1 5c 5e 0a e4 75 08 c7 06 5c 5e ff ff eb 05 92 cd 16
Podemos traducir rapidamente instrucciones ASM a opcodes por ejemplo con la ayuda de algun ensamblador online. A mi me gusta el de shell-storm [2], ya que es sencillo, funcional y sobre todo porque admite tambien x86 en 16 bits. Simplemente escribimos la/s instruccion/es, marcamos las opciones x86 (16) e Inline y pulsamos el boton Assemble.

Ah, si aun queda alguien ahi fuera que lo vaya a jugar en un DOS puro, desde la version 5.0 puede añadir la siguiente linea al CONFIG.SYS (no soportado por DOSBox):
SWITCHES /K
/K - Causes an enhanced keyboard to act as though it were an older standard keyboard.

Feliz reversing.

[1] California Games https://www.mediafire.com/file/v1rbjsg5499ipc1/CGAMES.7z/file
[2] https://shell-storm.org/online/Online-Assembler-and-Disassembler/

Related Posts by Categories



0 comentarios :

Publicar un comentario

Nota: solo los miembros de este blog pueden publicar comentarios.