Ejemplo n.º 1
0
/* not secure */
void elf_loader(const char * file) {
	int filelen=0;
	char * addr = load(file, &filelen);
	if(!addr) {
		TRACE("Could not read file");
		kernel_freeze();
		return;
	}
	Elf64_Ehdr *hdr = (Elf64_Ehdr *)addr;
	if(!elf_check_supported(hdr)) {
		TRACE("ELF File cannot be loaded");
		kernel_freeze();
		return;
	}
	TRACE("e_entry:%lX e_phnum:%d e_shnum:%d", hdr->e_entry, hdr->e_phnum, hdr->e_shnum);
	size_t allocsize = 0;
	for(int i=0; i<hdr->e_phnum; i++) {
		Elf64_Phdr *seg = elf_segment(hdr, i);
		#if 0
		TRACE("SGMT: type:%X flags:%X offset:%lX vaddr:%lX filesz:%lX memsz:%lX align:%lX",
			seg->p_type, seg->p_flags, seg->p_offset, seg->p_vaddr,
			seg->p_filesz, seg->p_memsz, seg->p_align);
		#endif
		if(seg->p_type == 1) {
			allocsize = imax(allocsize, seg->p_vaddr + seg->p_memsz);
		}
	}
	char *prgmp = kernel_calloc(allocsize, 1); //TODO:align this correctly
	bzero(prgmp, allocsize);
	if(!prgmp) {
		TRACE("Malloc failed");
		kernel_freeze();
		return;
	}
	for(int i=0; i<hdr->e_phnum; i++) {
		Elf64_Phdr *seg = elf_segment(hdr, i);
		memcpy(prgmp+seg->p_vaddr, addr + seg->p_offset, seg->p_filesz);
	}
	size_t pid = kernel_exec((uintptr_t)(prgmp + hdr->e_entry), 0x465);
	tmp_exec_stuff(pid, (size_t)prgmp, hdr->e_entry, allocsize);	
}
Ejemplo n.º 2
0
cap_pair elf_loader_mem(Elf_Env *env, void *p, size_t *minaddr, size_t *maxaddr, size_t *entry) {
	char *addr = (char *)p;
	size_t lowaddr = (size_t)(-1);
	Elf64_Ehdr *hdr = (Elf64_Ehdr *)addr;
	if(!elf_check_supported(env, hdr)) {
		ERROR("ELF File cannot be loaded");
		return NULL_PAIR;
	}

	Elf64_Addr e_entry = hdr->e_entry;
	TRACE("e_entry:%lX e_phnum:%d e_shnum:%d", hdr->e_entry, hdr->e_phnum, hdr->e_shnum);

	size_t allocsize = 0;
	for(int i=0; i<hdr->e_phnum; i++) {
		Elf64_Phdr *seg = elf_segment(hdr, i);
		TRACE("SGMT: type:%X flags:%X offset:%lX vaddr:%lX filesz:%lX memsz:%lX align:%lX",
			  seg->p_type, seg->p_flags, seg->p_offset, seg->p_vaddr,
			  seg->p_filesz, seg->p_memsz, seg->p_align);
		if(seg->p_filesz > seg->p_memsz) {
			ERROR("Section is larger in file than in memory");
			return NULL_PAIR;
		}
		if(seg->p_type == PT_LOAD) {
			size_t bound = seg->p_vaddr + seg->p_memsz;
			allocsize = umax(allocsize, bound);
			lowaddr = umin(lowaddr, seg->p_vaddr);
			TRACE("lowaddr:%lx allocsize:%lx bound:%lx", lowaddr, allocsize, bound);
		} else if(seg->p_type == PT_GNUSTACK || seg->p_type == PT_PHDR || seg->p_type == PT_GNURELRO) {
            /* Ignore these headers */
		} else {
			ERROR("Unknown section");
			return NULL_PAIR;
		}
	}

	cap_pair pair = env->alloc(allocsize);
	char *prgmp = pair.data;
	if(!prgmp) {
		ERROR("alloc failed");
		return NULL_PAIR;
	}

	TRACE("Allocated %lx bytes of target memory", allocsize);
	ENV_PRINT_CAP(env, prgmp);

	for(int i=0; i<hdr->e_phnum; i++) {
		Elf64_Phdr *seg = elf_segment(hdr, i);
		if(seg->p_type == 1) {
			TRACE("memcpy: [%lx %lx] <-- [%lx %lx] (%lx bytes)",
				  seg->p_vaddr, seg->p_vaddr + seg->p_filesz,
				  seg->p_offset, seg->p_offset + seg->p_filesz,
				  seg->p_filesz);
			env->memcpy(prgmp+seg->p_vaddr, addr + seg->p_offset, seg->p_filesz);
		}
	}
	env->free(addr);

	if(minaddr)	*minaddr = lowaddr;
	if(maxaddr)	*maxaddr = allocsize;
	if(entry)	*entry   = e_entry;

	return pair;
}