Skip to content

Commit d18719c

Browse files
committed
fix(YouTube - Client spoof): Spoof all user agents
1 parent 743a02f commit d18719c

File tree

3 files changed

+74
-46
lines changed

3 files changed

+74
-46
lines changed

api/revanced-patches.api

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1514,10 +1514,12 @@ public final class app/revanced/patches/youtube/misc/dimensions/spoof/SpoofDevic
15141514
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
15151515
}
15161516

1517-
public final class app/revanced/patches/youtube/misc/fix/playback/ClientSpoofPatch : app/revanced/patcher/patch/BytecodePatch {
1517+
public final class app/revanced/patches/youtube/misc/fix/playback/ClientSpoofPatch : app/revanced/patches/all/misc/transformation/BaseTransformInstructionsPatch {
15181518
public static final field INSTANCE Lapp/revanced/patches/youtube/misc/fix/playback/ClientSpoofPatch;
1519-
public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V
1520-
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
1519+
public synthetic fun filterMap (Lcom/android/tools/smali/dexlib2/iface/ClassDef;Lcom/android/tools/smali/dexlib2/iface/Method;Lcom/android/tools/smali/dexlib2/iface/instruction/Instruction;I)Ljava/lang/Object;
1520+
public fun filterMap (Lcom/android/tools/smali/dexlib2/iface/ClassDef;Lcom/android/tools/smali/dexlib2/iface/Method;Lcom/android/tools/smali/dexlib2/iface/instruction/Instruction;I)Lkotlin/Triple;
1521+
public synthetic fun transform (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;Ljava/lang/Object;)V
1522+
public fun transform (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;Lkotlin/Triple;)V
15211523
}
15221524

15231525
public final class app/revanced/patches/youtube/misc/fix/playback/SpoofSignaturePatch : app/revanced/patcher/patch/BytecodePatch {
Lines changed: 69 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,87 @@
11
package app.revanced.patches.youtube.misc.fix.playback
22

3-
import app.revanced.util.exception
4-
import app.revanced.patcher.data.BytecodeContext
5-
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
63
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
7-
import app.revanced.patcher.patch.BytecodePatch
4+
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
85
import app.revanced.patcher.patch.annotation.CompatiblePackage
96
import app.revanced.patcher.patch.annotation.Patch
10-
import app.revanced.patches.youtube.misc.fix.playback.fingerprints.UserAgentHeaderBuilderFingerprint
11-
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
7+
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
8+
import app.revanced.patches.all.misc.transformation.BaseTransformInstructionsPatch
9+
import app.revanced.patches.all.misc.transformation.IMethodCall
10+
import app.revanced.patches.all.misc.transformation.Instruction35cInfo
11+
import app.revanced.patches.all.misc.transformation.filterMapInstruction35c
12+
import app.revanced.util.getReference
13+
import com.android.tools.smali.dexlib2.iface.ClassDef
14+
import com.android.tools.smali.dexlib2.iface.Method
15+
import com.android.tools.smali.dexlib2.iface.instruction.Instruction
16+
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
17+
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
1218

1319
@Patch(
1420
name = "Client spoof",
1521
description = "Adds options to spoof the client to allow video playback.",
1622
dependencies = [SpoofSignaturePatch::class],
1723
compatiblePackages = [
18-
CompatiblePackage(
19-
"com.google.android.youtube", [
20-
"18.48.39",
21-
"18.49.37",
22-
"19.01.34",
23-
"19.02.39",
24-
"19.03.36",
25-
"19.04.38",
26-
"19.05.36",
27-
"19.06.39",
28-
"19.07.40",
29-
"19.08.36",
30-
"19.09.37"
31-
]
32-
)
33-
]
24+
CompatiblePackage("com.google.android.youtube"),
25+
],
3426
)
35-
object ClientSpoofPatch : BytecodePatch(
36-
setOf(UserAgentHeaderBuilderFingerprint)
37-
) {
27+
object ClientSpoofPatch : BaseTransformInstructionsPatch<Instruction35cInfo>() {
3828
private const val ORIGINAL_PACKAGE_NAME = "com.google.android.youtube"
29+
private const val USER_AGENT_STRING_BUILDER_APPEND_METHOD_REFERENCE =
30+
"Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;"
3931

40-
override fun execute(context: BytecodeContext) {
41-
UserAgentHeaderBuilderFingerprint.result?.let { result ->
42-
val insertIndex = result.scanResult.patternScanResult!!.endIndex
43-
result.mutableMethod.apply {
44-
val packageNameRegister = getInstruction<FiveRegisterInstruction>(insertIndex).registerD
32+
override fun filterMap(
33+
classDef: ClassDef,
34+
method: Method,
35+
instruction: Instruction,
36+
instructionIndex: Int,
37+
) = filterMapInstruction35c<MethodCall>(
38+
"Lapp/revanced/integrations",
39+
classDef,
40+
instruction,
41+
instructionIndex,
42+
)
4543

46-
addInstruction(insertIndex, "const-string v$packageNameRegister, \"$ORIGINAL_PACKAGE_NAME\"")
47-
}
44+
override fun transform(mutableMethod: MutableMethod, entry: Instruction35cInfo) {
45+
val (_, _, instructionIndex) = entry
4846

49-
} ?: throw UserAgentHeaderBuilderFingerprint.exception
47+
// Replace the result of context.getPackageName(), if it is used in a user agent string.
48+
mutableMethod.apply {
49+
// After context.getPackageName() the result is moved to a register.
50+
val targetRegister = (
51+
getInstruction(instructionIndex + 1)
52+
as? OneRegisterInstruction ?: return
53+
).registerA
54+
55+
// IndexOutOfBoundsException is not possible here,
56+
// but no such occurrences are present in the app.
57+
val referee = getInstruction(instructionIndex + 2).getReference<MethodReference>()?.toString()
58+
59+
// This can technically also match non-user agent string builder append methods,
60+
// but no such occurrences are present in the app.
61+
if (referee != USER_AGENT_STRING_BUILDER_APPEND_METHOD_REFERENCE) {
62+
return
63+
}
64+
65+
// Overwrite the result of context.getPackageName() with the original package name.
66+
replaceInstruction(
67+
instructionIndex + 1,
68+
"const-string v$targetRegister, \"${ORIGINAL_PACKAGE_NAME}\"",
69+
)
70+
}
71+
}
72+
73+
@Suppress("unused")
74+
private enum class MethodCall(
75+
override val definedClassName: String,
76+
override val methodName: String,
77+
override val methodParams: Array<String>,
78+
override val returnType: String,
79+
) : IMethodCall {
80+
GetPackageName(
81+
"Landroid/content/Context;",
82+
"getPackageName",
83+
emptyArray(),
84+
"Ljava/lang/String;",
85+
),
5086
}
5187
}

src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/fingerprints/UserAgentHeaderBuilderFingerprint.kt

Lines changed: 0 additions & 10 deletions
This file was deleted.

0 commit comments

Comments
 (0)