Fix XSharedPreference permission

This commit is contained in:
LoveSy 2020-12-15 15:35:19 +08:00 committed by kotori0
parent 7c2efab7e0
commit 57f15c1fc1
4 changed files with 33 additions and 16 deletions

View File

@ -1,11 +1,12 @@
package com.elderdrivers.riru.edxp._hooker.impl; package com.elderdrivers.riru.edxp._hooker.impl;
import android.annotation.SuppressLint;
import android.app.ActivityThread; import android.app.ActivityThread;
import android.app.ContextImpl; import android.app.ContextImpl;
import android.app.LoadedApk; import android.app.LoadedApk;
import android.content.ComponentName; import android.content.ComponentName;
import android.content.Context;
import android.content.pm.ApplicationInfo; import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.res.CompatibilityInfo; import android.content.res.CompatibilityInfo;
import android.content.res.XResources; import android.content.res.XResources;
@ -26,7 +27,7 @@ import de.robv.android.xposed.XposedInit;
public class HandleBindApp extends XC_MethodHook { public class HandleBindApp extends XC_MethodHook {
@Override @Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable { protected void beforeHookedMethod(MethodHookParam param) {
try { try {
Hookers.logD("ActivityThread#handleBindApplication() starts"); Hookers.logD("ActivityThread#handleBindApplication() starts");
ActivityThread activityThread = (ActivityThread) param.thisObject; ActivityThread activityThread = (ActivityThread) param.thisObject;
@ -59,25 +60,35 @@ public class HandleBindApp extends XC_MethodHook {
boolean isModule = false; boolean isModule = false;
int xposedminversion = -1; int xposedminversion = -1;
boolean xposedsharedprefs = false;
try { try {
ApkParser ap = ApkParser.create(new File(appInfo.sourceDir)); ApkParser ap = ApkParser.create(new File(appInfo.sourceDir));
isModule = ap.getApkMeta().metaData.containsKey("xposedmodule"); isModule = ap.getApkMeta().metaData.containsKey("xposedmodule");
if(isModule) if (isModule) {
xposedminversion = Integer.parseInt(ap.getApkMeta().metaData.get("xposedminversion")); xposedminversion = Integer.parseInt(ap.getApkMeta().metaData.get("xposedminversion"));
xposedsharedprefs = ap.getApkMeta().metaData.containsKey("xposedsharedprefs");
}
} catch (NumberFormatException | IOException e) { } catch (NumberFormatException | IOException e) {
Hookers.logE("ApkParser fails", e); Hookers.logE("ApkParser fails", e);
} }
if (isModule && xposedminversion > 92) { if (isModule && (xposedminversion > 92 || xposedsharedprefs)) {
Utils.logW("New modules detected, hook preferences"); Utils.logW("New modules detected, hook preferences");
XposedHelpers.findAndHookMethod(ContextImpl.class, "getSharedPreferences", File.class, int.class, new XC_MethodHook() { XposedHelpers.findAndHookMethod(ContextImpl.class, "checkMode", int.class, new XC_MethodHook() {
@SuppressWarnings("deprecation")
@SuppressLint("WorldReadableFiles")
@Override @Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable { protected void afterHookedMethod(MethodHookParam param) {
String fileName = ((File) param.args[0]).getName(); if (((int) param.args[0] & Context.MODE_WORLD_READABLE) != 0) {
File file = new File(ConfigManager.getPrefsPath(appInfo.packageName), fileName); param.setThrowable(null);
file.createNewFile(); }
file.setReadable(true, false); }
param.args[0] = file; });
XposedHelpers.findAndHookMethod(ContextImpl.class, "getPreferencesDir", new XC_MethodHook() {
@SuppressLint({"SetWorldReadable", "WorldReadableFiles"})
@Override
protected void afterHookedMethod(MethodHookParam param) {
param.setResult(new File(ConfigManager.getPrefsPath(appInfo.packageName)));
} }
}); });
} }

View File

@ -227,7 +227,7 @@ namespace edxp {
if (!app_pkg_name.empty()) if (!app_pkg_name.empty())
scope.emplace(std::move(app_pkg_name)); scope.emplace(std::move(app_pkg_name));
} }
if(!scope.empty()) if (!scope.empty())
scope.insert(module_pkg_name); // Always add module itself scope.insert(module_pkg_name); // Always add module itself
if (IsInstaller(module_pkg_name)) scope.erase("android"); if (IsInstaller(module_pkg_name)) scope.erase("android");
LOGI("scope of %s is:\n%s", module_pkg_name.c_str(), ([&scope = scope]() { LOGI("scope of %s is:\n%s", module_pkg_name.c_str(), ([&scope = scope]() {
@ -295,7 +295,10 @@ namespace edxp {
} }
fs::permissions(prefs_path, fs::perms::owner_all | fs::perms::group_all | fs::permissions(prefs_path, fs::perms::owner_all | fs::perms::group_all |
fs::perms::others_exec); fs::perms::others_exec);
path_chown(prefs_path, uid, 0); if (const auto &[r_uid, r_gid] = path_own(prefs_path);
(uid != -1 && r_uid != uid) || r_gid != 1000u) {
path_chown(prefs_path, uid, 1000u, false);
}
} }
if (IsInstaller(pkg_name) || pkg_name == "android") { if (IsInstaller(pkg_name) || pkg_name == "android") {
auto conf_path = GetConfigPath(); auto conf_path = GetConfigPath();

View File

@ -5,7 +5,7 @@ android {
ndkVersion androidCompileNdkVersion ndkVersion androidCompileNdkVersion
defaultConfig { defaultConfig {
minSdkVersion minSdkVersion minSdkVersion androidMinSdkVersion.toInteger()
} }
sourceSets { sourceSets {

View File

@ -75,15 +75,18 @@ public final class XSharedPreferences implements SharedPreferences {
if (m.contains("/" + packageName + "-")) { if (m.contains("/" + packageName + "-")) {
boolean isModule = false; boolean isModule = false;
int xposedminversion = -1; int xposedminversion = -1;
boolean xposedsharedprefs = false;
try { try {
ApkParser ap = ApkParser.create(new File(m)); ApkParser ap = ApkParser.create(new File(m));
isModule = ap.getApkMeta().metaData.containsKey("xposedmodule"); isModule = ap.getApkMeta().metaData.containsKey("xposedmodule");
if(isModule) if(isModule) {
xposedminversion = Integer.parseInt(ap.getApkMeta().metaData.get("xposedminversion")); xposedminversion = Integer.parseInt(ap.getApkMeta().metaData.get("xposedminversion"));
xposedsharedprefs = ap.getApkMeta().metaData.containsKey("xposedsharedprefs");
}
} catch (NumberFormatException | IOException e) { } catch (NumberFormatException | IOException e) {
Log.w(TAG, "Apk parser fails: " + e); Log.w(TAG, "Apk parser fails: " + e);
} }
newModule = isModule && xposedminversion > 92; newModule = isModule && (xposedminversion > 92 || xposedsharedprefs);
} }
} }
if (newModule && XposedInit.prefsBasePath != null) { if (newModule && XposedInit.prefsBasePath != null) {