Exemplo n.º 1
0
static void
entry_breakpoint_on_hit(struct breakpoint *a, struct process *proc)
{
	struct entry_breakpoint *bp = (void *)a;
	if (proc == NULL || proc->leader == NULL)
		return;
	arch_addr_t dyn_addr = bp->dyn_addr;
	delete_breakpoint(proc, bp->super.addr);
	linkmap_init(proc, dyn_addr);
	arch_dynlink_done(proc);
}
Exemplo n.º 2
0
static int entry_breakpoint_on_hit(struct task *task, struct breakpoint *a)
{
	struct entry_breakpoint *entry_bp = (void *)a;

	if (!task)
		return 0;

	breakpoint_delete(task, &entry_bp->breakpoint);
	linkmap_init(task, entry_bp->dyn_addr);
	return 1;
}
Exemplo n.º 3
0
int
main(int argc, char *argv[])
{
	printf("sysconfig v%s %s/%s %s " __TIME__ " " __DATE__  "\n", 
	       PACKAGE_VERSION, CONFIG_PLATFORM, CONFIG_SRCARCH, CONFIG_ARCH);

	info_cpu();
	info_sys();

	linkmap_init();


	linkmap_fini();

	return 0;
}
Exemplo n.º 4
0
struct library_symbol *
read_elf(Process *proc) {
	struct ltelf lte[MAX_LIBRARIES + 1];
	size_t i;
	struct opt_x_t *xptr;
	struct opt_x_t *opt_x_loc = opt_x;
	struct library_symbol **lib_tail = NULL;
	int exit_out = 0;
	int count = 0;

	debug(DEBUG_FUNCTION, "read_elf(file=%s)", proc->filename);

	memset(lte, 0, sizeof(lte));
	library_symbols = NULL;
	library_num = 0;
	proc->libdl_hooked = 0;

	if (do_init_elf(lte, proc->filename))
		return NULL;

	memcpy(&main_lte, lte, sizeof(struct ltelf));

	if (opt_p && opt_p->pid > 0) {
		linkmap_init(proc, lte);
		proc->libdl_hooked = 1;
	}

	proc->e_machine = lte->ehdr.e_machine;

	for (i = 0; i < library_num; ++i) {
		if (do_init_elf(&lte[i + 1], library[i]))
			error(EXIT_FAILURE, errno, "Can't open \"%s\"",
			      library[i]);
	}

	if (!options.no_plt) {
#ifdef __mips__
		// MIPS doesn't use the PLT and the GOT entries get changed
		// on startup.
		proc->need_to_reinitialize_breakpoints = 1;
		for(i=lte->mips_gotsym; i<lte->dynsym_count;i++){
			GElf_Sym sym;
			const char *name;
			GElf_Addr addr = arch_plt_sym_val(lte, i, 0);
			if (gelf_getsym(lte->dynsym, i, &sym) == NULL){
				error(EXIT_FAILURE, 0,
						"Couldn't get relocation from \"%s\"",
						proc->filename);
			}
			name=lte->dynstr+sym.st_name;
			if(ELF64_ST_TYPE(sym.st_info) != STT_FUNC){
				debug(2,"sym %s not a function",name);
				continue;
			}
			add_library_symbol(addr, name, &library_symbols, 0,
					ELF64_ST_BIND(sym.st_info) != 0);
			if (!lib_tail)
				lib_tail = &(library_symbols->next);
		}
#else
		for (i = 0; i < lte->relplt_count; ++i) {
			GElf_Rel rel;
			GElf_Rela rela;
			GElf_Sym sym;
			GElf_Addr addr;
			void *ret;
			const char *name;

			if (lte->relplt->d_type == ELF_T_REL) {
				ret = gelf_getrel(lte->relplt, i, &rel);
				rela.r_offset = rel.r_offset;
				rela.r_info = rel.r_info;
				rela.r_addend = 0;
			} else
				ret = gelf_getrela(lte->relplt, i, &rela);

			if (ret == NULL
					|| ELF64_R_SYM(rela.r_info) >= lte->dynsym_count
					|| gelf_getsym(lte->dynsym, ELF64_R_SYM(rela.r_info),
						&sym) == NULL)
				error(EXIT_FAILURE, 0,
						"Couldn't get relocation from \"%s\"",
						proc->filename);

#ifdef PLT_REINITALISATION_BP
			if (!sym.st_value && PLTs_initialized_by_here)
				proc->need_to_reinitialize_breakpoints = 1;
#endif

			name = lte->dynstr + sym.st_name;
			count = library_num ? library_num+1 : 0;

			if (in_load_libraries(name, lte, count, NULL)) {
				enum toplt pltt;
				if (sym.st_value == 0 && lte->plt_stub_vma != 0) {
					pltt = LS_TOPLT_EXEC;
					addr = lte->plt_stub_vma + PPC_PLT_STUB_SIZE * i;
				}
				else {
					pltt = PLTS_ARE_EXECUTABLE(lte)
						?  LS_TOPLT_EXEC : LS_TOPLT_POINT;
					addr = arch_plt_sym_val(lte, i, &rela);
				}

				add_library_symbol(addr, name, &library_symbols, pltt,
						ELF64_ST_BIND(sym.st_info) == STB_WEAK);
				if (!lib_tail)
					lib_tail = &(library_symbols->next);
			}
		}
#endif // !__mips__
#ifdef PLT_REINITALISATION_BP
		struct opt_x_t *main_cheat;

		if (proc->need_to_reinitialize_breakpoints) {
			/* Add "PLTs_initialized_by_here" to opt_x list, if not
				 already there. */
			main_cheat = (struct opt_x_t *)malloc(sizeof(struct opt_x_t));
			if (main_cheat == NULL)
				error(EXIT_FAILURE, 0, "Couldn't allocate memory");
			main_cheat->next = opt_x_loc;
			main_cheat->found = 0;
			main_cheat->name = PLTs_initialized_by_here;

			for (xptr = opt_x_loc; xptr; xptr = xptr->next)
				if (strcmp(xptr->name, PLTs_initialized_by_here) == 0
						&& main_cheat) {
					free(main_cheat);
					main_cheat = NULL;
					break;
				}
			if (main_cheat)
				opt_x_loc = main_cheat;
		}
#endif
	} else {
		lib_tail = &library_symbols;
	}

	for (i = 0; i < lte->symtab_count; ++i) {
		GElf_Sym sym;
		GElf_Addr addr;
		const char *name;

		if (gelf_getsym(lte->symtab, i, &sym) == NULL)
			error(EXIT_FAILURE, 0,
			      "Couldn't get symbol from \"%s\"",
			      proc->filename);

		name = lte->strtab + sym.st_name;
		addr = sym.st_value;
		if (!addr)
			continue;

		for (xptr = opt_x_loc; xptr; xptr = xptr->next)
			if (xptr->name && strcmp(xptr->name, name) == 0) {
				/* FIXME: Should be able to use &library_symbols as above.  But
				   when you do, none of the real library symbols cause breaks. */
				add_library_symbol(opd2addr(lte, addr),
						   name, lib_tail, LS_TOPLT_NONE, 0);
				xptr->found = 1;
				break;
			}
	}

	unsigned found_count = 0;

	for (xptr = opt_x_loc; xptr; xptr = xptr->next) {
		if (xptr->found)
			continue;

		GElf_Sym sym;
		GElf_Addr addr;
		if (in_load_libraries(xptr->name, lte, library_num+1, &sym)) {
			debug(2, "found symbol %s @ %#" PRIx64 ", adding it.",
					xptr->name, sym.st_value);
			addr = sym.st_value;
			if (ELF32_ST_TYPE (sym.st_info) == STT_FUNC) {
				add_library_symbol(addr, xptr->name, lib_tail, LS_TOPLT_NONE, 0);
				xptr->found = 1;
				found_count++;
			}
		}
		if (found_count == opt_x_cnt){
			debug(2, "done, found everything: %d\n", found_count);
			break;
		}
	}

	for (xptr = opt_x_loc; xptr; xptr = xptr->next)
		if ( ! xptr->found) {
			char *badthing = "WARNING";
#ifdef PLT_REINITALISATION_BP
			if (strcmp(xptr->name, PLTs_initialized_by_here) == 0) {
				if (lte->ehdr.e_entry) {
					add_library_symbol (
						opd2addr (lte, lte->ehdr.e_entry),
						PLTs_initialized_by_here,
						lib_tail, 1, 0);
					fprintf (stderr, "WARNING: Using e_ent"
						 "ry from elf header (%p) for "
						 "address of \"%s\"\n", (void*)
						 (long) lte->ehdr.e_entry,
						 PLTs_initialized_by_here);
					continue;
				}
				badthing = "ERROR";
				exit_out = 1;
			}
#endif
			fprintf (stderr,
				 "%s: Couldn't find symbol \"%s\" in file \"%s\" assuming it will be loaded by libdl!"
				 "\n", badthing, xptr->name, proc->filename);
		}
	if (exit_out) {
		exit (1);
	}

	for (i = 0; i < library_num + 1; ++i)
		do_close_elf(&lte[i]);

	return library_symbols;
}
Exemplo n.º 5
0
struct libref *elf_read_main_binary(struct task *task, int was_attached)
{
	char fname[PATH_MAX];
	int ret;
	char *filename;
	struct mt_elf mte = { };
	unsigned long entry;
	unsigned long base;
	struct libref *libref;

