Use rirud to read files from /data/adb
This commit is contained in:
parent
baf1d6b6bb
commit
f04628e997
|
|
@ -43,9 +43,19 @@ ext {
|
|||
riruModuleId = "edxp"
|
||||
zipPathMagiskRelease = "$buildDir/tmp/release/magisk"
|
||||
|
||||
moduleMinRiruApiVersion = 9
|
||||
moduleMinRiruVersionName = "v22.0"
|
||||
moduleMaxRiruApiVersion = 9
|
||||
moduleMinRiruApiVersion = 10
|
||||
moduleMinRiruVersionName = "v23.0"
|
||||
moduleMaxRiruApiVersion = 10
|
||||
}
|
||||
|
||||
repositories {
|
||||
mavenLocal()
|
||||
jcenter()
|
||||
maven { url 'https://dl.bintray.com/rikkaw/Libraries' }
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'rikka.ndk:riru:10'
|
||||
}
|
||||
|
||||
android {
|
||||
|
|
@ -54,6 +64,10 @@ android {
|
|||
minSdkVersion rootProject.ext.minSdkVersion
|
||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||
|
||||
buildFeatures {
|
||||
prefab true
|
||||
}
|
||||
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
abiFilters 'arm64-v8a', 'armeabi-v7a', 'x86', 'x86_64'
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
cmake_minimum_required(VERSION 3.4.1)
|
||||
|
||||
add_subdirectory(xhook)
|
||||
add_subdirectory(riru)
|
||||
add_subdirectory(yahfa)
|
||||
add_subdirectory(android)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +0,0 @@
|
|||
cmake_minimum_required(VERSION 3.4.1)
|
||||
|
||||
aux_source_directory(src SRC_LIST)
|
||||
add_library(riru STATIC ${SRC_LIST})
|
||||
|
||||
target_include_directories(riru INTERFACE src)
|
||||
|
|
@ -1,169 +0,0 @@
|
|||
#ifndef RIRU_H
|
||||
#define RIRU_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <jni.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
// ---------------------------------------------------------
|
||||
|
||||
typedef void(onModuleLoaded_v9)();
|
||||
|
||||
typedef int(shouldSkipUid_v9)(int uid);
|
||||
|
||||
typedef void(nativeForkAndSpecializePre_v9)(
|
||||
JNIEnv *env, jclass cls, jint *uid, jint *gid, jintArray *gids, jint *runtimeFlags,
|
||||
jobjectArray *rlimits, jint *mountExternal, jstring *seInfo, jstring *niceName,
|
||||
jintArray *fdsToClose, jintArray *fdsToIgnore, jboolean *is_child_zygote,
|
||||
jstring *instructionSet, jstring *appDataDir, jboolean *isTopApp, jobjectArray *pkgDataInfoList,
|
||||
jobjectArray *whitelistedDataInfoList, jboolean *bindMountAppDataDirs, jboolean *bindMountAppStorageDirs);
|
||||
|
||||
typedef void(nativeForkAndSpecializePost_v9)(JNIEnv *env, jclass cls, jint res);
|
||||
|
||||
typedef void(nativeForkSystemServerPre_v9)(
|
||||
JNIEnv *env, jclass cls, uid_t *uid, gid_t *gid, jintArray *gids, jint *runtimeFlags,
|
||||
jobjectArray *rlimits, jlong *permittedCapabilities, jlong *effectiveCapabilities);
|
||||
|
||||
typedef void(nativeForkSystemServerPost_v9)(JNIEnv *env, jclass cls, jint res);
|
||||
|
||||
typedef void(nativeSpecializeAppProcessPre_v9)(
|
||||
JNIEnv *env, jclass cls, jint *uid, jint *gid, jintArray *gids, jint *runtimeFlags,
|
||||
jobjectArray *rlimits, jint *mountExternal, jstring *seInfo, jstring *niceName,
|
||||
jboolean *startChildZygote, jstring *instructionSet, jstring *appDataDir,
|
||||
jboolean *isTopApp, jobjectArray *pkgDataInfoList, jobjectArray *whitelistedDataInfoList,
|
||||
jboolean *bindMountAppDataDirs, jboolean *bindMountAppStorageDirs);
|
||||
|
||||
typedef void(nativeSpecializeAppProcessPost_v9)(JNIEnv *env, jclass cls);
|
||||
|
||||
typedef struct {
|
||||
int supportHide;
|
||||
int version;
|
||||
const char *versionName;
|
||||
onModuleLoaded_v9 *onModuleLoaded;
|
||||
shouldSkipUid_v9 *shouldSkipUid;
|
||||
nativeForkAndSpecializePre_v9 *forkAndSpecializePre;
|
||||
nativeForkAndSpecializePost_v9 *forkAndSpecializePost;
|
||||
nativeForkSystemServerPre_v9 *forkSystemServerPre;
|
||||
nativeForkSystemServerPost_v9 *forkSystemServerPost;
|
||||
nativeSpecializeAppProcessPre_v9 *specializeAppProcessPre;
|
||||
nativeSpecializeAppProcessPost_v9 *specializeAppProcessPost;
|
||||
} RiruModuleInfoV9;
|
||||
|
||||
// ---------------------------------------------------------
|
||||
|
||||
typedef void *(RiruGetFunc_v9)(uint32_t token, const char *name);
|
||||
|
||||
typedef void (RiruSetFunc_v9)(uint32_t token, const char *name, void *func);
|
||||
|
||||
typedef void *(RiruGetJNINativeMethodFunc_v9)(uint32_t token, const char *className, const char *name, const char *signature);
|
||||
|
||||
typedef void (RiruSetJNINativeMethodFunc_v9)(uint32_t token, const char *className, const char *name, const char *signature, void *func);
|
||||
|
||||
typedef const JNINativeMethod *(RiruGetOriginalJNINativeMethodFunc_v9)(const char *className, const char *name, const char *signature);
|
||||
|
||||
typedef void *(RiruGetGlobalValue_v9)(const char *key);
|
||||
|
||||
typedef void(RiruPutGlobalValue_v9)(const char *key, void *value);
|
||||
|
||||
typedef struct {
|
||||
|
||||
uint32_t token;
|
||||
RiruGetFunc_v9 *getFunc;
|
||||
RiruGetJNINativeMethodFunc_v9 *getJNINativeMethodFunc;
|
||||
RiruSetFunc_v9 *setFunc;
|
||||
RiruSetJNINativeMethodFunc_v9 *setJNINativeMethodFunc;
|
||||
RiruGetOriginalJNINativeMethodFunc_v9 *getOriginalJNINativeMethodFunc;
|
||||
RiruGetGlobalValue_v9 *getGlobalValue;
|
||||
RiruPutGlobalValue_v9 *putGlobalValue;
|
||||
} RiruApiV9;
|
||||
|
||||
typedef void *(RiruInit_t)(void *);
|
||||
|
||||
#ifdef RIRU_MODULE
|
||||
#define RIRU_EXPORT __attribute__((visibility("default"))) __attribute__((used))
|
||||
|
||||
/*
|
||||
* Init will be called three times.
|
||||
*
|
||||
* The first time:
|
||||
* Returns the highest version number supported by both Riru and the module.
|
||||
*
|
||||
* arg: (int *) Riru's API version
|
||||
* returns: (int *) the highest possible API version
|
||||
*
|
||||
* The second time:
|
||||
* Returns the RiruModuleX struct created by the module (X is the return of the first call).
|
||||
*
|
||||
* arg: (RiruApiVX *) RiruApi strcut, this pointer can be saved for further use
|
||||
* returns: (RiruModuleX *) RiruModule strcut
|
||||
*
|
||||
* The second time:
|
||||
* Let the module to cleanup (such as RiruModuleX struct created before).
|
||||
*
|
||||
* arg: null
|
||||
* returns: (ignored)
|
||||
*
|
||||
*/
|
||||
void* init(void *arg) RIRU_EXPORT;
|
||||
|
||||
extern int riru_api_version;
|
||||
extern RiruApiV9 *riru_api_v9;
|
||||
|
||||
inline void *riru_get_func(const char *name) {
|
||||
if (riru_api_version == 9) {
|
||||
return riru_api_v9->getFunc(riru_api_v9->token, name);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
inline void *riru_get_native_method_func(const char *className, const char *name, const char *signature) {
|
||||
if (riru_api_version == 9) {
|
||||
return riru_api_v9->getJNINativeMethodFunc(riru_api_v9->token, className, name, signature);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
inline const JNINativeMethod *riru_get_original_native_methods(const char *className, const char *name, const char *signature) {
|
||||
if (riru_api_version == 9) {
|
||||
return riru_api_v9->getOriginalJNINativeMethodFunc(className, name, signature);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
inline void riru_set_func(const char *name, void *func) {
|
||||
if (riru_api_version == 9) {
|
||||
riru_api_v9->setFunc(riru_api_v9->token, name, func);
|
||||
}
|
||||
}
|
||||
|
||||
inline void riru_set_native_method_func(const char *className, const char *name, const char *signature,
|
||||
void *func) {
|
||||
if (riru_api_version == 9) {
|
||||
riru_api_v9->setJNINativeMethodFunc(riru_api_v9->token, className, name, signature, func);
|
||||
}
|
||||
}
|
||||
|
||||
inline void *riru_get_global_value(const char *key) {
|
||||
if (riru_api_version == 9) {
|
||||
return riru_api_v9->getGlobalValue(key);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
inline void riru_put_global_value(const char *key, void *value) {
|
||||
if (riru_api_version == 9) {
|
||||
riru_api_v9->putGlobalValue(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //RIRU_H
|
||||
|
|
@ -7,5 +7,6 @@ aux_source_directory(src/jni SRC_JNI_LIST)
|
|||
include_directories(include src)
|
||||
add_library(riru_edxp SHARED ${SRC_LIST} ${SRC_JNI_LIST})
|
||||
|
||||
find_package(riru REQUIRED CONFIG)
|
||||
find_library(log-lib log)
|
||||
target_link_libraries(riru_edxp yahfa riru xhook android dobby ${log-lib})
|
||||
target_link_libraries(riru_edxp yahfa riru::riru xhook android dobby ${log-lib})
|
||||
|
|
@ -19,6 +19,7 @@
|
|||
#include "art/runtime/native/native_util.h"
|
||||
#include "config_manager.h"
|
||||
#include "utils.h"
|
||||
#include "rirud_socket.h"
|
||||
|
||||
/*
|
||||
* Logic:
|
||||
|
|
@ -79,22 +80,23 @@
|
|||
* of the conf on its own data dir)
|
||||
*
|
||||
*/
|
||||
|
||||
namespace edxp {
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
fs::path ConfigManager::RetrieveBaseConfigPath() const {
|
||||
fs::path misc_path("/data/adb/edxp/misc_path");
|
||||
if (path_exists(misc_path)) {
|
||||
std::ifstream ifs(misc_path);
|
||||
if (ifs.good()) {
|
||||
return fs::path("/data/misc") /
|
||||
std::string{std::istream_iterator<char>(ifs),
|
||||
std::istream_iterator<char>()} /
|
||||
std::to_string(user_);
|
||||
}
|
||||
try {
|
||||
RirudSocket rirud_socket{};
|
||||
auto path = rirud_socket.ReadFile(misc_path);
|
||||
path.erase(std::find_if(path.rbegin(), path.rend(), [](unsigned char ch) {
|
||||
return !std::isspace(ch);
|
||||
}).base(), path.end());
|
||||
return fs::path("/data/misc") / path / std::to_string(user_);
|
||||
} catch (const RirudSocket::RirudSocketException &e) {
|
||||
LOGE("%s", e.what());
|
||||
return {};
|
||||
}
|
||||
LOGW("fallback because %s is not accessible", misc_path.c_str());
|
||||
return data_path_prefix_ / kPrimaryInstallerPkgName;
|
||||
}
|
||||
|
||||
std::string ConfigManager::RetrieveInstallerPkgName() const {
|
||||
|
|
@ -257,7 +259,7 @@ namespace edxp {
|
|||
}
|
||||
|
||||
bool ConfigManager::InitConfigPath() const {
|
||||
if (base_config_path_.string().rfind("/data/misc") != 0) return true;
|
||||
if (base_config_path_.empty()) return false;
|
||||
try {
|
||||
fs::create_directories(base_config_path_);
|
||||
fs::permissions(base_config_path_.parent_path(),
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
#include "logging.h"
|
||||
#include "config.h"
|
||||
#include "edxp_context.h"
|
||||
#include "riru.h"
|
||||
#include <riru.h>
|
||||
#include "config_manager.h"
|
||||
#include "native_hook.h"
|
||||
|
||||
|
|
@ -90,7 +90,7 @@ namespace edxp {
|
|||
}
|
||||
|
||||
int riru_api_version;
|
||||
RiruApiV9 *riru_api_v9;
|
||||
RiruApiV10 *riru_api_v10;
|
||||
|
||||
RIRU_EXPORT void *init(void *arg) {
|
||||
static int step = 0;
|
||||
|
|
@ -106,11 +106,13 @@ RIRU_EXPORT void *init(void *arg) {
|
|||
}
|
||||
case 2: {
|
||||
switch (riru_api_version) {
|
||||
case 10:
|
||||
[[fallthrough]];
|
||||
case 9: {
|
||||
riru_api_v9 = (RiruApiV9 *) arg;
|
||||
riru_api_v10 = (RiruApiV10 *) arg;
|
||||
|
||||
auto module = (RiruModuleInfoV9 *) malloc(sizeof(RiruModuleInfoV9));
|
||||
memset(module, 0, sizeof(RiruModuleInfoV9));
|
||||
auto module = (RiruModuleInfoV10 *) malloc(sizeof(RiruModuleInfoV10));
|
||||
memset(module, 0, sizeof(RiruModuleInfoV10));
|
||||
_module = module;
|
||||
|
||||
module->supportHide = true;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,105 @@
|
|||
//
|
||||
// Created by loves on 12/2/2020.
|
||||
//
|
||||
|
||||
#include "rirud_socket.h"
|
||||
#include <unistd.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <logging.h>
|
||||
#include <cerrno>
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
template<>
|
||||
void RirudSocket::Write<std::string>(const std::string &str) {
|
||||
auto count = str.size();
|
||||
auto *buf = str.data();
|
||||
Write(buf, count);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void RirudSocket::Write(const T &obj) {
|
||||
auto len = sizeof(T);
|
||||
auto *buf = &obj;
|
||||
Write(reinterpret_cast<const char*>(buf), len);
|
||||
}
|
||||
|
||||
template<>
|
||||
void RirudSocket::Read<std::string>(std::string &str) {
|
||||
auto count = str.size();
|
||||
auto *buf = str.data();
|
||||
Read(buf, count);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void RirudSocket::Read(T &obj) {
|
||||
auto len = sizeof(T);
|
||||
auto *buf = &obj;
|
||||
Read(reinterpret_cast<char*>(buf), len);
|
||||
}
|
||||
|
||||
RirudSocket::RirudSocket() {
|
||||
if ((fd_ = socket(PF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0)) < 0) {
|
||||
throw RirudSocketException(strerror(errno));
|
||||
}
|
||||
|
||||
struct sockaddr_un addr{
|
||||
.sun_family = AF_UNIX,
|
||||
.sun_path={0}
|
||||
};
|
||||
strcpy(addr.sun_path + 1, "rirud");
|
||||
socklen_t socklen = sizeof(sa_family_t) + strlen(addr.sun_path + 1) + 1;
|
||||
|
||||
if (connect(fd_, reinterpret_cast<struct sockaddr *>(&addr), socklen) == -1) {
|
||||
throw RirudSocketException(strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
RirudSocket::~RirudSocket() {
|
||||
if (fd_ != -1)
|
||||
close(fd_);
|
||||
}
|
||||
|
||||
std::string RirudSocket::ReadFile(const fs::path &path) {
|
||||
Write(ACTION_READ_FILE);
|
||||
Write(path.string().size());
|
||||
Write(path.string());
|
||||
int32_t rirud_errno;
|
||||
Read(rirud_errno);
|
||||
if(rirud_errno != 0) {
|
||||
throw RirudSocketException(strerror(rirud_errno));
|
||||
}
|
||||
uint32_t file_size;
|
||||
Read(file_size);
|
||||
std::string content;
|
||||
content.resize(file_size);
|
||||
Read(content);
|
||||
return content;
|
||||
}
|
||||
|
||||
void RirudSocket::Write(const char *buf, size_t len) const {
|
||||
auto count = len;
|
||||
while (count > 0) {
|
||||
ssize_t size = write(fd_, buf, count < SSIZE_MAX ? count : SSIZE_MAX);
|
||||
if (size == -1) {
|
||||
if (errno == EINTR) continue;
|
||||
else throw RirudSocketException(strerror(errno));
|
||||
}
|
||||
buf = buf + size;
|
||||
count -= size;
|
||||
}
|
||||
}
|
||||
|
||||
void RirudSocket::Read(char *out, size_t len) const {
|
||||
while (len > 0) {
|
||||
ssize_t ret = read(fd_, out, len);
|
||||
if (ret <= 0) {
|
||||
if(errno == EINTR) continue;
|
||||
else throw RirudSocketException(strerror(errno));
|
||||
}
|
||||
out = out + ret;
|
||||
len -= ret;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
//
|
||||
// Created by loves on 12/2/2020.
|
||||
//
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <filesystem>
|
||||
|
||||
|
||||
class RirudSocket {
|
||||
public:
|
||||
// class DirIter {};
|
||||
|
||||
class RirudSocketException : public std::runtime_error {
|
||||
public:
|
||||
RirudSocketException(const std::string &what) : std::runtime_error(what) {}
|
||||
};
|
||||
|
||||
RirudSocket();
|
||||
|
||||
std::string ReadFile(const std::filesystem::path &path);
|
||||
|
||||
// DirIter ReadDir(const std::filesystem::path &path);
|
||||
// DirIter RecursiveReadDir(const std::filesystem::path &path);
|
||||
|
||||
~RirudSocket();
|
||||
|
||||
private:
|
||||
RirudSocket(const RirudSocket &) = delete;
|
||||
|
||||
RirudSocket operator=(const RirudSocket &) = delete;
|
||||
|
||||
|
||||
inline static const uint32_t ACTION_READ_FILE = 4;
|
||||
|
||||
template<typename T>
|
||||
void Write(const T &);
|
||||
|
||||
template<typename T>
|
||||
void Read(T &);
|
||||
|
||||
void Write(const char *buf, size_t len) const;
|
||||
|
||||
void Read(char *buf, size_t len) const;
|
||||
|
||||
int fd_ = -1;
|
||||
};
|
||||
|
|
@ -1,4 +1,2 @@
|
|||
allow system_server system_server process execmem
|
||||
allow system_server system_server memprotect mmap_zero
|
||||
# TODO: use rirud
|
||||
allow zygote adb_data_file file { getattr read }
|
||||
allow system_server system_server memprotect mmap_zero
|
||||
|
|
@ -1,2 +1,3 @@
|
|||
androidCompileSdkVersion=30
|
||||
androidCompileNdkVersion=22.0.6917172
|
||||
androidCompileNdkVersion=22.0.6917172
|
||||
android.prefabVersion=1.1.2
|
||||
Loading…
Reference in New Issue