COMO ROMPER LLAVES DE HARDWARE
Las empresas y los productos mencionados en el presente texto NO EXISTEN.
Todo lo publicado en esta nota es absolutamente FALSO.
Lo que Ud. está a punto de leer es resultado de la decadente y absurda
imaginación del autor que, al no tener otra cosa que hacer, se puso a
escribir esto.
CUALQUIER PARECIDO CON LA REALIDAD ES PURA COINCIDENCIA.
Nos centraremos en solo dos de estos bits: el Interrupt Enable y el Trap.15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ | | | | | O | D | I | T | S | Z | | A | | P | | C | +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
bit 0: C: Carry bit 2: P: Parity bit 4: A: Auxiliar Carry bit 6: Z: Zero bit 7: S: Sign bit 8: T: Trap bit 9: I: Interrupt Enable bit 10: D: Direction bit 11: O: Overflow
paso 1: pushf paso 2: push ax pushf pop ax and ax, ( 65535 - ( bit I | bit T ) ) push ax popf pop ax pasos 3 y 4: call far [ 0000 : 4*X ]
--------------------BEGIN TRAP.ASM------------------------------------- ; ;TRAP.ASM - (c) 1998 - Maruja ; ;Ejemplo de funcionamiento de la interrupcion TRAP ; .model tiny .code org 100h inicio: jmp Arranque ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; settrap_msg db 'TRAP ON', 13, 10, '$' untrap_msg db 'TRAP OFF', 13, 10, '$' trap_msg db 'TRAP!', 13, 10, '$' vieja90 dd ? vieja91 dd ? vieja01 dd ? ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; SetTrap: push ax push bp mov bp, sp mov ax, [bp+8] ;Obtener flags de la pila or ah, 1 ;Activar bit T mov [bp+8], ax ;Colocar nuevos flags en la pila push dx ;Imprimir mensaje 'TRAP ON' push ds push cs pop ds lea dx, settrap_msg mov ah, 9 int 21h pop ds pop dx pop bp pop ax iret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; UnTrap: push ax push bp mov bp, sp mov ax, [bp+8] ;Obtener flags de la pila and ah, 0FEh ;Desactivar bit T mov [bp+8], ax ;Colocar nuevos flags en la pila push dx ;Imprimir mensaje 'TRAP OFF' push ds push cs pop ds lea dx, untrap_msg mov ah, 9 int 21h pop ds pop dx pop bp pop ax iret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Trap: push dx ;Imprimir mensaje 'TRAP!' push ds push ax push cs pop ds lea dx, trap_msg mov ah, 9 int 21h pop ax pop ds pop dx iret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; SetearVectores: mov ax, 3501h ;Obtener vector de interrupcion TRAP int 21h ;(tipo 1) y guardarlo mov word ptr vieja01, bx mov bx, es mov word ptr vieja01+2, bx mov ax, 3590h ;Obtener vector de interrupcion 90h int 21h ;y guardarlo mov word ptr vieja90, bx mov bx, es mov word ptr vieja90+2, bx mov ax, 3591h ;Obtener vector de interrupcion 91h int 21h ;y guardarlo mov word ptr vieja91, bx mov bx, es mov word ptr vieja91+2, bx mov ax, 2590h ;Hacer que una INT 90h ejecute el lea dx, SetTrap ;codigo 'SetTrap' int 21h mov ax, 2591h ;Hacer que una INT 91h ejecute el lea dx, UnTrap ;codigo 'UnTrap' int 21h mov ax, 2501h ;Hacer que la interrupcion TRAP lea dx, Trap ;provoque la ejecucion del codigo int 21h ;'Trap' ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; RestaurarVectores: mov ax, 2501h ;Restaurar vector anterior lds dx, dword ptr vieja01 ;interrupcion TRAP int 21h mov ax, 2590h ;Restaurar vector anterior lds dx, dword ptr cs:vieja90 ;interrupcion 90h int 21h mov ax, 2591h ;Restaurar vector anterior lds dx, dword ptr cs:vieja91 ;interrupcion 91h ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Arranque: call SetearVectores int 90h ;Activar Trap mov ax, 1 mov dx, 2 nop int 91h ;Desactivar Trap Call RestaurarVectores mov ax, 4C00h ;Terminar programa int 21h end inicio --------------------END TRAP.ASM---------------------------------------Este programa se compila (usando el Turbette Assembler) y se ejecuta de la siguiente manera:
C:\>TASM TRAP.ASM ... C:\>TLINK /t TRAP ... C:\>TRAP.COM TRAP ON TRAP! TRAP! TRAP! TRAP OFF C:\>No voy a entrar en detalles sobre la inicialización del programa ya que se asume que el lector tiene los conocimientos necesarios de assembler como para entenderlo por sí mismo (solo se recuerda que cuando comienza la ejecución de un archivo .COM es: CS = DS = ES).
0960:0001: xor ax, ax 0960:0002: inc axLuego de ejecutarse el 'XOR' el CS:IP contiene 0960:0002, como el bit T está activo, en vez de ejecutarse el 'INC' se genera una interrupción TRAP. El estado de la pila dentro de la rutina Trap es el siguiente:
+------+------+-------+-------------...--------------------+ | 0002 | 0960 | FLAGS | XXXX XXXX XX...XXXX XXXX XXXX XXXX | +------+------+-------+-------------...--------------------+ SPEl SP (stack pointer) está apuntando al último elemento guardado en la pila (al IP del programa original). En SP+2 se encuentra el CS y en SP+4 estan los flags (no olvidar que en la pila se guardan elementos de 16 bits). Lo que debemos hacer es obtener de la pila la dirección del código interrumpido y restarle a su IP el valor necesario para ubicarlo en la instrucción anterior (para que apunte al 'XOR'). Una vez hecho esto podemos leer el código de operación (opcode) de la instrucción trapeada y saber si es o no un IN o un OUT.
--------------------BEGIN OPCODES.ASM---------------------------------- ; ;OPCODES.ASM - (c) 1998 - Maruja ; ;Programa para conocer los codigos de operacion de las ;instrucciones que permiten el acceso a los puertos de E/S ; .model tiny .code org 100h inicio: in al, dx in ax, dx out dx, al out dx, ax nop nop nop nop nop nop mov ax, 4C00h int 21h end inicio --------------------END OPCODES.ASM------------------------------------Compilando y usando el debug del DOS:
C:\>TASM OPCODES.ASM ... C:\>TLINK /t OPCODES ... C:\>DEBUG OPCODES.COM -d 144F:0100 EC ED EE EF 90 90 90 90-90 90 B8 00 4C CD 21 00 ............L.!. 144F:0110 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 144F:0120 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 144F:0130 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 144F:0140 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 144F:0150 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 144F:0160 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ 144F:0170 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ -q C:\>Aquí se observan claramente los códigos (en hexadecimal) de cada una de las instrucciones:
IN AL, DX = EC IN AX, DX = ED OUT DX, AL = EE OUT DX, AX = EF NOP = 90 MOV AX, 4C00h = B8 00 4C INT 21h = CD 21Basandosé en los datos recién obtenidos, el programa IOTRAP.ASM se encarga de rastrear cada una de las operaciones de E/S que puedan ocurrir. Las diferencias entre este programa y el programa TRAP.ASM se encuentran en las rutinas 'Trap' y 'Arraque', es por esto que solamente se muestran estas dos:
--------------------BEGIN IOTRAP.ASM - TRAP & ARRANQUE----------------- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Trap: SP_INICIAL EQU $ push dx ;Salvar registros utilizados push ds push ax push si push bp SP_FINAL EQU $ mov bp, sp ;Obtener CS:IP Interrumpido mov si, [bp + (SP_FINAL-SP_INICIAL)*2 + 2 ] mov ds, si mov si, [bp + (SP_FINAL-SP_INICIAL)*2 ] dec si ;DS:SI = CS:IP Instruccion previa mov al, byte ptr [si] ;Obtener opcode instruccion previa cmp al, 0ECh ;El opcode es 0ECh ? jb Trap_salir ;Si es menor salir cmp al, 0EFh ;El opcode es 0EFh ? ja Trap_salir ;Si es mayor salir push cs ;Como el opcode es uno entre pop ds ;0ECh y 0EFh imprimir mensaje TRAP! lea dx, trap_msg mov ah, 9 int 21h Trap_salir: pop bp ;Recuperar registros y salir pop si pop ax pop ds pop dx iret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Arranque: call SetearVectores int 90h ;Activar Trap mov ax, 1 mov dx, 60h nop in al, 60h in al, dx in ax, dx in ax, 60h int 91h ;Desactivar Trap Call RestaurarVectores mov ax, 4C00h ;Terminar programa int 21h end inicio --------------------END IOTRAP.ASM - TRAP & ARRANQUE-------------------Compilando y ejecutando el programa se obtiene:
C:\>TASM IOTRAP.ASM ... C:\>TLINK /t IOTRAP ... C:\>IOTRAP.COM TRAP ON TRAP! TRAP! TRAP OFF C:\>Explicación de las rutinas:
mov ax, 0EE00h xor dx, dxLuego del 'MOV' se ejecuta la Trap con el CS:IP del 'XOR' en la pila, cuando nuestra rutina decrementa en uno el IP va a parar sobre la última parte del dato que se carga en 'AX', osea sobre 0EEh, con lo cuál la Trap asumirá, erroneamente, que la instrucción reciente fué un 'OUT DX,AL' en vez de un 'MOV'. Lo verificamos en el programa IOTRAP2.ASM:
--------------------BEGIN IOTRAP2.ASM - ARRANQUE----------------------- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Arranque: call SetearVectores int 90h ;Activar Trap mov ax, 1 mov dx, 60h nop in al, 60h in al, dx in ax, dx in ax, 60h mov ax, 0EE00h xor dx, dx int 91h ;Desactivar Trap Call RestaurarVectores mov ax, 4C00h ;Terminar programa int 21h end inicio ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; --------------------END IOTRAP2.ASM - ARRANQUE-------------------------Las diferencias con IOTRAP.ASM están solamente en la rutina 'Arranque'. Compilando y ejecutando obtenemos:
C:\>TASM IOTRAP2.ASM ... C:\>TLINK /t IOTRAP2 ... C:\>IOTRAP2.COM TRAP ON TRAP! TRAP! TRAP! TRAP OFF C:\>¡Un mensaje más que en el ejemplo anterior! Esto significa que la Trap confundió el 'MOV AX,0EE00h' con un 'OUT DX,AL' ya que no calculó correctamente la dirección exacta de esa instrucción. Una posible solución a este problema puede ser:
--------------------BEGIN IOTRAP3.ASM - TRAP--------------------------- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; IPanterior dw 0 CSanterior dw 0 Trap: SP_INICIAL EQU $ push dx ;Salvar registros utilizados push ds push ax push si push bp SP_FINAL EQU $ cmp cs:CSanterior, 0 ;CSanterior tiene un valor incorrecto ? jz Trap_salir ;Si: salir mov si, cs:CSanterior mov ds, si mov si, cs:IPanterior ;DS:SI = CS:IP instruccion anterior mov al, byte ptr [si] ;Obtener opcode cmp al, 0ECh ;El opcode es 0ECh ? jb Trap_salir ;Si es menor salir cmp al, 0EFh ;El opcode es 0EFh ? ja Trap_salir ;Si es mayor salir push cs ;Como el opcode es uno entre pop ds ;0ECh y 0EFh imprimir mensaje TRAP! lea dx, trap_msg mov ah, 9 int 21h Trap_salir: mov bp, sp ;Guardar CS:IP de proxima instruccion mov si, [bp + (SP_FINAL-SP_INICIAL)*2 + 2 ] mov cs:CSanterior, si mov si, [bp + (SP_FINAL-SP_INICIAL)*2 ] mov cs:IPanterior, si pop bp ;Recuperar registros y salir pop si pop ax pop ds pop dx iret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; --------------------END IOTRAP3.ASM - TRAP-----------------------------Al compilar y ejecutar se tiene:
C:\>TASM IOTRAP3.ASM ... C:\>TLINK /t IOTRAP3 ... C:\>IOTRAP3.COM TRAP ON TRAP! TRAP! TRAP OFF C:\>¡Perfecto! Solamente hay 2 instrucciones IN válidas.
Dirección Contenido ------------------------------------------- 0040:0008h Dirección base de LPT1 0040:000Ah Dirección base de LPT2 0040:000Ch Dirección base de LPT3 0040:000Eh Dirección base de LPT4Si bien existe la posibilidad de tener un cuarto puerto paralelo, el DOS no lo reconoce.
--------------------BEGIN LPT1CAP1.ASM--------------------------------- ; ;LPT1CAP1.ASM - (c) 1998 - Maruja ; ;Ejemplo de rastreo de operaciones en el puerto LPT1 ; .model tiny .code org 100h inicio: jmp Arranque ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; IN_BYTE EQU 0ECh ;IN AL, DX IN_WORD EQU 0EDh ;IN AX, DX OUT_BYTE EQU 0EEh ;OUT DX, AL OUT_WORD EQU 0EFh ;OUT DX, AX ES_OUT EQU 32768 ;Bit 15 flags ES_WORD EQU 16384 ;Bit 14 flags vieja90 dd ? ;Direccion original INT 90h vieja91 dd ? ;Direccion original INT 91h vieja01 dd ? ;Direccion original TRAP IPanterior dw 0 ;CS:IP Instruccion anterior CSanterior dw 0 lpt11 dw ? ;Direccion base (1er registro) de LPT1 lpt13 dw ? ;Direccion 3er registro de LPT1 TAMBUF EQU 256*8 ;Longitud buffer buffer db TAMBUF dup (0) ;Buffer temporal para datos capturados index dw 0 ;Posicion en buffer filename db 'C:\LPT.DAT', 0 ;Archivo con datos capturados ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; SetTrap: push ax push bp mov bp, sp mov ax, [bp+8] ;Obtener flags de la pila or ah, 1 ;Activar bit T mov [bp+8], ax ;Colocar nuevos flags en la pila pop bp pop ax iret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; UnTrap: push ax push bp mov bp, sp mov ax, [bp+8] ;Obtener flags de la pila and ah, 0FEh ;Desactivar bit T mov [bp+8], ax ;Colocar nuevos flags en la pila cmp cs:index, 0 ;El buffer esta vacio ? jz UnTrap_salir ;Si: salir push bx push cx push dx push ds call GrabarBuffer ;Forzar la grabacion del buffer pop ds pop dx pop cx pop bx UnTrap_salir: pop bp pop ax iret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Trap: SP_INICIAL EQU $ push ax ;Salvar registros utilizados push bx push cx push dx push si push ds push bp SP_FINAL EQU $ cmp cs:CSanterior, 0 ;CSanterior tiene un valor incorrecto ? jz Trap_salir ;Si: salir mov si, cs:CSanterior mov ds, si mov si, cs:IPanterior ;DS:SI = CS:IP instruccion anterior mov cl, byte ptr [si] ;Obtener opcode cmp cl, IN_BYTE ;El opcode es alguno entre jb Trap_salir ;IN_BYTE u OUT_WORD ? cmp cl, OUT_WORD ja Trap_salir ;No: salir push cs pop ds cmp dx, lpt11 ;Acceso a alguno de los puertos LPT1 ? jb Trap_salir cmp dx, lpt13 ja Trap_salir ;No: salir call CapturarAcceso Trap_salir: mov bp, sp ;Guardar CS:IP de proxima instruccion mov si, [bp + (SP_FINAL-SP_INICIAL)*2 + 2 ] mov cs:CSanterior, si mov si, [bp + (SP_FINAL-SP_INICIAL)*2 ] mov cs:IPanterior, si pop bp ;Recuperar registros y salir pop ds pop si pop dx pop cx pop bx pop ax iret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; CapturarAcceso: ;AX = Dato; DX = Puerto; CL = Opcode cmp cl, OUT_WORD ;Es un OUT ? je CA_setout cmp cl, OUT_BYTE jne CA_verdata CA_setout: or dx, ES_OUT ;Si: setear bit 15 CA_verdata: cmp cl, IN_WORD ;El dato es word ? je CA_setword cmp cl, OUT_WORD jne CA_push CA_setword: or dx, ES_WORD ;Si: setear bit 14 CA_push: lea si, buffer ;Guardar estructura en buffer add si, index mov cx, CSanterior mov [si], cx ;Guardar CS mov cx, IPanterior mov [si+2], cx ;Guardar IP mov [si+4], dx ;Guardar Flags mov [si+6], ax ;Guardar Dato add index, 8 ;Actualizar indice cmp index, TAMBUF ;El buffer esta lleno ? je GrabarBuffer ;Si: grabar buffer en disco ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; GrabarBuffer: mov ax, 3D02h ;Abrir archivo para L/E lea dx, filename int 21h jnc GB_append mov ah, 3Ch ;Si no existe crearlo xor cx, cx int 21h jc GB_salir ;Si hubo error salir GB_append: mov bx, ax ;Poner archivo en modo append mov ax, 4202h xor dx, dx xor cx, cx int 21h mov ah, 40h ;Grabar buffer mov cx, index lea dx, buffer int 21h mov ah, 3Eh ;Cerrar archivo int 21h mov index, 0 ;Resetear indice GB_salir: ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; SetearVectores: mov ax, 3501h ;Obtener vector de interrupcion TRAP int 21h ;(tipo 1) y guardarlo mov word ptr vieja01, bx mov bx, es mov word ptr vieja01+2, bx mov ax, 3590h ;Obtener vector de interrupcion 90h int 21h ;y guardarlo mov word ptr vieja90, bx mov bx, es mov word ptr vieja90+2, bx mov ax, 3591h ;Obtener vector de interrupcion 91h int 21h ;y guardarlo mov word ptr vieja91, bx mov bx, es mov word ptr vieja91+2, bx mov ax, 2590h ;Hacer que una INT 90h ejecute el lea dx, SetTrap ;codigo 'SetTrap' int 21h mov ax, 2591h ;Hacer que una INT 91h ejecute el lea dx, UnTrap ;codigo 'UnTrap' int 21h mov ax, 2501h ;Hacer que la interrupcion TRAP lea dx, Trap ;provoque la ejecucion del codigo int 21h ;'Trap' ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; RestaurarVectores: mov ax, 2501h ;Restaurar vector anterior lds dx, dword ptr vieja01 ;interrupcion TRAP int 21h mov ax, 2590h ;Restaurar vector anterior lds dx, dword ptr cs:vieja90 ;interrupcion 90h int 21h mov ax, 2591h ;Restaurar vector anterior lds dx, dword ptr cs:vieja91 ;interrupcion 91h ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; GetLPT1: mov di, 40h mov es, di mov di, 8 ;ES:DI = 0040:0008h mov ax, word ptr es:[di] mov lpt11, ax add ax, 2 mov lpt13, ax ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Arranque: call GetLPT1 ;Obtener direcciones de LPT1 call SetearVectores int 90h ;Activar Trap xor ax, ax mov dx, lpt11 ;DX = LPT1 registro 1 out dx, al inc dx ;DX = LPT1 registro 2 in ax, dx out dx, ax inc dx ;DX = LPT1 registro 3 in al, dx inc dx ;DX = LPT1Base+4: NO es LPT1 in ax, dx int 91h ;Desactivar Trap Call RestaurarVectores mov ax, 4C00h ;Terminar programa int 21h end inicio ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; --------------------END LPT1CAP1.ASM-----------------------------------Compilando y ejecutando:
C:\>TASM LPT1CAP1.ASM ... C:\>TLINK /t LPT1CAP1 ... C:\>LPT1CAP1.COM C:\>DIR *.DAT Volumen en unidad C es PINDONGA Número de serie de volumen es 2D4B-1CD6 Directorio de C:\ LPT DAT 32 01/09/98 23:44 1 archivo(s) 32 bytes 804421632 bytes libres C:\>Se ha creado un archivo de 32 bytes de longitud, esto significa que se capturaron 4 accesos al puerto LPT1. Antes de examinar este archivo se comentará el programa ya que hubo algunos cambios importantes con respecto a los anteriores:
--------------------BEGIN IOVIEW.C------------------------------------- /* ** IOVIEW.C - (c) 1998 - Maruja ** Muestra (en forma entendible) los datos capturados en operaciones de E/S ** ** Modo de uso: IOVIEW file ** Donde file es el nombre del archivo con los datos capturados */ #include <>stdio.h> #include <>stdlib.h> /* Teseteo de Flags */ #define TEST_OUT(flag) (flag & 32768) /* bit 15 = OUT */ #define TEST_WORD(flag) (flag & 16384) /* bit 14 = WORD */ #define GET_PORT(flag) (flag & 2047) /* Estructura basica */ typedef struct { unsigned int cs, ip, flags, data; } TRAP; int main (int can, char *arg[]) { FILE *f; TRAP i; /* Verificar que se encuentre el nombre del file */ if (can < 2) { fprintf (stderr, "%s: Falta el nombre del archivo con los datos capturados\n\r", arg[0]); exit (-1); } /* Abrir archivo de datos */ if (! (f = fopen (arg[1], "rb")) ) { fprintf (stderr, "%s: ", arg[0]); perror (arg[1]); exit (-1); } /* Mostrar informacion */ printf ("\nArchivo: '%s'", arg[1]); for (;;) { /* Leer estructura */ if (!fread (&i, sizeof (TRAP), 1, f)) break; /* Mostrar en forma humana */ printf ("\n%04X:%04X\t%s\t%03X, ", i.cs, i.ip, TEST_OUT(i.flags) ? "OUT" : "IN", GET_PORT(i.flags)); if (TEST_WORD(i.flags)) printf ("%04X\t(WORD)", i.data); else printf ("%02X \t(BYTE)", i.data & 255); } printf ("\n"); return 0; } --------------------END IOVIEW.C---------------------------------------Compilando con cualquier compilador de C y luego ejecutando...
C:\>CC IOVIEW.C ... C:\>IOVIEW LPT.DAT Archivo: 'LPT.DAT' 0E61:0AA5 OUT 278, 00 (BYTE) 0E61:0AA7 IN 279, CC87 (WORD) 0E61:0AA8 OUT 279, CC87 (WORD) 0E61:0AAA IN 27A, CC (BYTE) C:\>Esto se lee así:
C:\>LDR GESTION.EXE Loading C:\GESTION.EXE ... ... :bpio 278 ;Breakpoint on I/O access :bpio 279 :bpio 27a[ Suspender ejecución si hay algún acceso al puerto LPT1 ]
:bpint 21 ah=4b ;Breakpoint on Interrupt[ Suspender ejecución cuando se carga y/o ejecuta un programa ]
:bpint 21 ah=4c[ Suspender ejecución cuando finaliza un programa ]
:x ;Run Break Point at 0E1B:03BB 0E1B:03B8 B8004B MOV AX, 4B00 > 0E1B:03BB CD21 INT 21 ;Load and execute program 0E1B:03BD 7236 JB 03F5 ...[ El programa protegido (gestion.exe) carga y ejecuta al programa de protección (protect.exe) ]
:t ;One Step > 0123:109E 90 NOP 0123:109F 90 NOP 0123:10A0 E8CC00 CALL 116F ...[ Inicio del código de la interrupción tipo 21h ]
:p ret ;Run until return > FDC9:423C CF IRET ...[ Punto final de la funcion 4Bh del DOS ]
:t > 1AE3:0000 BA3E1C MOV DX, 1C3E 1AE3:0003 8EDA MOV DS, DX 1AE3:0005 8C066801 MOV [0168], ES 1AE3:0009 33ED XOR BP, BP 1AE3:000B 8BC4 MOV AX, BP ...[ Punto de entrada del programa de protección ]
:x Break Point at 18B4:0855 18B4:0854 EC IN AL, DX > 18B4:0855 EB01 JMP 0858 18B4:0857 28 . 18B4:0858 2EA20200 MOV CS:[0002], AL 18B4:085C BB0100 MOV BX, 0001 18B4:085F B055 MOV AL, 55 18B4:0861 EE OUT DX, AL ...[ Rutina que accede a la llave ]
C:\>LDR GESTION.EXE Loading C:\GESTION.EXE ... ... :bc * ;Clear all breakpoints :bpm 18b4:0854 ;Breakpoint on memory access :x ... :x Break Point at 179D:021C > 179D:021C C47E8F LES DI, [BP-08] 179D:021F 03F8 ADD DI, AX 179D:0221 268B15 MOV DX, ES:[DI] 179D:0224 8B46FE MOV AX, [BP-02] 179D:0227 D1E0 SHL AX, 1 179D:0229 C47E8F LES DI, [BP-08] 179D:022C 03F8 ADD DI, AX 179D:022E 268B05 MOV AX, ES:[DI] 179D:0231 33C2 XOR AX, DX 179D:0233 8BD0 MOV DX, AX 179D:0235 8B46FE MOV AX, [BP-02] 179D:0238 D1E0 SHL AX, 1 179D:023A C47E8F LES DI, [BP-08] 179D:023D 03F8 ADD DI, AX 179D:023F 268915 MOV ES:[DI], DX 179D:0242 837EFE01 CMP WORD PTR [BP-02], 1 179D:0246 75CB JNZ 0213 ...[ Rutina que desencripta el codigo que accede a la llave ]
... C47EF8 LES DI, [BP-08] 179D:023D CD90 INT 90 268915 MOV ES:[DI], DX ...Podemos hacerlo desde el debugger pero para un cambio permanente tenemos que modificar directamente al ejecutable, esto lo podemos hacer con algún tipo de editor de archivos como ser el 'disquetitor' del 'MarronOrton Utilitis':
C:\>COPY PROTECT.EXE ORIGINAL.EXE C:\>DISQUETITOR PROTECT.EXE /WPedimos a este utilitario que busque la secuencia:
C4 7E 8F 03 F8 26 8B 15 8B 46 FE D1 E0 C4 7E 8F 03 F8 26 8B 05 33 C2 8B D0 8B 46 FE D1 E0 C4 7E 8F 03 F8 26 89 15y cambiamos la última ocurrencia del '03 F8' con un 'CD 90' de tal manera que quede así:
C4 7E 8F 03 F8 26 8B 15 8B 46 FE D1 E0 C4 7E 8F 03 F8 26 8B 05 33 C2 8B D0 8B 46 FE D1 E0 C4 7E 8F CD 90 26 89 15El 'CD' es el código de operación de la instrucción INT, el siguiente byte es el tipo de interrupción a generar, por eso 'CD 90' es el código de máquina de la instrucción 'INT 90h'. (Observar la salida generada por el debug del DOS cuando se lo utilizó para obtener los códigos de operación de los INs y OUTs).
--------------------BEGIN LPT1CAP.ASM---------------------------------- ; ;LPT1CAP.ASM - (c) 1998 - Maruja ; ;Programa residente que captura todos los accesos al puerto LPT1 ;Se activa con 'INT 90h' y se desactiva con 'INT 91h' ; .model tiny .code org 100h inicio: jmp Arranque ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; IN_BYTE EQU 0ECh ;IN AL, DX IN_WORD EQU 0EDh ;IN AX, DX OUT_BYTE EQU 0EEh ;OUT DX, AL OUT_WORD EQU 0EFh ;OUT DX, AX ES_OUT EQU 32768 ;Bit 15 flags ES_WORD EQU 16384 ;Bit 14 flags IPanterior dw 0 ;CS:IP Instruccion anterior CSanterior dw 0 lpt11 dw ? ;Direccion base (1er registro) de LPT1 lpt13 dw ? ;Direccion 3er registro de LPT1 TAMBUF EQU 4096*8 ;Longitud buffer (grande) buffer db TAMBUF dup (0) ;Buffer temporal para datos capturados index dw 0 ;Posicion en buffer filename db 'C:\LPT.DAT', 0 ;Archivo con datos capturados ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; SetTrap: push ax push bp mov bp, sp mov ax, [bp+8] ;Obtener flags de la pila or ah, 1 ;Activar bit T mov [bp+8], ax ;Colocar nuevos flags en la pila push dx push ds push cs pop ds mov ax, 2501h ;Setear nuestro vector de int TRAP lea dx, Trap int 21h pop ds pop dx pop bp pop ax ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; INSTRUCCION ORIGINAL EN EL ARCHIVO DE PROTECCION ; QUE FUE CAMBIADA POR EL 'INT 90h' (CD 90) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ADD DI, AX ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; iret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; UnTrap: push ax push bp mov bp, sp mov ax, [bp+8] ;Obtener flags de la pila and ah, 0FEh ;Desactivar bit T mov [bp+8], ax ;Colocar nuevos flags en la pila cmp cs:index, 0 ;El buffer est vac¡o ? jz UnTrap_salir ;Si: salir push bx push cx push dx push ds push cs pop ds call GrabarBuffer ;Forzar la grabacion del buffer pop ds pop dx pop cx pop bx UnTrap_salir: pop bp pop ax iret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Trap: SP_INICIAL EQU $ push ax ;Salvar registros utilizados push bx push cx push dx push si push ds push bp SP_FINAL EQU $ cmp cs:CSanterior, 0 ;CSanterior tiene un valor incorrecto ? jz Trap_salir ;Si: salir mov si, cs:CSanterior mov ds, si mov si, cs:IPanterior ;DS:SI = CS:IP instrucci¢n anterior mov cl, byte ptr [si] ;Obtener opcode cmp cl, IN_BYTE ;El opcode es alguno entre jb Trap_salir ;IN_BYTE u OUT_WORD ? cmp cl, OUT_WORD ja Trap_salir ;No: salir push cs pop ds cmp dx, lpt11 ;Acceso a alguno de los puertos LPT1 ? jb Trap_salir cmp dx, lpt13 ja Trap_salir ;No: salir call CapturarAcceso Trap_salir: mov bp, sp ;Guardar CS:IP de proxima instruccion mov si, [bp + (SP_FINAL-SP_INICIAL)*2 + 2 ] mov cs:CSanterior, si mov si, [bp + (SP_FINAL-SP_INICIAL)*2 ] mov cs:IPanterior, si pop bp ;Recuperar registros y salir pop ds pop si pop dx pop cx pop bx pop ax iret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; CapturarAcceso: ;AX = Dato; DX = Puerto; CL = Opcode cmp cl, OUT_WORD ;Es un OUT ? je CA_setout cmp cl, OUT_BYTE jne CA_verdata CA_setout: or dx, ES_OUT ;Si: setear bit 15 CA_verdata: cmp cl, IN_WORD ;El dato es word ? je CA_setword cmp cl, OUT_WORD jne CA_push CA_setword: or dx, ES_WORD ;Si: setear bit 14 CA_push: lea si, buffer ;Guardar estructura en buffer add si, index mov cx, CSanterior mov [si], cx ;Guardar CS mov cx, IPanterior mov [si+2], cx ;Guardar IP mov [si+4], dx ;Guardar Flags mov [si+6], ax ;Guardar Dato add index, 8 ;Actualizar indice cmp index, TAMBUF ;El buffer esta lleno ? je GrabarBuffer ;Si: grabar buffer en disco ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; GrabarBuffer: mov ax, 3D02h ;Abrir archivo para L/E lea dx, filename int 21h jnc GB_append mov ah, 3Ch ;Si no existe crearlo xor cx, cx int 21h jc GB_salir ;Si hubo error salir GB_append: mov bx, ax ;Poner archivo en modo append mov ax, 4202h xor dx, dx xor cx, cx int 21h mov ah, 40h ;Grabar buffer mov cx, index lea dx, buffer int 21h mov ah, 3Eh ;Cerrar archivo int 21h mov index, 0 ;Resetear indice GB_salir: ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; FINRESID EQU $ ;Aca termina el residente ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; SetearVectores: mov ax, 2590h ;Hacer que una INT 90h ejecute el lea dx, SetTrap ;codigo 'SetTrap' int 21h mov ax, 2591h ;Hacer que una INT 91h ejecute el lea dx, UnTrap ;codigo 'UnTrap' int 21h mov ax, 2501h ;Hacer que la interrupcion TRAP lea dx, Trap ;provoque la ejecucion del codigo int 21h ;'Trap' ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; GetLPT1: push es ;Obtener registros de LPT1 mov di, 40h mov es, di mov di, 8 ;ES:DI = 0040:0008h mov ax, word ptr es:[di] mov lpt11, ax ;lpt11 = Registro 1 LPT1 add ax, 2 mov lpt13, ax ;lpt13 = Registro 3 LPT1 pop es ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; mok db 13, 10, 'OK', 13, 10, '$' myaestoy db 13, 10, 'Ya estaba residente', 13, 10, '$' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Arranque: push ds ;El offset del vector de xor si, si ;interrupcion 90h es igual mov ds, si ;al offset de la SetTrap ? mov si, 240h mov ax, word ptr [si] pop ds cmp ax, offset SetTrap jne A_instalar ;No: instalar residente lea dx, myaestoy ;Como el residente ya estaba mov ah, 9 ;instalado mostrar mensaje int 21h ;y salir mov ax, 4C00h int 21h A_instalar: call GetLPT1 ;Obtener direcciones de LPT1 call SetearVectores ;Setear nuevos vectores de ints lea dx, mok ;Mostrar mensaje 'OK' mov ah, 9 int 21h mov ax, 3100h ;Terminar y quedar residente lea dx, FINRESID shr dx, 4 inc dx int 21h end inicio ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; --------------------END LPT1CAP.ASM------------------------------------Operamos:
C:\>TASM LPT1CAP.ASM ... C:\>TLINK /t LPT1CAP ... C:\>DEL LPT.DAT C:\>LPT1CAP OK C:\>LPT1CAP Ya estaba residente C:\>GESTION.EXE ... ... C:\>DIR *.DAT Volumen en unidad C es PINDONGA Número de serie de volumen es 2D4B-1CD6 Directorio de C:\ Archivo no se encontró C:\>¿Qué pasó que no apareció el archivo con los datos capturados? Nada malo: el nuevo buffer del residente tiene capacidad para 4096 accesos y el programa de protección no realizó tantos, para vaciarlo usamos al programa FLUSH.ASM:
--------------------BEGIN FLUSH.ASM------------------------------------ ; ;FLUSH.ASM - (c) 1998 - Maruja ; ;Baja el contenido del buffer de la rutina TRAP residente a disco ; .model tiny .code org 100h inicio: int 91h mov ax, 4C00h int 21h end inicio --------------------END FLUSH.ASM--------------------------------------Luego:
C:\>TASM FLUSH.ASM ... C:\>TLINK /t FLUSH ... C:\>FLUSH.COM C:\>DIR *.DAT Volumen en unidad C es PINDONGA Número de serie de volumen es 2D4B-1CD6 Directorio de C:\ LPT DAT 14032 06/09/98 23:10 1 archivo(s) 2048 bytes 804409628 bytes libres C:\>¡Muejejee! Se han hecho 1754 accesos en LPT1.
C:\>REN LPT.DAT 1.DAT C:\>GESTION.EXE ... C:\>FLUSH.COM C:\>REN LPT.DAT 2.DAT C:\>GESTION.EXE ... C:\>FLUSH.COM C:\>REN LPT.DAT 3.DAT C:\>GESTION.EXE ... C:\>FLUSH.COM C:\>REN LPT.DAT 4.DAT C:\>GESTION.EXE ... C:\>FLUSH.COM C:\>REN LPT.DAT 5.DAT C:\>DIR C:\*.DAT Volumen en unidad C es PINDONGA Número de serie de volumen es 2D4B-1CD6 Directorio de C:\ 1 DAT 14032 10/09/98 18:09 2 DAT 14912 10/09/98 18:10 3 DAT 15488 10/09/98 18:10 4 DAT 14048 10/09/98 18:11 5 DAT 15792 10/09/98 18:11 5 archivo(s) 74272 bytes 757170176 bytes libres C:\>¡Ooohh! ¡Parece que los muchachos quieren guerra! Por cada ejecución se hicieron 1754, 1864, 1936, 1756, y 1974 accesos respectivamente, veamos el contenido del primero:
C:\>IOVIEW 1.DAT Archivo: '1.dat' 1BCB:0854 IN 278, 00 (BYTE) 1BCB:0861 OUT 278, 55 (BYTE) 1BCB:0865 IN 278, 55 (BYTE) 1BCB:0874 OUT 278, AA (BYTE) 1BCB:0878 IN 278, AA (BYTE) 1BCB:0887 OUT 278, 00 (BYTE) 1BCB:00E2 IN 278, 00 (BYTE) 1BCB:00F9 IN 27A, CC (BYTE) 1BCB:00FF OUT 27A, CC (BYTE) 1BCB:010D OUT 278, 92 (BYTE) 1BCB:011D OUT 278, B2 (BYTE) 1BCB:014A IN 279, 96 (BYTE) 1BCB:0195 OUT 278, 40 (BYTE) 1BCB:01B8 OUT 278, 00 (BYTE) 1BCB:0195 OUT 278, FA (BYTE) 1BCB:01B8 OUT 278, BA (BYTE) 1BCB:0195 OUT 278, F8 (BYTE) 1BCB:01B8 OUT 278, B8 (BYTE) 1BCB:0195 OUT 278, F2 (BYTE) 1BCB:01B8 OUT 278, B2 (BYTE) 1BCB:0195 OUT 278, F0 (BYTE) 1BCB:01B8 OUT 278, B0 (BYTE) 1BCB:0195 OUT 278, EA (BYTE) 1BCB:01B8 OUT 278, AA (BYTE) 1BCB:0195 OUT 278, E8 (BYTE) 1BCB:01B8 OUT 278, A8 (BYTE) 1BCB:0195 OUT 278, E2 (BYTE) 1BCB:01B8 OUT 278, A2 (BYTE) 1BCB:0195 OUT 278, E0 (BYTE) 1BCB:01B8 OUT 278, A0 (BYTE) 1BCB:0195 OUT 278, DA (BYTE) 1BCB:01B8 OUT 278, 9A (BYTE) 1BCB:0195 OUT 278, D8 (BYTE) 1BCB:01B8 OUT 278, 98 (BYTE) 1BCB:0195 OUT 278, D2 (BYTE) 1BCB:01B8 OUT 278, 92 (BYTE) 1BCB:0195 OUT 278, D0 (BYTE) 1BCB:01B8 OUT 278, 90 (BYTE) 1BCB:0195 OUT 278, CA (BYTE) 1BCB:01B8 OUT 278, 8A (BYTE) 1BCB:0195 OUT 278, C8 (BYTE) 1BCB:01B8 OUT 278, 88 (BYTE) 1BCB:0195 OUT 278, C2 (BYTE) 1BCB:01B8 OUT 278, 82 (BYTE) 1BCB:0195 OUT 278, C0 (BYTE) 1BCB:01B8 OUT 278, 80 (BYTE) 1BCB:0195 OUT 278, 7A (BYTE) 1BCB:01B8 OUT 278, 3A (BYTE) 1BCB:0195 OUT 278, 78 (BYTE) 1BCB:01B8 OUT 278, 38 (BYTE) 1BCB:0195 OUT 278, 72 (BYTE) 1BCB:01B8 OUT 278, 32 (BYTE) 1BCB:0195 OUT 278, 70 (BYTE) 1BCB:01B8 OUT 278, 30 (BYTE) 1BCB:0195 OUT 278, 6A (BYTE) 1BCB:01B8 OUT 278, 2A (BYTE) 1BCB:0195 OUT 278, 68 (BYTE) 1BCB:01B8 OUT 278, 28 (BYTE) 1BCB:0195 OUT 278, 62 (BYTE) 1BCB:01B8 OUT 278, 22 (BYTE) 1BCB:0195 OUT 278, 60 (BYTE) 1BCB:01B8 OUT 278, 20 (BYTE) 1BCB:0195 OUT 278, 5A (BYTE) 1BCB:01B8 OUT 278, 1A (BYTE) 1BCB:01C5 OUT 278, A2 (BYTE) 1BCB:01EC OUT 278, E2 (BYTE) 1BCB:020F OUT 278, A2 (BYTE) 1BCB:0219 OUT 278, B2 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:0244 OUT 278, F2 (BYTE) 1BCB:0267 OUT 278, B2 (BYTE) 1BCB:0272 IN 279, 96 (BYTE) 1BCB:02FD OUT 278, 40 (BYTE) 1BCB:0320 OUT 278, 00 (BYTE) 1BCB:02FD OUT 278, FA (BYTE) 1BCB:0320 OUT 278, BA (BYTE) 1BCB:02FD OUT 278, F8 (BYTE) 1BCB:0320 OUT 278, B8 (BYTE) 1BCB:02FD OUT 278, F2 (BYTE) 1BCB:0320 OUT 278, B2 (BYTE) 1BCB:02FD OUT 278, F0 (BYTE) 1BCB:0320 OUT 278, B0 (BYTE) 1BCB:02FD OUT 278, EA (BYTE) 1BCB:0320 OUT 278, AA (BYTE) 1BCB:02FD OUT 278, E8 (BYTE) 1BCB:0320 OUT 278, A8 (BYTE) 1BCB:02FD OUT 278, E2 (BYTE) 1BCB:0320 OUT 278, A2 (BYTE) 1BCB:02FD OUT 278, E0 (BYTE) 1BCB:0320 OUT 278, A0 (BYTE) 1BCB:02FD OUT 278, DA (BYTE) 1BCB:0320 OUT 278, 9A (BYTE) 1BCB:02FD OUT 278, D8 (BYTE) 1BCB:0320 OUT 278, 98 (BYTE) 1BCB:02FD OUT 278, D2 (BYTE) 1BCB:0320 OUT 278, 92 (BYTE) 1BCB:02FD OUT 278, D0 (BYTE) 1BCB:0320 OUT 278, 90 (BYTE) 1BCB:02FD OUT 278, CA (BYTE) 1BCB:0320 OUT 278, 8A (BYTE) 1BCB:02FD OUT 278, C8 (BYTE) 1BCB:0320 OUT 278, 88 (BYTE) 1BCB:02FD OUT 278, C2 (BYTE) 1BCB:0320 OUT 278, 82 (BYTE) 1BCB:02FD OUT 278, C0 (BYTE) 1BCB:0320 OUT 278, 80 (BYTE) 1BCB:02FD OUT 278, 7A (BYTE) 1BCB:0320 OUT 278, 3A (BYTE) 1BCB:02FD OUT 278, 78 (BYTE) 1BCB:0320 OUT 278, 38 (BYTE) 1BCB:02FD OUT 278, 72 (BYTE) 1BCB:0320 OUT 278, 32 (BYTE) 1BCB:02FD OUT 278, 70 (BYTE) 1BCB:0320 OUT 278, 30 (BYTE) 1BCB:02FD OUT 278, 6A (BYTE) 1BCB:0320 OUT 278, 2A (BYTE) 1BCB:02FD OUT 278, 68 (BYTE) 1BCB:0320 OUT 278, 28 (BYTE) 1BCB:02FD OUT 278, 62 (BYTE) 1BCB:0320 OUT 278, 22 (BYTE) 1BCB:02FD OUT 278, 60 (BYTE) 1BCB:0320 OUT 278, 20 (BYTE) 1BCB:02FD OUT 278, 5A (BYTE) 1BCB:0320 OUT 278, 1A (BYTE) 1BCB:02FD OUT 278, 58 (BYTE) 1BCB:0320 OUT 278, 18 (BYTE) 1BCB:02FD OUT 278, 52 (BYTE) 1BCB:0320 OUT 278, 12 (BYTE) 1BCB:02FD OUT 278, 50 (BYTE) 1BCB:0320 OUT 278, 10 (BYTE) 1BCB:02FD OUT 278, 4A (BYTE) 1BCB:0320 OUT 278, 0A (BYTE) 1BCB:02FD OUT 278, 48 (BYTE) 1BCB:0320 OUT 278, 08 (BYTE) 1BCB:02FD OUT 278, 42 (BYTE) 1BCB:0320 OUT 278, 02 (BYTE) 1BCB:02FD OUT 278, 40 (BYTE) 1BCB:0320 OUT 278, 00 (BYTE) 1BCB:02FD OUT 278, FA (BYTE) 1BCB:0320 OUT 278, BA (BYTE) 1BCB:02FD OUT 278, F8 (BYTE) 1BCB:0320 OUT 278, B8 (BYTE) 1BCB:02FD OUT 278, F2 (BYTE) 1BCB:0320 OUT 278, B2 (BYTE) 1BCB:032D OUT 278, 92 (BYTE) 1BCB:0338 IN 279, 96 (BYTE) 1BCB:0357 OUT 27A, 0C (BYTE) 1BCB:07CD OUT 278, 00 (BYTE) 1BCB:00E2 IN 278, 00 (BYTE) 1BCB:040B IN 278, 00 (BYTE) 1BCB:0423 OUT 278, 73 (BYTE) 1BCB:0435 OUT 27A, 0C (BYTE) 1BCB:043F IN 27A, CC (BYTE) 1BCB:0474 OUT 278, 05 (BYTE) 1BCB:0484 OUT 278, 85 (BYTE) 1BCB:04E8 OUT 278, 95 (BYTE) 1BCB:04F8 OUT 278, B5 (BYTE) 1BCB:04E8 OUT 278, 95 (BYTE) 1BCB:04F8 OUT 278, B5 (BYTE) 1BCB:04E8 OUT 278, 85 (BYTE) 1BCB:04F8 OUT 278, A5 (BYTE) 1BCB:04E8 OUT 278, 95 (BYTE) 1BCB:04F8 OUT 278, B5 (BYTE) 1BCB:04E8 OUT 278, 95 (BYTE) 1BCB:04F8 OUT 278, B5 (BYTE) 1BCB:04E8 OUT 278, 95 (BYTE) 1BCB:04F8 OUT 278, B5 (BYTE) 1BCB:04E8 OUT 278, 95 (BYTE) 1BCB:04F8 OUT 278, B5 (BYTE) 1BCB:04E8 OUT 278, 95 (BYTE) 1BCB:04F8 OUT 278, B5 (BYTE) 1BCB:04E8 OUT 278, 95 (BYTE) 1BCB:04F8 OUT 278, B5 (BYTE) 1BCB:0498 OUT 278, 85 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0398 OUT 278, 85 (BYTE) 1BCB:03AA OUT 27A, 04 (BYTE) 1BCB:03B8 OUT 278, C5 (BYTE) 1BCB:03C4 OUT 278, 85 (BYTE) 1BCB:03D6 OUT 27A, 0C (BYTE) 1BCB:04E8 OUT 278, 95 (BYTE) 1BCB:04F8 OUT 278, B5 (BYTE) 1BCB:04E8 OUT 278, 95 (BYTE) 1BCB:04F8 OUT 278, B5 (BYTE) 1BCB:04E8 OUT 278, 85 (BYTE) 1BCB:04F8 OUT 278, A5 (BYTE) 1BCB:04E8 OUT 278, 95 (BYTE) 1BCB:04F8 OUT 278, B5 (BYTE) 1BCB:04E8 OUT 278, 95 (BYTE) 1BCB:04F8 OUT 278, B5 (BYTE) 1BCB:04E8 OUT 278, 95 (BYTE) 1BCB:04F8 OUT 278, B5 (BYTE) 1BCB:04E8 OUT 278, 95 (BYTE) 1BCB:04F8 OUT 278, B5 (BYTE) 1BCB:04E8 OUT 278, 95 (BYTE) 1BCB:04F8 OUT 278, B5 (BYTE) 1BCB:04E8 OUT 278, 95 (BYTE) 1BCB:04F8 OUT 278, B5 (BYTE) 1BCB:0498 OUT 278, 85 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 86 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 86 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 86 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 86 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 86 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 86 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 86 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 86 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0474 OUT 278, 05 (BYTE) 1BCB:0484 OUT 278, 85 (BYTE) 1BCB:0398 OUT 278, 85 (BYTE) 1BCB:03AA OUT 27A, 04 (BYTE) 1BCB:03B8 OUT 278, C5 (BYTE) 1BCB:03C4 OUT 278, 85 (BYTE) 1BCB:03D6 OUT 27A, 0C (BYTE) 1BCB:04E8 OUT 278, 97 (BYTE) 1BCB:04F8 OUT 278, B7 (BYTE) 1BCB:04E8 OUT 278, 97 (BYTE) 1BCB:04F8 OUT 278, B7 (BYTE) 1BCB:04E8 OUT 278, 87 (BYTE) 1BCB:04F8 OUT 278, A7 (BYTE) 1BCB:04E8 OUT 278, 87 (BYTE) 1BCB:04F8 OUT 278, A7 (BYTE) 1BCB:04E8 OUT 278, 87 (BYTE) 1BCB:04F8 OUT 278, A7 (BYTE) 1BCB:04E8 OUT 278, 87 (BYTE) 1BCB:04F8 OUT 278, A7 (BYTE) 1BCB:04E8 OUT 278, 87 (BYTE) 1BCB:04F8 OUT 278, A7 (BYTE) 1BCB:04E8 OUT 278, 87 (BYTE) 1BCB:04F8 OUT 278, A7 (BYTE) 1BCB:04E8 OUT 278, 87 (BYTE) 1BCB:04F8 OUT 278, A7 (BYTE) 1BCB:05A5 OUT 278, 85 (BYTE) 1BCB:05B1 OUT 278, 95 (BYTE) 1BCB:05C4 IN 279, 86 (BYTE) 1BCB:05F7 OUT 278, A5 (BYTE) 1BCB:0602 IN 279, 86 (BYTE) 1BCB:0616 OUT 278, 95 (BYTE) 1BCB:0638 IN 279, 96 (BYTE) 1BCB:05F7 OUT 278, A5 (BYTE) 1BCB:0602 IN 279, 96 (BYTE) 1BCB:0616 OUT 278, 95 (BYTE) 1BCB:0638 IN 279, 96 (BYTE) 1BCB:05F7 OUT 278, A5 (BYTE) 1BCB:0602 IN 279, 96 (BYTE) 1BCB:0616 OUT 278, 95 (BYTE) 1BCB:0638 IN 279, 96 (BYTE) 1BCB:05F7 OUT 278, A5 (BYTE) 1BCB:0602 IN 279, 96 (BYTE) 1BCB:0616 OUT 278, 95 (BYTE) 1BCB:0638 IN 279, 96 (BYTE) 1BCB:05F7 OUT 278, A5 (BYTE) 1BCB:0602 IN 279, 96 (BYTE) 1BCB:0616 OUT 278, 95 (BYTE) 1BCB:0638 IN 279, 96 (BYTE) 1BCB:05F7 OUT 278, A5 (BYTE) 1BCB:0602 IN 279, 96 (BYTE) 1BCB:0616 OUT 278, 95 (BYTE) 1BCB:0638 IN 279, 86 (BYTE) 1BCB:05F7 OUT 278, A5 (BYTE) 1BCB:0602 IN 279, 86 (BYTE) 1BCB:0616 OUT 278, 95 (BYTE) 1BCB:0638 IN 279, 86 (BYTE) 1BCB:0474 OUT 278, 05 (BYTE) 1BCB:0484 OUT 278, 85 (BYTE) 1BCB:0398 OUT 278, 85 (BYTE) 1BCB:03AA OUT 27A, 04 (BYTE) 1BCB:03B8 OUT 278, C5 (BYTE) 1BCB:03C4 OUT 278, 85 (BYTE) 1BCB:03D6 OUT 27A, 0C (BYTE) 1BCB:04E8 OUT 278, 95 (BYTE) 1BCB:04F8 OUT 278, B5 (BYTE) 1BCB:04E8 OUT 278, 95 (BYTE) 1BCB:04F8 OUT 278, B5 (BYTE) 1BCB:04E8 OUT 278, 85 (BYTE) 1BCB:04F8 OUT 278, A5 (BYTE) 1BCB:04E8 OUT 278, 95 (BYTE) 1BCB:04F8 OUT 278, B5 (BYTE) 1BCB:04E8 OUT 278, 95 (BYTE) 1BCB:04F8 OUT 278, B5 (BYTE) 1BCB:04E8 OUT 278, 95 (BYTE) 1BCB:04F8 OUT 278, B5 (BYTE) 1BCB:04E8 OUT 278, 95 (BYTE) 1BCB:04F8 OUT 278, B5 (BYTE) 1BCB:04E8 OUT 278, 85 (BYTE) 1BCB:04F8 OUT 278, A5 (BYTE) 1BCB:04E8 OUT 278, 85 (BYTE) 1BCB:04F8 OUT 278, A5 (BYTE) 1BCB:0498 OUT 278, 85 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 86 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 86 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 86 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 86 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 86 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 86 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 86 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 86 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 86 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 86 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 86 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 86 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 86 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 86 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 86 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 86 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 86 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 86 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 86 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0474 OUT 278, 05 (BYTE) 1BCB:0484 OUT 278, 85 (BYTE) 1BCB:040B IN 278, 85 (BYTE) 1BCB:0423 OUT 278, 73 (BYTE) 1BCB:0435 OUT 27A, 0C (BYTE) 1BCB:043F IN 27A, CC (BYTE) 1BCB:0474 OUT 278, 05 (BYTE) 1BCB:0484 OUT 278, 85 (BYTE) 1BCB:04E8 OUT 278, 95 (BYTE) 1BCB:04F8 OUT 278, B5 (BYTE) 1BCB:04E8 OUT 278, 95 (BYTE) 1BCB:04F8 OUT 278, B5 (BYTE) 1BCB:04E8 OUT 278, 85 (BYTE) 1BCB:04F8 OUT 278, A5 (BYTE) 1BCB:04E8 OUT 278, 95 (BYTE) 1BCB:04F8 OUT 278, B5 (BYTE) 1BCB:04E8 OUT 278, 95 (BYTE) 1BCB:04F8 OUT 278, B5 (BYTE) 1BCB:04E8 OUT 278, 95 (BYTE) 1BCB:04F8 OUT 278, B5 (BYTE) 1BCB:04E8 OUT 278, 95 (BYTE) 1BCB:04F8 OUT 278, B5 (BYTE) 1BCB:04E8 OUT 278, 95 (BYTE) 1BCB:04F8 OUT 278, B5 (BYTE) 1BCB:04E8 OUT 278, 95 (BYTE) 1BCB:04F8 OUT 278, B5 (BYTE) 1BCB:0498 OUT 278, 85 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0537 OUT 278, 85 (BYTE) 1BCB:0543 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0537 OUT 278, 85 (BYTE) 1BCB:0543 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0537 OUT 278, 85 (BYTE) 1BCB:0543 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0537 OUT 278, 85 (BYTE) 1BCB:0543 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0537 OUT 278, 85 (BYTE) 1BCB:0543 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0537 OUT 278, 85 (BYTE) 1BCB:0543 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0537 OUT 278, 85 (BYTE) 1BCB:0543 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0537 OUT 278, 85 (BYTE) 1BCB:0543 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0537 OUT 278, 85 (BYTE) 1BCB:0543 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0537 OUT 278, 85 (BYTE) 1BCB:0543 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0537 OUT 278, 85 (BYTE) 1BCB:0543 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0537 OUT 278, 85 (BYTE) 1BCB:0543 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0537 OUT 278, 85 (BYTE) 1BCB:0543 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0537 OUT 278, 85 (BYTE) 1BCB:0543 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0537 OUT 278, 85 (BYTE) 1BCB:0543 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0537 OUT 278, 85 (BYTE) 1BCB:0543 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0398 OUT 278, 85 (BYTE) 1BCB:03AA OUT 27A, 04 (BYTE) 1BCB:03B8 OUT 278, C5 (BYTE) 1BCB:03C4 OUT 278, 85 (BYTE) 1BCB:03D6 OUT 27A, 0C (BYTE) 1BCB:03EE OUT 278, C5 (BYTE) 1BCB:03FA OUT 278, 85 (BYTE) 1BCB:04E8 OUT 278, 95 (BYTE) 1BCB:04F8 OUT 278, B5 (BYTE) 1BCB:04E8 OUT 278, 95 (BYTE) 1BCB:04F8 OUT 278, B5 (BYTE) 1BCB:04E8 OUT 278, 85 (BYTE) 1BCB:04F8 OUT 278, A5 (BYTE) 1BCB:04E8 OUT 278, 95 (BYTE) 1BCB:04F8 OUT 278, B5 (BYTE) 1BCB:04E8 OUT 278, 95 (BYTE) 1BCB:04F8 OUT 278, B5 (BYTE) 1BCB:04E8 OUT 278, 95 (BYTE) 1BCB:04F8 OUT 278, B5 (BYTE) 1BCB:04E8 OUT 278, 95 (BYTE) 1BCB:04F8 OUT 278, B5 (BYTE) 1BCB:04E8 OUT 278, 95 (BYTE) 1BCB:04F8 OUT 278, B5 (BYTE) 1BCB:04E8 OUT 278, 95 (BYTE) 1BCB:04F8 OUT 278, B5 (BYTE) 1BCB:0498 OUT 278, 85 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0537 OUT 278, 85 (BYTE) 1BCB:0543 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0537 OUT 278, 85 (BYTE) 1BCB:0543 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0537 OUT 278, 85 (BYTE) 1BCB:0543 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0537 OUT 278, 85 (BYTE) 1BCB:0543 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0537 OUT 278, 85 (BYTE) 1BCB:0543 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0537 OUT 278, 85 (BYTE) 1BCB:0543 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0537 OUT 278, 85 (BYTE) 1BCB:0543 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0537 OUT 278, 85 (BYTE) 1BCB:0543 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0537 OUT 278, 85 (BYTE) 1BCB:0543 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0537 OUT 278, 85 (BYTE) 1BCB:0543 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0537 OUT 278, 85 (BYTE) 1BCB:0543 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0537 OUT 278, 85 (BYTE) 1BCB:0543 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0537 OUT 278, 85 (BYTE) 1BCB:0543 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0537 OUT 278, 85 (BYTE) 1BCB:0543 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0537 OUT 278, 85 (BYTE) 1BCB:0543 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0537 OUT 278, 85 (BYTE) 1BCB:0543 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:040B IN 278, 95 (BYTE) 1BCB:0423 OUT 278, 73 (BYTE) 1BCB:0435 OUT 27A, 0C (BYTE) 1BCB:043F IN 27A, CC (BYTE) 1BCB:0474 OUT 278, 05 (BYTE) 1BCB:0484 OUT 278, 85 (BYTE) 1BCB:04E8 OUT 278, 95 (BYTE) 1BCB:04F8 OUT 278, B5 (BYTE) 1BCB:04E8 OUT 278, 95 (BYTE) 1BCB:04F8 OUT 278, B5 (BYTE) 1BCB:04E8 OUT 278, 85 (BYTE) 1BCB:04F8 OUT 278, A5 (BYTE) 1BCB:04E8 OUT 278, 85 (BYTE) 1BCB:04F8 OUT 278, A5 (BYTE) 1BCB:04E8 OUT 278, 85 (BYTE) 1BCB:04F8 OUT 278, A5 (BYTE) 1BCB:04E8 OUT 278, 85 (BYTE) 1BCB:04F8 OUT 278, A5 (BYTE) 1BCB:04E8 OUT 278, 85 (BYTE) 1BCB:04F8 OUT 278, A5 (BYTE) 1BCB:04E8 OUT 278, 85 (BYTE) 1BCB:04F8 OUT 278, A5 (BYTE) 1BCB:04E8 OUT 278, 85 (BYTE) 1BCB:04F8 OUT 278, A5 (BYTE) 1BCB:0498 OUT 278, 85 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0537 OUT 278, 85 (BYTE) 1BCB:0543 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0537 OUT 278, 85 (BYTE) 1BCB:0543 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0537 OUT 278, 85 (BYTE) 1BCB:0543 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0537 OUT 278, 85 (BYTE) 1BCB:0543 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0537 OUT 278, 85 (BYTE) 1BCB:0543 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0537 OUT 278, 85 (BYTE) 1BCB:0543 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0537 OUT 278, 85 (BYTE) 1BCB:0543 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0537 OUT 278, 85 (BYTE) 1BCB:0543 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0537 OUT 278, 85 (BYTE) 1BCB:0543 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0537 OUT 278, 85 (BYTE) 1BCB:0543 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0537 OUT 278, 85 (BYTE) 1BCB:0543 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0537 OUT 278, 85 (BYTE) 1BCB:0543 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0537 OUT 278, 85 (BYTE) 1BCB:0543 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0537 OUT 278, 85 (BYTE) 1BCB:0543 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0537 OUT 278, 85 (BYTE) 1BCB:0543 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0537 OUT 278, 85 (BYTE) 1BCB:0543 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0398 OUT 278, 85 (BYTE) 1BCB:03AA OUT 27A, 04 (BYTE) 1BCB:03B8 OUT 278, C5 (BYTE) 1BCB:03C4 OUT 278, 85 (BYTE) 1BCB:03D6 OUT 27A, 0C (BYTE) 1BCB:03EE OUT 278, C5 (BYTE) 1BCB:03FA OUT 278, 85 (BYTE) 1BCB:04E8 OUT 278, 95 (BYTE) 1BCB:04F8 OUT 278, B5 (BYTE) 1BCB:04E8 OUT 278, 95 (BYTE) 1BCB:04F8 OUT 278, B5 (BYTE) 1BCB:04E8 OUT 278, 85 (BYTE) 1BCB:04F8 OUT 278, A5 (BYTE) 1BCB:04E8 OUT 278, 85 (BYTE) 1BCB:04F8 OUT 278, A5 (BYTE) 1BCB:04E8 OUT 278, 85 (BYTE) 1BCB:04F8 OUT 278, A5 (BYTE) 1BCB:04E8 OUT 278, 85 (BYTE) 1BCB:04F8 OUT 278, A5 (BYTE) 1BCB:04E8 OUT 278, 85 (BYTE) 1BCB:04F8 OUT 278, A5 (BYTE) 1BCB:04E8 OUT 278, 85 (BYTE) 1BCB:04F8 OUT 278, A5 (BYTE) 1BCB:04E8 OUT 278, 85 (BYTE) 1BCB:04F8 OUT 278, A5 (BYTE) 1BCB:0498 OUT 278, 85 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0537 OUT 278, 85 (BYTE) 1BCB:0543 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0537 OUT 278, 85 (BYTE) 1BCB:0543 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0537 OUT 278, 85 (BYTE) 1BCB:0543 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0537 OUT 278, 85 (BYTE) 1BCB:0543 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0537 OUT 278, 85 (BYTE) 1BCB:0543 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0537 OUT 278, 85 (BYTE) 1BCB:0543 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0537 OUT 278, 85 (BYTE) 1BCB:0543 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0537 OUT 278, 85 (BYTE) 1BCB:0543 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0537 OUT 278, 85 (BYTE) 1BCB:0543 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0537 OUT 278, 85 (BYTE) 1BCB:0543 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0537 OUT 278, 85 (BYTE) 1BCB:0543 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0537 OUT 278, 85 (BYTE) 1BCB:0543 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0537 OUT 278, 85 (BYTE) 1BCB:0543 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0537 OUT 278, 85 (BYTE) 1BCB:0543 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0537 OUT 278, 85 (BYTE) 1BCB:0543 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:0515 OUT 278, A5 (BYTE) 1BCB:0521 OUT 278, 95 (BYTE) 1BCB:0537 OUT 278, 85 (BYTE) 1BCB:0543 OUT 278, 95 (BYTE) 1BCB:0561 IN 279, 96 (BYTE) 1BCB:07CD OUT 278, 00 (BYTE)¡Que lo parió! Si hacemos lo mismo con los otros archivos observaremos cosas similarmente asquerosas. ¡Pero no os desesperéis! ¡Pensad! ¡Pensad un cachito!
--------------------BEGIN IOINS.C-------------------------------------- /* ** IOINS.C - (c) 1998 - Maruja ** Muestra (en forma entendible) los datos capturados en operaciones IN ** ** Modo de uso: IOINS file ** Donde file es el nombre del archivo con los datos */ #include <>stdio.h> #include <>stdlib.h> /* Teseteo de Flags */ #define TEST_OUT(flag) (flag & 32768) /* bit 15 = OUT */ #define TEST_WORD(flag) (flag & 16384) /* bit 14 = WORD */ #define GET_PORT(flag) (flag & 2047) /* Estructura basica */ typedef struct { unsigned int cs, ip, flags, data; } TRAP; int main (int can, char *arg[]) { FILE *f; TRAP i; /* Verificar que se encuentre el nombre del file */ if (can < 2) { fprintf (stderr, "%s: Falta el nombre del archivo con los datos capturados\n\r", arg[0]); exit (-1); } /* Abrir archivo de datos */ if (! (f = fopen (arg[1], "rb")) ) { fprintf (stderr, "%s: ", arg[0]); perror (arg[1]); exit (-1); } /* Mostrar informacion */ printf ("\nArchivo: '%s'", arg[1]); for (;;) { /* Leer estructura */ if (!fread (&i, sizeof (TRAP), 1, f)) break; /* Mostrar en forma humana */ if (!TEST_OUT(i.flags)) { printf ("\n%04X:%04X\tIN\t%03X, ", i.cs, i.ip, GET_PORT(i.flags)); if (TEST_WORD(i.flags)) printf ("%04X\t(WORD)", i.data); else printf ("%02X \t(BYTE)", i.data & 255); } } printf ("\n"); return 0; } --------------------END IOINS.C----------------------------------------Hagamos lo siguiente:
C:\>CC IOINS.C .. C:\>IOINS 1.DAT > IN1.ASC C:\>IOINS 2.DAT > IN2.ASC C:\>IOINS 3.DAT > IN3.ASC C:\>IOINS 4.DAT > IN4.ASC C:\>IOINS 5.DAT > IN5.ASC C:\>DIR C:\IN*.ASC Volumen en unidad C es PINDONGA Número de serie de volumen es 2D4B-1CD6 Directorio de C:\ IN1 ASC 13784 15/09/98 0:15 IN2 ASC 13784 15/09/98 0:16 IN3 ASC 13784 15/09/98 0:16 IN4 ASC 13784 15/09/98 0:17 IN5 ASC 13784 15/09/98 0:17 5 archivo(s) 68920 bytes 757334016 bytes libres C:\>[ Jejejejeje... La cantidad de INs es siempre la misma. Veamos si los datos tambien son los mismos... ]
C:\>FC IN1.ASC IN2.ASC Comparando archivos IN1.ASC y IN2.ASC ***** IN1.ASC Archivo: '1.DAT' 1BCB:0854 IN 278, 00 (BYTE) ***** IN2.ASC Archivo: '2.DAT' 1BCB:0854 IN 278, 00 (BYTE) ***** C:\>FC IN1.ASC IN3.ASC Comparando archivos IN1.ASC y IN3.ASC ***** IN1.ASC Archivo: '1.DAT' 1BCB:0854 IN 278, 00 (BYTE) ***** IN3.ASC Archivo: '3.DAT' 1BCB:0854 IN 278, 00 (BYTE) ***** C:\>FC IN1.ASC IN4.ASC Comparando archivos IN1.ASC y IN4.ASC ***** IN1.ASC Archivo: '1.DAT' 1BCB:0854 IN 278, 00 (BYTE) ***** IN4.ASC Archivo: '4.DAT' 1BCB:0854 IN 278, 00 (BYTE) ***** C:\>FC IN1.ASC IN5.ASC Comparando archivos IN1.ASC y IN5.ASC ***** IN1.ASC Archivo: '1.DAT' 1BCB:0854 IN 278, 00 (BYTE) ***** IN5.ASC Archivo: '5.DAT' 1BCB:0854 IN 278, 00 (BYTE) ***** C:\>Jurujujája... Sabemos que los 5 archivos tienen los mismos datos leídos y que las operaciones son de a bytes (osea: 'IN AL,DX' y 'OUT DX,AL'). Para poner los datos de la llave en un programa emulador necesitamos un conversor .DAT a .ASM, el programa DBIN.C se encarga de esto:
--------------------BEGIN DBIN.C--------------------------------------- /* ** DBIN.C - (c) 1998 - Maruja ** Muestra (en forma de codigo para ensamblador) los datos ** capturados en operaciones IN en orden de aparicion ** ** Modo de uso: DBIN file ** Donde file es el nombre del archivo con los datos ** ** IMPORTANTE: LOS DATOS DEBEN SER TODOS BYTES!! (IN AL, XX) */ #include <>stdio.h> #include <>stdlib.h> /* Bytes por linea */ #define COLUMNAS 10 /* Teseteo de Flags */ #define TEST_OUT(flag) (flag & 32768) /* bit 15 = OUT */ #define TEST_WORD(flag) (flag & 16384) /* bit 14 = WORD */ #define GET_PORT(flag) (flag & 2047) /* Estructura basica */ typedef struct { unsigned int cs, ip, flags, data; } TRAP; int main (int can, char *arg[]) { FILE *f; TRAP i; int cols, datos; /* Verificar que se encuentre el nombre del file */ if (can < 2) { fprintf (stderr, "%s: Falta el nombre del archivo con los datos capturados\n\r", arg[0]); exit (-1); } /* Abrir archivo de datos */ if (! (f = fopen (arg[1], "rb")) ) { fprintf (stderr, "%s: ", arg[0]); perror (arg[1]); exit (-1); } /* Mostrar informacion */ datos = 0; cols = 0; for (;;) { /* Leer estructura */ if (!fread (&i, sizeof (TRAP), 1, f)) break; /* Solamente si es IN */ if (!TEST_OUT(i.flags) ) { /* Contador de cantidad de INs */ datos++; /* Iniciar linea */ if (!cols) printf ("\n\t\tdb\t"); /* Mostrar en decimal */ printf ("%03u", i.data & 255); if (++cols == COLUMNAS) cols = 0; else printf (", "); } } /* Mostrar cantidad de datos */ printf ("\n\nKEYBUF\t\tEQU\t%u\n", datos); return 0; } --------------------END DBIN.C-----------------------------------------Ojo: Este programa asume que los INs son de la forma 'IN AL,DX'. Si el lector está experimentando con otra implementación del programa de protección debe hacer los cambios pertinentes.
C:\>CC DBIN.C .. C:\>DBIN 1.DAT > 1.ASM C:\>DBIN 2.DAT > 2.ASM C:\>DBIN 3.DAT > 3.ASM C:\>DBIN 4.DAT > 4.ASM C:\>DBIN 5.DAT > 5.ASM C:\>DIR C:\?.ASM Volumen en unidad C es PINDONGA Número de serie de volumen es 2D4B-1CD6 Directorio de C:\ 1 ASM 2468 16/09/98 22:14 2 ASM 2468 16/09/98 22:14 3 ASM 2468 16/09/98 22:14 4 ASM 2468 16/09/98 22:14 5 ASM 2468 16/09/98 22:14 5 archivo(s) 12340 bytes 756776960 bytes libres C:\>FC 1.ASM 2.ASM Comparando archivos 1.ASM y 2.ASM FC: no se encontraron diferencias C:\>FC 1.ASM 3.ASM Comparando archivos 1.ASM y 3.ASM FC: no se encontraron diferencias C:\>FC 1.ASM 4.ASM Comparando archivos 1.ASM y 4.ASM FC: no se encontraron diferencias C:\>FC 1.ASM 5.ASM Comparando archivos 1.ASM y 5.ASM FC: no se encontraron diferencias C:\>TYPE 1.ASM db 000, 085, 170, 000, 204, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 000, 000, 204, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 134, 134, 150, 134, 134, 150 db 134, 150, 134, 134, 134, 150, 150, 134, 134, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 134 db 134, 134, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 134, 134, 134, 134, 134, 134 db 134, 134, 150, 150, 150, 134, 150, 134, 134, 150 db 150, 150, 150, 134, 134, 150, 134, 134, 150, 134 db 150, 134, 134, 134, 150, 150, 133, 204, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 149, 204, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, KEYBUF EQU 444 C:\>Sabiendo que:
--------------------BEGIN KEYEMU1.ASM----------------------------------- ; ;KEYEMU1.ASM - (c) 1998 - Maruja ; ;Programa residente de prueba que emula la llave de harware ;marca 'SOStuare Look' que protege a un programa berreta de facturacion ; ;Confunde al programa de proteccion pero no al programa protegido ; .model tiny .code org 100h inicio: jmp Arranque ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; IN_BYTE EQU 0ECh ;IN AL, DX IPanterior dw 0 ;CS:IP Instruccion anterior CSanterior dw 0 lpt11 dw ? ;Direccion base (1er registro) de LPT1 lpt13 dw ? ;Direccion 3er registro de LPT1 KEYBUF EQU 444 keyindex dw 0 keydata db 000, 085, 170, 000, 204, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 000, 000, 204, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 134, 134, 150, 134, 134, 150 db 134, 150, 134, 134, 134, 150, 150, 134, 134, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 134 db 134, 134, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 134, 134, 134, 134, 134, 134 db 134, 134, 150, 150, 150, 134, 150, 134, 134, 150 db 150, 150, 150, 134, 134, 150, 134, 134, 150, 134 db 150, 134, 134, 134, 150, 150, 133, 204, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 149, 204, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; SetTrap: push ax push bp mov bp, sp mov ax, [bp+8] ;Obtener flags de la pila or ah, 1 ;Activar bit T mov [bp+8], ax ;Colocar nuevos flags en la pila push dx push ds push cs pop ds mov ax, 2501h ;Setear nuestro vector de int TRAP lea dx, Trap int 21h pop ds pop dx pop bp pop ax ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; INSTRUCCION ORIGINAL EN EL ARCHIVO DE PROTECCION ; QUE FUE CAMBIADA POR EL 'INT 90h' (CD 90) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ADD DI, AX ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; iret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; UnTrap: push ax push bp mov bp, sp mov ax, [bp+8] ;Obtener flags de la pila and ah, 0FEh ;Desactivar bit T mov [bp+8], ax ;Colocar nuevos flags en la pila mov cs:keyindex, 0 ;Resetear posicion en buffer de llave pop bp pop ax iret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Trap: SP_INICIAL EQU $ push cx ;Salvar registros utilizados push si push ds push bp SP_FINAL EQU $ cmp cs:CSanterior, 0 ;CSanterior tiene un valor incorrecto ? jz Trap_salir ;Si: salir mov si, cs:CSanterior mov ds, si mov si, cs:IPanterior ;DS:SI = CS:IP instruccion anterior mov cl, byte ptr [si] ;Obtener opcode cmp cl, IN_BYTE ;El opcode es IN_BYTE ? jne Trap_salir ;No: salir push cs pop ds cmp dx, lpt11 ;Acceso a alguno de los puertos LPT1 ? jb Trap_salir cmp dx, lpt13 ja Trap_salir ;No: salir call EmularKey ;Si: emular llave Trap_salir: mov bp, sp ;Guardar CS:IP de proxima instruccion mov si, [bp + (SP_FINAL-SP_INICIAL)*2 + 2 ] mov cs:CSanterior, si mov si, [bp + (SP_FINAL-SP_INICIAL)*2 ] mov cs:IPanterior, si pop bp ;Recuperar registros y salir pop ds pop si pop cx iret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; EmularKey: ;En AL pone el mismo dato que pondria la llave lea si, keydata ;Posicionarse en el buffer add si, keyindex mov al, byte ptr [si] ;Obtener dato de la llave ;) inc keyindex cmp keyindex, KEYBUF ;Ya llego al ultimo dato ? jne EK_salir mov keyindex, 0 ;Si: resetear posicion en el buffer EK_salir: ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; FINRESID EQU $ ;Aca termina el residente ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; SetearVectores: mov ax, 2590h ;Hacer que una INT 90h ejecute el lea dx, SetTrap ;codigo 'SetTrap' int 21h mov ax, 2591h ;Hacer que una INT 91h ejecute el lea dx, UnTrap ;codigo 'UnTrap' int 21h ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; GetLPT1: push es ;Obtener registros de LPT1 mov di, 40h mov es, di mov di, 8 ;ES:DI = 0040:0008h mov ax, word ptr es:[di] mov lpt11, ax ;lpt11 = Registro 1 LPT1 add ax, 2 mov lpt13, ax ;lpt13 = Registro 3 LPT1 pop es ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; mok db 13, 10, 'OK', 13, 10, '$' myaestoy db 13, 10, 'Ya estaba residente', 13, 10, '$' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Arranque: push ds ;El offset del vector de xor si, si ;interrupcion 90h es igual mov ds, si ;al offset de la SetTrap ? mov si, 240h mov ax, word ptr [si] pop ds cmp ax, offset SetTrap jne A_instalar ;No: instalar residente lea dx, myaestoy ;Como el residente ya estaba mov ah, 9 ;instalado mostrar mensaje int 21h ;y salir mov ax, 4C00h int 21h A_instalar: call GetLPT1 ;Obtener direcciones de LPT1 call SetearVectores ;Setear nuevos vectores de ints lea dx, mok ;Mostrar mensaje 'OK' mov ah, 9 int 21h mov ax, 3100h ;Terminar y quedar residente lea dx, FINRESID shr dx, 4 inc dx int 21h end inicio ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; --------------------END KEYEMU1.ASM-------------------------------------Descripción de las variables:
EJECUCION NORMAL
EJECUCION UTILIZANDO KEYEMU1
C:\>TASM KEYEMU1.ASM ... C:\>TLINK /t KEYEMU1 ... C:\>REN PROTECT.EXE MODIFIC.EXE C:\>COPY ORIGINAL.EXE PROTECT.EXE C:\>GESTION.EXE * El módulo 'SOStuare Look' con número de serie: 00-00000 no está instalado. C:\>DEL PROTECT.EXE C:\>COPY MODIFIC.EXE PROTECT.EXE C:\>KEYEMU1 OK C:\>GESTION.EXE ... ... ... ... ... ... ... +---------------------------------------------------------------+ | El módulo SOStuare Look ha sido retirado | | Oprima cualquier tecla para reiniciar el sistema | +---------------------------------------------------------------+Se ha engañado totalmente al archivo de protección pero el programa protegido dijo: '¡No contaban con mi astucia!'.
C:\>DEL PROTECT.EXE C:\>COPY ORIGINAL.EXE PROTECT.EXE C:\>LDR GESTION.EXE Loading C:\GESTION.EXE ... ... :bpint 21 ah=4c :x Break Point at 1AE3:01A3 1AE3:018F E85500 CALL 01E7 1AE3:0192 A16401 MOV AX, [0164] 1AE3:0195 E83500 CALL 01CD 1AE3:0198 BB1502 MOV BX, 0215 1AE3:019B E80700 CALL 01A5 1AE3:019E A16201 MOV AX, [0162] 1AE3:01A1 B44C MOV AH, 4C > 1AE3:01A3 CD21 INT 21 ;Terminate process ...[ El programa de protección termina y le devuelve el control al programa protegido ]
:t > 0123:109E 90 NOP 0123:109F 90 NOP 0123:10A0 E8CC00 CALL 116F ...[ Inicio del código de la interrupción tipo 21h ]
:p ret > FDC9:423C CF IRET ...[ Punto final de la función 4Ch del DOS ]
:t > 0E0B:05D6 7303 JAE 05BD ...[ Inicio del código del programa de facturación ya desencriptado ]
:bpio 278 :bpio 279 :bpio 27a :x Break Point at 0E0B:0AF9 0E0B:0AF8 EC IN AL, DX > 0E0B:0AF9 EB01 JMP 0AFC ...[ Código que accede al puerto paralelo ]
:p ret > 0E0B:12D9 C3 RET ...[ Termina la ejecución del código que accede a la llave ]
:t 0E0B:1300 2E8C0E0105 MOV CS:[0501], CS 0E0B:1307 E8CEF7 CALL 0ADD > 0E0B:130F 2E803EFE0401 CMP BYTE PTR CS:[04FE], 01 ;CS:[04FE]=01 0E0B:1315 7502 JNZ 1319 0E0B:1317 EB0B JMP 1324 0E0B:1319 E8C1F7 CALL 0ADD ...[ 0E0B:0ADD es la dirección de la rutina que accede a la llave directamente, pero esta sección de código genera dos accesos, por lo tanto, asumimos que es parte de un sistema de verificación de los datos de ésta, veamos como termina... ]
:p ret :t 0E0B:0892 2EFF1EDD03 CALL FAR CS:[03DD] > 0E0B:0897 2E803ED50300 CMP BYTE PTR CS:[03D5], 00 ;CS:[03D5]=00 0E0B:089D 7409 JZ 08A8 0E0B:089F 2EC706D8031200 MOV WORD PTR CS:[03D8], 0012 0E0B:08A6 EB07 JMP 08AF 0E0B:08A8 2EC706D8038F00 MOV WORD PTR CS:[03D8], 008F 0E0B:08AF 2EC606D40300 MOV BYTE PTR CS:[03D4], 00 0E0B:08B5 2E833EF80300 CMP WORD PTR CS:[03D8], 00 0E0B:08BB 7405 JZ 08C2 0E0B:08BD 2EFF0ED803 DEC WORD PTR CS:[03D8] 0E0B:08C2 CF IRET[ Era de esperar: el sistema que accede a la llave está dentro de una interrupción -la última instrucción es un IRET-, veamos cuál es... ]
:p ret :t 3799:00F0 55 PUSH BP 3799:00F1 CD16 INT 16 > 3799:00F3 5D POP BP[ ¡Já! En vez de utilizar la obvia interrupción Timer Tick usa la 16h del BIOS que se encarga de casi todo lo que tiene que ver con el teclado.
:a e0b:892 0E0B:0892 iret 0E0B:0893[ Ahora limpiamos todos los breakpoints, sacamos la llave, y dejamos correr al programa como si nada... ]
:bc * :x ... ... ... ... ... C:\>Hemos solucionado el problema: el programa protegido ya no accede a la llave. Tenemos que hacer algo para que el IRET se ponga en forma automática. No podemos modificar al programa de facturación porque está encriptado, por lo tanto, tendremos que provocar otro desvío en el archivo de protección en algún lugar después de la desencripción. El mejor lugar para esto es el momento en que dicho programa termina su ejecución. Recordando esa parte del código:
1AE3:018F E85500 CALL 01E7 1AE3:0192 A16401 MOV AX, [0164] 1AE3:0195 E83500 CALL 01CD 1AE3:0198 BB1502 MOV BX, 0215 1AE3:019B E80700 CALL 01A5 1AE3:019E A16201 MOV AX, [0162] 1AE3:01A1 B44C MOV AH, 4C 1AE3:01A3 CD21 INT 21Con la gran ayuda del 'disquetitor':
C:\>DISQUETITOR MODIFIC.EXE /WBuscamos la secuencia:
E8 55 00 A1 64 01 E8 35 00 BB 15 02 E8 07 00 A1 62 01 B4 4C CD 21y reemplazamos el 'B4 4C' con un 'CD 92' quedando:
E8 55 00 A1 64 01 E8 35 00 BB 15 02 E8 07 00 A1 62 01 CD 92 CD 21luego se graban los cambios y, después de modificar al programa de emulación anterior, obtenemos a KEYEMU.ASM:
--------------------BEGIN KEYEMU.ASM------------------------------------ ; ;KEYEMU.ASM - (c) 1998 - Maruja ; ;Programa residente que emula a la perfeccion a la llave de hardware ;marca 'SOStuare Look' que protege a un programa berreta de facturacion ; .model tiny .code org 100h inicio: jmp Arranque ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; IN_BYTE EQU 0ECh ;IN AL, DX IPanterior dw 0 ;CS:IP Instruccion anterior CSanterior dw 0 lpt11 dw ? ;Direccion base (1er registro) de LPT1 lpt13 dw ? ;Direccion 3er registro de LPT1 IRET_CODE EQU 0CFh ;Opcode de 'IRET' OFF_PROTEGIDO EQU 0892h ;Offset del programa protegido en el ;que se anula el llamado a la rutina ;de la llave KEYBUF EQU 444 keyindex dw 0 keydata db 000, 085, 170, 000, 204, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 000, 000, 204, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 134, 134, 150, 134, 134, 150 db 134, 150, 134, 134, 134, 150, 150, 134, 134, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 134 db 134, 134, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 134, 134, 134, 134, 134, 134 db 134, 134, 150, 150, 150, 134, 150, 134, 134, 150 db 150, 150, 150, 134, 134, 150, 134, 134, 150, 134 db 150, 134, 134, 134, 150, 150, 133, 204, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 149, 204, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 db 150, 150, 150, 150 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; SetTrap: push ax push bp mov bp, sp mov ax, [bp+8] ;Obtener flags de la pila or ah, 1 ;Activar bit T mov [bp+8], ax ;Colocar nuevos flags en la pila push dx push ds push cs pop ds mov ax, 2501h ;Setear nuestro vector de int TRAP lea dx, Trap int 21h pop ds pop dx pop bp pop ax ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; INSTRUCCION ORIGINAL EN EL ARCHIVO DE PROTECCION ; QUE FUE CAMBIADA POR EL 'INT 90h' (CD 90) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ADD DI, AX ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; iret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Trap: SP_INICIAL EQU $ push cx ;Salvar registros utilizados push si push ds push bp SP_FINAL EQU $ cmp cs:CSanterior, 0 ;CSanterior tiene un valor incorrecto ? jz Trap_salir ;Si: salir mov si, cs:CSanterior mov ds, si mov si, cs:IPanterior ;DS:SI = CS:IP instruccion anterior mov cl, byte ptr [si] ;Obtener opcode cmp cl, IN_BYTE ;El opcode es IN_BYTE ? jne Trap_salir ;No: salir push cs pop ds cmp dx, lpt11 ;Acceso a alguno de los puertos LPT1 ? jb Trap_salir cmp dx, lpt13 ja Trap_salir ;No: salir call EmularKey ;Si: emular llave Trap_salir: mov bp, sp ;Guardar CS:IP de proxima instruccion mov si, [bp + (SP_FINAL-SP_INICIAL)*2 + 2 ] mov cs:CSanterior, si mov si, [bp + (SP_FINAL-SP_INICIAL)*2 ] mov cs:IPanterior, si pop bp ;Recuperar registros y salir pop ds pop si pop cx iret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; EmularKey: ;En AL pone el mismo dato que pondria la llave lea si, keydata ;Posicionarse en el buffer add si, keyindex mov al, byte ptr [si] ;Obtener dato de la llave ;) inc keyindex cmp keyindex, KEYBUF ;Ya llego al ultimo dato ? jne EK_salir mov keyindex, 0 ;Si: resetear posicion en el buffer EK_salir: ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; SetJMP: push si push ds push bx push ax mov ah, 51h ;Obtener direccion del PSP int 21h mov ds, bx mov si, 0Ch ;El offset 0Ch del PSP contiene el ;segmento del codigo al que se debe ;volver cuando termine el programa de ;proteccion mov bx, word ptr [si] ;Cancelar llamada a la rutina de mov ds, bx ;lectura de la llave mov si, OFF_PROTEGIDO mov byte ptr [si], IRET_CODE pop ax pop bx pop ds pop si ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; INSTRUCCION ORIGINAL EN EL ARCHIVO DE PROTECCION ; QUE FUE CAMBIADA POR EL 'INT 92h' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; MOV AH, 4Ch ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; iret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; FINRESID EQU $ ;Aca termina el residente ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; SetearVectores: mov ax, 2590h ;Hacer que una INT 90h ejecute el lea dx, SetTrap ;codigo 'SetTrap' int 21h mov ax, 2592h ;Hacer que una INT 92h ejecute el lea dx, SetJMP ;codigo 'SetJMP' int 21h ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; GetLPT1: push es ;Obtener registros de LPT1 mov di, 40h mov es, di mov di, 8 ;ES:DI = 0040:0008h mov ax, word ptr es:[di] mov lpt11, ax ;lpt11 = Registro 1 LPT1 add ax, 2 mov lpt13, ax ;lpt13 = Registro 3 LPT1 pop es ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; mok db 13, 10, 'OK', 13, 10, '$' myaestoy db 13, 10, 'Ya estaba residente', 13, 10, '$' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Arranque: push ds ;El offset del vector de xor si, si ;interrupcion 90h es igual mov ds, si ;al offset de la SetTrap ? mov si, 240h mov ax, word ptr [si] pop ds cmp ax, offset SetTrap jne A_instalar ;No: instalar residente lea dx, myaestoy ;Como el residente ya estaba mov ah, 9 ;instalado mostrar mensaje int 21h ;y salir mov ax, 4C00h int 21h A_instalar: call GetLPT1 ;Obtener direcciones de LPT1 call SetearVectores ;Setear nuevos vectores de ints lea dx, mok ;Mostrar mensaje 'OK' mov ah, 9 int 21h mov ax, 3100h ;Terminar y quedar residente lea dx, FINRESID shr dx, 4 inc dx int 21h end inicio ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; --------------------END KEYEMU.ASM--------------------------------------Explicación de las variables:
C:\>DEL PROTECT.EXE C:\>REN MODIFIC.EXE PROTECT.EXE C:\>TASM KEYEMU.ASM ... C:\>TLINK /t KEYEMU ... C:\>KEYEMU OK C:\>GESTION ... ... ... ... ... ... ... ... C:\>El programa funciona sín llave de hardware.
Sín otro particular, saludo a Uds. en forma muy atte.
Maruja
**************END OF TRANSMISSION***************