feat(youtube/spoof-signature-verification): automatic signature spoofing

Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
This commit is contained in:
LisoUseInAIKyrios 2023-03-17 21:58:41 +04:00 committed by GitHub
parent 289ef56f5c
commit f1395f49fa
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 60 additions and 3 deletions

View file

@ -0,0 +1,17 @@
package app.revanced.patches.youtube.misc.fix.playback.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.Opcode
// Resolves to the method CronetDataSource.open
// https://androidx.tech/artifacts/media3/media3-datasource-cronet/1.0.0-alpha03-source/androidx/media3/datasource/cronet/CronetDataSource.java.html
object OpenCronetDataSourceFingerprint : MethodFingerprint(
opcodes = listOf(
Opcode.MOVE_RESULT,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
),
strings = listOf(
"err_cleartext_not_permitted",
),
)

View file

@ -7,27 +7,50 @@ import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.data.toMethodWalker import app.revanced.patcher.data.toMethodWalker
import app.revanced.patcher.extensions.addInstructions import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.extensions.instruction
import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patches.shared.settings.preference.impl.StringResource
import app.revanced.patches.shared.settings.preference.impl.SwitchPreference
import app.revanced.patches.youtube.misc.fix.playback.annotation.ProtobufSpoofCompatibility import app.revanced.patches.youtube.misc.fix.playback.annotation.ProtobufSpoofCompatibility
import app.revanced.patches.youtube.misc.fix.playback.fingerprints.OpenCronetDataSourceFingerprint
import app.revanced.patches.youtube.misc.fix.playback.fingerprints.ProtobufParameterBuilderFingerprint import app.revanced.patches.youtube.misc.fix.playback.fingerprints.ProtobufParameterBuilderFingerprint
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
@Patch @Patch
@Name("spoof-signature-verification") @Name("spoof-signature-verification")
@Description("Spoofs the client to prevent playback issues.") @Description("Spoofs the client to prevent playback issues.")
@ProtobufSpoofCompatibility @ProtobufSpoofCompatibility
@DependsOn([IntegrationsPatch::class, SettingsPatch::class])
@Version("0.0.1") @Version("0.0.1")
class SpoofSignatureVerificationPatch : BytecodePatch( class SpoofSignatureVerificationPatch : BytecodePatch(
listOf(ProtobufParameterBuilderFingerprint) listOf(
ProtobufParameterBuilderFingerprint,
OpenCronetDataSourceFingerprint,
)
) { ) {
override fun execute(context: BytecodeContext): PatchResult { override fun execute(context: BytecodeContext): PatchResult {
SettingsPatch.PreferenceScreen.MISC.addPreferences(
SwitchPreference(
"revanced_spoof_signature_verification",
StringResource("revanced_spoof_signature_verification_title", "Spoof app signature"),
false,
StringResource("revanced_spoof_signature_verification_summary_on", "App signature spoofed"),
StringResource("revanced_spoof_signature_verification_summary_off", "App signature not spoofed")
)
)
// hook parameter
ProtobufParameterBuilderFingerprint.result?.let { ProtobufParameterBuilderFingerprint.result?.let {
val setParamMethod = context val setParamMethod = context
.toMethodWalker(it.method) .toMethodWalker(it.method)
.nextMethod(it.scanResult.patternScanResult!!.startIndex, true).getMethod() as MutableMethod .nextMethod(it.scanResult.patternScanResult!!.startIndex, true).getMethod() as MutableMethod
setParamMethod.apply { setParamMethod.apply {
val protobufParameterRegister = 3 val protobufParameterRegister = 3
@ -35,13 +58,30 @@ class SpoofSignatureVerificationPatch : BytecodePatch(
addInstructions( addInstructions(
0, 0,
""" """
invoke-static {p$protobufParameterRegister}, $INTEGRATIONS_CLASS_DESCRIPTOR->getVerificationSpoofOverride(Ljava/lang/String;)Ljava/lang/String; invoke-static {p$protobufParameterRegister}, $INTEGRATIONS_CLASS_DESCRIPTOR->overrideProtobufParameter(Ljava/lang/String;)Ljava/lang/String;
move-result-object p$protobufParameterRegister move-result-object p$protobufParameterRegister
""" """
) )
} }
} ?: return ProtobufParameterBuilderFingerprint.toErrorResult() } ?: return ProtobufParameterBuilderFingerprint.toErrorResult()
// hook video playback result
OpenCronetDataSourceFingerprint.result?.let {
it.mutableMethod.apply {
val getHeadersInstructionIndex = it.scanResult.patternScanResult!!.endIndex
val responseCodeRegister =
(instruction(getHeadersInstructionIndex - 2) as OneRegisterInstruction).registerA
addInstructions(
getHeadersInstructionIndex + 1,
"""
invoke-static {v$responseCodeRegister}, $INTEGRATIONS_CLASS_DESCRIPTOR->onResponse(I)V
"""
)
}
} ?: return OpenCronetDataSourceFingerprint.toErrorResult()
return PatchResultSuccess() return PatchResultSuccess()
} }