Skip to content

Commit

Permalink
fix(tiktok/tiktok-settings): some fingerprints are broken
Browse files Browse the repository at this point in the history
  • Loading branch information
inotia00 committed Jan 11, 2023
1 parent 66cf6e9 commit 1baa542
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 109 deletions.
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package app.revanced.patches.tiktok.feedfilter.fingerprints

import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode

object FeedApiServiceLIZFingerprint : MethodFingerprint(
access = AccessFlags.PUBLIC or AccessFlags.STATIC or AccessFlags.FINAL or AccessFlags.SYNTHETIC,
customFingerprint = { methodDef ->
methodDef.definingClass.endsWith("/FeedApiService;") && methodDef.name == "LIZ"
}
opcodes = listOf(
Opcode.RETURN_OBJECT,
Opcode.MOVE_EXCEPTION
),
customFingerprint = { it.definingClass.endsWith("/FeedApiService;") }
)
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package app.revanced.patches.tiktok.feedfilter.patch

import app.revanced.extensions.toErrorResult
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
Expand All @@ -15,7 +16,6 @@ import app.revanced.patches.tiktok.feedfilter.fingerprints.FeedApiServiceLIZFing
import app.revanced.patches.tiktok.misc.integrations.patch.IntegrationsPatch
import app.revanced.patches.tiktok.misc.settings.fingerprints.SettingsStatusLoadFingerprint
import app.revanced.patches.tiktok.misc.settings.patch.SettingsPatch
import org.jf.dexlib2.Opcode
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction

@Patch
Expand All @@ -31,21 +31,24 @@ class FeedFilterPatch : BytecodePatch(
)
) {
override fun execute(context: BytecodeContext): PatchResult {
val method = FeedApiServiceLIZFingerprint.result!!.mutableMethod
for ((index, instruction) in method.implementation!!.instructions.withIndex()) {
if (instruction.opcode != Opcode.RETURN_OBJECT) continue
val feedItemsRegister = (instruction as OneRegisterInstruction).registerA
method.addInstruction(
index,
"invoke-static {v$feedItemsRegister}, Lapp/revanced/tiktok/feedfilter/FeedItemsFilter;->filter(Lcom/ss/android/ugc/aweme/feed/model/FeedItemList;)V"
)
break
}
val method2 = SettingsStatusLoadFingerprint.result!!.mutableMethod
method2.addInstruction(

FeedApiServiceLIZFingerprint.result?.let {
val index = it.scanResult.patternScanResult!!.startIndex

with (it.mutableMethod) {
val register = (this.implementation!!.instructions[index] as OneRegisterInstruction).registerA
addInstruction(
index,
"invoke-static {v$register}, Lapp/revanced/tiktok/feedfilter/FeedItemsFilter;->filter(Lcom/ss/android/ugc/aweme/feed/model/FeedItemList;)V"
)
}
} ?: return FeedApiServiceLIZFingerprint.toErrorResult()

SettingsStatusLoadFingerprint.result?.mutableMethod?.addInstruction(
0,
"invoke-static {}, Lapp/revanced/tiktok/settingsmenu/SettingsStatus;->enableFeedFilter()V"
)
) ?: return SettingsStatusLoadFingerprint.toErrorResult()

return PatchResultSuccess()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
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,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.CONST_STRING
),
customFingerprint = {
it.definingClass == "Lcom/ss/android/ugc/aweme/setting/page/AboutPage;" &&
it.name == "onViewCreated"
}
)

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -8,104 +8,110 @@ import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.addInstructions
import app.revanced.patcher.extensions.instruction
import app.revanced.patcher.extensions.replaceInstruction
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultError
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
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.fingerprints.AboutViewFingerprint
import app.revanced.patches.tiktok.misc.settings.fingerprints.AboutPageFingerprint
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.builder.instruction.BuilderInstruction21c
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
import org.jf.dexlib2.iface.instruction.ReferenceInstruction
import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
import org.jf.dexlib2.iface.instruction.formats.Instruction35c
import org.jf.dexlib2.iface.reference.StringReference
import org.jf.dexlib2.iface.reference.TypeReference