	filename = pid2name(task->pid);
	if (!filename)
		return NULL;

	libref = libref_new(LIBTYPE_MAIN);
	if (libref == NULL)
		goto fail1;

	ret = readlink(filename, fname, sizeof(fname) - 1);
	if (ret == -1)
		goto fail2;

	fname[ret] = 0;

	free(filename);

	libref_set_filename(libref, fname);

	if (elf_read(&mte, task, fname) == -1)
		goto fail3;

	task->is_64bit = is_64bit(&mte);

	if (process_get_entry(task, &entry, &base) < 0) {
		fprintf(stderr, "Couldn't find process entry of %s\n", filename);
		goto fail3;
	}

	mte.bias = entry - mte.ehdr.e_entry - mte.vstart;
	mte.entry_addr = entry;

	if (elf_lib_init(&mte, task, libref))
		goto fail3;

	close_elf(&mte);

	report_attach(task, was_attached);

	library_add(task, libref);

	if (!mte.interp)
		return libref;

	struct mt_elf mte_ld = { };

	if (copy_str_from_proc(task, ARCH_ADDR_T(mte.bias + mte.interp - mte.vstart), fname, sizeof(fname)) == -1) {
		fprintf(stderr, "fatal error: cannot get loader name for pid=%d\n", task->pid);
		abort();
	}

