fix(Tiktok - Settings): bump compatibility (#2656)

This commit is contained in:
Vu Hoan Huy 2023-07-20 06:13:33 +07:00 committed by GitHub
parent 2870d2619a
commit 6641356d41
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 88 additions and 88 deletions

View File

@ -1,17 +0,0 @@
package app.revanced.patches.tiktok.misc.settings.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.Opcode
object AboutPageFingerprint : MethodFingerprint(
opcodes = listOf(
Opcode.CONST, // copyrightPolicyLabel resource id
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.CONST_STRING
),
customFingerprint = { methodDef, _ ->
methodDef.definingClass == "Lcom/ss/android/ugc/aweme/setting/page/AboutPage;" &&
methodDef.name == "onViewCreated"
}
)

View File

@ -0,0 +1,22 @@
package app.revanced.patches.tiktok.misc.settings.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.Opcode
object AddSettingsEntryFingerprint : MethodFingerprint(
opcodes = listOf(
Opcode.CONST_CLASS,
Opcode.APUT_OBJECT,
Opcode.INVOKE_VIRTUAL,
Opcode.IGET_OBJECT,
Opcode.IGET_OBJECT,
Opcode.INVOKE_VIRTUAL,
Opcode.IGET_OBJECT,
Opcode.IGET_OBJECT,
Opcode.INVOKE_VIRTUAL,
),
customFingerprint = { methodDef, _ ->
methodDef.definingClass.endsWith("/SettingNewVersionFragment;") &&
methodDef.name == "onViewCreated"
}
)

View File

@ -0,0 +1,9 @@
package app.revanced.patches.tiktok.misc.settings.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
object SettingsEntryFingerprint : MethodFingerprint(
strings = listOf(
"pls pass item or extends the EventUnit"
)
)

View File

@ -0,0 +1,10 @@
package app.revanced.patches.tiktok.misc.settings.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
object SettingsEntryInfoFingerprint : MethodFingerprint(
strings = listOf(
"ExposeItem(title=",
", icon="
)
)

View File

@ -1,10 +0,0 @@
package app.revanced.patches.tiktok.misc.settings.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
object SettingsOnViewCreatedFingerprint : MethodFingerprint(
customFingerprint = { methodDef, _ ->
methodDef.definingClass.endsWith("/SettingNewVersionFragment;") &&
methodDef.name == "onViewCreated"
}
)

View File

@ -6,24 +6,19 @@ import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
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.PatchResultError
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.DependsOn
import app.revanced.patcher.patch.annotations.Patch import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.util.smali.ExternalLabel
import app.revanced.patches.tiktok.misc.integrations.patch.IntegrationsPatch import app.revanced.patches.tiktok.misc.integrations.patch.IntegrationsPatch
import app.revanced.patches.tiktok.misc.settings.annotations.SettingsCompatibility import app.revanced.patches.tiktok.misc.settings.annotations.SettingsCompatibility
import app.revanced.patches.tiktok.misc.settings.fingerprints.AboutPageFingerprint import app.revanced.patches.tiktok.misc.settings.fingerprints.*
import app.revanced.patches.tiktok.misc.settings.fingerprints.AdPersonalizationActivityOnCreateFingerprint
import app.revanced.patches.tiktok.misc.settings.fingerprints.SettingsOnViewCreatedFingerprint
import org.jf.dexlib2.Opcode import org.jf.dexlib2.Opcode
import org.jf.dexlib2.iface.instruction.FiveRegisterInstruction import org.jf.dexlib2.iface.instruction.FiveRegisterInstruction
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
import org.jf.dexlib2.iface.instruction.ReferenceInstruction
import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
@Patch @Patch
@DependsOn([IntegrationsPatch::class]) @DependsOn([IntegrationsPatch::class])
@ -33,65 +28,44 @@ import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
@Version("0.0.1") @Version("0.0.1")
class SettingsPatch : BytecodePatch( class SettingsPatch : BytecodePatch(
listOf( listOf(
AboutPageFingerprint,
AdPersonalizationActivityOnCreateFingerprint, AdPersonalizationActivityOnCreateFingerprint,
SettingsOnViewCreatedFingerprint, AddSettingsEntryFingerprint,
SettingsEntryFingerprint,
SettingsEntryInfoFingerprint,
) )
) { ) {
override fun execute(context: BytecodeContext): PatchResult { override fun execute(context: BytecodeContext): PatchResult {
SettingsOnViewCreatedFingerprint.result?.mutableMethod?.apply { // Find the class name of classes which construct a settings entry
val instructions = implementation!!.instructions val settingsButtonClass = SettingsEntryFingerprint.result?.classDef?.type?.toClassName()
?: return SettingsEntryFingerprint.toErrorResult()
val settingsButtonInfoClass = SettingsEntryInfoFingerprint.result?.classDef?.type?.toClassName()
?: return SettingsEntryInfoFingerprint.toErrorResult()
// Find the indices that need to be patched. // Create a settings entry for 'revanced settings' and add it to settings fragment
val copyrightPolicyLabelId = AboutPageFingerprint.result?.let { AddSettingsEntryFingerprint.result?.apply {
val startIndex = it.scanResult.patternScanResult!!.startIndex scanResult.patternScanResult?.startIndex?.let {
it.mutableMethod.getInstruction<WideLiteralInstruction>(startIndex).wideLiteral val settingsEntries = mutableMethod.getInstruction(it + 3)
} ?: return AboutPageFingerprint.toErrorResult() val addEntry = mutableMethod.getInstruction(it + 5)
// Add the settings entry created to the settings fragment
val copyrightIndex = instructions.indexOfFirst { mutableMethod.addInstructions(
(it as? ReferenceInstruction)?.reference.toString() == "copyright_policy" it + 6,
} - 6 listOf(
settingsEntries,
addEntry
// fixme: instead use Method.indexOfFirstConstantInstructionValue() )
val copyrightPolicyIndex = instructions.indexOfFirst {
(it as? WideLiteralInstruction)?.wideLiteral == copyrightPolicyLabelId
} + 2
// Replace an existing settings entry with ReVanced settings entry.
arrayOf(
copyrightIndex,
copyrightPolicyIndex
).forEach { index ->
val instruction = getInstruction(index)
if (instruction.opcode != Opcode.MOVE_RESULT_OBJECT)
return PatchResultError("Hardcoded offset changed.")
val settingsEntryStringRegister = (instruction as OneRegisterInstruction).registerA
// Replace the settings entry string with a custom one.
replaceInstruction(
index,
"""
const-string v$settingsEntryStringRegister, "ReVanced Settings"
"""
) )
// These instructions call a method that create a settings entry use reflection base on the class name of classes that construct settings entry
// Replace the OnClickListener class with a custom one. mutableMethod.addInstructions(
val onClickListener = getInstruction<ReferenceInstruction>(index + 4).reference.toString() it + 6,
context.findClass(onClickListener)?.mutableClass?.methods?.first {
it.name == "onClick"
}?.addInstructions(
0,
""" """
invoke-static {}, $INTEGRATIONS_CLASS_DESCRIPTOR->startSettingsActivity()V const-string v1, "$settingsButtonClass"
return-void const-string v2, "$settingsButtonInfoClass"
invoke-static {v1, v2}, $CREATE_SETTINGS_ENTRY_METHOD_DESCRIPTOR
move-result-object v1
""" """
) ?: return PatchResultError("Could not find the onClick method.") )
} }
} ?: return AddSettingsEntryFingerprint.toErrorResult()
} ?: return SettingsOnViewCreatedFingerprint.toErrorResult()
// Initialize the settings menu once the replaced setting entry is clicked. // Initialize the settings menu once the replaced setting entry is clicked.
AdPersonalizationActivityOnCreateFingerprint.result?.mutableMethod?.apply { AdPersonalizationActivityOnCreateFingerprint.result?.mutableMethod?.apply {
@ -101,18 +75,25 @@ class SettingsPatch : BytecodePatch(
val thisRegister = getInstruction<FiveRegisterInstruction>(initializeSettingsIndex - 1).registerC val thisRegister = getInstruction<FiveRegisterInstruction>(initializeSettingsIndex - 1).registerC
addInstructions( addInstructionsWithLabels(
initializeSettingsIndex, initializeSettingsIndex,
""" """
invoke-static {v$thisRegister}, $INITIALIZE_SETTINGS_METHOD_DESCRIPTOR invoke-static {v$thisRegister}, $INITIALIZE_SETTINGS_METHOD_DESCRIPTOR
move-result v0
if-eqz v0, :notrevanced
return-void return-void
""" """,
ExternalLabel("notrevanced", getInstruction(initializeSettingsIndex))
) )
} ?: return AdPersonalizationActivityOnCreateFingerprint.toErrorResult() } ?: return AdPersonalizationActivityOnCreateFingerprint.toErrorResult()
return PatchResultSuccess() return PatchResultSuccess()
} }
private fun String.toClassName(): String {
return substring(1, this.length - 1).replace("/", ".")
}
private companion object { private companion object {
private const val INTEGRATIONS_CLASS_DESCRIPTOR = private const val INTEGRATIONS_CLASS_DESCRIPTOR =
"Lapp/revanced/tiktok/settingsmenu/SettingsMenu;" "Lapp/revanced/tiktok/settingsmenu/SettingsMenu;"
@ -120,6 +101,11 @@ class SettingsPatch : BytecodePatch(
private const val INITIALIZE_SETTINGS_METHOD_DESCRIPTOR = private const val INITIALIZE_SETTINGS_METHOD_DESCRIPTOR =
"$INTEGRATIONS_CLASS_DESCRIPTOR->initializeSettings(" + "$INTEGRATIONS_CLASS_DESCRIPTOR->initializeSettings(" +
"Lcom/bytedance/ies/ugc/aweme/commercialize/compliance/personalization/AdPersonalizationActivity;" + "Lcom/bytedance/ies/ugc/aweme/commercialize/compliance/personalization/AdPersonalizationActivity;" +
")V" ")Z"
private const val CREATE_SETTINGS_ENTRY_METHOD_DESCRIPTOR =
"$INTEGRATIONS_CLASS_DESCRIPTOR->createSettingsEntry(" +
"Ljava/lang/String;" +
"Ljava/lang/String;" +
")Ljava/lang/Object;"
} }
} }