@Patch
@DependsOn([IntegrationsPatch::class])
@Name("settings")
@Name("tiktok-settings")
@Description("Adds ReVanced settings to TikTok.")
@SettingsCompatibility
@Version("0.0.1")
class SettingsPatch : BytecodePatch(
listOf(
AboutPageFingerprint,
AdPersonalizationActivityOnCreateFingerprint,
SettingsOnViewCreatedFingerprint,
)
) {
override fun execute(context: BytecodeContext): PatchResult {
SettingsOnViewCreatedFingerprint.result?.let {
AboutViewFingerprint.resolve(context, it.method, it.classDef)
}
// Patch Settings UI to add 'Revanced Settings'.
val targetIndexes = findOptionsOnClickIndex()
with(SettingsOnViewCreatedFingerprint.result!!.mutableMethod) {
for (index in targetIndexes) {
if (
instruction(index).opcode != Opcode.NEW_INSTANCE ||
instruction(index - 4).opcode != Opcode.MOVE_RESULT_OBJECT
)

AboutPageFingerprint.result?.let {
val startIndex = it.scanResult.patternScanResult!!.startIndex

with(it.mutableMethod.implementation!!.instructions) {
copyrightPolicyLabelId = (this[startIndex] as WideLiteralInstruction).wideLiteral
}

} ?: return AboutPageFingerprint.toErrorResult()

SettingsOnViewCreatedFingerprint.result?.mutableMethod?.let { method ->
val copyrightInstructions = method.implementation!!.instructions

val copyrightIndex = copyrightInstructions.indexOfFirst {
it.opcode == Opcode.CONST_STRING &&
(it as BuilderInstruction21c).reference.toString() == "copyright_policy"
} - 6

val copyrightPolicyIndex = copyrightInstructions.indexOfFirst {
it.opcode == Opcode.CONST &&
(it as WideLiteralInstruction).wideLiteral == copyrightPolicyLabelId
} + 2

arrayOf(
copyrightIndex,
copyrightPolicyIndex
).forEach {
if (method.instruction(it).opcode != Opcode.MOVE_RESULT_OBJECT)
return PatchResultError("Hardcode offset changed.")
patchOptionNameAndOnClickEvent(index, context)
val register = (method.instruction(it) as OneRegisterInstruction).registerA

method.insertSettings(context, it, register)
}
}
// Implement settings screen in `AdPersonalizationActivity`
with(AdPersonalizationActivityOnCreateFingerprint.result!!.mutableMethod) {
for ((index, instruction) in implementation!!.instructions.withIndex()) {

} ?: return SettingsOnViewCreatedFingerprint.toErrorResult()

AdPersonalizationActivityOnCreateFingerprint.result?.mutableMethod?.let {
for ((index, instruction) in it.implementation!!.instructions.withIndex()) {
if (instruction.opcode != Opcode.INVOKE_SUPER) continue
val thisRegister = (instruction as Instruction35c).registerC
addInstructions(
it.addInstructions(
index + 1,
"""
invoke-static {v$thisRegister}, Lapp/revanced/tiktok/settingsmenu/SettingsMenu;->initializeSettings(Lcom/bytedance/ies/ugc/aweme/commercialize/compliance/personalization/AdPersonalizationActivity;)V
return-void
"""
)
break
}
}
return PatchResultSuccess()
}

private fun findOptionsOnClickIndex(): IntArray {
val results = IntArray(2)
SettingsOnViewCreatedFingerprint.result?.apply {
for ((index, instruction) in mutableMethod.implementation!!.instructions.withIndex()) {
// Old UI settings option to replace to 'Revanced Settings'
if (instruction.opcode == Opcode.CONST_STRING) {
val string = ((instruction as ReferenceInstruction).reference as StringReference).string
if (string == "copyright_policy") {
results[0] = index - 2
break
}
}
return PatchResultSuccess()
}
} ?: return AdPersonalizationActivityOnCreateFingerprint.toErrorResult()

// New UI settings option to replace to 'Revanced Settings'
results[1] = AboutViewFingerprint.result!!.scanResult.patternScanResult!!.startIndex
} ?: throw SettingsOnViewCreatedFingerprint.toErrorResult()
return results
return PatchResultError("Could not find the method to hook.")
}

private fun patchOptionNameAndOnClickEvent(index: Int, context: BytecodeContext) {
with(SettingsOnViewCreatedFingerprint.result!!.mutableMethod) {
// Patch option name
val overrideRegister = (instruction(index - 4) as OneRegisterInstruction).registerA
private companion object {
var copyrightPolicyLabelId: Long = -1

fun MutableMethod.insertSettings(
context: BytecodeContext,
index: Int,
overrideRegister: Int
) {
replaceInstruction(
index - 4,
index,
"""
const-string v$overrideRegister, "Revanced Settings"
"""
)

// Patch option OnClick Event
with(((instruction(index) as ReferenceInstruction).reference as TypeReference).type) {
with(((instruction(index + 4) as ReferenceInstruction).reference as TypeReference).type) {
context.findClass(this)!!.mutableClass.methods.first { it.name == "onClick" }
.addInstructions(
0,
Expand Down

0 comments on commit 1baa542

Please sign in to comment.