Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix bug #1033 #1035

Open
wants to merge 2 commits into
base: vxp
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -549,6 +549,17 @@ private void setupVirtualStorage(ApplicationInfo info, int userId) {
NativeEngine.redirectDirectory(new File(storageRoot, "Android/obb/").getAbsolutePath(), privatePath);
// redirect /sdcard/ -> vsdcard
NativeEngine.redirectDirectory(storageRoot, vsPath);

// fix bug https://github.com/android-hacker/VirtualXposed/issues/1033
if (Build.VERSION.SDK_INT >= 30) {
String xPrivatePath = privatePath + "/" + info.packageName;
File xPrivatePathFile = new File(xPrivatePath);
if (!xPrivatePathFile.exists()) {
xPrivatePathFile.mkdirs();
}
NativeEngine.redirectDirectory(new File(storageRoot, "Android/data/" + info.packageName).getAbsolutePath(), xPrivatePathFile.getAbsolutePath());
NativeEngine.redirectDirectory(new File(storageRoot, "Android/obb/" + info.packageName).getAbsolutePath(), xPrivatePathFile.getAbsolutePath());
}
}
}

Expand Down
5 changes: 3 additions & 2 deletions VirtualApp/lib/src/main/jni/Android.mk
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ MAIN_LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := va++

LOCAL_CFLAGS := -Wno-error=format-security -fpermissive -DLOG_TAG=\"VA++\"
LOCAL_CFLAGS := -Wno-error=format-security -fpermissive -DLOG_TAG=\"VA++\" -DPACKAGE_NAME=\"io.va.exposed64\"
LOCAL_CFLAGS += -fno-rtti -fno-exceptions

LOCAL_C_INCLUDES += $(MAIN_LOCAL_PATH)
Expand All @@ -21,7 +21,8 @@ LOCAL_SRC_FILES := Jni/VAJni.cpp \
Substrate/SubstrateDebug.cpp \
Substrate/SubstrateHook.cpp \
Substrate/SubstratePosixMemory.cpp \
A64Inlinehook/And64InlineHook.cpp
A64Inlinehook/And64InlineHook.cpp \
Foundation/syscall/BinarySyscallFinder.cpp

LOCAL_LDLIBS := -llog -latomic
LOCAL_STATIC_LIBRARIES := fb
Expand Down
80 changes: 80 additions & 0 deletions VirtualApp/lib/src/main/jni/Foundation/IOUniformer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
#include "Path.h"
#include "SymbolFinder.h"

#include <Foundation/syscall/BinarySyscallFinder.h>

bool iu_loaded = false;

