Skip to content

Commit

Permalink
feat(Discord): Add Plugin loader patch
Browse files Browse the repository at this point in the history
  • Loading branch information
oSumAtrIX committed Sep 13, 2024
1 parent 96e03ca commit d4ac006
Show file tree
Hide file tree
Showing 7 changed files with 127 additions and 0 deletions.
13 changes: 13 additions & 0 deletions api/revanced-patches.api
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,11 @@ public final class app/revanced/patches/cieid/restrictions/root/BypassRootChecks
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
}

public final class app/revanced/patches/discord/misc/plugin/PluginLoaderPatch : app/revanced/patches/shared/misc/react/BaseReactPreloadScriptBootstrapperPatch {
public static final field INSTANCE Lapp/revanced/patches/discord/misc/plugin/PluginLoaderPatch;
public fun getIntegrationsClassDescriptor ()Ljava/lang/String;
}

public final class app/revanced/patches/duolingo/ad/DisableAdsPatch : app/revanced/patcher/patch/BytecodePatch {
public static final field INSTANCE Lapp/revanced/patches/duolingo/ad/DisableAdsPatch;
public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V
Expand Down Expand Up @@ -960,6 +965,14 @@ public final class app/revanced/patches/shared/misc/mapping/ResourceMappingPatch
public fun toString ()Ljava/lang/String;
}

public abstract class app/revanced/patches/shared/misc/react/BaseReactPreloadScriptBootstrapperPatch : app/revanced/patcher/patch/BytecodePatch {
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/util/Set;Ljava/util/Set;ZLjava/util/Set;Lkotlin/Pair;)V
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/util/Set;Ljava/util/Set;ZLjava/util/Set;Lkotlin/Pair;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
public abstract fun getIntegrationsClassDescriptor ()Ljava/lang/String;
}

public abstract class app/revanced/patches/shared/misc/settings/BaseSettingsResourcePatch : app/revanced/patcher/patch/ResourcePatch, java/io/Closeable, java/util/Set, kotlin/jvm/internal/markers/KMutableSet {
public fun <init> ()V
public fun <init> (Lkotlin/Pair;Ljava/util/Set;)V
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package app.revanced.patches.discord.misc.plugin

import app.revanced.patches.discord.misc.plugin.fingerprints.MainActivityOnCreateFingerprint
import app.revanced.patches.shared.misc.react.BaseReactPreloadScriptBootstrapperPatch

@Suppress("unused")
object PluginLoaderPatch : BaseReactPreloadScriptBootstrapperPatch(
name = "Plugin loader",
description = "Bootstraps a plugin loader.",
mainActivityOnCreateFingerprintInsertIndexPair = MainActivityOnCreateFingerprint to 2,
) {
override val integrationsClassDescriptor = "Lapp/revanced/integrations/discord/plugin/BunnyBootstrapperPatch;"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package app.revanced.patches.discord.misc.plugin.fingerprints

import app.revanced.patcher.fingerprint.MethodFingerprint

internal object MainActivityOnCreateFingerprint : MethodFingerprint(
customFingerprint = { method, classDef -> method.name == "onCreate" && classDef.endsWith("ReactActivity;") },
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package app.revanced.patches.shared.misc.react

import app.revanced.patcher.PatchClass
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.getInstructions
import app.revanced.patcher.fingerprint.MethodFingerprint
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMutable
import app.revanced.patches.shared.misc.react.fingerprints.LoadScriptFromAssetsFingerprint
import app.revanced.patches.shared.misc.react.fingerprints.LoadScriptFromFileFingerprint
import app.revanced.util.resultOrThrow
import com.android.tools.smali.dexlib2.builder.MutableMethodImplementation
import com.android.tools.smali.dexlib2.immutable.ImmutableMethod

abstract class BaseReactPreloadScriptBootstrapperPatch(
name: String? = null,
description: String? = null,
compatiblePackages: Set<CompatiblePackage>? = null,
dependencies: Set<PatchClass>? = null,
use: Boolean = true,
fingerprints: Set<MethodFingerprint> = emptySet(),
private val mainActivityOnCreateFingerprintInsertIndexPair: Pair<MethodFingerprint, Int>,
) : BytecodePatch(
name = name,
description = description,
compatiblePackages = compatiblePackages,
dependencies = dependencies,
use = use,
requiresIntegrations = true,
fingerprints = setOf(
LoadScriptFromAssetsFingerprint,
LoadScriptFromFileFingerprint,
mainActivityOnCreateFingerprintInsertIndexPair.first,
) + fingerprints,
) {
abstract val integrationsClassDescriptor: String

override fun execute(context: BytecodeContext) {
val (mainActivityOnCreateFingerprint, insertIndex) = mainActivityOnCreateFingerprintInsertIndexPair
val loadScriptFromAssetMethod = LoadScriptFromAssetsFingerprint.resultOrThrow().mutableMethod
val (catalystInstanceImplClassDef, loadScriptFromFileMethod) = LoadScriptFromFileFingerprint.resultOrThrow()
.let { it.mutableClass to it.mutableMethod }

// Create preload script on main activity creation.
mainActivityOnCreateFingerprint.resultOrThrow().mutableMethod.addInstructions(
insertIndex, // Skip super call.
"invoke-static { p0 }, " +
"$integrationsClassDescriptor->hookOnCreate(Landroid/app/Activity;)V",
)

// Copy of loadScriptFromFile method acts as a preload script loader.
catalystInstanceImplClassDef.methods.add(
ImmutableMethod(
loadScriptFromFileMethod.definingClass,
"loadPreloadScriptFromFile",
loadScriptFromFileMethod.parameters,
loadScriptFromFileMethod.returnType,
loadScriptFromFileMethod.accessFlags,
null,
null,
MutableMethodImplementation(4),
).toMutable().apply {
// Copy list as the reference is modified below.
addInstructions(loadScriptFromFileMethod.getInstructions().toList())
},
)

// Load preload script.
listOf(loadScriptFromFileMethod, loadScriptFromAssetMethod).forEach { loadScriptMethod ->
loadScriptMethod.addInstructions(
0,
"invoke-static { v0 }, $integrationsClassDescriptor->" +
"hookLoadScriptFromFile($catalystInstanceImplClassDef)V",
)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package app.revanced.patches.shared.misc.react.fingerprints

import app.revanced.patcher.fingerprint.MethodFingerprint

internal abstract class CatalystInstanceImplFingerprint(methodName: String) :
MethodFingerprint(
customFingerprint = { method, classDef ->
method.name == methodName && classDef.endsWith("CatalystInstanceImpl;")
},
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package app.revanced.patches.shared.misc.react.fingerprints

internal object LoadScriptFromAssetsFingerprint : CatalystInstanceImplFingerprint("loadScriptFromAssets")
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package app.revanced.patches.shared.misc.react.fingerprints

internal object LoadScriptFromFileFingerprint : CatalystInstanceImplFingerprint("loadScriptFromFile")

0 comments on commit d4ac006

Please sign in to comment.