news 2026/10/17 4:33:55

FeurStagram网络层屏蔽全解析:从TigonServiceLayer到URI拦截,如何在请求发出前干掉Reels和广告

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
FeurStagram网络层屏蔽全解析:从TigonServiceLayer到URI拦截,如何在请求发出前干掉Reels和广告

【免费下载链接】FeurStagram

Instagram without Reels, feed or ads: an open-source, updatable Instagram app for Android that keeps DMs and stories.

项目地址:https://gitcode.com/gh_mirrors/fe/FeurStagram
点击查看免费下载

FeurStagram 是一个开源的 Instagram 改造方案(Android 平台),它的核心能力之一就是在网络层拦截请求:Reels 短视频流、首页信息流、推荐位和广告,在数据包真正发出之前就被"扼杀"。本文带你完整解析这条链路——从TigonServiceLayer的字节码挂钩,到 URI 黑名单,再到 JSON 解析层的内联广告过滤,看看它到底是怎么做到"无 Reels、无广告、无推荐"的。

为什么要在网络层拦截,而不是隐藏界面?

常见的"去 Reels"思路是在界面层面把入口藏起来,但那样做有两个问题:

  • 请求照发不误,数据照样下载,只是你看不见而已;
  • Instagram 一旦改版,界面结构变了,补丁就失效。

FeurStagram 选择了更彻底的路线:在 Instagram 自己的网络栈内部设卡。它不碰 UI 布局,而是在请求 URI 已经生成、但还没发出的那一瞬间做检查——命中黑名单就抛出一个IOException,Instagram 会把它当成一次普通的"网络失败",对应页面自然就是空白。

这套逻辑全部集中在两个模块:

  • 补丁定义:NetworkBlockPatch.kt
  • 拦截规则:Block.java

第一道闸门:挂钩 TigonServiceLayer.startRequest

Instagram 的所有 API 请求都经过它内部的网络层com.instagram.api.tigon.TigonServiceLayer,发请求的入口方法是startRequest。这两个名字没有被混淆、且跨版本稳定,是绝佳的挂钩锚点。

NetworkBlockPatch.kt#L19-L53 中的补丁做了三件事:

  1. 定位锚点:在startRequest的方法体里,找到一条iget-object指令——它把请求的java.net.URI对象加载进寄存器。这一步是纯结构匹配(按指令类型找,不依赖任何具体变量名),所以 Instagram 后续怎么重命名都打不中它;
  2. 注入检查:紧跟在那条指令后面,插入一条对Block.throwIfBlocked(URI)的调用,把刚取出的 URI 交给拦截器;
  3. 借力打力:throwIfBlocked命中黑名单时抛出IOException。因为注入点正好位于 Instagram 原本的 try 块内,这个异常会被当作常规网络错误吞掉,页面停留在空状态——不崩溃、不闪退、不留日志痕迹。

用一句话概括:FeurStagram 不需要 Instagram"配合"隐藏任何东西,它只是让 Instagram 自己以为"网络断了"。

第二道闸门:URI 黑名单清单

真正的拦截规则写在 Block.java#L91-L129 的throwIfBlocked方法里,分两大类:

🔒 可开关的内容拦截(由设置面板控制)

拦截目标匹配的 URI 路径(部分)对应开关
首页信息流/feed/timeline/Home Feed
Reels 流/clips/home/、/clips/discover、/clips/get_blend_medias/Reels
探索页/discover/topical_exploreExplore
快拍托盘/feed/reels_trayStories
推荐位/discover/ayml/、/discover/chaining/等 16 个路径Suggested
广告接口/api/v1/ads/、/feed/contextual_multi_ads/等 13 个路径Ads

每一类都对应设置面板里的独立开关(源码在 Config.java),想开哪个、关哪个完全由你决定。

🚫 永远拦截的接口(无开关、无条件)

下面这些端点无论怎么设置都会被掐掉,因为它们对普通用户没有任何正向价值:

  • /feed/injected_reels_media(信息流里注入的 Reels 媒体)
  • /logging/、/api/v1/stats/(埋点与统计上报)
  • /api/v1/commerce/、/api/v1/shopping/(购物/电商接口)
  • /api/v1/media/.../seen("已看过"追踪)

注意源码里一个细节:injected_reels_media的匹配故意不带末尾斜杠,因为服务端还有个_www变体(/feed/injected_reels_media_www/),带斜杠的精确匹配会漏掉它。这类"补丁级"的抠细节,正是网络层方案比界面隐藏更稳的原因。

第三道闸门:JSON 解析层,抓内联广告

URI 拦截有个盲区:有些广告根本没有自己的 URL。Instagram 会把广告单元和"推荐内容"直接塞进时间线响应体里,作为 JSON 数组中的一个条目,形如:

{ "feed_timeline": [ { "media_or_ad": {...} }, { "ad4ad": {...} }, { "clips_netego": {...} } ] }

这些条目随主请求一起到达,网络层的Block根本看不到它们。于是 FeurStagram 在反序列化环节又设了一卡:

