示例#1
0
文件: init.c 项目: jarn0x/Escape
void load_init(int argc,char **argv) {
    uintptr_t addr;
    if(lookup_byName(NULL,"__libc_preinit",&addr)) {
        fPreinit preinit = (fPreinit)addr;
        preinit(0,argc,argv);
    }

    for(sSharedLib *l = libs; l != NULL; l = l->next)
        load_initLib(l);
}
示例#2
0
文件: lookup.c 项目: Nils-TUD/Escape
A_REGPARM(0) uintptr_t lookup_resolve(A_UNUSED SavedRegs regs,sSharedLib *lib,size_t off) {
#endif
	sElfSym *foundSym;
	ulong info,offset;
	if(lib->jmprelType == DT_REL) {
		sElfRel *rel = (sElfRel*)((uintptr_t)lib->jmprel + off);
		info = rel->r_info;
		offset = rel->r_offset;
	}
	else {
		// TODO it's only the index on x86_64?
		sElfRela *rel = (sElfRela*)lib->jmprel + off;
		info = rel->r_info;
		offset = rel->r_offset;
	}

	sElfSym *sym = lib->dynsyms + ELF_R_SYM(info);
	uintptr_t value = 0,*addr;
	foundSym = lookup_byName(NULL,lib->dynstrtbl + sym->st_name,&value);
	if(foundSym == NULL)
		error("Unable to find symbol %s",lib->dynstrtbl + sym->st_name);
	addr = (uintptr_t*)(offset + lib->loadAddr);

#if defined(CALLTRACE_PID)
	pid = getpid();
	if(pid == CALLTRACE_PID) {
		if(depth < 100) {
			sSharedLib *calling = libs;
			for(sSharedLib *l = libs; l != NULL; l = l->next) {
				if(retAddr >= l->loadAddr && retAddr < l->loadAddr + l->textSize) {
					calling = l;
					break;
				}
			}
			debugf("%*s\\ %x(%s) -> %s (%x)\n",depth,"",retAddr - calling->loadAddr,
					calling->name,lib->dynstrtbl + sym->st_name,value);
			depth++;
		}
	}
	else
		*addr = value;
#else
	DBGDL("Found: %s @ %p (off: %p) in %s (GOT: 0x%x)\n",
		lib->dynstrtbl + sym->st_name,value,value - lib->loadAddr,lib->name,off);
	*addr = value;
#endif

	return value;
}
示例#3
0
文件: setup.c 项目: Logout22/Escape
uintptr_t load_setupProg(int binFd,A_UNUSED uintptr_t a,A_UNUSED uintptr_t b,A_UNUSED size_t c,
	int argc,char **argv) {
#else
uintptr_t load_setupProg(int binFd,int argc,char **argv) {
#endif
	sSharedLib *prog;
	uintptr_t entryPoint;

	/* create entry for program */
	prog = (sSharedLib*)malloc(sizeof(sSharedLib));
	if(!prog)
		load_error("Not enough mem!");
	prog->isDSO = false;
	prog->relocated = false;
	prog->initialized = false;
	prog->dynstrtbl = NULL;
	prog->dyn = NULL;
	prog->name = "-Main-";
	prog->deps = NULL;
	appendto(&libs,prog);

	/* load program including shared libraries into linked list */
	load_doLoad(binFd,prog);

	/* load segments into memory */
	entryPoint = load_addSegments();

#if PRINT_LOADADDR
	for(sSharedLib *l = libs; l != NULL; l = l->next) {
		uintptr_t addr;
		lookup_byName(NULL,"_start",&addr);
		debugf("[%d] Loaded %s @ %p .. %p (text @ %p) with deps: ",
				getpid(),l->name,l->loadAddr,l->loadAddr + l->textSize,addr);
		for(sDep *dl = l->deps; dl != NULL; dl = dl->next)
			debugf("%s ",dl->lib->name);
		debugf("\n");
	}
#endif

	/* relocate everything we need so that the program can start */
	load_reloc();

	/* call global constructors */
	load_init(argc,argv);

	return entryPoint;
}
示例#4
0
文件: reloc.c 项目: Logout22/Escape
static void load_relocDyn(sSharedLib *l,void *entries,size_t size,uint type) {
	sElfRel *rel = (sElfRel*)((uintptr_t)entries + l->loadAddr);
	sElfRela *rela = (sElfRela*)((uintptr_t)entries + l->loadAddr);
	size_t count = type == DT_REL ? size / sizeof(sElfRel) : size / sizeof(sElfRela);
	for(size_t x = 0; x < count; x++) {
		ulong info,offset,addend;
		if(type == DT_REL) {
			info = rel[x].r_info;
			offset = rel[x].r_offset;
			addend = 0;
		}
		else {
			info = rela[x].r_info;
			offset = rela[x].r_offset;
			addend = rela[x].r_addend;
		}

		int rtype = ELF_R_TYPE(info);
		if(rtype == R_NONE)
			continue;

		size_t symIndex = ELF_R_SYM(info);
		sElfSym *sym = l->dynsyms + symIndex;
		const char *symname = l->dynstrtbl + sym->st_name;
		uintptr_t value = sym->st_value;
		uintptr_t *ptr = (uintptr_t*)(offset + l->loadAddr);

		if(rtype == R_JUMP_SLOT) {
			value = *ptr;
			if(*ptr == 0 || LD_BIND_NOW) {
				if(!lookup_byName(l,symname,&value)) {
					if(!lookup_byName(NULL,symname,&value))
						load_error("Unable to find symbol '%s'\n",symname);
				}
				value -= l->loadAddr;
			}
		}
		/* if the symbol-value is 0, it seems that we have to lookup the symbol now and
		 * store that value instead. TODO I'm not sure if thats correct */
		else if(rtype != R_RELATIVE && (rtype == R_COPY || value == 0)) {
			if(!lookup_byName(l,symname,&value))
				load_error("Unable to find symbol '%s'\n",symname);
			// we'll add that again
			value -= l->loadAddr;
		}

		switch(rtype) {
			case R_COPY:
				memcpy((void*)offset,(void*)(value + l->loadAddr),sym->st_size);
				/* set the GOT-Entry in the library of the symbol to the address we've copied
				 * the value to. TODO I'm not sure if that's the intended way... */
				load_adjustCopyGotEntry(symname,offset);
				break;

			default:
				if(!perform_reloc(l,rtype,offset,ptr,value,addend)) {
					load_error("In library %s: Unknown relocation: off=%p info=%p type=%d addend=%x\n",
						l->name,offset,info,ELF_R_TYPE(info),addend);
				}
				break;
		}

		DBGDL("Rel (%s) off=%p reloc=%p value=%p symbol=%s\n",
		 	load_getRelName(rtype),offset,*ptr,value,symname);
	}
}