From 2692251daf4c8a3ca6986cece8f7fc0822de150f Mon Sep 17 00:00:00 2001 From: notaz Date: Tue, 12 Jan 2016 03:48:50 +0200 Subject: [PATCH] do yet more path wrapping --- loader/emu.c | 21 ++++++++++++++------- loader/header.h | 2 ++ loader/override.c | 9 ++++++--- loader/patches.c | 9 +++++++++ loader/syscalls.S | 1 + loader/syscalls.h | 1 + 6 files changed, 33 insertions(+), 10 deletions(-) diff --git a/loader/emu.c b/loader/emu.c index 5adcc5d..77f9a6d 100644 --- a/loader/emu.c +++ b/loader/emu.c @@ -1319,13 +1319,15 @@ static const struct { const char *to; } path_map[] = { { "/mnt/tmp", "./tmp" }, + { "/mnt/sd", "./mntsd" }, }; -static const char *wrap_path(const char *path) +const char *emu_wrap_path(const char *path) { char *buff, *p; size_t size; int i, len; + long ret; // do only path mapping for now for (i = 0; i < ARRAY_SIZE(path_map); i++) { @@ -1340,6 +1342,11 @@ static const char *wrap_path(const char *path) snprintf(buff + len, size - len, "%s%s", path_map[i].to, path + len + strlen(path_map[i].from)); dbg("mapped path \"%s\" -> \"%s\"\n", path, buff); + + ret = g_mkdir_raw(path_map[i].to, 0666); + if (ret != 0 && ret != -EEXIST) + err("mkdir(%s): %ld\n", path_map[i].to, ret); + return buff; } } @@ -1347,7 +1354,7 @@ static const char *wrap_path(const char *path) return path; } -static void wrap_path_free(const char *w_path, const char *old_path) +void emu_wrap_path_free(const char *w_path, const char *old_path) { if (w_path != old_path) free((void *)w_path); @@ -1358,9 +1365,9 @@ void *emu_do_fopen(const char *path, const char *mode) const char *w_path; FILE *ret; - w_path = wrap_path(path); + w_path = emu_wrap_path(path); ret = fopen(w_path, mode); - wrap_path_free(w_path, path); + emu_wrap_path_free(w_path, path); return ret; } @@ -1387,7 +1394,7 @@ int emu_do_system(const char *command) // absolute path, but not a system command need_ginge = 1; - p2 = wrap_path(command); + p2 = emu_wrap_path(command); if (need_ginge) { make_local_path(tmp_path, sizeof(tmp_path), "ginge_prep"); p = tmp_path + strlen(tmp_path); @@ -1396,7 +1403,7 @@ int emu_do_system(const char *command) } else snprintf(tmp_path, sizeof(tmp_path), "%s", p2); - wrap_path_free(p2, command); + emu_wrap_path_free(p2, command); dbg("system: \"%s\"\n", tmp_path); @@ -1436,7 +1443,7 @@ long emu_do_execve(const char *filename, char * const argv[], make_local_path(prep_path, 512, "ginge_prep"); new_argv[0] = prep_path; new_argv[1] = "--nomenu"; - new_argv[2] = wrap_path(filename); + new_argv[2] = emu_wrap_path(filename); if (argv[0] != NULL) for (i = 1; argv[i] != NULL; i++) diff --git a/loader/header.h b/loader/header.h index 7bff116..29841ea 100644 --- a/loader/header.h +++ b/loader/header.h @@ -52,6 +52,8 @@ long emu_do_read(int fd, void *buf, int count); void *emu_do_fopen(const char *path, const char *mode); int emu_do_system(const char *command); long emu_do_execve(const char *filename, char *const argv[], char *const envp[]); +const char *emu_wrap_path(const char *path); +void emu_wrap_path_free(const char *w_path, const char *old_path); int host_init(void); int host_read_btns(void); diff --git a/loader/override.c b/loader/override.c index 3d0d0cc..f98a4db 100644 --- a/loader/override.c +++ b/loader/override.c @@ -48,7 +48,7 @@ static const struct dev_fd_t takeover_devs[] = { #endif }; -static long w_open_raw(const char *pathname, int flags, mode_t mode) +long w_open_raw(const char *pathname, int flags, mode_t mode) { long ret; int i; @@ -70,8 +70,11 @@ static long w_open_raw(const char *pathname, int flags, mode_t mode) } } - if (i == ARRAY_SIZE(takeover_devs)) - ret = g_open_raw(pathname, flags, mode); + if (i == ARRAY_SIZE(takeover_devs)) { + const char *w_path = emu_wrap_path(pathname); + ret = g_open_raw(w_path, flags, mode); + emu_wrap_path_free(w_path, pathname); + } if (ret >= 0) { for (i = 0; emu_interesting_fds[i].name != NULL; i++) { diff --git a/loader/patches.c b/loader/patches.c index d272b56..901de51 100644 --- a/loader/patches.c +++ b/loader/patches.c @@ -31,6 +31,13 @@ static const unsigned int sig_open_a1[] = { }; #define sig_mask_open_a1 sig_mask_all +static const unsigned int sig_hw_open[] = { + 0xef900005, // svc 0x900005 + 0xe3700a01, // cmn r0, #0x1000 + 0xe1a04000, // mov r4, r0 +}; +#define sig_mask_hw_open sig_mask_all + static const unsigned int sig_mmap[] = { 0xe92d000f, // push {r0, r1, r2, r3} 0xe1a0000d, // mov r0, sp @@ -170,6 +177,7 @@ asm( \ " ldmfd sp!, {r1-r3,r12,lr,pc}\n" \ ); +SVC_CMN_R0_MOV_R4_WRAPPER(hw_open, w_open_raw) SVC_CMN_R0_MOV_R4_WRAPPER(hw_read, w_read_raw) SVC_CMN_R0_MOV_R4_WRAPPER(hw_ioctl, w_ioctl_raw) SVC_CMN_R0_MOV_R4_WRAPPER(hw_execve, w_execve_raw) @@ -187,6 +195,7 @@ static const struct { } patches[] = { PATCH (open), PATCH_(open_a1, w_open, 0), + PATCH_(hw_open, hw_open, 1), PATCH (mmap), PATCH (mmap2), // mmap2 syscall PATCH (munmap), diff --git a/loader/syscalls.S b/loader/syscalls.S index 6d48fbd..d478582 100644 --- a/loader/syscalls.S +++ b/loader/syscalls.S @@ -96,6 +96,7 @@ raw_syscall_easy g_munmap_raw, __NR_munmap raw_syscall_easy g_ioctl_raw, __NR_ioctl raw_syscall_easy g_close_raw, __NR_close raw_syscall_easy g_chdir_raw, __NR_chdir +raw_syscall_easy g_mkdir_raw, __NR_mkdir raw_syscall_easy g_futex_raw, __NR_futex raw_syscall_easy g_nanosleep_raw, __NR_nanosleep raw_syscall_easy g_readlink_raw, __NR_readlink diff --git a/loader/syscalls.h b/loader/syscalls.h index 3dfc44a..9978532 100644 --- a/loader/syscalls.h +++ b/loader/syscalls.h @@ -21,6 +21,7 @@ long g_munmap_raw(void *addr, size_t length); long g_ioctl_raw(int fd, unsigned long request, ...); long g_close_raw(int fd); long g_chdir_raw(const char *path); +long g_mkdir_raw(const char *pathname, unsigned int mode); long g_futex_raw(int *uaddr, int op, int val, const struct timespec *timeout); long g_nanosleep_raw(const struct timespec *req, struct timespec *rem); -- 2.39.2