Skip to content

Commit

Permalink
add support for v4.2.5 and use DexKit for not tested versions
Browse files Browse the repository at this point in the history
  • Loading branch information
Juby210 committed Oct 27, 2023
1 parent 7c3035c commit 876f7ce
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 17 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# SwiftBackupPrem
Swift Backup Premium LSPosed module (tested on v4.2.3).
Swift Backup Premium LSPosed module (tested on v4.2.3 and v4.2.5, but should also work on newer versions - thanks to [DexKit](https://github.com/LuckyPray/DexKit)).

Optionally also allows you to set your own firebase credentials, so only your firebase instance is used.

Expand Down
5 changes: 3 additions & 2 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ android {
applicationId = "io.github.juby210.swiftbackupprem"
minSdk = 27
targetSdk = 34
versionCode = 200
versionName = "2.0.0"
versionCode = 201
versionName = "2.0.1"
}

buildTypes {
Expand Down Expand Up @@ -50,6 +50,7 @@ android {

dependencies {
compileOnly("de.robv.android.xposed:api:82")
implementation("org.luckypray:dexkit:2.0.0-rc7")

// AndroidX
implementation("androidx.core:core-ktx:1.12.0")
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
android:value="true" />
<meta-data
android:name="xposeddescription"
android:value="Swift Backup Premium (tested on v4.2.3)" />
android:value="Swift Backup Premium" />
<meta-data
android:name="xposedminversion"
android:value="93" />
Expand Down
3 changes: 3 additions & 0 deletions app/src/main/java/io/github/juby210/swiftbackupprem/Consts.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,7 @@ object Consts {
const val gcmDefaultSenderId = "gcm_defaultSenderId"
const val googleStorageBucket = "google_storage_bucket"
const val projectId = "project_id"

@JvmStatic
val classNames = mapOf(561 to "kf.s0", 569 to "rf.r0")
}
75 changes: 63 additions & 12 deletions app/src/main/java/io/github/juby210/swiftbackupprem/Module.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
package io.github.juby210.swiftbackupprem;

import android.content.Context;
import android.widget.Toast;

import org.luckypray.dexkit.DexKitBridge;
import org.luckypray.dexkit.query.FindClass;
import org.luckypray.dexkit.query.matchers.*;

import java.lang.reflect.Modifier;
import java.util.Arrays;

import de.robv.android.xposed.*;
Expand All @@ -10,6 +16,7 @@

public final class Module implements IXposedHookLoadPackage {
public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) throws Throwable {
if (!lpparam.packageName.equals("org.swiftapps.swiftbackup")) return;
System.loadLibrary("nativelib");

var xPrefs = new XSharedPreferences(BuildConfig.APPLICATION_ID);
Expand Down Expand Up @@ -48,23 +55,67 @@ public void beforeHookedMethod(MethodHookParam param) throws Throwable {
prefs.getProjectId()
)
);
} else c.getDeclaredMethod("initializeApp", Context.class).invoke(null, param.thisObject);

var ctx = (Context) param.thisObject;
var ver = Integer.valueOf(ctx.getPackageManager().getPackageInfo(lpparam.packageName, 0).versionCode);
var classNames = Consts.getClassNames();
Class<?> classClientId;
if (classNames.containsKey(ver)) classClientId = cl.loadClass(classNames.get(ver));
else {
System.loadLibrary("dexkit");
try (DexKitBridge bridge = DexKitBridge.create(lpparam.appInfo.sourceDir)) {
var classData = bridge.findClass(
FindClass.create()
.excludePackages("android", "androidx", "com", "iammert", "java", "javax", "kotlin", "kotlinx", "moe", "nz.mega",
"okhttp3", "okio", "org", "retrofit", "rikka")
.matcher(
ClassMatcher.create()
.fields(
FieldsMatcher.create()
.add(FieldMatcher.create().modifiers(Modifier.PUBLIC | Modifier.STATIC | Modifier.FINAL).name("a"))
.add(FieldMatcher.create().modifiers(Modifier.PRIVATE | Modifier.STATIC | Modifier.FINAL).name("b"))
.add(FieldMatcher.create().modifiers(Modifier.PRIVATE | Modifier.STATIC | Modifier.FINAL).name("c")
.type("java.lang.String"))
.add(FieldMatcher.create().modifiers(Modifier.PRIVATE | Modifier.STATIC | Modifier.FINAL).name("d")
.type("android.net.Uri"))
.count(4)
)
.addMethod(
MethodMatcher.create()
.modifiers(Modifier.PUBLIC | Modifier.FINAL)
.returnType("android.content.Intent")
.name("f")
.addParamType("boolean")
)
)
).firstOrNull();

if (classData == null) {
Toast.makeText(
ctx,
"[SBP] Couldn't fully hook Swift Backup. Check if there's module update or report an issue.",
Toast.LENGTH_LONG
).show();
classClientId = null;
} else classClientId = classData.getInstance(cl);
}
}

if (classClientId != null) {
XposedBridge.hookMethod(classClientId.getDeclaredMethod("f", boolean.class), new XC_MethodHook() {
public void beforeHookedMethod(MethodHookParam param) throws Throwable {
var clientId = c.getDeclaredField("c");
clientId.setAccessible(true);
clientId.set(null, prefs.getClientId());
}
});
}
} else c.getDeclaredMethod("initializeApp", Context.class).invoke(null, param.thisObject);
}
});

if (customFirebaseApp) {
var c = cl.loadClass("kf.s0");
XposedBridge.hookMethod(c.getDeclaredMethod("f", boolean.class), new XC_MethodHook() {
public void beforeHookedMethod(MethodHookParam param) throws Throwable {
var clientId = c.getDeclaredField("c");
clientId.setAccessible(true);
clientId.set(null, prefs.getClientId());
}
});

if (customFirebaseApp)
XposedHelpers.findAndHookMethod("org.swiftapps.swiftbackup.cloud.d", cl, "d", XC_MethodReplacement.returnConstant(Boolean.FALSE));
}

var c = cl.loadClass("org.swiftapps.swiftbackup.common.V$a");
for (var m : c.getDeclaredMethods()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ class PreferencesManager(private val prefs: SharedPreferences) {
getter: (key: String, defaultValue: T) -> T,
private val setter: (key: String, newValue: T) -> Unit
) {
@Suppress("RedundantSetter")
var value by mutableStateOf(getter(key, defaultValue))
private set

Expand Down

0 comments on commit 876f7ce

Please sign in to comment.