Use inline hook to append allow-across-fork file whitelist
This commit is contained in:
parent
c4978b7344
commit
7eaae6d898
|
|
@ -1,5 +1,9 @@
|
|||
package com.elderdrivers.riru.edxp.framework;
|
||||
|
||||
import com.elderdrivers.riru.edxp.util.Utils;
|
||||
|
||||
import de.robv.android.xposed.XposedHelpers;
|
||||
|
||||
public class Zygote {
|
||||
|
||||
// prevent from fatal error caused by holding not whitelisted file descriptors when forking zygote
|
||||
|
|
@ -8,4 +12,12 @@ public class Zygote {
|
|||
|
||||
public static native void reopenFilesAfterFork();
|
||||
|
||||
public static void allowFileAcrossFork(String path) {
|
||||
try {
|
||||
Class zygote = XposedHelpers.findClass("com.android.internal.os.Zygote", null);
|
||||
XposedHelpers.callStaticMethod(zygote, "nativeAllowFileAcrossFork", path);
|
||||
} catch (Throwable throwable) {
|
||||
Utils.logE("error when allowFileAcrossFork", throwable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ import android.text.TextUtils;
|
|||
|
||||
import com.elderdrivers.riru.edxp.config.ConfigManager;
|
||||
import com.elderdrivers.riru.edxp.deopt.PrebuiltMethodsDeopter;
|
||||
import com.elderdrivers.riru.edxp.framework.Zygote;
|
||||
import com.elderdrivers.riru.edxp.util.ProcessUtils;
|
||||
import com.elderdrivers.riru.edxp.util.Utils;
|
||||
|
||||
|
|
@ -87,16 +86,12 @@ public class BlackWhiteListProxy extends BaseProxy {
|
|||
// loadModules once for all child processes of zygote
|
||||
// TODO maybe just save initZygote callbacks and call them when whitelisted process forked?
|
||||
mRouter.loadModulesSafely(true);
|
||||
Zygote.closeFilesBeforeFork();
|
||||
}
|
||||
|
||||
private void onForkPostCommon(boolean isSystemServer, String appDataDir, String niceName) {
|
||||
ConfigManager.appDataDir = appDataDir;
|
||||
ConfigManager.niceName = niceName;
|
||||
final boolean isDynamicModulesMode = ConfigManager.isDynamicModulesEnabled();
|
||||
if (!isDynamicModulesMode) {
|
||||
Zygote.reopenFilesAfterFork();
|
||||
}
|
||||
mRouter.onEnterChildProcess();
|
||||
if (!checkNeedHook(appDataDir, niceName)) {
|
||||
// if is blacklisted, just stop here
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ package com.elderdrivers.riru.edxp.proxy;
|
|||
|
||||
import com.elderdrivers.riru.edxp.config.ConfigManager;
|
||||
import com.elderdrivers.riru.edxp.deopt.PrebuiltMethodsDeopter;
|
||||
import com.elderdrivers.riru.edxp.framework.Zygote;
|
||||
|
||||
import static com.elderdrivers.riru.edxp.util.FileUtils.getDataPathPrefix;
|
||||
|
||||
|
|
@ -27,7 +26,6 @@ public class NormalProxy extends BaseProxy {
|
|||
mRouter.installBootstrapHooks(false);
|
||||
// only load modules for secondary zygote
|
||||
mRouter.loadModulesSafely(true);
|
||||
Zygote.closeFilesBeforeFork();
|
||||
}
|
||||
|
||||
public void forkAndSpecializePost(int pid, String appDataDir, String niceName) {
|
||||
|
|
@ -35,7 +33,6 @@ public class NormalProxy extends BaseProxy {
|
|||
ConfigManager.appDataDir = appDataDir;
|
||||
ConfigManager.niceName = niceName;
|
||||
mRouter.prepare(false);
|
||||
Zygote.reopenFilesAfterFork();
|
||||
mRouter.onEnterChildProcess();
|
||||
// load modules for each app process on its forked if dynamic modules mode is on
|
||||
mRouter.loadModulesSafely(false);
|
||||
|
|
@ -57,7 +54,6 @@ public class NormalProxy extends BaseProxy {
|
|||
// because if not global hooks installed in initZygote might not be
|
||||
// propagated to processes not forked via forkAndSpecialize
|
||||
mRouter.loadModulesSafely(true);
|
||||
Zygote.closeFilesBeforeFork();
|
||||
}
|
||||
|
||||
public void forkSystemServerPost(int pid) {
|
||||
|
|
@ -65,7 +61,6 @@ public class NormalProxy extends BaseProxy {
|
|||
ConfigManager.appDataDir = getDataPathPrefix() + "android";
|
||||
ConfigManager.niceName = "system_server";
|
||||
mRouter.prepare(true);
|
||||
Zygote.reopenFilesAfterFork();
|
||||
mRouter.onEnterChildProcess();
|
||||
// reload module list if dynamic mode is on
|
||||
mRouter.loadModulesSafely(false);
|
||||
|
|
|
|||
|
|
@ -3,10 +3,10 @@ import org.gradle.internal.os.OperatingSystem
|
|||
|
||||
apply plugin: 'com.android.library'
|
||||
|
||||
version "v0.4.4.1_alpha"
|
||||
version "v0.4.4.2_alpha"
|
||||
|
||||
ext {
|
||||
versionCode = "4410"
|
||||
versionCode = "4420"
|
||||
module_name = "EdXposed"
|
||||
jar_dest_dir = "${projectDir}/template_override/system/framework/"
|
||||
is_windows = OperatingSystem.current().isWindows()
|
||||
|
|
|
|||
|
|
@ -21,20 +21,26 @@ namespace edxp {
|
|||
static constexpr auto kInjectDexPath = "/system/framework/edxp.jar:"
|
||||
"/system/framework/eddalvikdx.jar:"
|
||||
"/system/framework/eddexmaker.jar";
|
||||
|
||||
static constexpr auto kEntryClassName = "com.elderdrivers.riru.edxp.core.Main";
|
||||
static constexpr auto kClassLinkerClassName = "com.elderdrivers.riru.edxp.art.ClassLinker";
|
||||
static constexpr auto kSandHookClassName = "com.swift.sandhook.SandHook";
|
||||
static constexpr auto kSandHookNeverCallClassName = "com.swift.sandhook.ClassNeverCall";
|
||||
|
||||
static constexpr auto kLibArtName = "libart.so";
|
||||
static constexpr auto kLibFwkName = "libandroid_runtime.so";
|
||||
|
||||
static const auto kLibBasePath = std::string(LP_SELECT("/system/lib/", "/system/lib64/"));
|
||||
static const auto kLibRuntimeBasePath = std::string(LP_SELECT("/apex/com.android.runtime/lib/",
|
||||
"/apex/com.android.runtime/lib64/"));
|
||||
static const auto kLibRuntimeBasePath = std::string(
|
||||
LP_SELECT("/apex/com.android.runtime/lib/", "/apex/com.android.runtime/lib64/"));
|
||||
|
||||
static const auto kLibArtPath =
|
||||
(GetAndroidApiLevel() >= ANDROID_Q ? kLibRuntimeBasePath : kLibBasePath) + "libart.so";
|
||||
(GetAndroidApiLevel() >= ANDROID_Q ? kLibRuntimeBasePath : kLibBasePath) + kLibArtName;
|
||||
static const auto kLibWhalePath = kLibBasePath + "libwhale.edxp.so";
|
||||
static const auto kLibSandHookPath = kLibBasePath + "libsandhook.edxp.so";
|
||||
static const auto kLibFwPath = kLibBasePath + "libandroidfw.so";
|
||||
static const auto kLibDlPath = kLibBasePath + "libdl.so";
|
||||
static const auto kLibFwkPath = kLibBasePath + kLibFwkName;
|
||||
|
||||
inline const char *const BoolToString(bool b) {
|
||||
return b ? "true" : "false";
|
||||
|
|
|
|||
|
|
@ -0,0 +1,37 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <android-base/strings.h>
|
||||
#include "base/object.h"
|
||||
|
||||
namespace android {
|
||||
|
||||
// Static whitelist of open paths that the zygote is allowed to keep open.
|
||||
static const char *kPathWhitelist[] = {
|
||||
"/data/app/",
|
||||
"/data/app-private/"
|
||||
};
|
||||
|
||||
class FileDescriptorWhitelist : public edxp::HookedObject {
|
||||
|
||||
public:
|
||||
FileDescriptorWhitelist(void *thiz) : HookedObject(thiz) {}
|
||||
|
||||
static void Setup(void *handle, HookFunType hook_func) {
|
||||
HOOK_FUNC(IsAllowed,
|
||||
"_ZNK23FileDescriptorWhitelist9IsAllowedERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEE");
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
CREATE_HOOK_STUB_ENTRIES(bool, IsAllowed, void *thiz, const std::string &path) {
|
||||
for (const auto &whitelist_path : kPathWhitelist) {
|
||||
if (android::base::StartsWith(path, whitelist_path))
|
||||
return true;
|
||||
}
|
||||
return IsAllowedBackup(thiz, path);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
|
@ -16,19 +16,23 @@
|
|||
#include "art/runtime/class_linker.h"
|
||||
#include "art/runtime/gc/heap.h"
|
||||
#include "art/runtime/hidden_api.h"
|
||||
#include "framework/fd_utils.h"
|
||||
|
||||
namespace edxp {
|
||||
|
||||
static bool installed = false;
|
||||
static bool art_hooks_installed = false;
|
||||
static bool fwk_hooks_installed = false;
|
||||
static HookFunType hook_func = nullptr;
|
||||
|
||||
void InstallArtHooks(void *art_handle);
|
||||
|
||||
void InstallFwkHooks(void *fwk_handle);
|
||||
|
||||
CREATE_HOOK_STUB_ENTRIES(void *, mydlopen, const char *file_name, int flags,
|
||||
const void *caller) {
|
||||
void *handle = mydlopenBackup(file_name, flags, caller);
|
||||
if (std::string(file_name).find("libart.so") != std::string::npos) {
|
||||
if (std::string(file_name).find(kLibArtName) != std::string::npos) {
|
||||
InstallArtHooks(handle);
|
||||
}
|
||||
return handle;
|
||||
|
|
@ -69,6 +73,9 @@ namespace edxp {
|
|||
ScopedDlHandle art_handle(kLibArtPath.c_str());
|
||||
InstallArtHooks(art_handle.Get());
|
||||
}
|
||||
|
||||
ScopedDlHandle fwk_handle(kLibFwkPath.c_str());
|
||||
InstallFwkHooks(fwk_handle.Get());
|
||||
}
|
||||
|
||||
void InstallArtHooks(void *art_handle) {
|
||||
|
|
@ -85,5 +92,12 @@ namespace edxp {
|
|||
LOGI("ART hooks installed");
|
||||
}
|
||||
|
||||
void InstallFwkHooks(void *fwk_handle) {
|
||||
if (fwk_hooks_installed) {
|
||||
return;
|
||||
}
|
||||
android::FileDescriptorWhitelist::Setup(fwk_handle, hook_func);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#!/system/bin/sh
|
||||
|
||||
EDXP_VERSION="0.4.4.1_alpha (4410)"
|
||||
EDXP_VERSION="0.4.4.2_alpha (4420)"
|
||||
ANDROID_SDK=`getprop ro.build.version.sdk`
|
||||
BUILD_DESC=`getprop ro.build.description`
|
||||
PRODUCT=`getprop ro.build.product`
|
||||
|
|
|
|||
Loading…
Reference in New Issue