Skip to content

Commit

Permalink
Add Xposed back (for GitHub releases only), closes #8
Browse files Browse the repository at this point in the history
  • Loading branch information
TacoTheDank committed Apr 27, 2021
1 parent f1c153f commit 8f3477f
Show file tree
Hide file tree
Showing 9 changed files with 240 additions and 1 deletion.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ Extremely useful for app debugging.

Scoop supports both rooted and non-rooted devices (though non-rooted devices require some [setup](https://github.com/TacoTheDank/Scoop#guide)).

Scoop also supports Xposed, but only the GitHub releases will do so. F-Droid releases will [NOT](https://github.com/TacoTheDank/Scoop/issues/8#issuecomment-827222534) support Xposed.
If you want to use Scoop with Xposed, you must use the release builds from the GitHub repository.

Features:
- Search (apps, stack traces)
Expand All @@ -41,7 +43,6 @@ Most important differences with this fork:
- Lots of under-the-hood improvements
- Using topjohnwu's libsu
- App now has an adaptive icon
- Removed Xposed support

You can also read the release notes for changes that have been made to the app since then.

Expand Down
16 changes: 16 additions & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,18 @@ android {
preDexLibraries true
}

flavorDimensions "dimension"
productFlavors {
// No Xposed support
fdroid {
dimension "dimension"
}
// Xposed support
github {
dimension "dimension"
}
}

buildTypes {
release {
minifyEnabled true
Expand Down Expand Up @@ -59,6 +71,10 @@ android {
}

dependencies {
// Xposed (only for GitHub release builds)
githubCompileOnly files('libs/xposed-api-82.jar')
githubCompileOnly files('libs/xposed-api-82-sources.jar')

// Kotlin
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"

Expand Down
Binary file added app/libs/xposed-api-82-sources.jar
Binary file not shown.
Binary file added app/libs/xposed-api-82.jar
Binary file not shown.
4 changes: 4 additions & 0 deletions app/proguard-rules.pro
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,9 @@

-dontobfuscate

-keep class tk.wasdennnoch.scoop.XposedHook
-keep class tk.wasdennnoch.scoop.MockThrowable { *; }
-keep class androidx.appcompat.widget.SearchView { *; }
-keep class tk.wasdennnoch.scoop.data.crash.Crash { *; }

-keep class de.robv.android.xposed.** { *; }
103 changes: 103 additions & 0 deletions app/src/github/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="tk.wasdennnoch.scoop"
android:installLocation="internalOnly">

<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission
android:name="android.permission.READ_LOGS"
tools:ignore="ProtectedPermissions" />

<application
android:name=".ScoopApplication"
android:allowBackup="true"
android:fullBackupContent="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<meta-data
android:name="xposedmodule"
android:value="true" />
<meta-data
android:name="xposedminversion"
android:value="82" />
<meta-data
android:name="preloaded_fonts"
android:resource="@array/preloaded_fonts" />

<activity
android:name=".ui.MainActivity"
android:configChanges="orientation|screenSize|screenLayout"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
<category android:name="de.robv.android.xposed.category.MODULE_SETTINGS" />
</intent-filter>
</activity>
<activity
android:name=".ui.DetailActivity"
android:parentActivityName=".ui.MainActivity"
tools:ignore="UnusedAttribute">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".ui.MainActivity" />
</activity>
<activity
android:name=".ui.SettingsActivity"
android:label="@string/settings_title">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.NOTIFICATION_PREFERENCES" />
</intent-filter>
</activity>
<activity
android:name=".ui.BlacklistAppsActivity"
android:label="@string/blacklist_title" />
<activity
android:name=".ui.AboutActivity"
android:label="@string/about_title" />

<receiver
android:name=".receiver.CrashReceiver"
android:exported="true"
tools:ignore="ExportedReceiver">
<intent-filter>
<action android:name="tk.wasdennnoch.scoop.EXCEPTION" />
</intent-filter>
</receiver>
<receiver
android:name=".receiver.ShareReceiver"
android:exported="true"
tools:ignore="ExportedReceiver">
<intent-filter>
<action android:name="tk.wasdennnoch.scoop.ACTION_SHARE" />
<action android:name="tk.wasdennnoch.scoop.ACTION_COPY" />
</intent-filter>
</receiver>

<service
android:name=".IndicatorService"
android:enabled="true" />

<receiver
android:name=".receiver.StopReceiver"
android:enabled="true" />

<service
android:name=".detector.CrashDetectorService"
android:enabled="true"
android:process=":crashDetectorService" />
<service
android:name=".dogbin.DogbinUploadService"
android:enabled="true"
android:exported="false" />
</application>

</manifest>
1 change: 1 addition & 0 deletions app/src/github/assets/xposed_init
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
tk.wasdennnoch.scoop.XposedHook
111 changes: 111 additions & 0 deletions app/src/github/java/tk/wasdennnoch/scoop/XposedHook.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
package tk.wasdennnoch.scoop;

import android.app.Application;
import android.content.Intent;
import android.util.Log;

import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XC_MethodReplacement;
import de.robv.android.xposed.XposedHelpers;
import de.robv.android.xposed.callbacks.XC_LoadPackage;
import tk.wasdennnoch.scoop.receiver.CrashReceiver;

@SuppressWarnings("WeakerAccess")
public class XposedHook implements IXposedHookLoadPackage {

private static String mPkg;
private Application mApplication;
private boolean mSent;
private final XC_MethodHook uncaughtExceptionHook = new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
if (mSent) {
Log.d("scoop", "uncaughtExceptionHook (" + mPkg + "): Broadcast already sent");
return;
}
Log.d("scoop", "uncaughtExceptionHook (" + mPkg + "): Sending broadcast");
Throwable t = (Throwable) param.args[1];
Intent intent = new Intent(Intents.INTENT_ACTION)
.setClassName(BuildConfig.APPLICATION_ID, CrashReceiver.class.getName())
.putExtra(Intents.INTENT_PACKAGE_NAME, mApplication.getPackageName())
.putExtra(Intents.INTENT_TIME, System.currentTimeMillis())
.putExtra(Intents.INTENT_DESCRIPTION, t.toString())
.putExtra(Intents.INTENT_STACKTRACE, Log.getStackTraceString(t));
// Just send everything here because it costs no performance (well, technically
// it does, but the process is about to die anyways, so I don't care).
// Also I have no idea how to detect custom subclasses efficiently.
mApplication.sendBroadcast(intent);
mSent = true; // Doesn't need to be reset as process dies soon
}
};
private final XC_MethodHook setUncaughtExceptionHandlerHook = new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
if (param.args[0] != null)
hookUncaughtException(param.args[0].getClass());
}
};

@Override
public void handleLoadPackage(final XC_LoadPackage.LoadPackageParam lpparam) throws Throwable {
if (lpparam.packageName.equals("android")) return;
mPkg = lpparam.packageName;
XposedHelpers.findAndHookConstructor(Application.class, new XC_MethodHook() {
@Override
protected void beforeHookedMethod(XC_MethodHook.MethodHookParam param) throws Throwable {
mApplication = (Application) param.thisObject;
mSent = false;
}
});
XposedHelpers.findAndHookMethod(
Thread.class,
"setDefaultUncaughtExceptionHandler",
Thread.UncaughtExceptionHandler.class,
setUncaughtExceptionHandlerHook);

XposedHelpers.findAndHookMethod(
Thread.class,
"setUncaughtExceptionHandler",
Thread.UncaughtExceptionHandler.class,
setUncaughtExceptionHandlerHook);

XposedHelpers.findAndHookMethod(
ThreadGroup.class,
"uncaughtException",
Thread.class,
Throwable.class,
uncaughtExceptionHook);

// Gets initialized in between native application creation, handleLoadPackage gets
// called after native creation
hookUncaughtException(Thread.getDefaultUncaughtExceptionHandler().getClass());

if (lpparam.packageName.equals(BuildConfig.APPLICATION_ID)) {
XposedHelpers.findAndHookMethod(
ScoopApplication.class,
"xposedActive",
XC_MethodReplacement.returnConstant(true));
}
}

private void hookUncaughtException(Class<?> clazz) {
int i = 0;
do { // Search through superclasses
try {
XposedHelpers.findAndHookMethod(
clazz,
"uncaughtException",
Thread.class,
Throwable.class,
uncaughtExceptionHook);
Log.d("scoop", "hookUncaughtException (" + mPkg
+ "): Hooked class " + clazz.getName() + " after " + i + " loops");
return;
} catch (Throwable ignore) {
}
i++;
} while ((clazz = clazz.getSuperclass()) != null);
Log.d("scoop", "hookUncaughtException (" + mPkg + "): No class found to hook!");
}
}
3 changes: 3 additions & 0 deletions fastlane/metadata/android/en-US/full_description.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ Extremely useful for app debugging.

Scoop supports both rooted and non-rooted devices (though non-rooted devices require some setup; see the repository wiki for details).

Scoop also supports Xposed, but only the GitHub releases will do so. F-Droid releases will NOT support Xposed.
If you want to use Scoop with Xposed, you must use the release builds from the GitHub repository.

Features:
- Search (apps, stack traces)
- Crash preview in notifications (configurable in settings)
Expand Down

0 comments on commit 8f3477f

Please sign in to comment.