FeedItemFilterPatch.kt 挂钩信息条目的 JSON 解析方法(指纹锚定在media_or_ad、clips_netego、ad4ad这类服务端协议字符串和未混淆的方法名片段parseFromJson上,而不是脆弱的类名)。解析循环每读到一个条目的类型键,就会被引导先调用 Block.replaceFeedItemType():

  • 命中广告键(ad4ad、intent_aware_ad_pivot…)或推荐键(clips_netego、suggested_users…)→ 把类型键改写为垃圾值feurstagram_blocked;
  • 这个垃圾值在 Instagram 解析器的 switch 里不匹配任何分支,条目自然落入"未知类型"分支被丢弃——不抛异常、不崩解析,其他正常帖子完好无损。

这里还有个"踩坑"设计:指纹用的类型 token 列表刻意保持短小。注释里记录了 issue #117 的教训——曾经列表里包含已下线的in_feed_survey,Instagram 444 版把该字段从解析器移除后,整条指纹失配、所有内联广告过滤静默失效。所以列表只保留真正"承重"的四个 token。

拦截生效的开关从哪来?

所有拦截都受运行时开关门控,配置存储在SharedPreferences(feurstagram_prefs),由 Config.java 管理:

  • block_feed/block_reels/block_ads等开关对应设置面板的每个滑块;
  • Permanent lock(硬核模式):锁定后,某个界面只能越封越严、无法反开,适合真的想戒掉 Reels 的人(见 Config.java#L57-L72);
  • 任何开关变动都会触发一次"干净重启",避免旧的 UI 状态残留。

补丁侧的兼容性配置在 Constants.kt:目标写死为com.instagram.android且version = null,意味着补丁默认跟随 Instagram 的每一个未来版本,这也是"可更新"这一卖点能成立的基础。

如何验证拦截真的在工作?🔍

开发者用了一个很巧妙的"探测器"——Debug Bridge(DebugBridge.java)。在 debug 构建中,通过 ADB 广播即可打开网络追踪:

adb shell am broadcast -p com.instagram.android -a com.feurstagram.debug.TRACE --ez value true

开启后,throwIfBlocked会把 Instagram 请求的每一条 URI 路径打到logcat(tag:FeurNet),内联单元过滤也会打印drop/keep + 类型名(tag:FeurFeed)。这正是维护者的日常工作流:当某个新界面换了端点、开始"漏"进来时,看日志就能定位到该补哪条 URI 规则。正式发布的包里这些代码路径恒为关闭,不会有任何额外开销。

小结:三层防线,请求还没出门就被拦下

层级挂钩点干掉什么关键文件
网络层TigonServiceLayer.startRequest独立端点的 Reels / 信息流 / 探索 / 推荐 / 广告 / 埋点NetworkBlockPatch.kt
网络层Block.throwIfBlockedURI 黑名单上述所有 URI + 无条件拦截的统计/购物接口Block.java
解析层FeedItemparseFromJson内联在时间线 JSON 里的广告与推荐条目FeedItemFilterPatch.kt

FeurStagram 的思路可以总结为一句话:不跟界面斗智斗勇,直接掐断数据源——请求要么不发出(URI 拦截),要么解析到一半被"降级"成无效条目(JSON 过滤)。配合未混淆锚点 + 协议字符串指纹的定位策略,这套方案能相当长久地扛住 Instagram 的版本更新。

如果你想亲自动手试试效果对比、查看完整安装步骤,可以浏览项目文档目录:docs/。

【免费下载链接】FeurStagram

Instagram without Reels, feed or ads: an open-source, updatable Instagram app for Android that keeps DMs and stories.

项目地址:https://gitcode.com/gh_mirrors/fe/FeurStagram
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/17 4:32:57

小模型也能做RAG检索路由:RouteRAG的降本增效实践

RouteRAG 这个名字,最近在几个做 RAG 落地的技术群里反复被提到。一开始我以为又是什么依赖大模型的“重型框架”,仔细摸了一遍才明白,它的核心思路恰恰相反:用一个小模型去承担检索策略的规划工作,让大模型回归生成本…

作者头像 李华
网站建设 2026/10/17 4:32:30

Verilog状态机实现流水灯:从状态图到三段式代码实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/17 4:31:14

Win10下OpenCV 4.5.1源码编译实战:VS2019+CMake静态库与contrib配置

1. 为什么在2024年还要折腾OpenCV 4.5.1的源码编译先把结论摆在前面:如果你只是想在Python里跑个cv2.imread,pip装个预编译包就够了,完全没必要碰源码编译。但只要你遇到下面这几种情况,源码编译就是绕不过去的坎。第一种&#xf…

作者头像 李华
网站建设 2026/10/17 4:31:12

分布式文件系统Frangipani核心架构:锁、缓存与日志恢复

LEC 11的Frangipani论文,我前后读了三遍才算真正吃透。第一遍看完只觉得它是一个比较特别的分布式文件系统,第二遍才意识到它把“分布式锁客户端缓存私有日志”这三个基础组件组合出了一种极其优雅的架构,第三遍时我自己动手写了一个简化版&a…

作者头像 李华
网站建设 2026/10/17 4:31:06

图即代码:diagram-design 让架构图告别手工维护

1. 从“画图”到“写图”:diagram-design 的核心思路老实说,diagram-design 这个项目最初不是什么宏大的平台规划,就是我被架构文档里的图反复折腾到崩溃之后,决定把“画图”这件事彻底改成“写代码”。当时我正在维护一个模拟项目…

作者头像 李华