diff --git a/include/libc_shim.h b/include/libc_shim.h index 944a00c..70721b4 100644 --- a/include/libc_shim.h +++ b/include/libc_shim.h @@ -1,6 +1,7 @@ #pragma once #include +#include namespace shim { @@ -19,6 +20,8 @@ namespace shim { shimmed_symbol(const char *name, Ret (*ptr)(Args..., ...)) : name(name), value((void*) ptr) {} }; + + extern std::string android_data_dir; std::vector get_shimmed_symbols(); diff --git a/src/common.cpp b/src/common.cpp index 22f2a92..b5fb880 100644 --- a/src/common.cpp +++ b/src/common.cpp @@ -45,6 +45,8 @@ using namespace shim; +std::string shim::android_data_dir; + #ifdef __i386__ extern "C" unsigned long __umoddi3(unsigned long a, unsigned long b); extern "C" unsigned long __udivdi3(unsigned long a, unsigned long b); @@ -492,9 +494,75 @@ long fakesyscall(long sysno, ...) { return ENOSYS; } +namespace shim { + int unlink(const char *path) { + //TODO retarget + if(path && !memcmp(path, "/data/data/", 11)) { + return unlink((shim::android_data_dir + std::string(path + 10)).data()); + } + return ::unlink(path); + } + int rmdir(const char *path) { + //TODO retarget + if(path && !memcmp(path, "/data/data/", 11)) { + return rmdir((shim::android_data_dir + std::string(path + 10)).data()); + } + return ::rmdir(path); + } + + int link(const char *path1, const char *path2) { + //TODO retarget + if(path1 && !memcmp(path1, "/data/data/", 11)) { + return link((shim::android_data_dir + std::string(path1 + 10)).data(), path2); + } + if(path2 && !memcmp(path2, "/data/data/", 11)) { + return link(path1, (shim::android_data_dir + std::string(path2 + 10)).data()); + } + return ::link(path1, path2); + } + + int symlink(const char *path1, const char *path2) { + //TODO retarget + if(path1 && !memcmp(path1, "/data/data/", 11)) { + return symlink((shim::android_data_dir + std::string(path1 + 10)).data(), path2); + } + if(path2 && !memcmp(path2, "/data/data/", 11)) { + return symlink(path1, (shim::android_data_dir + std::string(path2 + 10)).data()); + } + return ::symlink(path1, path2); + } + + int access(const char *path, int type) { + //TODO retarget + if(path && !memcmp(path, "/data/data/", 11)) { + return access((shim::android_data_dir + std::string(path + 10)).data(), type); + } + return ::access(path, type); + } + + int chown(const char *path, uid_t __owner, gid_t __group) { + //TODO retarget + if(path && !memcmp(path, "/data/data/", 11)) { + return chown((shim::android_data_dir + std::string(path + 10)).data(), __owner, __group); + } + return ::chown(path, __owner, __group); + } + + int chdir(const char *path) { + //TODO retarget + if(path && !memcmp(path, "/data/data/", 11)) { + return chdir((shim::android_data_dir + std::string(path + 10)).data()); + } + return ::chdir(path); + } + +} + + + void shim::add_unistd_shimmed_symbols(std::vector &list) { list.insert(list.end(), { - {"access", WithErrnoUpdate(::access)}, + {"access", WithErrnoUpdate(access)}, {"lseek", WithErrnoUpdate(::lseek)}, {"close", WithErrnoUpdate(::close)}, {"read", WithErrnoUpdate(::read)}, @@ -505,10 +573,10 @@ void shim::add_unistd_shimmed_symbols(std::vector &list) { {"sleep", WithErrnoUpdate(::sleep)}, {"usleep", WithErrnoUpdate(::usleep)}, {"pause", WithErrnoUpdate(::pause)}, - {"chown", WithErrnoUpdate(::chown)}, + {"chown", WithErrnoUpdate(chown)}, {"fchown", WithErrnoUpdate(::fchown)}, {"lchown", WithErrnoUpdate(::lchown)}, - {"chdir", WithErrnoUpdate(::chdir)}, + {"chdir", WithErrnoUpdate(chdir)}, {"fchdir", WithErrnoUpdate(::fchdir)}, {"getcwd", WithErrnoUpdate(::getcwd)}, {"dup", WithErrnoUpdate(::dup)}, @@ -530,11 +598,11 @@ void shim::add_unistd_shimmed_symbols(std::vector &list) { {"fork", WithErrnoUpdate(::fork)}, {"vfork", WithErrnoUpdate(::vfork)}, {"isatty", WithErrnoUpdate(::isatty)}, - {"link", WithErrnoUpdate(::link)}, - {"symlink", WithErrnoUpdate(::symlink)}, - {"readlink", WithErrnoUpdate(::readlink)}, - {"unlink", WithErrnoUpdate(::unlink)}, - {"rmdir", WithErrnoUpdate(::rmdir)}, + {"link", WithErrnoUpdate(link)}, + {"symlink", WithErrnoUpdate(symlink)}, + {"readlink", WithErrnoUpdate(readlink)}, + {"unlink", WithErrnoUpdate(unlink)}, + {"rmdir", WithErrnoUpdate(rmdir)}, {"gethostname", WithErrnoUpdate(::gethostname)}, {"fsync", WithErrnoUpdate(::fsync)}, {"sync", WithErrnoUpdate(::sync)}, diff --git a/src/cstdio.cpp b/src/cstdio.cpp index 020ff51..22c3794 100644 --- a/src/cstdio.cpp +++ b/src/cstdio.cpp @@ -34,7 +34,13 @@ static bionic::FILE *wrap_file(::FILE *file) { return ret; } +#include + bionic::FILE *shim::fopen(const char *filename, const char *mode) { + //TODO retarget + if(filename && !memcmp(filename, "/data/data/", 11)) { + return fopen((shim::android_data_dir + std::string(filename + 10)).data(), mode); + } return wrap_file(::fopen(filename, mode)); } @@ -43,6 +49,10 @@ bionic::FILE* shim::fdopen(int fd, const char *mode) { } bionic::FILE* shim::freopen(const char *filename, const char *mode, bionic::FILE *stream) { + //TODO retarget + if(filename && !memcmp(filename, "/data/data/", 11)) { + return freopen((shim::android_data_dir + std::string(filename + 10)).data(), mode, stream); + } return wrap_file(::freopen(filename, mode, stream->wrapped)); } @@ -131,6 +141,26 @@ char *shim::__fgets_chk(char *dst, int len, FILE *stream, size_t max_len) { return ::fgets(dst, len, stream); } +namespace shim { + int remove(const char *path) { + //TODO retarget + if(path && !memcmp(path, "/data/data/", 11)) { + return remove((shim::android_data_dir + std::string(path + 10)).data()); + } + return ::remove(path); + } + int rename(const char *path1, const char *path2) { + //TODO retarget + if(path1 && !memcmp(path1, "/data/data/", 11)) { + return rename((shim::android_data_dir + std::string(path1 + 10)).data(), path2); + } + if(path2 && !memcmp(path2, "/data/data/", 11)) { + return rename(path1, (shim::android_data_dir + std::string(path2 + 10)).data()); + } + return ::rename(path1, path2); + } +} + void shim::add_cstdio_shimmed_symbols(std::vector &list) { bionic::init_standard_files(); @@ -185,8 +215,8 @@ void shim::add_cstdio_shimmed_symbols(std::vector &list) { {"getw", AutoArgRewritten(::getw)}, {"putw", AutoArgRewritten(::putw)}, - {"remove", ::remove}, - {"rename", ::rename}, + {"remove", remove}, + {"rename", rename}, {"putchar", ::putchar}, {"puts", ::puts}, diff --git a/src/dirent.cpp b/src/dirent.cpp index 229b689..fa122f6 100644 --- a/src/dirent.cpp +++ b/src/dirent.cpp @@ -11,6 +11,10 @@ static bionic::DIR *wrap_dir(::DIR *dir) { } bionic::DIR *shim::opendir(const char *name) { + //TODO retarget + if(name && !memcmp(name, "/data/data/", 11)) { + return opendir((shim::android_data_dir + std::string(name + 10)).data()); + } return wrap_dir(::opendir(name)); } diff --git a/src/file_misc.cpp b/src/file_misc.cpp index 11bb350..7e0147f 100644 --- a/src/file_misc.cpp +++ b/src/file_misc.cpp @@ -105,12 +105,21 @@ int shim::open(const char *pathname, bionic::file_status_flags flags, ...) { va_end(ap); } + //TODO retarget + if(pathname && !memcmp(pathname, "/data/data/", 11)) { + return open((shim::android_data_dir + std::string(pathname + 10)).data(), flags, mode); + } + int ret = ::open(pathname, hflags, mode); bionic::update_errno(); return ret; } int shim::open_2(const char *pathname, bionic::file_status_flags flags) { + //TODO retarget + if(pathname && !memcmp(pathname, "/data/data/", 11)) { + return open_2((shim::android_data_dir + std::string(pathname + 10)).data(), flags); + } int hflags = bionic::to_host_file_status_flags(flags); int ret = ::open(pathname, hflags, 0); bionic::update_errno(); diff --git a/src/stat.cpp b/src/stat.cpp index c62c0a3..38f2f33 100644 --- a/src/stat.cpp +++ b/src/stat.cpp @@ -22,12 +22,18 @@ void bionic::from_host(struct ::stat64 const &info, stat &result) { result.st_ctim = info.st_ctim; result.st_ino = info.st_ino; } - +#include +#include int shim::stat(const char *path, bionic::stat *s) { - struct ::stat64 tmp = {}; - int ret = ::stat64(path, &tmp); - bionic::from_host(tmp, *s); - return ret; + //TODO retarget + if(path && !memcmp(path, "/data/data/", 11)) { + return stat((shim::android_data_dir + std::string(path + 10)).data(), s); + } else { + struct ::stat64 tmp = {}; + int ret = ::stat64(path, &tmp); + bionic::from_host(tmp, *s); + return ret; + } } int shim::fstat(int fd, shim::bionic::stat *s) { @@ -59,6 +65,10 @@ void bionic::from_host(struct ::stat const &info, stat &result) { } int shim::stat(const char *path, bionic::stat *s) { + //TODO retarget + if(path && !memcmp(path, "/data/data/", 11)) { + return stat((shim::android_data_dir + std::string(path + 10)).data(), s); + } struct ::stat tmp = {}; int ret = ::stat(path, &tmp); bionic::from_host(tmp, *s); @@ -73,6 +83,22 @@ int shim::fstat(int fd, shim::bionic::stat *s) { } #endif +namespace shim { + int chmod(const char *path, mode_t __mode) { + //TODO retarget + if(path && !memcmp(path, "/data/data/", 11)) { + return chmod((shim::android_data_dir + std::string(path + 10)).data(), __mode); + } + return ::chmod(path, __mode); + } + int mkdir(const char *path, mode_t __mode) { + //TODO retarget + if(path && !memcmp(path, "/data/data/", 11)) { + return mkdir((shim::android_data_dir + std::string(path + 10)).data(), __mode); + } + return ::mkdir(path, __mode); + } +} void shim::add_stat_shimmed_symbols(std::vector &list) { list.insert(list.end(), { @@ -80,9 +106,9 @@ void shim::add_stat_shimmed_symbols(std::vector &list) { {"fstat", fstat}, {"stat64", stat}, {"fstat64", fstat}, - {"chmod", ::chmod}, + {"chmod", chmod}, {"fchmod", ::fchmod}, {"umask", ::umask}, - {"mkdir", ::mkdir}, + {"mkdir", mkdir}, }); } \ No newline at end of file