From 3a9df5f3175384b6a0661267fb59f51021109d83 Mon Sep 17 00:00:00 2001 From: Christian Weiske Date: Thu, 30 Jan 2020 21:36:29 +0100 Subject: [PATCH 1/1] --- README.rst | 1 + xposed.java | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+) create mode 100644 README.rst create mode 100644 xposed.java diff --git a/README.rst b/README.rst new file mode 100644 index 0000000..c841727 --- /dev/null +++ b/README.rst @@ -0,0 +1 @@ +It did not work. FF3 still crashes. \ No newline at end of file diff --git a/xposed.java b/xposed.java new file mode 100644 index 0000000..fc63f6c --- /dev/null +++ b/xposed.java @@ -0,0 +1,72 @@ +import java.lang.reflect.Method; + +import de.robv.android.xposed.IXposedHookCmdInit; +import de.robv.android.xposed.XC_MethodHook; +import de.robv.android.xposed.XposedBridge; +import de.robv.android.xposed.XposedHelpers; +import de.robv.android.xposed.callbacks.XC_LoadPackage; + +public class Mypackage implements IXposedHookCmdInit +{ + @Override + public void initCmdApp(StartupParam startupParam) throws Throwable { + if (!startupParam.startClassName.equals("com.android.commands.pm.Pm")) { + return; + } + //XposedBridge.log("startup:" + startupParam.startClassName); + + /* + Final Fantasy 3 has a native library lib__57d5__.so that tries to clear the data + for all apk files in /data/app/. We do not know why. + + It fails to do this for root-owned packages like this xposed module. + See + https://forum.xda-developers.com/xposed/framework-xposed-rom-modding-modifying-t1574401/page170#1700 + + We simply prevent it from doing that. + + https://android.googlesource.com/platform/frameworks/base/+/refs/tags/android-4.1.2_r1/core/java/android/app/ActivityManagerNative.java#2880 + + public boolean clearApplicationUserData( + String packageName, IPackageDataObserver observer, final int userId + ) + */ + XposedHelpers.findAndHookMethod( + "android.app.ActivityManagerProxy", + null, + "clearApplicationUserData", + String.class, + "android.content.pm.IPackageDataObserver", + int.class, + new XC_MethodHook() { + @Override + protected void beforeHookedMethod(MethodHookParam param) throws Throwable { + String packageName = (String) param.args[0]; + XposedBridge.log("clearApplicationUserData: " + packageName); + if (!packageName.equals("mypackage")) { + return; + } + + param.setResult(true); + + //we do not have direct access to IPackageDataObserver, so we have to dance + Object observer = param.args[1]; + if(observer != null) { + Class iPackageDataObserverClass = Class.forName("android.content.pm.IPackageDataObserver"); + Class[] paramTypes = {String.class, boolean.class}; + Method onRemoveCompletedMethod = iPackageDataObserverClass.getMethod("onRemoveCompleted", paramTypes); + Object[] params = {packageName, true}; + try { + onRemoveCompletedMethod.invoke(observer, params); + //observer.onRemoveCompleted(packageName, true); + } catch (Exception e) { + XposedBridge.log("Observer no longer exists."); + } + } + //end dance + } + } + ); + + } +} -- 2.30.2