mirror of
https://github.com/ReVanced/revanced-patches.git
synced 2026-01-19 09:03:58 +00:00
finish batch1
This commit is contained in:
@@ -184,7 +184,6 @@ val spoofBuildInfoPatch = bytecodePatch(
|
||||
type,
|
||||
user,
|
||||
)
|
||||
},
|
||||
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
package app.revanced.patches.googlenews.misc.extension.hooks
|
||||
|
||||
import app.revanced.patcher.definingClass
|
||||
import app.revanced.patcher.extensions.instructions
|
||||
import app.revanced.patcher.instructions
|
||||
import app.revanced.patcher.invoke
|
||||
import app.revanced.patcher.name
|
||||
import app.revanced.patches.shared.misc.extension.extensionHook
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
@@ -10,32 +15,30 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||
private var getApplicationContextIndex = -1
|
||||
|
||||
internal val startActivityInitHook = extensionHook(
|
||||
getInsertIndex = { method ->
|
||||
getApplicationContextIndex = method.indexOfFirstInstructionOrThrow {
|
||||
getInsertIndex = {
|
||||
getApplicationContextIndex = indexOfFirstInstructionOrThrow {
|
||||
getReference<MethodReference>()?.name == "getApplicationContext"
|
||||
}
|
||||
|
||||
getApplicationContextIndex + 2 // Below the move-result-object instruction.
|
||||
},
|
||||
getContextRegister = { method ->
|
||||
val moveResultInstruction = method.implementation!!.instructions.elementAt(getApplicationContextIndex + 1)
|
||||
as OneRegisterInstruction
|
||||
getContextRegister = {
|
||||
val moveResultInstruction = instructions.elementAt(getApplicationContextIndex + 1) as OneRegisterInstruction
|
||||
"v${moveResultInstruction.registerA}"
|
||||
},
|
||||
) {
|
||||
opcodes(
|
||||
Opcode.INVOKE_STATIC,
|
||||
Opcode.MOVE_RESULT,
|
||||
Opcode.CONST_4,
|
||||
Opcode.IF_EQZ,
|
||||
Opcode.CONST,
|
||||
Opcode.INVOKE_VIRTUAL,
|
||||
Opcode.IPUT_OBJECT,
|
||||
Opcode.IPUT_BOOLEAN,
|
||||
Opcode.INVOKE_VIRTUAL, // Calls startActivity.getApplicationContext().
|
||||
Opcode.MOVE_RESULT_OBJECT,
|
||||
name("onCreate")
|
||||
definingClass("/StartActivity;"::endsWith)
|
||||
instructions(
|
||||
Opcode.INVOKE_STATIC(),
|
||||
Opcode.MOVE_RESULT(),
|
||||
Opcode.CONST_4(),
|
||||
Opcode.IF_EQZ(),
|
||||
Opcode.CONST(),
|
||||
Opcode.INVOKE_VIRTUAL(),
|
||||
Opcode.IPUT_OBJECT(),
|
||||
Opcode.IPUT_BOOLEAN(),
|
||||
Opcode.INVOKE_VIRTUAL(), // Calls startActivity.getApplicationContext().
|
||||
Opcode.MOVE_RESULT_OBJECT(),
|
||||
)
|
||||
custom { methodDef, classDef ->
|
||||
methodDef.name == "onCreate" && classDef.endsWith("/StartActivity;")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
package app.revanced.patches.googlenews.misc.gms
|
||||
|
||||
import app.revanced.patcher.fingerprint
|
||||
import app.revanced.patcher.BytecodePatchContextMethodMatching.gettingFirstMutableMethodDeclaratively
|
||||
import app.revanced.patcher.definingClass
|
||||
import app.revanced.patcher.name
|
||||
import app.revanced.patcher.patch.BytecodePatchContext
|
||||
|
||||
internal val magazinesActivityOnCreateFingerprint = fingerprint {
|
||||
custom { methodDef, classDef ->
|
||||
methodDef.name == "onCreate" && classDef.endsWith("/StartActivity;")
|
||||
}
|
||||
internal val BytecodePatchContext.magazinesActivityOnCreateMethod by gettingFirstMutableMethodDeclaratively {
|
||||
name("onCreate")
|
||||
definingClass("/StartActivity;"::endsWith)
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ import app.revanced.patches.shared.misc.gms.gmsCoreSupportResourcePatch
|
||||
val gmsCoreSupportPatch = gmsCoreSupportPatch(
|
||||
fromPackageName = MAGAZINES_PACKAGE_NAME,
|
||||
toPackageName = REVANCED_MAGAZINES_PACKAGE_NAME,
|
||||
getMainActivityOnCreate = magazinesActivityOnCreateFingerprint,
|
||||
getMainActivityOnCreateMethod = { magazinesActivityOnCreateMethod },
|
||||
extensionPatch = extensionPatch,
|
||||
gmsCoreSupportResourcePatchFactory = ::gmsCoreSupportResourcePatch,
|
||||
) {
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
package app.revanced.patches.googlephotos.misc.extension
|
||||
|
||||
import app.revanced.patcher.definingClass
|
||||
import app.revanced.patcher.extensions.instructions
|
||||
import app.revanced.patcher.instructions
|
||||
import app.revanced.patcher.invoke
|
||||
import app.revanced.patcher.name
|
||||
import app.revanced.patches.shared.misc.extension.extensionHook
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
@@ -10,28 +15,26 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||
private var getApplicationContextIndex = -1
|
||||
|
||||
internal val homeActivityInitHook = extensionHook(
|
||||
getInsertIndex = { method ->
|
||||
getApplicationContextIndex = method.indexOfFirstInstructionOrThrow {
|
||||
getInsertIndex = {
|
||||
getApplicationContextIndex = indexOfFirstInstructionOrThrow {
|
||||
getReference<MethodReference>()?.name == "getApplicationContext"
|
||||
}
|
||||
|
||||
getApplicationContextIndex + 2 // Below the move-result-object instruction.
|
||||
},
|
||||
getContextRegister = { method ->
|
||||
val moveResultInstruction = method.implementation!!.instructions.elementAt(getApplicationContextIndex + 1)
|
||||
as OneRegisterInstruction
|
||||
getContextRegister = {
|
||||
val moveResultInstruction = instructions.elementAt(getApplicationContextIndex + 1) as OneRegisterInstruction
|
||||
"v${moveResultInstruction.registerA}"
|
||||
},
|
||||
) {
|
||||
opcodes(
|
||||
Opcode.CONST_STRING,
|
||||
Opcode.INVOKE_STATIC,
|
||||
Opcode.MOVE_RESULT_OBJECT,
|
||||
Opcode.IF_NEZ,
|
||||
Opcode.INVOKE_VIRTUAL, // Calls getApplicationContext().
|
||||
Opcode.MOVE_RESULT_OBJECT,
|
||||
name("onCreate")
|
||||
definingClass("/HomeActivity;"::endsWith)
|
||||
instructions(
|
||||
Opcode.CONST_STRING(),
|
||||
Opcode.INVOKE_STATIC(),
|
||||
Opcode.MOVE_RESULT_OBJECT(),
|
||||
Opcode.IF_NEZ(),
|
||||
Opcode.INVOKE_VIRTUAL(), // Calls getApplicationContext().
|
||||
Opcode.MOVE_RESULT_OBJECT(),
|
||||
)
|
||||
custom { methodDef, classDef ->
|
||||
methodDef.name == "onCreate" && classDef.endsWith("/HomeActivity;")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
package app.revanced.patches.googlephotos.misc.gms
|
||||
|
||||
import app.revanced.patcher.fingerprint
|
||||
import app.revanced.patcher.BytecodePatchContextMethodMatching.gettingFirstMutableMethodDeclaratively
|
||||
import app.revanced.patcher.definingClass
|
||||
import app.revanced.patcher.name
|
||||
import app.revanced.patcher.patch.BytecodePatchContext
|
||||
|
||||
internal val homeActivityOnCreateFingerprint = fingerprint {
|
||||
custom { methodDef, classDef ->
|
||||
methodDef.name == "onCreate" && classDef.endsWith("/HomeActivity;")
|
||||
}
|
||||
internal val BytecodePatchContext.homeActivityOnCreateMethod by gettingFirstMutableMethodDeclaratively {
|
||||
name("onCreate")
|
||||
definingClass("/HomeActivity;"::endsWith)
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ import app.revanced.patches.shared.misc.gms.gmsCoreSupportPatch
|
||||
val gmsCoreSupportPatch = gmsCoreSupportPatch(
|
||||
fromPackageName = PHOTOS_PACKAGE_NAME,
|
||||
toPackageName = REVANCED_PHOTOS_PACKAGE_NAME,
|
||||
getMainActivityOnCreate = homeActivityOnCreateFingerprint,
|
||||
getMainActivityOnCreateMethod = { homeActivityOnCreateMethod },
|
||||
extensionPatch = extensionPatch,
|
||||
gmsCoreSupportResourcePatchFactory = ::gmsCoreSupportResourcePatch,
|
||||
) {
|
||||
|
||||
@@ -18,5 +18,5 @@ val checkWatchHistoryDomainNameResolutionPatch = checkWatchHistoryDomainNameReso
|
||||
)
|
||||
},
|
||||
|
||||
mainActivityFingerprint = mainActivityOnCreateMethod
|
||||
getMainActivityMethod = { mainActivityOnCreateMethod }
|
||||
)
|
||||
|
||||
@@ -6,5 +6,6 @@ import app.revanced.patches.shared.misc.extension.sharedExtensionPatch
|
||||
|
||||
val sharedExtensionPatch = sharedExtensionPatch(
|
||||
"music",
|
||||
applicationInitHook, applicationInitOnCreateHook
|
||||
applicationInitHook,
|
||||
applicationInitOnCreateHook
|
||||
)
|
||||
|
||||
@@ -1,18 +1,15 @@
|
||||
package app.revanced.patches.music.misc.extension.hooks
|
||||
|
||||
import app.revanced.patcher.*
|
||||
import app.revanced.patches.music.shared.YOUTUBE_MUSIC_MAIN_ACTIVITY_CLASS_TYPE
|
||||
import app.revanced.patches.shared.misc.extension.activityOnCreateExtensionHook
|
||||
import app.revanced.patches.shared.misc.extension.extensionHook
|
||||
|
||||
internal val applicationInitHook = extensionHook {
|
||||
returns("V")
|
||||
parameters()
|
||||
instructions(
|
||||
addString("activity")
|
||||
)
|
||||
custom { method, _ -> method.name == "onCreate" }
|
||||
name("onCreate")
|
||||
returnType("V")
|
||||
parameterTypes()
|
||||
instructions("activity"())
|
||||
}
|
||||
|
||||
internal val applicationInitOnCreateHook = activityOnCreateExtensionHook(
|
||||
YOUTUBE_MUSIC_MAIN_ACTIVITY_CLASS_TYPE
|
||||
)
|
||||
internal val applicationInitOnCreateHook = activityOnCreateExtensionHook(YOUTUBE_MUSIC_MAIN_ACTIVITY_CLASS_TYPE)
|
||||
|
||||
@@ -8,7 +8,7 @@ fun disableAdsPatch(block: BytecodePatchBuilder.() -> Unit = {}) = bytecodePatch
|
||||
name = "Disable ads",
|
||||
) {
|
||||
apply {
|
||||
isAdsEnabledFingerprint.method.returnEarly(false)
|
||||
isAdsEnabledMethod.returnEarly(false)
|
||||
}
|
||||
|
||||
block()
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
package app.revanced.patches.reddit.customclients.sync.ads
|
||||
|
||||
import app.revanced.patcher.BytecodePatchContextMethodMatching.gettingFirstMutableMethodDeclaratively
|
||||
import app.revanced.patcher.accessFlags
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import app.revanced.patcher.fingerprint
|
||||
import app.revanced.patcher.patch.BytecodePatchContext
|
||||
import app.revanced.patcher.returnType
|
||||
|
||||
internal val isAdsEnabledFingerprint = fingerprint {
|
||||
internal val BytecodePatchContext.isAdsEnabledMethod by gettingFirstMutableMethodDeclaratively("SyncIapHelper") {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC)
|
||||
returns("Z")
|
||||
strings("SyncIapHelper")
|
||||
returnType("Z")
|
||||
}
|
||||
|
||||
@@ -1,13 +1,8 @@
|
||||
package app.revanced.patches.shared.layout.theme
|
||||
|
||||
import app.revanced.patcher.patch.BytecodePatchBuilder
|
||||
import app.revanced.patcher.patch.BytecodePatchContext
|
||||
import app.revanced.patcher.patch.PatchException
|
||||
import app.revanced.patcher.patch.bytecodePatch
|
||||
import app.revanced.patcher.patch.resourcePatch
|
||||
import app.revanced.patcher.patch.stringOption
|
||||
import app.revanced.patcher.patch.*
|
||||
import app.revanced.util.childElementsSequence
|
||||
import java.util.Locale
|
||||
import java.util.*
|
||||
|
||||
internal const val THEME_COLOR_OPTION_DESCRIPTION = "Can be a hex color (#RRGGBB) or a color resource reference."
|
||||
|
||||
@@ -56,7 +51,8 @@ internal fun validateColorName(colorString: String): Boolean {
|
||||
* Dark theme color option for YouTube and YT Music Theme patches.
|
||||
*/
|
||||
internal val darkThemeBackgroundColorOption = stringOption(
|
||||
key = "darkThemeBackgroundColor",
|
||||
name = "Dark theme background color",
|
||||
description = THEME_COLOR_OPTION_DESCRIPTION,
|
||||
default = "@android:color/black",
|
||||
values = mapOf(
|
||||
"Pure black" to "@android:color/black",
|
||||
@@ -69,9 +65,7 @@ internal val darkThemeBackgroundColorOption = stringOption(
|
||||
"Dark yellow" to "#282900",
|
||||
"Dark orange" to "#291800",
|
||||
"Dark red" to "#290000",
|
||||
),
|
||||
name = "Dark theme background color",
|
||||
description = THEME_COLOR_OPTION_DESCRIPTION
|
||||
)
|
||||
)
|
||||
|
||||
/**
|
||||
@@ -104,10 +98,9 @@ internal fun baseThemeResourcePatch(
|
||||
lightColorNames: Set<String> = THEME_DEFAULT_LIGHT_COLOR_NAMES,
|
||||
lightColorReplacement: (() -> String)? = null
|
||||
) = resourcePatch {
|
||||
|
||||
apply {
|
||||
// After patch option validators are fixed https://github.com/ReVanced/revanced-patcher/issues/372
|
||||
// This should changed to a patch option validator.
|
||||
// This should be changed to a patch option validator.
|
||||
val darkColor by darkThemeBackgroundColorOption
|
||||
if (!validateColorName(darkColor!!)) {
|
||||
throw PatchException("Invalid dark theme color: $darkColor")
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
package app.revanced.patches.shared.misc.checks
|
||||
|
||||
import android.os.Build.*
|
||||
import app.revanced.patcher.Fingerprint
|
||||
import app.revanced.patcher.extensions.addInstruction
|
||||
import app.revanced.patcher.patch.BytecodePatchContext
|
||||
import app.revanced.patcher.patch.Patch
|
||||
import app.revanced.patcher.patch.bytecodePatch
|
||||
import app.revanced.patches.all.misc.resources.addResources
|
||||
import app.revanced.patches.all.misc.resources.addResourcesPatch
|
||||
import com.android.tools.smali.dexlib2.iface.value.MutableEncodedValue
|
||||
import com.android.tools.smali.dexlib2.iface.value.MutableLongEncodedValue
|
||||
import com.android.tools.smali.dexlib2.iface.value.MutableStringEncodedValue
|
||||
import app.revanced.patches.all.misc.resources.addResources
|
||||
import app.revanced.patches.all.misc.resources.addResourcesPatch
|
||||
import com.android.tools.smali.dexlib2.immutable.value.ImmutableLongEncodedValue
|
||||
import com.android.tools.smali.dexlib2.immutable.value.ImmutableStringEncodedValue
|
||||
import com.android.tools.smali.dexlib2.mutable.MutableClassDef
|
||||
import com.android.tools.smali.dexlib2.mutable.MutableMethod
|
||||
import java.nio.charset.StandardCharsets
|
||||
import java.security.MessageDigest
|
||||
import kotlin.io.encoding.Base64
|
||||
@@ -21,7 +23,7 @@ private const val EXTENSION_CLASS_DESCRIPTOR =
|
||||
"Lapp/revanced/extension/shared/checks/CheckEnvironmentPatch;"
|
||||
|
||||
fun checkEnvironmentPatch(
|
||||
mainActivityOnCreateFingerprint: Fingerprint,
|
||||
getMainActivityOnCreateMethod: BytecodePatchContext.() -> MutableMethod,
|
||||
extensionPatch: Patch,
|
||||
vararg compatiblePackages: String,
|
||||
) = bytecodePatch(
|
||||
@@ -38,20 +40,20 @@ fun checkEnvironmentPatch(
|
||||
addResources("shared", "misc.checks.checkEnvironmentPatch")
|
||||
|
||||
fun setPatchInfo() {
|
||||
fun <T : MutableEncodedValue> Fingerprint.setClassFields(vararg fieldNameValues: Pair<String, T>) {
|
||||
fun <T : MutableEncodedValue> MutableClassDef.setClassFields(vararg fieldNameValues: Pair<String, T>) {
|
||||
val fieldNameValueMap = mapOf(*fieldNameValues)
|
||||
|
||||
classDef.fields.forEach { field ->
|
||||
fields.forEach { field ->
|
||||
field.initialValue = fieldNameValueMap[field.name] ?: return@forEach
|
||||
}
|
||||
}
|
||||
|
||||
patchInfoFingerprint.setClassFields(
|
||||
patchInfoClassDef.setClassFields(
|
||||
"PATCH_TIME" to System.currentTimeMillis().encoded,
|
||||
)
|
||||
|
||||
fun setBuildInfo() {
|
||||
patchInfoBuildFingerprint.setClassFields(
|
||||
patchInfoBuildClassDef.setClassFields(
|
||||
"PATCH_BOARD" to BOARD.encodedAndHashed,
|
||||
"PATCH_BOOTLOADER" to BOOTLOADER.encodedAndHashed,
|
||||
"PATCH_BRAND" to BRAND.encodedAndHashed,
|
||||
@@ -82,7 +84,7 @@ fun checkEnvironmentPatch(
|
||||
}
|
||||
}
|
||||
|
||||
fun invokeCheck() = mainActivityOnCreateFingerprint.method.addInstruction(
|
||||
fun invokeCheck() = getMainActivityOnCreateMethod().addInstruction(
|
||||
0,
|
||||
"invoke-static/range { p0 .. p0 }, $EXTENSION_CLASS_DESCRIPTOR->check(Landroid/app/Activity;)V",
|
||||
)
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
package app.revanced.patches.shared.misc.checks
|
||||
|
||||
import app.revanced.patcher.fingerprint
|
||||
import app.revanced.patcher.BytecodePatchContextClassDefMatching.gettingFirstMutableClassDefDeclaratively
|
||||
import app.revanced.patcher.patch.BytecodePatchContext
|
||||
|
||||
internal val patchInfoFingerprint = fingerprint {
|
||||
custom { _, classDef -> classDef.type == "Lapp/revanced/extension/shared/checks/PatchInfo;" }
|
||||
}
|
||||
internal val BytecodePatchContext.patchInfoClassDef by gettingFirstMutableClassDefDeclaratively(
|
||||
"Lapp/revanced/extension/shared/checks/PatchInfo;"
|
||||
)
|
||||
|
||||
internal val patchInfoBuildFingerprint = fingerprint {
|
||||
custom { _, classDef -> classDef.type == "Lapp/revanced/extension/shared/checks/PatchInfo\$Build;" }
|
||||
}
|
||||
internal val BytecodePatchContext.patchInfoBuildClassDef by gettingFirstMutableClassDefDeclaratively(
|
||||
$$"Lapp/revanced/extension/shared/checks/PatchInfo$Build;"
|
||||
)
|
||||
|
||||
@@ -2,23 +2,16 @@ package app.revanced.patches.shared.misc.debugging
|
||||
|
||||
import app.revanced.patcher.extensions.addInstructions
|
||||
import app.revanced.patcher.extensions.getInstruction
|
||||
import app.revanced.patcher.immutableClassDef
|
||||
import app.revanced.patcher.patch.BytecodePatchBuilder
|
||||
import app.revanced.patcher.patch.BytecodePatchContext
|
||||
import app.revanced.patcher.patch.bytecodePatch
|
||||
import app.revanced.patcher.patch.resourcePatch
|
||||
import app.revanced.patches.all.misc.resources.addResources
|
||||
import app.revanced.patches.all.misc.resources.addResourcesPatch
|
||||
import app.revanced.patches.shared.misc.settings.preference.BasePreference
|
||||
import app.revanced.patches.shared.misc.settings.preference.BasePreferenceScreen
|
||||
import app.revanced.patches.shared.misc.settings.preference.NonInteractivePreference
|
||||
import app.revanced.patches.shared.misc.settings.preference.PreferenceScreenPreference
|
||||
import app.revanced.patches.shared.misc.settings.preference.*
|
||||
import app.revanced.patches.shared.misc.settings.preference.PreferenceScreenPreference.Sorting
|
||||
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
|
||||
import app.revanced.util.ResourceGroup
|
||||
import app.revanced.util.copyResources
|
||||
import app.revanced.util.findInstructionIndicesReversedOrThrow
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
import app.revanced.util.indexOfFirstInstructionReversedOrThrow
|
||||
import app.revanced.util.*
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||
|
||||
@@ -45,7 +38,8 @@ internal fun enableDebuggingPatch(
|
||||
apply {
|
||||
copyResources(
|
||||
"settings",
|
||||
ResourceGroup("drawable",
|
||||
ResourceGroup(
|
||||
"drawable",
|
||||
// Action buttons.
|
||||
"revanced_settings_copy_all.xml",
|
||||
"revanced_settings_deselect_all.xml",
|
||||
@@ -105,9 +99,7 @@ internal fun enableDebuggingPatch(
|
||||
)
|
||||
|
||||
// Hook the methods that look up if a feature flag is active.
|
||||
experimentalBooleanFeatureFlagFingerprint.match(
|
||||
experimentalFeatureFlagParentFingerprint.originalClassDef
|
||||
).method.apply {
|
||||
experimentalFeatureFlagParentMethod.immutableClassDef.getExperimentalBooleanFeatureFlagMethod().apply {
|
||||
findInstructionIndicesReversedOrThrow(Opcode.RETURN).forEach { index ->
|
||||
val register = getInstruction<OneRegisterInstruction>(index).registerA
|
||||
|
||||
@@ -121,15 +113,13 @@ internal fun enableDebuggingPatch(
|
||||
}
|
||||
}
|
||||
|
||||
experimentalDoubleFeatureFlagFingerprint.match(
|
||||
experimentalFeatureFlagParentFingerprint.originalClassDef
|
||||
).method.apply {
|
||||
experimentalFeatureFlagParentMethod.immutableClassDef.getExperimentalDoubleFeatureFlagMethod().apply {
|
||||
val insertIndex = indexOfFirstInstructionOrThrow(Opcode.MOVE_RESULT_WIDE)
|
||||
|
||||
addInstructions(
|
||||
insertIndex,
|
||||
"""
|
||||
move-result-wide v0 # Also clobbers v1 (p0) since result is wide.
|
||||
move-result-wide v0 # Also clobbers v1 (p0) since result is wide.
|
||||
invoke-static/range { v0 .. v5 }, $EXTENSION_CLASS_DESCRIPTOR->isDoubleFeatureFlagEnabled(DJD)D
|
||||
move-result-wide v0
|
||||
return-wide v0
|
||||
@@ -137,9 +127,7 @@ internal fun enableDebuggingPatch(
|
||||
)
|
||||
}
|
||||
|
||||
experimentalLongFeatureFlagFingerprint.match(
|
||||
experimentalFeatureFlagParentFingerprint.originalClassDef
|
||||
).method.apply {
|
||||
experimentalFeatureFlagParentMethod.immutableClassDef.getExperimentalLongFeatureFlagMethod().apply {
|
||||
val insertIndex = indexOfFirstInstructionOrThrow(Opcode.MOVE_RESULT_WIDE)
|
||||
|
||||
addInstructions(
|
||||
@@ -153,21 +141,20 @@ internal fun enableDebuggingPatch(
|
||||
)
|
||||
}
|
||||
|
||||
if (hookStringFeatureFlag) experimentalStringFeatureFlagFingerprint.match(
|
||||
experimentalFeatureFlagParentFingerprint.originalClassDef
|
||||
).method.apply {
|
||||
val insertIndex = indexOfFirstInstructionReversedOrThrow(Opcode.MOVE_RESULT_OBJECT)
|
||||
if (hookStringFeatureFlag)
|
||||
experimentalFeatureFlagParentMethod.immutableClassDef.getExperimentalStringFeatureFlagMethod().apply {
|
||||
val insertIndex = indexOfFirstInstructionReversedOrThrow(Opcode.MOVE_RESULT_OBJECT)
|
||||
|
||||
addInstructions(
|
||||
insertIndex,
|
||||
"""
|
||||
move-result-object v0
|
||||
invoke-static { v0, p1, p2, p3 }, $EXTENSION_CLASS_DESCRIPTOR->isStringFeatureFlagEnabled(Ljava/lang/String;JLjava/lang/String;)Ljava/lang/String;
|
||||
move-result-object v0
|
||||
return-object v0
|
||||
"""
|
||||
)
|
||||
}
|
||||
addInstructions(
|
||||
insertIndex,
|
||||
"""
|
||||
move-result-object v0
|
||||
invoke-static { v0, p1, p2, p3 }, $EXTENSION_CLASS_DESCRIPTOR->isStringFeatureFlagEnabled(Ljava/lang/String;JLjava/lang/String;)Ljava/lang/String;
|
||||
move-result-object v0
|
||||
return-object v0
|
||||
"""
|
||||
)
|
||||
}
|
||||
|
||||
// There exists other experimental accessor methods for byte[]
|
||||
// and wrappers for obfuscated classes, but currently none of those are hooked.
|
||||
|
||||
@@ -1,35 +1,46 @@
|
||||
package app.revanced.patches.shared.misc.debugging
|
||||
|
||||
import app.revanced.patcher.fingerprint
|
||||
import app.revanced.patcher.BytecodePatchContextMethodMatching.gettingFirstMethodDeclaratively
|
||||
import app.revanced.patcher.ClassDefMethodMatching.firstMutableMethodDeclaratively
|
||||
import app.revanced.patcher.accessFlags
|
||||
import app.revanced.patcher.parameterTypes
|
||||
import app.revanced.patcher.patch.BytecodePatchContext
|
||||
import app.revanced.patcher.returnType
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.iface.ClassDef
|
||||
|
||||
internal val experimentalFeatureFlagParentFingerprint = fingerprint {
|
||||
internal val BytecodePatchContext.experimentalFeatureFlagParentMethod by gettingFirstMethodDeclaratively(
|
||||
"Unable to parse proto typed experiment flag: "
|
||||
) {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC)
|
||||
returns("L")
|
||||
parameters("L", "J", "[B")
|
||||
strings("Unable to parse proto typed experiment flag: ")
|
||||
returnType("L")
|
||||
parameterTypes("L", "J", "[B")
|
||||
}
|
||||
|
||||
internal val experimentalBooleanFeatureFlagFingerprint = fingerprint {
|
||||
context(_: BytecodePatchContext)
|
||||
internal fun ClassDef.getExperimentalBooleanFeatureFlagMethod() = firstMutableMethodDeclaratively {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC)
|
||||
returns("Z")
|
||||
parameters("L", "J", "Z")
|
||||
returnType("Z")
|
||||
parameterTypes("L", "J", "Z")
|
||||
}
|
||||
|
||||
internal val experimentalDoubleFeatureFlagFingerprint = fingerprint {
|
||||
context(_: BytecodePatchContext)
|
||||
internal fun ClassDef.getExperimentalDoubleFeatureFlagMethod() = firstMutableMethodDeclaratively {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||
returns("D")
|
||||
parameters("J", "D")
|
||||
returnType("D")
|
||||
parameterTypes("J", "D")
|
||||
}
|
||||
|
||||
internal val experimentalLongFeatureFlagFingerprint = fingerprint {
|
||||
context(_: BytecodePatchContext)
|
||||
internal fun ClassDef.getExperimentalLongFeatureFlagMethod() = firstMutableMethodDeclaratively {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||
returns("J")
|
||||
parameters("J", "J")
|
||||
returnType("J")
|
||||
parameterTypes("J", "J")
|
||||
}
|
||||
|
||||
internal val experimentalStringFeatureFlagFingerprint = fingerprint {
|
||||
context(_: BytecodePatchContext)
|
||||
internal fun ClassDef.getExperimentalStringFeatureFlagMethod() = firstMutableMethodDeclaratively {
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||
returns("Ljava/lang/String;")
|
||||
parameters("J", "Ljava/lang/String;")
|
||||
returnType("Ljava/lang/String;")
|
||||
parameterTypes("J", "Ljava/lang/String;")
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package app.revanced.patches.shared.misc.dns
|
||||
|
||||
import app.revanced.patcher.Fingerprint
|
||||
import app.revanced.patcher.extensions.addInstruction
|
||||
import app.revanced.patcher.patch.BytecodePatchBuilder
|
||||
import app.revanced.patcher.patch.BytecodePatchContext
|
||||
import app.revanced.patcher.patch.bytecodePatch
|
||||
import app.revanced.patches.all.misc.resources.addResources
|
||||
import com.android.tools.smali.dexlib2.mutable.MutableMethod
|
||||
|
||||
private const val EXTENSION_CLASS_DESCRIPTOR =
|
||||
"Lapp/revanced/extension/shared/patches/CheckWatchHistoryDomainNameResolutionPatch;"
|
||||
@@ -16,7 +16,7 @@ private const val EXTENSION_CLASS_DESCRIPTOR =
|
||||
internal fun checkWatchHistoryDomainNameResolutionPatch(
|
||||
block: BytecodePatchBuilder.() -> Unit = {},
|
||||
executeBlock: BytecodePatchContext.() -> Unit = {},
|
||||
mainActivityFingerprint: Fingerprint
|
||||
getMainActivityMethod: BytecodePatchContext.() -> MutableMethod
|
||||
) = bytecodePatch(
|
||||
name = "Check watch history domain name resolution",
|
||||
description = "Checks if the device DNS server is preventing user watch history from being saved.",
|
||||
@@ -28,7 +28,7 @@ internal fun checkWatchHistoryDomainNameResolutionPatch(
|
||||
|
||||
addResources("shared", "misc.dns.checkWatchHistoryDomainNameResolutionPatch")
|
||||
|
||||
mainActivityFingerprint.method.addInstruction(
|
||||
getMainActivityMethod().addInstruction(
|
||||
0,
|
||||
"invoke-static/range { p0 .. p0 }, $EXTENSION_CLASS_DESCRIPTOR->checkDnsResolver(Landroid/app/Activity;)V",
|
||||
)
|
||||
|
||||
@@ -4,6 +4,7 @@ import app.revanced.patcher.extensions.addInstruction
|
||||
import app.revanced.patcher.extensions.instructions
|
||||
import app.revanced.patcher.extensions.replaceInstruction
|
||||
import app.revanced.patcher.patch.*
|
||||
import app.revanced.patcher.patch.BytecodePatchContext
|
||||
import app.revanced.patches.all.misc.packagename.changePackageNamePatch
|
||||
import app.revanced.patches.all.misc.packagename.setOrGetFallbackPackageName
|
||||
import app.revanced.patches.all.misc.resources.addResources
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package app.revanced.patches.spotify.misc.check
|
||||
|
||||
import app.revanced.patches.shared.misc.checks.checkEnvironmentPatch
|
||||
import app.revanced.patches.spotify.shared.mainActivityOnCreateFingerprint
|
||||
import app.revanced.patches.spotify.misc.extension.sharedExtensionPatch
|
||||
import app.revanced.patches.spotify.shared.mainActivityOnCreateMethod
|
||||
|
||||
internal val checkEnvironmentPatch = checkEnvironmentPatch(
|
||||
mainActivityOnCreateFingerprint = mainActivityOnCreateFingerprint,
|
||||
getMainActivityOnCreateMethod = { mainActivityOnCreateMethod },
|
||||
extensionPatch = sharedExtensionPatch,
|
||||
"com.spotify.music",
|
||||
)
|
||||
|
||||
@@ -2,13 +2,13 @@ package app.revanced.patches.spotify.misc.extension
|
||||
|
||||
import app.revanced.patcher.extensions.getInstruction
|
||||
import app.revanced.patches.shared.misc.extension.extensionHook
|
||||
import app.revanced.patches.spotify.shared.mainActivityOnCreateFingerprint
|
||||
import app.revanced.patches.spotify.shared.mainActivityOnCreateMethod
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
||||
import com.android.tools.smali.dexlib2.iface.reference.FieldReference
|
||||
|
||||
internal val mainActivityOnCreateHook = extensionHook { mainActivityOnCreateFingerprint }
|
||||
internal val mainActivityOnCreateHook = extensionHook { mainActivityOnCreateMethod }
|
||||
|
||||
internal val loadOrbitLibraryHook = extensionHook {
|
||||
// FIXME: Creating this is a mess and needs refactoring.
|
||||
|
||||
@@ -1,15 +1,21 @@
|
||||
package app.revanced.patches.spotify.shared
|
||||
|
||||
import app.revanced.patcher.BytecodePatchContextMethodMatching.gettingFirstMutableMethodDeclaratively
|
||||
import app.revanced.patcher.accessFlags
|
||||
import app.revanced.patcher.definingClass
|
||||
import app.revanced.patcher.fingerprint
|
||||
import app.revanced.patcher.name
|
||||
import app.revanced.patcher.parameterTypes
|
||||
import app.revanced.patcher.patch.BytecodePatchContext
|
||||
import app.revanced.patcher.returnType
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
|
||||
private const val SPOTIFY_MAIN_ACTIVITY = "Lcom/spotify/music/SpotifyMainActivity;"
|
||||
|
||||
internal val mainActivityOnCreateFingerprint = fingerprint {
|
||||
internal val BytecodePatchContext.mainActivityOnCreateMethod by gettingFirstMutableMethodDeclaratively {
|
||||
name("onCreate")
|
||||
definingClass(SPOTIFY_MAIN_ACTIVITY)
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||
returns("V")
|
||||
parameters("Landroid/os/Bundle;")
|
||||
custom { method, classDef ->
|
||||
method.name == "onCreate" && classDef.type == SPOTIFY_MAIN_ACTIVITY
|
||||
}
|
||||
returnType("V")
|
||||
parameterTypes("Landroid/os/Bundle;")
|
||||
}
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
package app.revanced.patches.tiktok.misc.extension
|
||||
|
||||
import app.revanced.patcher.definingClass
|
||||
import app.revanced.patcher.name
|
||||
import app.revanced.patcher.parameterTypes
|
||||
import app.revanced.patches.shared.misc.extension.activityOnCreateExtensionHook
|
||||
import app.revanced.patches.shared.misc.extension.extensionHook
|
||||
|
||||
@@ -16,19 +19,15 @@ internal val initHook = activityOnCreateExtensionHook(
|
||||
internal val jatoInitHook = extensionHook(
|
||||
getContextRegister = { "p1" }
|
||||
) {
|
||||
parameters("Landroid/content/Context;")
|
||||
custom { method, classDef ->
|
||||
classDef.type == "Lcom/ss/android/ugc/aweme/legoImp/task/JatoInitTask;" &&
|
||||
method.name == "run"
|
||||
}
|
||||
name("run")
|
||||
definingClass("Lcom/ss/android/ugc/aweme/legoImp/task/JatoInitTask;")
|
||||
parameterTypes("Landroid/content/Context;")
|
||||
}
|
||||
|
||||
internal val storeRegionInitHook = extensionHook(
|
||||
getContextRegister = { "p1" }
|
||||
) {
|
||||
parameters("Landroid/content/Context;")
|
||||
custom { method, classDef ->
|
||||
classDef.type == "Lcom/ss/android/ugc/aweme/legoImp/task/StoreRegionInitTask;" &&
|
||||
method.name == "run"
|
||||
}
|
||||
name("run")
|
||||
definingClass("Lcom/ss/android/ugc/aweme/legoImp/task/StoreRegionInitTask;")
|
||||
parameterTypes("Landroid/content/Context;")
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package app.revanced.patches.twitter.misc.hook
|
||||
|
||||
import app.revanced.patcher.patch.bytecodePatch
|
||||
import app.revanced.patches.twitter.misc.hook.json.JsonHook
|
||||
import app.revanced.patches.twitter.misc.hook.json.addJsonHook
|
||||
import app.revanced.patches.twitter.misc.hook.json.jsonHook
|
||||
import app.revanced.patches.twitter.misc.hook.json.jsonHookPatch
|
||||
|
||||
fun hookPatch(
|
||||
@@ -19,6 +19,6 @@ fun hookPatch(
|
||||
)
|
||||
|
||||
apply {
|
||||
addJsonHook(JsonHook(hookClassDescriptor))
|
||||
addJsonHook(jsonHook(hookClassDescriptor))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,27 +1,29 @@
|
||||
package app.revanced.patches.twitter.misc.hook.json
|
||||
|
||||
import app.revanced.patcher.fingerprint
|
||||
import app.revanced.patcher.*
|
||||
import app.revanced.patcher.BytecodePatchContextClassDefMatching.gettingFirstClassDef
|
||||
import app.revanced.patcher.ClassDefMethodMatching.firstMutableMethodDeclaratively
|
||||
import app.revanced.patcher.patch.BytecodePatchContext
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.iface.ClassDef
|
||||
|
||||
internal val jsonHookPatchFingerprint = fingerprint {
|
||||
opcodes(
|
||||
Opcode.INVOKE_INTERFACE, // Add dummy hook to hooks list.
|
||||
internal val jsonHookPatchMethodMatch = firstMethodComposite {
|
||||
name("<clinit>")
|
||||
instructions(
|
||||
Opcode.INVOKE_INTERFACE(), // Add dummy hook to hooks list.
|
||||
// Add hooks to the hooks list.
|
||||
Opcode.INVOKE_STATIC, // Call buildList.
|
||||
Opcode.INVOKE_STATIC(), // Call buildList.
|
||||
)
|
||||
custom { method, _ -> method.name == "<clinit>" }
|
||||
}
|
||||
|
||||
internal val jsonInputStreamFingerprint = fingerprint {
|
||||
custom { method, _ ->
|
||||
if (method.parameterTypes.isEmpty()) {
|
||||
false
|
||||
} else {
|
||||
method.parameterTypes.first() == "Ljava/io/InputStream;"
|
||||
}
|
||||
context(_: BytecodePatchContext)
|
||||
internal fun ClassDef.getJsonInputStreamMethod() = firstMutableMethodDeclaratively {
|
||||
custom {
|
||||
if (parameterTypes.isEmpty()) false
|
||||
else parameterTypes.first() == "Ljava/io/InputStream;"
|
||||
}
|
||||
}
|
||||
|
||||
internal val loganSquareFingerprint = fingerprint {
|
||||
custom { _, classDef -> classDef.endsWith("LoganSquare;") }
|
||||
internal val BytecodePatchContext.loganSquareClassDef by gettingFirstClassDef {
|
||||
type.endsWith("LoganSquare;")
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package app.revanced.patches.twitter.misc.hook.json
|
||||
|
||||
import app.revanced.patcher.BytecodePatchContextClassDefMatching.firstClassDef
|
||||
import app.revanced.patcher.extensions.addInstructions
|
||||
import app.revanced.patcher.extensions.removeInstructions
|
||||
import app.revanced.patcher.firstClassDef
|
||||
import app.revanced.patcher.patch.BytecodePatchContext
|
||||
import app.revanced.patcher.patch.PatchException
|
||||
import app.revanced.patcher.patch.bytecodePatch
|
||||
@@ -15,24 +15,21 @@ import java.io.InvalidClassException
|
||||
*
|
||||
* @param jsonHook The [JsonHook] to add.
|
||||
*/
|
||||
context(BytecodePatchContext)
|
||||
fun addJsonHook(
|
||||
fun BytecodePatchContext.addJsonHook(
|
||||
jsonHook: JsonHook,
|
||||
) {
|
||||
if (jsonHook.added) return
|
||||
|
||||
jsonHookPatchFingerprint.method.apply {
|
||||
// Insert hooks right before calling buildList.
|
||||
val insertIndex = jsonHookPatchFingerprint.instructionMatches.last().index
|
||||
// Insert hooks right before calling buildList.
|
||||
val insertIndex = jsonHookPatchMethodMatch.indices.last()
|
||||
|
||||
addInstructions(
|
||||
insertIndex,
|
||||
"""
|
||||
sget-object v1, ${jsonHook.descriptor}->INSTANCE:${jsonHook.descriptor}
|
||||
invoke-interface {v0, v1}, Ljava/util/List;->add(Ljava/lang/Object;)Z
|
||||
""",
|
||||
)
|
||||
}
|
||||
jsonHookPatchMethodMatch.method.addInstructions(
|
||||
insertIndex,
|
||||
"""
|
||||
sget-object v1, ${jsonHook.descriptor}->INSTANCE:${jsonHook.descriptor}
|
||||
invoke-interface {v0, v1}, Ljava/util/List;->add(Ljava/lang/Object;)Z
|
||||
""",
|
||||
)
|
||||
|
||||
jsonHook.added = true
|
||||
}
|
||||
@@ -48,15 +45,13 @@ val jsonHookPatch = bytecodePatch(
|
||||
dependsOn(sharedExtensionPatch)
|
||||
|
||||
apply {
|
||||
jsonHookPatchFingerprint.apply {
|
||||
val jsonHookPatch = firstClassDef(JSON_HOOK_PATCH_CLASS_DESCRIPTOR)
|
||||
|
||||
matchOrNull(jsonHookPatch)
|
||||
jsonHookPatchMethodMatch.apply {
|
||||
match(firstClassDef(JSON_HOOK_PATCH_CLASS_DESCRIPTOR)).methodOrNull
|
||||
?: throw PatchException("Unexpected extension.")
|
||||
}
|
||||
|
||||
val jsonFactoryClassDef =
|
||||
loganSquareFingerprint.originalClassDef // Conveniently find the type to hook a method in, via a named field.
|
||||
loganSquareClassDef // Conveniently find the type to hook a method in, via a named field.
|
||||
.fields
|
||||
.firstOrNull { it.name == "JSON_FACTORY" }
|
||||
?.type
|
||||
@@ -64,7 +59,7 @@ val jsonHookPatch = bytecodePatch(
|
||||
?: throw PatchException("Could not find required class.")
|
||||
|
||||
// Hook the methods first parameter.
|
||||
jsonInputStreamFingerprint.match(jsonFactoryClassDef).method.addInstructions(
|
||||
jsonFactoryClassDef.getJsonInputStreamMethod().addInstructions(
|
||||
0,
|
||||
"""
|
||||
invoke-static { p1 }, $JSON_HOOK_PATCH_CLASS_DESCRIPTOR->parseJsonHook(Ljava/io/InputStream;)Ljava/io/InputStream;
|
||||
@@ -75,14 +70,19 @@ val jsonHookPatch = bytecodePatch(
|
||||
|
||||
afterDependents {
|
||||
// Remove hooks.add(dummyHook).
|
||||
jsonHookPatchFingerprint.method.apply {
|
||||
val addDummyHookIndex = jsonHookPatchFingerprint.instructionMatches.last().index - 2
|
||||
val addDummyHookIndex = jsonHookPatchMethodMatch.indices.last()
|
||||
|
||||
removeInstructions(addDummyHookIndex, 2)
|
||||
}
|
||||
jsonHookPatchMethodMatch.method.removeInstructions(addDummyHookIndex, 2)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class JsonHook internal constructor(
|
||||
internal val descriptor: String,
|
||||
) {
|
||||
internal var added = false
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a hook class.
|
||||
* The class has to extend on **JsonHook**.
|
||||
@@ -91,22 +91,18 @@ val jsonHookPatch = bytecodePatch(
|
||||
* @param descriptor The class descriptor of the hook.
|
||||
* @throws ClassNotFoundException If the class could not be found.
|
||||
*/
|
||||
context(BytecodePatchContext)
|
||||
class JsonHook(
|
||||
internal val descriptor: String,
|
||||
) {
|
||||
internal var added = false
|
||||
|
||||
init {
|
||||
firstClassDef(descriptor).let {
|
||||
it.also { classDef ->
|
||||
if (
|
||||
classDef.superclass != JSON_HOOK_CLASS_DESCRIPTOR ||
|
||||
!classDef.fields.any { field -> field.name == "INSTANCE" }
|
||||
) {
|
||||
throw InvalidClassException(classDef.type, "Not a hook class")
|
||||
}
|
||||
context(_: BytecodePatchContext)
|
||||
fun jsonHook(descriptor: String): JsonHook {
|
||||
firstClassDef(descriptor).let {
|
||||
it.also { classDef ->
|
||||
if (
|
||||
classDef.superclass != JSON_HOOK_CLASS_DESCRIPTOR ||
|
||||
!classDef.fields.any { field -> field.name == "INSTANCE" }
|
||||
) {
|
||||
throw InvalidClassException(classDef.type, "Not a hook class")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return JsonHook(JSON_HOOK_CLASS_DESCRIPTOR)
|
||||
}
|
||||
@@ -16,7 +16,7 @@ import app.revanced.patches.youtube.misc.playercontrols.injectVisibilityCheckCal
|
||||
import app.revanced.patches.youtube.misc.playercontrols.playerControlsPatch
|
||||
import app.revanced.patches.youtube.misc.settings.PreferenceScreen
|
||||
import app.revanced.patches.youtube.misc.settings.settingsPatch
|
||||
import app.revanced.patches.youtube.shared.mainActivityOnCreateFingerprint
|
||||
import app.revanced.patches.youtube.shared.mainActivityOnCreateMethod
|
||||
import app.revanced.patches.youtube.video.information.videoInformationPatch
|
||||
import app.revanced.util.ResourceGroup
|
||||
import app.revanced.util.copyResources
|
||||
@@ -85,7 +85,7 @@ val downloadsPatch = bytecodePatch(
|
||||
injectVisibilityCheckCall(BUTTON_DESCRIPTOR)
|
||||
|
||||
// Main activity is used to launch downloader intent.
|
||||
mainActivityOnCreateFingerprint.method.addInstruction(
|
||||
mainActivityOnCreateMethod.method.addInstruction(
|
||||
0,
|
||||
"invoke-static/range { p0 .. p0 }, ${EXTENSION_CLASS_DESCRIPTOR}->setMainActivity(Landroid/app/Activity;)V"
|
||||
)
|
||||
|
||||
@@ -5,7 +5,6 @@ import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
|
||||
import app.revanced.patches.youtube.misc.gms.Constants.YOUTUBE_MAIN_ACTIVITY_NAME
|
||||
import app.revanced.patches.youtube.misc.gms.Constants.YOUTUBE_PACKAGE_NAME
|
||||
import app.revanced.patches.youtube.misc.settings.PreferenceScreen
|
||||
import app.revanced.patches.youtube.shared.mainActivityOnCreateFingerprint
|
||||
|
||||
@Suppress("unused")
|
||||
val customBrandingPatch = baseCustomBrandingPatch(
|
||||
|
||||
@@ -14,10 +14,9 @@ import app.revanced.patches.shared.misc.mapping.resourceMappingPatch
|
||||
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
|
||||
import app.revanced.patches.youtube.misc.playservice.is_19_34_or_greater
|
||||
import app.revanced.patches.youtube.misc.playservice.is_19_49_or_greater
|
||||
import app.revanced.patches.youtube.misc.playservice.is_20_30_or_greater
|
||||
import app.revanced.patches.youtube.misc.playservice.is_20_34_or_greater
|
||||
import app.revanced.patches.youtube.misc.playservice.versionCheckPatch
|
||||
import app.revanced.patches.youtube.shared.mainActivityOnCreateFingerprint
|
||||
import app.revanced.patches.youtube.shared.mainActivityOnCreateMethod
|
||||
import app.revanced.util.findInstructionIndicesReversedOrThrow
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.insertLiteralOverride
|
||||
@@ -155,7 +154,7 @@ val seekbarColorPatch = bytecodePatch(
|
||||
}
|
||||
|
||||
// Hook the splash animation to set the a seekbar color.
|
||||
mainActivityOnCreateFingerprint.method.apply {
|
||||
mainActivityOnCreateMethod.method.apply {
|
||||
val setAnimationIntMethodName =
|
||||
lottieAnimationViewSetAnimationIntFingerprint.originalMethod.name
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ import app.revanced.patches.youtube.misc.playservice.is_20_09_or_greater
|
||||
import app.revanced.patches.youtube.misc.playservice.versionCheckPatch
|
||||
import app.revanced.patches.youtube.misc.settings.PreferenceScreen
|
||||
import app.revanced.patches.youtube.misc.settings.settingsPatch
|
||||
import app.revanced.patches.youtube.shared.mainActivityOnCreateFingerprint
|
||||
import app.revanced.patches.youtube.shared.mainActivityOnCreateMethod
|
||||
import app.revanced.util.findInstructionIndicesReversedOrThrow
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
@@ -65,7 +65,7 @@ val shortsAutoplayPatch = bytecodePatch(
|
||||
}
|
||||
|
||||
// Main activity is used to check if app is in pip mode.
|
||||
mainActivityOnCreateFingerprint.method.addInstruction(
|
||||
mainActivityOnCreateMethod.method.addInstruction(
|
||||
0,
|
||||
"invoke-static/range { p0 .. p0 }, $EXTENSION_CLASS_DESCRIPTOR->setMainActivity(Landroid/app/Activity;)V",
|
||||
)
|
||||
|
||||
@@ -17,7 +17,7 @@ import app.revanced.patches.youtube.misc.playservice.is_20_39_or_greater
|
||||
import app.revanced.patches.youtube.misc.playservice.versionCheckPatch
|
||||
import app.revanced.patches.youtube.misc.settings.PreferenceScreen
|
||||
import app.revanced.patches.youtube.misc.settings.settingsPatch
|
||||
import app.revanced.patches.youtube.shared.mainActivityOnCreateFingerprint
|
||||
import app.revanced.patches.youtube.shared.mainActivityOnCreateMethod
|
||||
import app.revanced.util.findFreeRegister
|
||||
import app.revanced.util.getReference
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
@@ -61,7 +61,7 @@ val openShortsInRegularPlayerPatch = bytecodePatch(
|
||||
)
|
||||
|
||||
// Activity is used as the context to launch an Intent.
|
||||
mainActivityOnCreateFingerprint.method.addInstruction(
|
||||
mainActivityOnCreateMethod.method.addInstruction(
|
||||
0,
|
||||
"invoke-static/range { p0 .. p0 }, $EXTENSION_CLASS_DESCRIPTOR->" +
|
||||
"setMainActivity(Landroid/app/Activity;)V",
|
||||
|
||||
@@ -7,7 +7,7 @@ import app.revanced.patches.all.misc.resources.addResourcesPatch
|
||||
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
|
||||
import app.revanced.patches.youtube.misc.settings.PreferenceScreen
|
||||
import app.revanced.patches.youtube.misc.settings.settingsPatch
|
||||
import app.revanced.patches.youtube.shared.mainActivityOnCreateFingerprint
|
||||
import app.revanced.patches.youtube.shared.mainActivityOnCreateMethod
|
||||
|
||||
private const val EXTENSION_CLASS_DESCRIPTOR =
|
||||
"Lapp/revanced/extension/youtube/patches/announcements/AnnouncementsPatch;"
|
||||
@@ -37,7 +37,7 @@ val announcementsPatch = bytecodePatch(
|
||||
SwitchPreference("revanced_announcements"),
|
||||
)
|
||||
|
||||
mainActivityOnCreateFingerprint.method.addInstruction(
|
||||
mainActivityOnCreateMethod.method.addInstruction(
|
||||
0,
|
||||
"invoke-static/range { p0 .. p0 }, $EXTENSION_CLASS_DESCRIPTOR->showAnnouncement(Landroid/app/Activity;)V",
|
||||
)
|
||||
|
||||
@@ -2,10 +2,10 @@ package app.revanced.patches.youtube.misc.check
|
||||
|
||||
import app.revanced.patches.shared.misc.checks.checkEnvironmentPatch
|
||||
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
|
||||
import app.revanced.patches.youtube.shared.mainActivityOnCreateFingerprint
|
||||
import app.revanced.patches.youtube.shared.mainActivityOnCreateMethod
|
||||
|
||||
internal val checkEnvironmentPatch = checkEnvironmentPatch(
|
||||
mainActivityOnCreateFingerprint = mainActivityOnCreateFingerprint,
|
||||
getMainActivityOnCreateMethod = { mainActivityOnCreateMethod },
|
||||
extensionPatch = sharedExtensionPatch,
|
||||
"com.google.android.youtube",
|
||||
)
|
||||
|
||||
@@ -2,7 +2,6 @@ package app.revanced.patches.youtube.misc.dns
|
||||
|
||||
import app.revanced.patches.shared.misc.dns.checkWatchHistoryDomainNameResolutionPatch
|
||||
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
|
||||
import app.revanced.patches.youtube.shared.mainActivityOnCreateFingerprint
|
||||
|
||||
val checkWatchHistoryDomainNameResolutionPatch = checkWatchHistoryDomainNameResolutionPatch(
|
||||
block = {
|
||||
@@ -19,5 +18,5 @@ val checkWatchHistoryDomainNameResolutionPatch = checkWatchHistoryDomainNameReso
|
||||
)
|
||||
)
|
||||
},
|
||||
mainActivityFingerprint = mainActivityOnCreateFingerprint
|
||||
getMainActivityMethod = mainActivityOnCreateFingerprint
|
||||
)
|
||||
|
||||
@@ -13,7 +13,6 @@ import app.revanced.patches.youtube.misc.gms.Constants.YOUTUBE_PACKAGE_NAME
|
||||
import app.revanced.patches.youtube.misc.settings.PreferenceScreen
|
||||
import app.revanced.patches.youtube.misc.settings.settingsPatch
|
||||
import app.revanced.patches.youtube.misc.spoof.spoofVideoStreamsPatch
|
||||
import app.revanced.patches.youtube.shared.mainActivityOnCreateFingerprint
|
||||
|
||||
@Suppress("unused")
|
||||
val gmsCoreSupportPatch = gmsCoreSupportPatch(
|
||||
|
||||
@@ -13,7 +13,6 @@ import app.revanced.patches.youtube.misc.playservice.is_20_14_or_greater
|
||||
import app.revanced.patches.youtube.misc.playservice.versionCheckPatch
|
||||
import app.revanced.patches.youtube.misc.settings.PreferenceScreen
|
||||
import app.revanced.patches.youtube.misc.settings.settingsPatch
|
||||
import app.revanced.patches.youtube.shared.mainActivityOnCreateFingerprint
|
||||
|
||||
val spoofVideoStreamsPatch = spoofVideoStreamsPatch(
|
||||
extensionClassDescriptor = "Lapp/revanced/extension/youtube/patches/spoof/SpoofVideoStreamsPatch;",
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package app.revanced.patches.youtube.shared
|
||||
|
||||
import app.revanced.patcher.BytecodePatchContextMethodMatching.firstMutableMethodDeclaratively
|
||||
import app.revanced.patcher.BytecodePatchContextMethodMatching.gettingFirstMutableMethodDeclaratively
|
||||
import app.revanced.patcher.InstructionLocation.MatchAfterImmediately
|
||||
import app.revanced.patcher.fieldAccess
|
||||
import app.revanced.patcher.fingerprint
|
||||
@@ -8,6 +10,11 @@ import app.revanced.patcher.methodCall
|
||||
import app.revanced.patcher.newInstance
|
||||
import app.revanced.patcher.opcode
|
||||
import app.revanced.patcher.addString
|
||||
import app.revanced.patcher.definingClass
|
||||
import app.revanced.patcher.name
|
||||
import app.revanced.patcher.parameterTypes
|
||||
import app.revanced.patcher.patch.BytecodePatchContext
|
||||
import app.revanced.patcher.returnType
|
||||
import app.revanced.patches.shared.misc.mapping.ResourceType
|
||||
import app.revanced.patches.shared.misc.mapping.resourceLiteral
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
@@ -58,12 +65,11 @@ internal val mainActivityOnBackPressedFingerprint = fingerprint {
|
||||
}
|
||||
}
|
||||
|
||||
internal val mainActivityOnCreateFingerprint = fingerprint {
|
||||
returns("V")
|
||||
parameters("Landroid/os/Bundle;")
|
||||
custom { method, classDef ->
|
||||
method.name == "onCreate" && classDef.type == YOUTUBE_MAIN_ACTIVITY_CLASS_TYPE
|
||||
}
|
||||
internal val BytecodePatchContext.mainActivityOnCreateMethod by gettingFirstMutableMethodDeclaratively {
|
||||
name("onCreate")
|
||||
definingClass(YOUTUBE_MAIN_ACTIVITY_CLASS_TYPE)
|
||||
returnType("V")
|
||||
parameterTypes("Landroid/os/Bundle;")
|
||||
}
|
||||
|
||||
internal val rollingNumberTextViewAnimationUpdateFingerprint = fingerprint {
|
||||
@@ -87,8 +93,8 @@ internal val rollingNumberTextViewAnimationUpdateFingerprint = fingerprint {
|
||||
)
|
||||
custom { _, classDef ->
|
||||
classDef.superclass == "Landroid/support/v7/widget/AppCompatTextView;" ||
|
||||
classDef.superclass ==
|
||||
"Lcom/google/android/libraries/youtube/rendering/ui/spec/typography/YouTubeAppCompatTextView;"
|
||||
classDef.superclass ==
|
||||
"Lcom/google/android/libraries/youtube/rendering/ui/spec/typography/YouTubeAppCompatTextView;"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,6 +134,10 @@ internal val videoQualityChangedFingerprint = fingerprint {
|
||||
newInstance("Lcom/google/android/libraries/youtube/innertube/model/media/VideoQuality;"),
|
||||
opcode(Opcode.IGET_OBJECT),
|
||||
opcode(Opcode.CHECK_CAST),
|
||||
fieldAccess(type = "I", opcode = Opcode.IGET, location = MatchAfterImmediately()), // Video resolution (human readable).
|
||||
fieldAccess(
|
||||
type = "I",
|
||||
opcode = Opcode.IGET,
|
||||
location = MatchAfterImmediately()
|
||||
), // Video resolution (human readable).
|
||||
)
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ import app.revanced.patches.youtube.misc.playservice.is_20_07_or_greater
|
||||
import app.revanced.patches.youtube.misc.playservice.versionCheckPatch
|
||||
import app.revanced.patches.youtube.misc.settings.PreferenceScreen
|
||||
import app.revanced.patches.youtube.misc.settings.settingsPatch
|
||||
import app.revanced.patches.youtube.shared.mainActivityOnCreateFingerprint
|
||||
|
||||
@Suppress("unused")
|
||||
val forceOriginalAudioPatch = forceOriginalAudioPatch(
|
||||
|
||||
Reference in New Issue
Block a user