	if (!elf_read(&mte_ld, task, fname)) {
		struct libref *libref;

		libref = libref_new(LIBTYPE_LOADER);
		if (libref == NULL)
			goto fail4;

		libref_set_filename(libref, fname);

		mte_ld.bias = base;
		mte_ld.entry_addr = base + mte_ld.ehdr.e_entry  - mte.vstart;

		ret = elf_lib_init(&mte_ld, task, libref);
		if (!ret) {
			library_add(task, libref);

			if (linkmap_init(task, ARCH_ADDR_T(mte.bias + mte.dyn - mte.vstart))) {
				arch_addr_t addr = find_solib_break(&mte_ld);
				if (!addr)
					addr = ARCH_ADDR_T(entry);

				struct entry_breakpoint *entry_bp = (void *)breakpoint_new_ext(task, addr, NULL, 0, sizeof(*entry_bp) - sizeof(entry_bp->breakpoint));
				if (!entry_bp)
					fprintf(stderr,
						"Couldn't initialize entry breakpoint for PID %d.\n"
						"Tracing events may be missed.\n",
						task->pid
					);
				else {
					entry_bp->breakpoint.on_hit = entry_breakpoint_on_hit;
					entry_bp->breakpoint.locked = 1;
					entry_bp->dyn_addr = ARCH_ADDR_T(mte.bias + mte.dyn - mte.vstart);

					breakpoint_enable(task, &entry_bp->breakpoint);
				}
			}
		}
		else {
			fprintf(stderr,
				"Couldn't read dynamic loader `%s` for PID %d.\n"
				"Tracing events may be missed.\n",
				fname,
				task->pid
			);
		}
fail4:
		close_elf(&mte_ld);
	}
	else {
		fprintf(stderr,
			"Couldn't open dynamic loader `%s` for PID %d.\n"
			"Tracing events may be missed.\n",
			fname,
			task->pid
		);
	}

	return libref;
fail3:
	close_elf(&mte);
fail2:
	libref_delete(libref);
fail1:
	free(filename);
	return libref;
}