-
-
Notifications
You must be signed in to change notification settings - Fork 320
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(Instagram): Added few patches #3604
base: dev
Are you sure you want to change the base?
Changes from all commits
2a4c2dc
ab1690f
535a50a
6a54ffb
685c7c8
71657ac
7589cef
0968783
1eb6017
bf5762b
af9fc80
4ec9a28
7ab6003
c36a50f
b6e2e8a
ddb9ed8
606f571
8788b4e
4603458
12ef5c9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package app.revanced.patches.instagram.misc.integrations | ||
|
||
import app.revanced.patcher.patch.annotation.Patch | ||
import app.revanced.patches.instagram.misc.integrations.fingerprints.MainActivityOnCreateFingerprint | ||
import app.revanced.patches.shared.misc.integrations.BaseIntegrationsPatch | ||
|
||
@Patch(requiresIntegrations = true) | ||
object IntegrationsPatch : BaseIntegrationsPatch( | ||
setOf(MainActivityOnCreateFingerprint), | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package app.revanced.patches.instagram.misc.integrations.fingerprints | ||
|
||
import app.revanced.patches.instagram.misc.integrations.fingerprints.MainActivityOnCreateFingerprint.getApplicationContextIndex | ||
import app.revanced.patches.shared.misc.integrations.BaseIntegrationsPatch.IntegrationsFingerprint | ||
import app.revanced.util.getReference | ||
import app.revanced.util.indexOfFirstInstructionOrThrow | ||
import com.android.tools.smali.dexlib2.builder.instruction.BuilderInstruction35c | ||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference | ||
|
||
internal object MainActivityOnCreateFingerprint : IntegrationsFingerprint( | ||
customFingerprint = { methodDef, _ -> | ||
methodDef.name == "onCreate" && methodDef.definingClass == "Lcom/instagram/app/InstagramAppShell;" | ||
}, | ||
insertIndexResolver = { method -> | ||
getApplicationContextIndex = method.indexOfFirstInstructionOrThrow { | ||
getReference<MethodReference>()?.name == "onCreate" | ||
} | ||
|
||
getApplicationContextIndex + 1 // Below the invoke-super instruction. | ||
}, | ||
contextRegisterResolver = { method -> | ||
val moveResultInstruction = method.implementation!!.instructions.elementAt(getApplicationContextIndex) | ||
as BuilderInstruction35c | ||
moveResultInstruction.registerC | ||
}, | ||
) { | ||
private var getApplicationContextIndex = -1 | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
package app.revanced.patches.instagram.patches.interaction.bio | ||
|
||
import app.revanced.patcher.data.BytecodeContext | ||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions | ||
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction | ||
import app.revanced.patcher.extensions.InstructionExtensions.getInstructions | ||
import app.revanced.patcher.patch.BytecodePatch | ||
import app.revanced.patcher.patch.annotation.CompatiblePackage | ||
import app.revanced.patcher.patch.annotation.Patch | ||
import app.revanced.patches.instagram.patches.interaction.bio.fingerprints.SelectableBioFingerprint | ||
import app.revanced.util.resultOrThrow | ||
import com.android.tools.smali.dexlib2.Opcode | ||
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction | ||
|
||
@Patch( | ||
name = "Selectable bio", | ||
description = "Make the user's bio selectable.", | ||
compatiblePackages = [CompatiblePackage("com.instagram.android")], | ||
) | ||
@Suppress("unused") | ||
object SelectableBioPatch : BytecodePatch( | ||
setOf(SelectableBioFingerprint), | ||
) { | ||
override fun execute(context: BytecodeContext) { | ||
SelectableBioFingerprint.resultOrThrow().mutableMethod.apply { | ||
val setBioTextIndex = getInstructions().first { it.opcode == Opcode.INVOKE_VIRTUAL }.location.index | ||
val setTextViewInstruction = getInstruction<FiveRegisterInstruction>(setBioTextIndex) | ||
val textViewRegister = setTextViewInstruction.registerC | ||
val textRegister = setTextViewInstruction.registerD | ||
|
||
// Make the textview selectable. | ||
addInstructions( | ||
setBioTextIndex + 1, | ||
""" | ||
const/4 v$textRegister, 0x1 | ||
invoke-virtual { v$textViewRegister, v$textRegister }, Landroid/widget/TextView;->setTextIsSelectable(Z)V | ||
""", | ||
) | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package app.revanced.patches.instagram.patches.interaction.bio.fingerprints | ||
|
||
import app.revanced.patcher.fingerprint.MethodFingerprint | ||
|
||
internal object SelectableBioFingerprint : MethodFingerprint( | ||
strings = listOf("is_bio_visible"), | ||
returnType = "V", | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
package app.revanced.patches.instagram.patches.interaction.links.browser | ||
|
||
import app.revanced.patcher.data.BytecodeContext | ||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels | ||
import app.revanced.patcher.extensions.InstructionExtensions.getInstructions | ||
import app.revanced.patcher.patch.BytecodePatch | ||
import app.revanced.patcher.patch.annotation.CompatiblePackage | ||
import app.revanced.patcher.patch.annotation.Patch | ||
import app.revanced.patcher.util.smali.ExternalLabel | ||
import app.revanced.patches.instagram.misc.integrations.IntegrationsPatch | ||
import app.revanced.patches.instagram.patches.interaction.links.browser.fingerprints.OpenLinksInExternalBrowserFingerprint | ||
import app.revanced.util.resultOrThrow | ||
|
||
@Patch( | ||
name = "Open links in external browser", | ||
dependencies = [IntegrationsPatch::class], | ||
compatiblePackages = [CompatiblePackage("com.instagram.android")], | ||
) | ||
@Suppress("unused") | ||
object OpenLinksInExternalBrowser : BytecodePatch( | ||
setOf(OpenLinksInExternalBrowserFingerprint), | ||
) { | ||
override fun execute(context: BytecodeContext) { | ||
OpenLinksInExternalBrowserFingerprint.resultOrThrow().let { it -> | ||
// Get the method that returns the url. | ||
val getUrlMethod = it.mutableClass.methods.first { | ||
it.returnType == "Ljava/lang/String;" && it.parameters.size == 0 | ||
}.name | ||
|
||
// Patch the method that opens the link in the internal browser. | ||
it.mutableClass.methods.last { it.returnType == "V" && it.parameters.size == 0 }.apply { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is not a safe approach. Please fingerprint the method and get it through that. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Basically that method originally has 4 lines, 2 const/4, 1 invoke and return-void. Moreover both the "get url" method and the method where the fragment is built is present in the same call. So I thought its easier to find the class and then find the methods accordingly |
||
val continueInstruction = getInstructions().first() | ||
|
||
// Call the openInExternalBrowser method. | ||
// If it returns true, return void. | ||
// If it returns false, proceed as usual. | ||
addInstructionsWithLabels( | ||
0, | ||
""" | ||
invoke-virtual { p0 }, ${it.classDef}->$getUrlMethod()Ljava/lang/String; | ||
move-result-object v0 | ||
|
||
invoke-static { v0 }, Lapp/revanced/integrations/instagram/links/ExternalBrowser;->openInExternalBrowser(Ljava/lang/String;)Z | ||
move-result v0 | ||
|
||
if-eqz v0, :not_opened | ||
return-void | ||
""", | ||
ExternalLabel("not_opened", continueInstruction), | ||
) | ||
} | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package app.revanced.patches.instagram.patches.interaction.links.browser.fingerprints | ||
|
||
import app.revanced.patcher.fingerprint.MethodFingerprint | ||
|
||
internal object OpenLinksInExternalBrowserFingerprint : MethodFingerprint( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Name the fingerprint like explained above. |
||
strings = listOf("TrackingInfo.ARG_HIDE_SYSTEM_BAR", "TrackingInfo.ARG_MODULE_NAME"), | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
package app.revanced.patches.instagram.patches.interaction.links.tracking | ||
|
||
import app.revanced.patcher.data.BytecodeContext | ||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions | ||
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction | ||
import app.revanced.patcher.extensions.InstructionExtensions.getInstructions | ||
import app.revanced.patcher.fingerprint.MethodFingerprint | ||
import app.revanced.patcher.patch.BytecodePatch | ||
import app.revanced.patcher.patch.annotation.CompatiblePackage | ||
import app.revanced.patcher.patch.annotation.Patch | ||
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod | ||
import app.revanced.patches.instagram.patches.interaction.links.tracking.fingerprints.* | ||
import app.revanced.util.getReference | ||
import app.revanced.util.resultOrThrow | ||
import com.android.tools.smali.dexlib2.Opcode | ||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction | ||
import com.android.tools.smali.dexlib2.iface.reference.TypeReference | ||
|
||
@Patch( | ||
name = "Sanitize sharing links", | ||
description = "Removes the tracking query parameters from links before they are shared.", | ||
compatiblePackages = [CompatiblePackage("com.instagram.android")], | ||
requiresIntegrations = true, | ||
) | ||
@Suppress("unused") | ||
object SanitizeSharingLinksPatch : BytecodePatch( | ||
setOf( | ||
StoryShareUrlFingerprint, | ||
LiveShareUrlFingerprint, | ||
PostShareClassFinderFingerprint, | ||
ProfileShareUrlFingerprint, | ||
HighlightsShareUrlFingerprint, | ||
Comment on lines
+28
to
+32
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These fingerprints need to be named according to the method they match too |
||
), | ||
) { | ||
private const val INVOKE_INTEGRATIONS_METHOD_INSTRUCTION = | ||
"Lapp/revanced/integrations/instagram/links/ShareLink;->sanitizeUrl(Ljava/lang/String;)Ljava/lang/String;" | ||
|
||
override fun execute(context: BytecodeContext) { | ||
fun sanitizeUrl(method: MutableMethod) = method.apply { | ||
val index = getInstructions().first { it.opcode == Opcode.IPUT_OBJECT }.location.index - 2 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please comment what this index does in the code |
||
// Register where the link is present. | ||
val register = getInstruction<OneRegisterInstruction>(index).registerA | ||
|
||
addInstructions( | ||
index + 1, | ||
""" | ||
invoke-static{ v$register }, $INVOKE_INTEGRATIONS_METHOD_INSTRUCTION | ||
move-result-object v$register | ||
""", | ||
) | ||
} | ||
|
||
fun sanitizeUrl(fingerprint: MethodFingerprint) = sanitizeUrl(fingerprint.resultOrThrow().mutableMethod) | ||
|
||
// Sanitize share link of stories. | ||
sanitizeUrl(StoryShareUrlFingerprint) | ||
// Sanitize share link of live. | ||
sanitizeUrl(LiveShareUrlFingerprint) | ||
// Sanitize share link of profile. | ||
sanitizeUrl(ProfileShareUrlFingerprint) | ||
// Sanitize share link of highlights. | ||
sanitizeUrl(HighlightsShareUrlFingerprint) | ||
// Sanitize share link of posts & reels. | ||
PostShareClassFinderFingerprint.resultOrThrow().mutableMethod.let { method -> | ||
val classIndex = method.getInstructions().last { it.opcode == Opcode.CONST_CLASS }.location.index | ||
val className = method.getInstruction(classIndex).getReference<TypeReference>()!!.type | ||
val parseJsonMethod = context.findClass(className)!!.mutableClass.methods.first { | ||
it.name == "parseFromJson" | ||
} | ||
|
||
sanitizeUrl(parseJsonMethod) | ||
} | ||
Comment on lines
+64
to
+72
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why aren't you using a fingerprint for this? |
||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package app.revanced.patches.instagram.patches.interaction.links.tracking.fingerprints | ||
|
||
import app.revanced.patcher.fingerprint.MethodFingerprint | ||
|
||
internal object HighlightsShareUrlFingerprint : MethodFingerprint( | ||
strings = listOf("story_highlights_to_share_url"), | ||
customFingerprint = { methodDef, _ -> | ||
methodDef.name == "parseFromJson" | ||
}, | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package app.revanced.patches.instagram.patches.interaction.links.tracking.fingerprints | ||
|
||
import app.revanced.patcher.fingerprint.MethodFingerprint | ||
|
||
internal object LiveShareUrlFingerprint : MethodFingerprint( | ||
strings = listOf("live_to_share_url"), | ||
customFingerprint = { methodDef, _ -> | ||
methodDef.name == "parseFromJson" | ||
}, | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package app.revanced.patches.instagram.patches.interaction.links.tracking.fingerprints | ||
|
||
import app.revanced.patcher.fingerprint.MethodFingerprint | ||
|
||
internal object PostShareClassFinderFingerprint : MethodFingerprint( | ||
strings = listOf("media/%s/permalink"), | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package app.revanced.patches.instagram.patches.interaction.links.tracking.fingerprints | ||
|
||
import app.revanced.patcher.fingerprint.MethodFingerprint | ||
|
||
internal object ProfileShareUrlFingerprint : MethodFingerprint( | ||
strings = listOf("profile_to_share_url"), | ||
customFingerprint = { methodDef, _ -> | ||
methodDef.name == "parseFromJson" | ||
}, | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package app.revanced.patches.instagram.patches.interaction.links.tracking.fingerprints | ||
|
||
import app.revanced.patcher.fingerprint.MethodFingerprint | ||
|
||
internal object StoryShareUrlFingerprint : MethodFingerprint( | ||
strings = listOf("story_item_to_share_url"), | ||
customFingerprint = { methodDef, _ -> | ||
methodDef.name == "parseFromJson" | ||
}, | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
package app.revanced.patches.instagram.patches.layout.menu.developer | ||
|
||
import app.revanced.patcher.data.BytecodeContext | ||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions | ||
import app.revanced.patcher.extensions.InstructionExtensions.getInstructions | ||
import app.revanced.patcher.patch.BytecodePatch | ||
import app.revanced.patcher.patch.annotation.CompatiblePackage | ||
import app.revanced.patcher.patch.annotation.Patch | ||
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod | ||
import app.revanced.patches.instagram.patches.layout.menu.developer.fingerprints.ShouldAddPrefTTLFingerprint | ||
import app.revanced.util.resultOrThrow | ||
import com.android.tools.smali.dexlib2.Opcode | ||
|
||
@Patch( | ||
name = "Enable developer menu", | ||
compatiblePackages = [CompatiblePackage("com.instagram.android")], | ||
) | ||
@Suppress("unused") | ||
object EnableDeveloperMenuPatch : BytecodePatch( | ||
setOf(ShouldAddPrefTTLFingerprint), | ||
) { | ||
override fun execute(context: BytecodeContext) { | ||
ShouldAddPrefTTLFingerprint.resultOrThrow().mutableMethod.let { method -> | ||
val isDeveloperMethodCallIndex = method.getInstructions().first { | ||
it.opcode == Opcode.INVOKE_STATIC | ||
}.location.index | ||
|
||
val isDeveloperMethod = context.toMethodWalker(method).nextMethod(isDeveloperMethodCallIndex, true) | ||
.getMethod() as MutableMethod | ||
|
||
isDeveloperMethod.addInstructions( | ||
0, | ||
""" | ||
const v0, 0x1 | ||
return v0 | ||
""", | ||
) | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package app.revanced.patches.instagram.patches.layout.menu.developer.fingerprints | ||
|
||
import app.revanced.patcher.fingerprint.MethodFingerprint | ||
|
||
internal object ShouldAddPrefTTLFingerprint : MethodFingerprint( | ||
customFingerprint = { methodDef, _ -> | ||
methodDef.name == "shouldAddPrefTTL" && methodDef.definingClass == "Lcom/instagram/debug/whoptions/WhitehatOptionsFragment;" | ||
}, | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please name fingerprints to the method they match to. If this one for example matches to the constructor, call it "ConstructBioViewFingerprint"