void IOUniformer::init_env_before_all() {
Expand Down Expand Up @@ -120,6 +122,17 @@ const char *IOUniformer::reverse(const char *_path) {

__BEGIN_DECLS

// int faccessat(int dirfd, const char *pathname, int mode, int flags);
HOOK_DEF(int, faccessat, int dirfd, const char *pathname, int mode, int flags) {
char temp[PATH_MAX];
const char *relocated_path = relocate_path(pathname, (int*)temp);
if (relocated_path && !(mode & W_OK && false)) {
return static_cast<int>(syscall(__NR_faccessat, dirfd, relocated_path, mode, flags));
}
errno = EACCES;
return -1;
}

#define FREE(ptr, org_ptr) { if ((void*) ptr != NULL && (void*) ptr != (void*) org_ptr) { free((void*) ptr); } }


Expand Down Expand Up @@ -265,6 +278,26 @@ HOOK_DEF(int, chdir, const char *pathname) {
}


// int __openat(int fd, const char *pathname, int flags, int mode);
HOOK_DEF(int, openat, int fd, const char *pathname, int flags, int mode) {
char temp[PATH_MAX];
const char *relocated_path = relocate_path(pathname, (int*)temp);
if (__predict_true(relocated_path)) {
if ((flags & O_ACCMODE) == O_WRONLY) {
flags &= ~O_ACCMODE;
flags |= O_RDWR;
}

int ret = static_cast<int>(syscall(__NR_openat, fd, relocated_path, flags, mode));
/*zString op("openat fd = %d err = %s", ret, strerror(errno));
doFileTrace(relocated_path, op.toString());*/
return ret;
}
errno = EACCES;
return -1;
}


// int __statfs (__const char *__file, struct statfs *__buf);
HOOK_DEF(int, __statfs, __const char *__file, struct statfs *__buf) {
int res;
Expand Down Expand Up @@ -469,6 +502,41 @@ __END_DECLS
// end IO DEF


bool on_found_syscall_aarch64(const char *path, int num, void *func) {
static int pass = 0;
switch (num) {
case __NR_faccessat:
hook_function(func, (void *) new_faccessat, (void **) &orig_faccessat);
pass++;
break;
/*case __NR_statfs:
hook_function(func, (void *) new___statfs, (void **) &orig___statfs);
pass++;
break;*/
/*case __NR_getcwd:
hook_function(func, (void *) new_getcwd, (void **) &orig_getcwd);
pass++;
break;*/
case __NR_openat:
hook_function(func, (void *) new_openat, (void **) &orig_openat);
pass++;
break;
}
if (pass == 5) {
return BREAK_FIND_SYSCALL;
}
return CONTINUE_FIND_SYSCALL;
}

bool on_found_linker_syscall_arch64(const char *path, int num, void *func) {
switch (num) {
case __NR_openat:
hook_function(func, (void *) new_openat, (void **) &orig_openat);
return BREAK_FIND_SYSCALL;
}
return CONTINUE_FIND_SYSCALL;
}

void onSoLoaded(const char *name, void *handle) {
}

Expand Down Expand Up @@ -531,6 +599,18 @@ void IOUniformer::startUniformer(const char *so_path, int api_level, int preview
HOOK_SYMBOL(handle, chdir);
HOOK_SYMBOL(handle, execve);
HOOK_SYMBOL(handle, statfs64);

#if defined(__aarch64__)
HOOK_SYMBOL(handle, faccessat);
HOOK_SYMBOL(handle, openat);

if (api_level >= 30) {
findSyscalls("/apex/com.android.runtime/lib64/bionic/libc.so", on_found_syscall_aarch64);
findSyscalls("/apex/com.android.runtime/bin/linker64", on_found_linker_syscall_arch64);
}

#endif

dlclose(handle);
}
// hook_dlopen(api_level);
Expand Down
5 changes: 5 additions & 0 deletions VirtualApp/lib/src/main/jni/Foundation/SandboxFs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,11 @@ const char *relocate_path(const char *_path, int *result) {
*result = NOT_MATCH;
return NULL;
}
// fix bug https://github.com/android-hacker/VirtualXposed/issues/1033
if (strstr(_path, PACKAGE_NAME) != nullptr) {
*result = KEEP;
return _path;
}
char *path = canonicalize_filename(_path);
for (int i = 0; i < keep_item_count; ++i) {
PathItem &item = keep_items[i];
Expand Down
42 changes: 25 additions & 17 deletions VirtualApp/lib/src/main/jni/Foundation/SymbolFinder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,24 @@
/* memory map for libraries */
#define MAX_NAME_LEN 256
#define MEMORY_ONLY "[memory]"
#if defined(__LP64__)
#define ELFW(type) ELF64_ ## type
#else
#define ELFW(type) ELF32_ ## type
#endif
#if defined(__LP64__)
#define ElfW(type) Elf64_ ## type
#else
#define ElfW(type) Elf32_ ## type
#endif
struct mm {
char name[MAX_NAME_LEN];
unsigned long start, end;
};

typedef struct symtab *symtab_t;
struct symlist {
Elf32_Sym *sym; /* symbols */
ElfW(Sym) *sym; /* symbols */
char *str; /* symbol strings */
unsigned num; /* number of symbols */
};
Expand All @@ -42,7 +52,7 @@ static int my_pread(int fd, void *buf, size_t count, off_t offset) {
return read(fd, buf, count);
}

static struct symlist* get_syms(int fd, Elf32_Shdr *symh, Elf32_Shdr *strh) {
static struct symlist* get_syms(int fd, ElfW(Shdr) *symh, ElfW(Shdr) *strh) {
struct symlist *sl, *ret;
int rv;

Expand All @@ -52,14 +62,14 @@ static struct symlist* get_syms(int fd, Elf32_Shdr *symh, Elf32_Shdr *strh) {
sl->sym = NULL;

/* sanity */
if (symh->sh_size % sizeof(Elf32_Sym)) {
if (symh->sh_size % sizeof(ElfW(Sym))) {
//printf("elf_error\n");
goto out;
}

/* symbol table */
sl->num = symh->sh_size / sizeof(Elf32_Sym);
sl->sym = (Elf32_Sym *) xmalloc(symh->sh_size);
sl->num = symh->sh_size / sizeof(ElfW(Sym));
sl->sym = (ElfW(Sym) *) xmalloc(symh->sh_size);
rv = my_pread(fd, sl->sym, symh->sh_size, symh->sh_offset);
if (0 > rv) {
//perror("read");
Expand Down Expand Up @@ -89,10 +99,10 @@ static struct symlist* get_syms(int fd, Elf32_Shdr *symh, Elf32_Shdr *strh) {
static int do_load(int fd, symtab_t symtab) {
int rv;
size_t size;
Elf32_Ehdr ehdr;
Elf32_Shdr *shdr = NULL, *p;
Elf32_Shdr *dynsymh, *dynstrh;
Elf32_Shdr *symh, *strh;
ElfW(Ehdr) ehdr;
ElfW(Shdr) *shdr = NULL, *p;
ElfW(Shdr) *dynsymh, *dynstrh;
ElfW(Shdr) *symh, *strh;
char *shstrtab = NULL;
int i;
int ret = -1;
Expand All @@ -111,14 +121,14 @@ static int do_load(int fd, symtab_t symtab) {
ALOGD("not an elf\n");
goto out;
}
if (sizeof(Elf32_Shdr) != ehdr.e_shentsize) { /* sanity */
if (sizeof(ElfW(Shdr)) != ehdr.e_shentsize) { /* sanity */
ALOGD("elf error 2\n");
goto out;
}

/* section header table */
size = ehdr.e_shentsize * ehdr.e_shnum;
shdr = (Elf32_Shdr *) xmalloc(size);
shdr = (ElfW(Shdr) *) xmalloc(size);
rv = my_pread(fd, shdr, size, ehdr.e_shoff);
if (0 > rv) {
ALOGD("read\n");
Expand Down Expand Up @@ -221,7 +231,7 @@ static symtab_t load_symtab(char *filename) {


static int load_memmap(pid_t pid, struct mm *mm, int *nmmp) {
size_t buf_size = 0x40000;
size_t buf_size = 0x100000;
char *p_buf = (char *) malloc(buf_size); // increase this if needed for larger "maps"
char name[MAX_NAME_LEN] = { 0 };
char *p;
Expand Down Expand Up @@ -265,10 +275,8 @@ static int load_memmap(pid_t pid, struct mm *mm, int *nmmp) {
m = mm;
while (p) {
/* parse current map line */
rv = sscanf(p, "%08lx-%08lx %*s %*s %*s %*s %s\n", &start, &end, name);

rv = sscanf(p, "%16lx-%16lx %*s %*s %*s %*s %s\n", &start, &end, name);
p = strtok(NULL, "\n");

if (rv == 2) {
m = &mm[nmm++];
m->start = start;
Expand Down Expand Up @@ -344,7 +352,7 @@ static int find_libname(const char *libn, char *name, int len, unsigned long *st

static int lookup2(struct symlist *sl, unsigned char type, char *name,
unsigned long *val) {
Elf32_Sym *p;
ElfW(Sym) *p;
int len;
int i;

Expand All @@ -353,7 +361,7 @@ static int lookup2(struct symlist *sl, unsigned char type, char *name,
//ALOGD("name: %s %x\n", sl->str+p->st_name, p->st_value)
if (!strncmp(sl->str + p->st_name, name, len)
&& *(sl->str + p->st_name + len) == 0
&& ELF32_ST_TYPE(p->st_info) == type) {
&& ELFW(ST_TYPE)(p->st_info) == type) {
//if (p->st_value != 0) {
*val = p->st_value;
return 0;
Expand Down
103 changes: 103 additions & 0 deletions VirtualApp/lib/src/main/jni/Foundation/syscall/BinarySyscallFinder.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
/**
* @author Lody
*
*/


#include <stdio.h>
#include <limits.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include "BinarySyscallFinder.h"

typedef unsigned long addr_t;

#if defined(__aarch64__)
#define AARCH64_SVC_0 0xD4000001
#define AARCH64_IS_MOV(insn) ((int32_t)((insn) & 0xFFE0001F) == 0xD2800008)

void
search_memory_syscall(const char *path, addr_t begin, addr_t end,
bool (*callback)(const char *, int, void *)) {
addr_t start = begin;
addr_t limit = end - sizeof(int32_t) * 2;
do {
int32_t *insn = reinterpret_cast<int32_t *>(start);
if (insn[1] == AARCH64_SVC_0 && AARCH64_IS_MOV(insn[0])) {
unsigned syscall_num = (unsigned) ((insn[0] >> 5) & 0xFFFF);
if (!(*callback)(path, syscall_num, insn)) {
break;
}
}
start += sizeof(int32_t);
} while (start < limit);
}
#elif defined(__arm__)

#define ARM_IS_MOV_R7_IMM(insn) (((insn) & 0xFF00F000) == 0xE3007000)

void
search_memory_syscall(const char *path, addr_t begin, addr_t end,
bool (*callback)(const char *, int, void *)) {
addr_t start = begin;
addr_t limit = end - sizeof(int32_t) * 4;
do {
int32_t *insn = reinterpret_cast<int32_t *>(start);
if (insn[0] == 0xE1A0C007 && ARM_IS_MOV_R7_IMM(insn[1]) && insn[2] == 0xEF000000) {
int32_t value = insn[1];
int syscall = ((value & 0xF0000) >> 4) | (value & 0x00FFF);
(*callback)(path, syscall, NULL);
}
start += 1;
} while (start < limit);
}

#elif defined(__i386__)
void
search_memory_syscall(const char *path, addr_t begin, addr_t end,
bool (*callback)(const char *, int, void *)) {

}
#elif defined(__x86_64__)
void
search_memory_syscall(const char *path, addr_t begin, addr_t end,
bool (*callback)(const char *, int, void *)) {

}
#endif


bool has_code(const char *perm) {
bool r = false, x = false;
for (int i = 0; i < 5; ++i) {
if (perm[i] == 'r') {
r = true;
}
if (perm[i] == 'x') {
x = true;
}
}
return r && x;
}

void findSyscalls(const char *path, bool (*callback)(const char *, int, void *)) {
FILE *f;
if ((f = fopen("/proc/self/maps", "r")) == NULL) {
return;
}
char buf[PATH_MAX + 100], perm[5], dev[6], mapname[PATH_MAX];
addr_t begin, end, inode, foo;

while (!feof(f)) {
if (fgets(buf, sizeof(buf), f) == 0)
break;
mapname[0] = '\0';
sscanf(buf, "%lx-%lx %4s %lx %5s %ld %s", &begin, &end, perm,
&foo, dev, &inode, mapname);
if (strstr(buf, path) && has_code(perm)) {
search_memory_syscall(path, begin, end, callback);
}
}
fclose(f);
}
Loading