VirtualApp/lib/src/main/jni/Foundation/IORelocator64.cpp
findSyscalls("/system/lib64/libc.so", on_found_syscall_aarch64);
findSyscalls("/system/bin/linker64", on_found_linker_syscall_arch64);
VirtualApp/lib/src/main/jni/Foundation/syscall/BinarySyscallFinder.cpp
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);
}
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);
}
bool on_found_syscall_aarch64(const char *path, int num, void *func) {
static int pass = 0;
switch (num) {
case __NR_fchmodat:
MSHookFunction(func, (void *) new_fchmodat, (void **) &orig_fchmodat);
pass++;
break;
case __NR_faccessat:
MSHookFunction(func, (void *) new_faccessat, (void **) &orig_faccessat);
pass++;
break;
case __NR_statfs:
MSHookFunction(func, (void *) new___statfs, (void **) &orig___statfs);
pass++;
break;
case __NR_getcwd:
MSHookFunction(func, (void *) new_getcwd, (void **) &orig_getcwd);
pass++;
break;
case __NR_openat:
MSHookFunction(func, (void *) new_openat, (void **) &orig_openat);
pass++;
break;
}
if (pass == 5) {
return BREAK_FIND_SYSCALL;
}
return CONTINUE_FIND_SYSCALL;
}