refactor(integrations): merge integrations code (#1052)

Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
This commit is contained in:
Sculas 2022-11-21 22:26:43 +01:00 committed by GitHub
parent 08bc92da58
commit ca459ab5bf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 89 additions and 90 deletions

View File

@ -2,13 +2,13 @@ package app.revanced.patches.tiktok.misc.integrations.fingerprints
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.tiktok.misc.integrations.annotations.TikTokIntegrationsCompatibility
import app.revanced.shared.patches.AbstractIntegrationsPatch.IntegrationsFingerprint
@Name("init-fingerprint")
@TikTokIntegrationsCompatibility
@Version("0.0.1")
object InitFingerprint : MethodFingerprint(
object InitFingerprint : IntegrationsFingerprint(
customFingerprint = { methodDef ->
methodDef.definingClass.endsWith("/AwemeHostApplication;") &&
methodDef.name == "onCreate"

View File

@ -1,38 +1,13 @@
package app.revanced.patches.tiktok.misc.integrations.patch
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.addInstruction
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultError
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patches.tiktok.misc.integrations.annotations.TikTokIntegrationsCompatibility
import app.revanced.patches.tiktok.misc.integrations.fingerprints.InitFingerprint
import app.revanced.shared.patches.AbstractIntegrationsPatch
@Name("tiktok-integrations")
@Description("Applies mandatory patches to implement the ReVanced integrations into the application.")
@TikTokIntegrationsCompatibility
@Version("0.0.1")
class TikTokIntegrationsPatch : BytecodePatch(
listOf(
InitFingerprint
)
) {
override fun execute(context: BytecodeContext): PatchResult {
if (context.findClass("Lapp/revanced/tiktok/utils/ReVancedUtils") == null)
return PatchResultError("Integrations have not been merged yet. This patch can not succeed without the integrations.")
val result = InitFingerprint.result!!
val method = result.mutableMethod
val implementation = method.implementation!!
val count = implementation.registerCount - 1
method.addInstruction(
0, "sput-object v$count, Lapp/revanced/tiktok/utils/ReVancedUtils;->context:Landroid/content/Context;"
)
return PatchResultSuccess()
}
}
class TikTokIntegrationsPatch : AbstractIntegrationsPatch(
"Lapp/revanced/tiktok/utils/ReVancedUtils;",
listOf(InitFingerprint)
)

View File

@ -2,12 +2,12 @@ package app.revanced.patches.youtube.misc.integrations.fingerprints
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.misc.integrations.annotations.IntegrationsCompatibility
import app.revanced.shared.patches.AbstractIntegrationsPatch.IntegrationsFingerprint
@Name("init-fingerprint")
@IntegrationsCompatibility
@Version("0.0.1")
object InitFingerprint : MethodFingerprint(
strings = listOf("Application creation")
object InitFingerprint : IntegrationsFingerprint(
strings = listOf("Application creation"),
)

View File

@ -2,12 +2,13 @@ package app.revanced.patches.youtube.misc.integrations.fingerprints
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.misc.integrations.annotations.IntegrationsCompatibility
import app.revanced.shared.patches.AbstractIntegrationsPatch.IntegrationsFingerprint
@Name("service-fingerprint")
@IntegrationsCompatibility
@Version("0.0.1")
object ServiceFingerprint : MethodFingerprint(
customFingerprint = { methodDef -> methodDef.definingClass.endsWith("ApiPlayerService;") && methodDef.name == "<init>" }
object ServiceFingerprint : IntegrationsFingerprint(
customFingerprint = { methodDef -> methodDef.definingClass.endsWith("ApiPlayerService;") && methodDef.name == "<init>" },
contextRegisterResolver = { it.implementation!!.registerCount - it.parameters.size }
)

View File

@ -2,15 +2,15 @@ package app.revanced.patches.youtube.misc.integrations.fingerprints
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.misc.integrations.annotations.IntegrationsCompatibility
import app.revanced.shared.patches.AbstractIntegrationsPatch.IntegrationsFingerprint
@Name("standalone-player-fingerprint")
@IntegrationsCompatibility
@Version("0.0.1")
object StandalonePlayerFingerprint : MethodFingerprint(
object StandalonePlayerFingerprint : IntegrationsFingerprint(
strings = listOf(
"Invalid PlaybackStartDescriptor. Returning the instance itself.",
"com.google.android.music",
)
),
)

View File

@ -1,59 +1,15 @@
package app.revanced.patches.youtube.misc.integrations.patch
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.MethodFingerprintExtensions.name
import app.revanced.patcher.extensions.addInstruction
import app.revanced.patcher.extensions.or
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultError
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMutable
import app.revanced.patcher.util.smali.toInstructions
import app.revanced.patches.youtube.misc.integrations.annotations.IntegrationsCompatibility
import app.revanced.patches.youtube.misc.integrations.fingerprints.InitFingerprint
import app.revanced.patches.youtube.misc.integrations.fingerprints.ServiceFingerprint
import app.revanced.patches.youtube.misc.integrations.fingerprints.StandalonePlayerFingerprint
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.immutable.ImmutableMethod
import org.jf.dexlib2.immutable.ImmutableMethodImplementation
import app.revanced.shared.patches.AbstractIntegrationsPatch
@Name("integrations")
@Description("Applies mandatory patches to implement the ReVanced integrations into the application.")
@IntegrationsCompatibility
@Version("0.0.1")
class IntegrationsPatch : BytecodePatch(
listOf(
InitFingerprint, StandalonePlayerFingerprint, ServiceFingerprint
)
) {
companion object {
private const val INTEGRATIONS_DESCRIPTOR = "Lapp/revanced/integrations/utils/ReVancedUtils;"
}
override fun execute(context: BytecodeContext): PatchResult {
if (context.findClass(INTEGRATIONS_DESCRIPTOR) == null)
return PatchResultError("Integrations have not been merged yet. This patch can not succeed without merging the integrations.")
arrayOf(InitFingerprint, StandalonePlayerFingerprint, ServiceFingerprint).map {
it to (it.result ?: return PatchResultError("${it.name} failed to resolve"))
}.forEach { (fingerprint, result) ->
with(result.mutableMethod) {
// parameter which holds the context
val contextParameter = if (fingerprint == ServiceFingerprint) parameters.size else 1
// register which holds the context
val contextRegister = implementation!!.registerCount - contextParameter
addInstruction(
0,
"sput-object v$contextRegister, $INTEGRATIONS_DESCRIPTOR->context:Landroid/content/Context;"
)
}
}
return PatchResultSuccess()
}
}
class IntegrationsPatch : AbstractIntegrationsPatch(
"Lapp/revanced/integrations/utils/ReVancedUtils;",
listOf(InitFingerprint, StandalonePlayerFingerprint, ServiceFingerprint),
)

View File

@ -0,0 +1,67 @@
package app.revanced.shared.patches
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.addInstruction
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultError
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.shared.patches.AbstractIntegrationsPatch.IntegrationsFingerprint.RegisterResolver
import org.jf.dexlib2.iface.Method
@Description("Applies mandatory patches to implement the ReVanced integrations into the application.")
@Version("0.0.1")
abstract class AbstractIntegrationsPatch(
private val integrationsDescriptor: String,
private val hooks: Iterable<IntegrationsFingerprint>
) : BytecodePatch(hooks) {
/**
* [MethodFingerprint] for integrations.
*
* @param contextRegisterResolver A [RegisterResolver] to get the register.
* @see MethodFingerprint
*/
abstract class IntegrationsFingerprint(
strings: Iterable<String>? = null,
customFingerprint: ((methodDef: Method) -> Boolean)? = null,
private val contextRegisterResolver: (Method) -> Int = object : RegisterResolver {}
) : MethodFingerprint(strings = strings, customFingerprint = customFingerprint) {
fun invoke(integrationsDescriptor: String): PatchResult {
result?.mutableMethod?.let { method ->
val contextRegister = contextRegisterResolver(method)
method.addInstruction(
0,
"sput-object v$contextRegister, " +
"$integrationsDescriptor->context:Landroid/content/Context;"
)
} ?: return PatchResultError("Could not find hook target fingerprint.")
return PatchResultSuccess()
}
interface RegisterResolver : (Method) -> Int {
override operator fun invoke(method: Method) = method.implementation!!.registerCount - 1
}
}
override fun execute(context: BytecodeContext): PatchResult {
if (context.findClass(integrationsDescriptor) == null) return MISSING_INTEGRATIONS
for (hook in hooks) hook.invoke(integrationsDescriptor).let {
if (it is PatchResultError) return it
}
return PatchResultSuccess()
}
private companion object {
val MISSING_INTEGRATIONS = PatchResultError(
"Integrations have not been merged yet. " +
"This patch can not succeed without merging the integrations."
)
}
}