Пример #1
0
/* Find and execute hook. */
int tracy_execute_hook(struct tracy *t, char *syscall, struct tracy_event *e) {
    struct tracy_ll_item *item;
    int hash;
    union {
            void *pvoid;
            tracy_hook_func pfunc;
        } _hax;


    if (TRACY_PRINT_SYSCALLS(t))
        printf(_y("%04d System call: %s (%ld) Pre: %d")"\n",
                e->child->pid, get_syscall_name_abi(e->syscall_num, e->abi),
                e->syscall_num, e->child->pre_syscall);

    hash = hash_syscall(syscall, e->abi);

    item = ll_find(t->hooks, hash);

    if (item) {
        /* printf("Executing hook for: %s\n", syscall); */

        /* ANSI C has some disadvantages too ... */
        _hax.pvoid = item->data;
        return _hax.pfunc(e);
    }

    if (t->defhook)
        return t->defhook(e);

    return TRACY_HOOK_NOHOOK;
}
Пример #2
0
static int redirect_file_access(struct tracy_event *e, int argpos,
				bool resolve_symlinks)
{
	struct tracy_sc_args a;
	int rc = TRACY_HOOK_CONTINUE;
	char *path = NULL;
	tracy_child_addr_t devname_new = NULL;
	struct fstab_rec *fstabrec;
	long *argptr;
	struct multiboot_child_data *mbc = e->child->custom;

	// call hook_open
	if (e->syscall_num == get_syscall_number_abi("open", e->abi)
	    || e->syscall_num == get_syscall_number_abi("openat", e->abi)) {
		int rc_open = hook_open(e, argpos, resolve_symlinks);
		if (rc_open)
			return rc_open;
	}

	if (e->child->pre_syscall) {
		// get path
		argptr = &e->args.a0;
		path = get_patharg(e->child, argptr[argpos], resolve_symlinks);
		if (!path) {
			rc = TRACY_HOOK_ABORT;
			goto out;
		}
		// check if we need to redirect this file
		fstabrec = get_fstab_rec(path);
		if (!fstabrec) {
			goto out;
		}
		// ignore symlinks for calls which don't resolve them
		struct stat sb;
		if (!resolve_symlinks && !lstat(path, &sb)
		    && S_ISLNK(sb.st_mode)) {
			goto out;
		}

		char *replacement =
		    fstabrec->replacement_bind ? fstabrec->
		    stub_device : fstabrec->replacement_device;

		DEBUG("%s(%s): redirect %s->%s arg=%d\n", __func__,
		      get_syscall_name_abi(e->syscall_num, e->abi), path,
		      replacement, argpos);

		// copy new devname
		devname_new = copy_patharg(e->child, replacement);
		if (!devname_new) {
			kperror("copy_patharg");
			rc = TRACY_HOOK_ABORT;
			goto out;
		}
		// copy args
		memcpy(&a, &(e->args), sizeof(struct tracy_sc_args));

		// modify args
		argptr = &a.a0;
		argptr[argpos] = (long)devname_new;

		// write new args
		if (tracy_modify_syscall_args(e->child, a.syscall, &a)) {
			kperror("tracy_modify_syscall_args");
			rc = TRACY_HOOK_ABORT;
			goto out;
		}
		// set devname so we can free it later
		mbc->memory = devname_new;
	} else {
		// free previous data
		if (mbc->memory) {
			free_patharg(e->child, mbc->memory);
			mbc->memory = NULL;
		}
	}

out:
	if (path)
		free(path);
	if (devname_new && rc)
		free_patharg(e->child, devname_new);
	return rc;
}