Fix resource hook on MediaTek (#1951)
This commit is contained in:
parent
05129a0dd8
commit
8febd8cc7a
|
|
@ -20,10 +20,11 @@
|
||||||
|
|
||||||
package de.robv.android.xposed;
|
package de.robv.android.xposed;
|
||||||
|
|
||||||
import static de.robv.android.xposed.XposedHelpers.setObjectField;
|
|
||||||
|
|
||||||
import android.app.ActivityThread;
|
import android.app.ActivityThread;
|
||||||
|
import android.content.ContextWrapper;
|
||||||
|
import android.content.pm.ApplicationInfo;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
|
import android.content.res.ResourcesImpl;
|
||||||
import android.content.res.TypedArray;
|
import android.content.res.TypedArray;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
|
@ -50,7 +51,6 @@ import de.robv.android.xposed.callbacks.XC_LoadPackage;
|
||||||
* This class contains most of Xposed's central logic, such as initialization and callbacks used by
|
* This class contains most of Xposed's central logic, such as initialization and callbacks used by
|
||||||
* the native side. It also includes methods to add new hooks.
|
* the native side. It also includes methods to add new hooks.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("JniMissingFunction")
|
|
||||||
public final class XposedBridge {
|
public final class XposedBridge {
|
||||||
/**
|
/**
|
||||||
* The system class loader which can be used to locate Android framework classes.
|
* The system class loader which can be used to locate Android framework classes.
|
||||||
|
|
@ -133,10 +133,29 @@ public final class XposedBridge {
|
||||||
ResourcesHook.makeInheritable(resClass);
|
ResourcesHook.makeInheritable(resClass);
|
||||||
ResourcesHook.makeInheritable(taClass);
|
ResourcesHook.makeInheritable(taClass);
|
||||||
ClassLoader myCL = XposedBridge.class.getClassLoader();
|
ClassLoader myCL = XposedBridge.class.getClassLoader();
|
||||||
|
assert myCL != null;
|
||||||
dummyClassLoader = ResourcesHook.buildDummyClassLoader(myCL.getParent(), resClass.getName(), taClass.getName());
|
dummyClassLoader = ResourcesHook.buildDummyClassLoader(myCL.getParent(), resClass.getName(), taClass.getName());
|
||||||
dummyClassLoader.loadClass("xposed.dummy.XResourcesSuperClass");
|
dummyClassLoader.loadClass("xposed.dummy.XResourcesSuperClass");
|
||||||
dummyClassLoader.loadClass("xposed.dummy.XTypedArraySuperClass");
|
dummyClassLoader.loadClass("xposed.dummy.XTypedArraySuperClass");
|
||||||
setObjectField(myCL, "parent", dummyClassLoader);
|
XposedHelpers.setObjectField(myCL, "parent", dummyClassLoader);
|
||||||
|
|
||||||
|
var contextField = XposedHelpers.findFieldIfExists(ResourcesImpl.class, "mAppContext");
|
||||||
|
// Used by com.mediatek.res.AsyncDrawableCache.putCacheList
|
||||||
|
if (contextField != null) {
|
||||||
|
var mediatekCompat = new ContextWrapper(null) {
|
||||||
|
private final ApplicationInfo info = new ApplicationInfo();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ApplicationInfo getApplicationInfo() {
|
||||||
|
info.processName = "system";
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// This field will be updated to correct value
|
||||||
|
// after ContextImpl.createAppContext
|
||||||
|
contextField.set(null, mediatekCompat);
|
||||||
|
}
|
||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
XposedBridge.log(throwable);
|
XposedBridge.log(throwable);
|
||||||
XposedInit.disableResources = true;
|
XposedInit.disableResources = true;
|
||||||
|
|
@ -405,7 +424,7 @@ public final class XposedBridge {
|
||||||
} else {
|
} else {
|
||||||
returnType = null;
|
returnType = null;
|
||||||
}
|
}
|
||||||
params = new Object[] {
|
params = new Object[]{
|
||||||
method,
|
method,
|
||||||
returnType,
|
returnType,
|
||||||
isStatic,
|
isStatic,
|
||||||
|
|
|
||||||
|
|
@ -22,11 +22,13 @@ package org.lsposed.lspd.service;
|
||||||
import static org.lsposed.lspd.service.ServiceManager.TAG;
|
import static org.lsposed.lspd.service.ServiceManager.TAG;
|
||||||
import static org.lsposed.lspd.service.ServiceManager.toGlobalNamespace;
|
import static org.lsposed.lspd.service.ServiceManager.toGlobalNamespace;
|
||||||
|
|
||||||
|
import android.content.ContextWrapper;
|
||||||
|
import android.content.pm.ApplicationInfo;
|
||||||
import android.content.res.AssetManager;
|
import android.content.res.AssetManager;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
|
import android.content.res.ResourcesImpl;
|
||||||
import android.os.ParcelFileDescriptor;
|
import android.os.ParcelFileDescriptor;
|
||||||
import android.os.Process;
|
import android.os.Process;
|
||||||
import android.os.RemoteException;
|
|
||||||
import android.os.SELinux;
|
import android.os.SELinux;
|
||||||
import android.os.SharedMemory;
|
import android.os.SharedMemory;
|
||||||
import android.system.ErrnoException;
|
import android.system.ErrnoException;
|
||||||
|
|
@ -134,12 +136,30 @@ public class ConfigFileManager {
|
||||||
Method addAssetPath = AssetManager.class.getDeclaredMethod("addAssetPath", String.class);
|
Method addAssetPath = AssetManager.class.getDeclaredMethod("addAssetPath", String.class);
|
||||||
addAssetPath.setAccessible(true);
|
addAssetPath.setAccessible(true);
|
||||||
//noinspection ConstantConditions
|
//noinspection ConstantConditions
|
||||||
if ((int) addAssetPath.invoke(am, daemonApkPath.toString()) > 0)
|
if ((int) addAssetPath.invoke(am, daemonApkPath.toString()) > 0) {
|
||||||
//noinspection deprecation
|
//noinspection deprecation
|
||||||
res = new Resources(am, null, null);
|
res = new Resources(am, null, null);
|
||||||
|
}
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
Log.e(TAG, Log.getStackTraceString(e));
|
Log.e(TAG, Log.getStackTraceString(e));
|
||||||
}
|
}
|
||||||
|
try {
|
||||||
|
@SuppressWarnings("JavaReflectionMemberAccess")
|
||||||
|
var contextField = ResourcesImpl.class.getDeclaredField("mAppContext");
|
||||||
|
contextField.setAccessible(true);
|
||||||
|
var mediatekCompat = new ContextWrapper(null) {
|
||||||
|
private final ApplicationInfo info = new ApplicationInfo();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ApplicationInfo getApplicationInfo() {
|
||||||
|
info.processName = "system";
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
contextField.set(null, mediatekCompat);
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
// Not a MediaTek device
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void reloadConfiguration() {
|
static void reloadConfiguration() {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue