mirror of
https://github.com/revanced/revanced-patches
synced 2024-12-04 19:22:52 +01:00
feat: add capability to filter from protobuf buffer
This commit is contained in:
parent
67d237c23f
commit
b738b6bf35
@ -0,0 +1,25 @@
|
|||||||
|
package app.revanced.patches.youtube.misc.litho.filter.fingerprints
|
||||||
|
|
||||||
|
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
|
||||||
|
import org.jf.dexlib2.Opcode
|
||||||
|
|
||||||
|
object ProtobufBufferFingerprint : MethodFingerprint(
|
||||||
|
opcodes = listOf(
|
||||||
|
Opcode.IGET_OBJECT, // References the field required below.
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
Opcode.IF_NEZ,
|
||||||
|
Opcode.CONST_4,
|
||||||
|
Opcode.GOTO,
|
||||||
|
Opcode.CHECK_CAST, // Casts the referenced field to a specific type that stores the protobuf buffer.
|
||||||
|
Opcode.INVOKE_VIRTUAL
|
||||||
|
)
|
||||||
|
)
|
@ -17,6 +17,7 @@ import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
|
|||||||
import app.revanced.patches.youtube.misc.litho.filter.annotation.LithoFilterCompatibility
|
import app.revanced.patches.youtube.misc.litho.filter.annotation.LithoFilterCompatibility
|
||||||
import app.revanced.patches.youtube.misc.litho.filter.fingerprints.ComponentContextParserFingerprint
|
import app.revanced.patches.youtube.misc.litho.filter.fingerprints.ComponentContextParserFingerprint
|
||||||
import app.revanced.patches.youtube.misc.litho.filter.fingerprints.EmptyComponentBuilderFingerprint
|
import app.revanced.patches.youtube.misc.litho.filter.fingerprints.EmptyComponentBuilderFingerprint
|
||||||
|
import app.revanced.patches.youtube.misc.litho.filter.fingerprints.ProtobufBufferFingerprint
|
||||||
import app.revanced.patches.youtube.misc.litho.filter.fingerprints.ReadComponentIdentifierFingerprint
|
import app.revanced.patches.youtube.misc.litho.filter.fingerprints.ReadComponentIdentifierFingerprint
|
||||||
import org.jf.dexlib2.iface.instruction.Instruction
|
import org.jf.dexlib2.iface.instruction.Instruction
|
||||||
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
|
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
|
||||||
@ -32,7 +33,9 @@ class LithoFilterPatch : BytecodePatch(
|
|||||||
) {
|
) {
|
||||||
override fun execute(context: BytecodeContext): PatchResult {
|
override fun execute(context: BytecodeContext): PatchResult {
|
||||||
ComponentContextParserFingerprint.result?.also {
|
ComponentContextParserFingerprint.result?.also {
|
||||||
arrayOf(EmptyComponentBuilderFingerprint, ReadComponentIdentifierFingerprint).forEach { fingerprint ->
|
arrayOf(
|
||||||
|
EmptyComponentBuilderFingerprint, ReadComponentIdentifierFingerprint, ProtobufBufferFingerprint
|
||||||
|
).forEach { fingerprint ->
|
||||||
if (!fingerprint.resolve(context, it.mutableMethod, it.mutableClass))
|
if (!fingerprint.resolve(context, it.mutableMethod, it.mutableClass))
|
||||||
return fingerprint.toErrorResult()
|
return fingerprint.toErrorResult()
|
||||||
}
|
}
|
||||||
@ -45,26 +48,54 @@ class LithoFilterPatch : BytecodePatch(
|
|||||||
val builderMethodDescriptor = instruction(builderMethodIndex).descriptor
|
val builderMethodDescriptor = instruction(builderMethodIndex).descriptor
|
||||||
val emptyComponentFieldDescriptor = instruction(emptyComponentFieldIndex).descriptor
|
val emptyComponentFieldDescriptor = instruction(emptyComponentFieldIndex).descriptor
|
||||||
// Register is overwritten right after it is used in this patch, therefore free to clobber.
|
// Register is overwritten right after it is used in this patch, therefore free to clobber.
|
||||||
val clobberedRegister = instruction(insertHookIndex - 1).twoRegisterA
|
val free = instruction<TwoRegisterInstruction>(insertHookIndex - 1).registerA
|
||||||
|
val free2 = instruction<OneRegisterInstruction>(insertHookIndex).registerA
|
||||||
|
|
||||||
@Suppress("UnnecessaryVariable")
|
@Suppress("UnnecessaryVariable")
|
||||||
// The register, this patch clobbers, is previously used for the StringBuilder,
|
// The register, this patch clobbers, is previously used for the StringBuilder,
|
||||||
// later on a new StringBuilder is instantiated on it.
|
// later on a new StringBuilder is instantiated on it.
|
||||||
val stringBuilderRegister = clobberedRegister
|
val stringBuilderRegister = free
|
||||||
|
|
||||||
val identifierRegister = instruction(ReadComponentIdentifierFingerprint.patternScanEndIndex).oneRegisterA
|
val identifierRegister =
|
||||||
|
instruction<OneRegisterInstruction>(ReadComponentIdentifierFingerprint.patternScanEndIndex).registerA
|
||||||
|
|
||||||
|
// Parameter that holds a ref to a type with a field that ref the protobuf buffer object.
|
||||||
|
val protobufParameterNumber = 3
|
||||||
|
|
||||||
|
// Get the field that stores an protobuf buffer required below.
|
||||||
|
val protobufBufferRefTypeRefFieldDescriptor =
|
||||||
|
instruction(ProtobufBufferFingerprint.patternScanStartIndex).descriptor
|
||||||
|
val protobufBufferRefTypeDescriptor =
|
||||||
|
instruction(ProtobufBufferFingerprint.patternScanEndIndex - 1).descriptor
|
||||||
|
val protobufBufferFieldDescriptor = "$protobufBufferRefTypeDescriptor->b:Ljava/nio/ByteBuffer;"
|
||||||
|
|
||||||
addInstructions(
|
addInstructions(
|
||||||
insertHookIndex, // right after setting the component.pathBuilder field,
|
insertHookIndex, // right after setting the component.pathBuilder field.
|
||||||
"""
|
"""
|
||||||
invoke-static {v$stringBuilderRegister, v$identifierRegister}, Lapp/revanced/integrations/patches/LithoFilterPatch;->filter(Ljava/lang/StringBuilder;Ljava/lang/String;)Z
|
# Get the protobuf buffer object.
|
||||||
move-result v$clobberedRegister
|
|
||||||
if-eqz v$clobberedRegister, :not_an_ad
|
move-object/from16 v$free2, p$protobufParameterNumber
|
||||||
move-object/from16 v$clobberedRegister, p1
|
iget-object v$free2, v$free2, $protobufBufferRefTypeRefFieldDescriptor
|
||||||
invoke-static {v$clobberedRegister}, $builderMethodDescriptor
|
check-cast v$free2, $protobufBufferRefTypeDescriptor
|
||||||
move-result-object v$clobberedRegister
|
|
||||||
iget-object v$clobberedRegister, v$clobberedRegister, $emptyComponentFieldDescriptor
|
# Register "free" now holds the protobuf buffer object
|
||||||
return-object v$clobberedRegister
|
|
||||||
|
iget-object v$free2, v$free2, $protobufBufferFieldDescriptor
|
||||||
|
|
||||||
|
# Invoke the filter method.
|
||||||
|
|
||||||
|
invoke-static { v$stringBuilderRegister, v$identifierRegister, v$free2 }, $FILTER_METHOD_DESCRIPTOR
|
||||||
|
move-result v$free
|
||||||
|
|
||||||
|
if-eqz v$free, :not_an_ad
|
||||||
|
|
||||||
|
# If the filter method returned true, then return a replacement empty component.
|
||||||
|
|
||||||
|
move-object/from16 v$free, p1
|
||||||
|
invoke-static {v$free}, $builderMethodDescriptor
|
||||||
|
move-result-object v$free
|
||||||
|
iget-object v$free, v$free, $emptyComponentFieldDescriptor
|
||||||
|
return-object v$free
|
||||||
""",
|
""",
|
||||||
listOf(ExternalLabel("not_an_ad", instruction(insertHookIndex)))
|
listOf(ExternalLabel("not_an_ad", instruction(insertHookIndex)))
|
||||||
)
|
)
|
||||||
@ -75,16 +106,20 @@ class LithoFilterPatch : BytecodePatch(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private companion object {
|
private companion object {
|
||||||
|
private val MethodFingerprint.patternScanResult
|
||||||
|
get() = result!!.scanResult.patternScanResult!!
|
||||||
|
|
||||||
val MethodFingerprint.patternScanEndIndex
|
val MethodFingerprint.patternScanEndIndex
|
||||||
get() = result!!.scanResult.patternScanResult!!.endIndex
|
get() = patternScanResult.endIndex
|
||||||
|
|
||||||
|
val MethodFingerprint.patternScanStartIndex
|
||||||
|
get() = patternScanResult.startIndex
|
||||||
|
|
||||||
val Instruction.descriptor
|
val Instruction.descriptor
|
||||||
get() = (this as ReferenceInstruction).reference.toString()
|
get() = (this as ReferenceInstruction).reference.toString()
|
||||||
|
|
||||||
val Instruction.oneRegisterA
|
const val FILTER_METHOD_DESCRIPTOR =
|
||||||
get() = (this as OneRegisterInstruction).registerA
|
"Lapp/revanced/integrations/patches/litho/LithoFilterPatch;" +
|
||||||
|
"->filter(Ljava/lang/StringBuilder;Ljava/lang/String;Ljava/nio/ByteBuffer;)Z"
|
||||||
val Instruction.twoRegisterA
|
|
||||||
get() = (this as TwoRegisterInstruction).registerA
|
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user