mirror of
https://github.com/ReVanced/revanced-patches.git
synced 2024-11-10 01:01:56 +01:00
feat(tiktok): sim-spoof
patch (#1088)
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
This commit is contained in:
parent
8409c34665
commit
53bb547cc1
4 changed files with 137 additions and 29 deletions
|
@ -1,22 +1,21 @@
|
||||||
package app.revanced.extensions
|
package app.revanced.extensions
|
||||||
|
|
||||||
import app.revanced.patcher.data.BytecodeContext
|
import app.revanced.patcher.data.BytecodeContext
|
||||||
import app.revanced.patcher.data.ResourceContext
|
|
||||||
import app.revanced.patcher.extensions.addInstructions
|
|
||||||
import app.revanced.patcher.patch.PatchResultError
|
|
||||||
import app.revanced.patcher.util.proxy.mutableTypes.MutableClass
|
import app.revanced.patcher.util.proxy.mutableTypes.MutableClass
|
||||||
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
|
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
|
||||||
import app.revanced.patcher.util.smali.toInstruction
|
import org.jf.dexlib2.iface.Method
|
||||||
import org.jf.dexlib2.AccessFlags
|
import org.jf.dexlib2.util.MethodUtil
|
||||||
import org.jf.dexlib2.Opcode
|
|
||||||
import org.jf.dexlib2.builder.MutableMethodImplementation
|
|
||||||
import org.jf.dexlib2.builder.instruction.BuilderInstruction11n
|
|
||||||
import org.jf.dexlib2.builder.instruction.BuilderInstruction11x
|
|
||||||
import org.jf.dexlib2.builder.instruction.BuilderInstruction21t
|
|
||||||
import org.jf.dexlib2.builder.instruction.BuilderInstruction35c
|
|
||||||
import org.jf.dexlib2.immutable.reference.ImmutableMethodReference
|
|
||||||
import org.w3c.dom.Node
|
import org.w3c.dom.Node
|
||||||
import java.nio.file.Files
|
|
||||||
|
/**
|
||||||
|
* Find the [MutableMethod] from a given [Method] in a [MutableClass].
|
||||||
|
*
|
||||||
|
* @param method The [Method] to find.
|
||||||
|
* @return The [MutableMethod].
|
||||||
|
*/
|
||||||
|
fun MutableClass.findMutableMethodOf(method: Method) = this.methods.first {
|
||||||
|
MethodUtil.methodSignaturesMatch(it, method)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* traverse the class hierarchy starting from the given root class
|
* traverse the class hierarchy starting from the given root class
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
package app.revanced.patches.tiktok.misc.spoof.sim.annotations
|
||||||
|
|
||||||
|
import app.revanced.patcher.annotation.Compatibility
|
||||||
|
import app.revanced.patcher.annotation.Package
|
||||||
|
|
||||||
|
@Compatibility(
|
||||||
|
[
|
||||||
|
Package("com.ss.android.ugc.trill"),
|
||||||
|
Package("com.zhiliaoapp.musically")
|
||||||
|
]
|
||||||
|
)
|
||||||
|
@Target(AnnotationTarget.CLASS)
|
||||||
|
@Retention(AnnotationRetention.RUNTIME)
|
||||||
|
internal annotation class SpoofSimCompatibility
|
|
@ -0,0 +1,110 @@
|
||||||
|
package app.revanced.patches.tiktok.misc.spoof.sim.patch
|
||||||
|
|
||||||
|
import app.revanced.extensions.findMutableMethodOf
|
||||||
|
import app.revanced.patcher.annotation.Description
|
||||||
|
import app.revanced.patcher.annotation.Name
|
||||||
|
import app.revanced.patcher.annotation.Version
|
||||||
|
import app.revanced.patcher.data.BytecodeContext
|
||||||
|
import app.revanced.patcher.extensions.addInstruction
|
||||||
|
import app.revanced.patcher.extensions.addInstructions
|
||||||
|
import app.revanced.patcher.extensions.instruction
|
||||||
|
import app.revanced.patcher.patch.BytecodePatch
|
||||||
|
import app.revanced.patcher.patch.PatchResult
|
||||||
|
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.TikTokIntegrationsPatch
|
||||||
|
import app.revanced.patches.tiktok.misc.settings.fingerprints.SettingsStatusLoadFingerprint
|
||||||
|
import app.revanced.patches.tiktok.misc.settings.patch.TikTokSettingsPatch
|
||||||
|
import app.revanced.patches.tiktok.misc.spoof.sim.annotations.SpoofSimCompatibility
|
||||||
|
import org.jf.dexlib2.Opcode
|
||||||
|
import org.jf.dexlib2.iface.instruction.OneRegisterInstruction
|
||||||
|
import org.jf.dexlib2.iface.instruction.formats.Instruction35c
|
||||||
|
import org.jf.dexlib2.iface.reference.MethodReference
|
||||||
|
|
||||||
|
@Patch(false)
|
||||||
|
@DependsOn([TikTokIntegrationsPatch::class, TikTokSettingsPatch::class])
|
||||||
|
@Name("sim-spoof")
|
||||||
|
@Description("Spoofs the information which is retrieved from the sim-card.")
|
||||||
|
@SpoofSimCompatibility
|
||||||
|
@Version("0.0.1")
|
||||||
|
class SpoofSimPatch : BytecodePatch() {
|
||||||
|
private companion object {
|
||||||
|
val replacements = hashMapOf(
|
||||||
|
"getSimCountryIso" to "getCountryIso",
|
||||||
|
"getNetworkCountryIso" to "getCountryIso",
|
||||||
|
"getSimOperator" to "getOperator",
|
||||||
|
"getNetworkOperator" to "getOperator",
|
||||||
|
"getSimOperatorName" to "getOperatorName",
|
||||||
|
"getNetworkOperatorName" to "getOperatorName"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun execute(context: BytecodeContext): PatchResult {
|
||||||
|
// Find all api call to check sim information
|
||||||
|
buildMap {
|
||||||
|
context.classes.forEach { classDef ->
|
||||||
|
classDef.methods.let { methods ->
|
||||||
|
buildMap methodList@{
|
||||||
|
methods.forEach methods@{ method ->
|
||||||
|
with(method.implementation?.instructions ?: return@methods) {
|
||||||
|
ArrayDeque<Pair<Int, String>>().also { patchIndices ->
|
||||||
|
this.forEachIndexed { index, instruction ->
|
||||||
|
if (instruction.opcode != Opcode.INVOKE_VIRTUAL) return@forEachIndexed
|
||||||
|
|
||||||
|
val methodRef =
|
||||||
|
(instruction as Instruction35c).reference as MethodReference
|
||||||
|
if (methodRef.definingClass != "Landroid/telephony/TelephonyManager;") return@forEachIndexed
|
||||||
|
|
||||||
|
replacements[methodRef.name]?.let { replacement ->
|
||||||
|
patchIndices.add(index to replacement)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.also { if (it.isEmpty()) return@methods }.let { patches ->
|
||||||
|
put(method, patches)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.also { if (it.isEmpty()) return@forEach }.let { methodPatches ->
|
||||||
|
put(classDef, methodPatches)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.forEach { (classDef, methods) ->
|
||||||
|
with(context.proxy(classDef).mutableClass) {
|
||||||
|
methods.forEach { (method, patches) ->
|
||||||
|
with(findMutableMethodOf(method)) {
|
||||||
|
while (!patches.isEmpty()) {
|
||||||
|
val (index, replacement) = patches.removeLast()
|
||||||
|
replaceReference(index, replacement)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enable patch in settings
|
||||||
|
with(SettingsStatusLoadFingerprint.result!!.mutableMethod) {
|
||||||
|
addInstruction(
|
||||||
|
0,
|
||||||
|
"invoke-static {}, Lapp/revanced/tiktok/settingsmenu/SettingsStatus;->enableSimSpoof()V"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return PatchResultSuccess()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Patch Android API and return fake sim information
|
||||||
|
private fun MutableMethod.replaceReference(index: Int, replacement: String) {
|
||||||
|
val resultReg = (instruction(index + 1) as OneRegisterInstruction).registerA
|
||||||
|
|
||||||
|
addInstructions(
|
||||||
|
index + 2,
|
||||||
|
"""
|
||||||
|
invoke-static {v$resultReg}, Lapp/revanced/tiktok/spoof/sim/SpoofSimPatch;->$replacement(Ljava/lang/String;)Ljava/lang/String;
|
||||||
|
move-result-object v$resultReg
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,28 +1,25 @@
|
||||||
package app.revanced.patches.youtube.ad.general.bytecode.patch
|
package app.revanced.patches.youtube.ad.general.bytecode.patch
|
||||||
|
|
||||||
|
import app.revanced.extensions.findMutableMethodOf
|
||||||
import app.revanced.patcher.annotation.Description
|
import app.revanced.patcher.annotation.Description
|
||||||
import app.revanced.patcher.annotation.Name
|
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.addInstruction
|
import app.revanced.patcher.extensions.addInstruction
|
||||||
import app.revanced.patcher.extensions.instruction
|
import app.revanced.patcher.extensions.instruction
|
||||||
import app.revanced.patcher.extensions.softCompareTo
|
|
||||||
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.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.proxy.mutableTypes.MutableClass
|
|
||||||
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
|
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
|
||||||
import app.revanced.patches.youtube.ad.general.annotation.GeneralAdsCompatibility
|
import app.revanced.patches.youtube.ad.general.annotation.GeneralAdsCompatibility
|
||||||
import app.revanced.patches.youtube.ad.general.bytecode.fingerprints.ReelConstructorFingerprint
|
import app.revanced.patches.youtube.ad.general.bytecode.fingerprints.ReelConstructorFingerprint
|
||||||
import app.revanced.patches.youtube.ad.general.resource.patch.GeneralAdsResourcePatch
|
import app.revanced.patches.youtube.ad.general.resource.patch.GeneralAdsResourcePatch
|
||||||
import org.jf.dexlib2.iface.Method
|
|
||||||
import org.jf.dexlib2.iface.instruction.TwoRegisterInstruction
|
import org.jf.dexlib2.iface.instruction.TwoRegisterInstruction
|
||||||
import org.jf.dexlib2.iface.instruction.formats.Instruction31i
|
import org.jf.dexlib2.iface.instruction.formats.Instruction31i
|
||||||
import org.jf.dexlib2.iface.instruction.formats.Instruction35c
|
import org.jf.dexlib2.iface.instruction.formats.Instruction35c
|
||||||
import org.jf.dexlib2.immutable.reference.ImmutableMethodReference
|
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
|
|
||||||
|
@ -35,18 +32,6 @@ import java.util.*
|
||||||
class GeneralAdsPatch : BytecodePatch(
|
class GeneralAdsPatch : BytecodePatch(
|
||||||
listOf(ReelConstructorFingerprint)
|
listOf(ReelConstructorFingerprint)
|
||||||
) {
|
) {
|
||||||
internal companion object {
|
|
||||||
private fun MutableClass.findMutableMethodOf(
|
|
||||||
method: Method
|
|
||||||
) = this.methods.first {
|
|
||||||
it.softCompareTo(
|
|
||||||
ImmutableMethodReference(
|
|
||||||
method.definingClass, method.name, method.parameters, method.returnType
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun execute(context: BytecodeContext): PatchResult {
|
override fun execute(context: BytecodeContext): PatchResult {
|
||||||
fun String.buildHideCall(viewRegister: Int) = "invoke-static { v$viewRegister }, " +
|
fun String.buildHideCall(viewRegister: Int) = "invoke-static { v$viewRegister }, " +
|
||||||
"Lapp/revanced/integrations/patches/GeneralAdsPatch;" +
|
"Lapp/revanced/integrations/patches/GeneralAdsPatch;" +
|
||||||
|
|
Loading…
Reference in a new issue