apsun / RemotePreferences

A drop-in solution for inter-app access to SharedPreferences.
MIT License
138 stars 32 forks source link

Exception thrown when accessing preferences from Xposed (Android 11) #13

Closed hahagu closed 3 years ago

hahagu commented 3 years ago

When using RemotePreferences on Xposed handleLoadPackage function, using the below code, exception is thrown. Therefore, the preferences are not being read correctly when it is called from a different uid.

Configuration is Device: POCO Phone F1 Android Version: Android 11 (crDroid 7.1) XPosed: EdXposed Canary (For Android 11, SandHook)

Exception: java.lang.SecurityException: Given calling package android does not match called's uid 10362

Code:

Context context = (Context) XposedHelpers.callMethod(activityThread, "getSystemContext");
pref = new RemotePreferences(context, "com.defyworks.xposed.spoofr.preferences", "main_prefs", true);

try {
    Boolean value = pref.getBoolean(lpp.packageName , false);
    LogManager.writeDebug("Pref Value for [" + lpp.packageName + "] is set " + value);
} catch (RemotePreferenceAccessException e) {
    LogManager.writeError("Could not read pref for [" + lpp.packageName + "]");
    LogManager.writeError("Reason for Error: \n" + e.getCause().toString());
}
apsun commented 3 years ago

Can you post your:

  1. AndroidManifest.xml declaration of the preference provider?

  2. Implementation of checkAccess in the preference provider, if you have one?

Also, does this only happen for the android package (tbh not sure what that is, I haven't done Xposed hooking in a long time though so my memory is fuzzy), or does it happen for all apps that you try to hook?

hahagu commented 3 years ago

Can you post your:

  1. AndroidManifest.xml declaration of the preference provider?
  2. Implementation of checkAccess in the preference provider, if you have one?

Also, does this only happen for the android package (tbh not sure what that is, I haven't done Xposed hooking in a long time though so my memory is fuzzy), or does it happen for all apps that you try to hook?

I do not have a implementation of checkAccess in place. Should it be present? Also, this happens on all packages upon hook, although that package name seems to always be shown as 'android' when using system contexts.

Preference Provider:

<provider
            android:name=".PreferenceProvider"
            android:authorities="com.defyworks.xposed.spoofr.preferences"
            android:exported="true"
            android:directBootAware="true"/>

Thanks!

apsun commented 3 years ago

I do not have a implementation of checkAccess in place. Should it be present?

If you don't override checkAccess, it will default to global read/write, so that shouldn't be the problem.

that package name seems to always be shown as 'android' when using system contexts

That seems suspicious. Can you try using the app's context instead of getSystemContext? You might have to defer the load to something later in the application startup instead of executing the logic directly in handleLoadPackage so that you can actually get a context object.

(No idea why this is happening, this is just my guess)

hahagu commented 3 years ago

I do not have a implementation of checkAccess in place. Should it be present?

If you don't override checkAccess, it will default to global read/write, so that shouldn't be the problem.

that package name seems to always be shown as 'android' when using system contexts

That seems suspicious. Can you try using the app's context instead of getSystemContext? You might have to defer the load to something later in the application startup instead of executing the logic directly in handleLoadPackage so that you can actually get a context object.

(No idea why this is happening, this is just my guess)

Not sure on how I would do that, but I will report back :)

apsun commented 3 years ago

You can try something like this: https://github.com/apsun/NekoSMS/blob/master/app/src/main/java/com/crossbowffs/nekosms/xposed/SmsHandlerHook.java#L186

Basically, instead of trying to read the preference immediately at load, read it from where you want to actually do the hooking, and there will be a context object nearby in the call stack that you can use.

hahagu commented 3 years ago

You can try something like this: https://github.com/apsun/NekoSMS/blob/master/app/src/main/java/com/crossbowffs/nekosms/xposed/SmsHandlerHook.java#L186

Basically, instead of trying to read the preference immediately at load, read it from where you want to actually do the hooking, and there will be a context object nearby in the call stack that you can use.

try{
XposedHelpers.findAndHookMethod(Activity.class, "onResume", new XC_MethodHook(){
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
Context context = (Activity) param.getResult();
LogManager.writeDebug("Hooked to package [" + context.getClass().getName() + "]");
Context alternateContext = AndroidAppHelper.currentApplication();
LogManager.writeDebug("Alternate Hook is [" + alternateContext.getClass().getName() + "]");
pref = new RemotePreferences(context, "com.defyworks.xposed.spoofr.preferences", "main_prefs", true);
}
});
} catch (NoSuchMethodError e) {
LogManager.writeDebug("Could Not Hook Method");
return;
}

Would this kind of a code work then?

Edit:

Just tried, null object reference. Also, the log doesn't seem to be written for some reason?

apsun commented 3 years ago

onResume returns void. You probably want param.thisObject instead.

hahagu commented 3 years ago

onResume returns void. You probably want param.thisObject instead.

I'm sorry to bother you. I'm quite new in writing for xposed, and I this is in fact my first module. param.thisObject solves the issue for reading the config file.

Thanks!

apsun commented 3 years ago

That's good to hear :-)

I will add a notice not to use the system context in the readme, thanks for exposing (heh) this issue!

hahagu commented 3 years ago

That's good to hear :-)

I will add a notice not to use the system context in the readme, thanks for exposing (heh) this issue!

Glad to have helped in some way :) I was just stuck on my problem lol