返回列表 发新帖

【实战教程】xposed实战去除加菲猫广告

  [复制链接]

63

主题

2700

帖子

1万

积分

博士生

萌新

Rank: 7Rank: 7Rank: 7

金币
641
好评
136
信誉
118

考神MT论坛帅哥MT论坛最佳新人MT论坛活跃会员

QQ
发表于 2021-12-4 19:06:01 | 显示全部楼层 | 阅读模式  来自 云南昆明
1.加菲猫影视1.6.2
2.HttpCanary
3.jadx-gui
4.Android Studio
5.MT管理器

一、前言:

---

前几天简简在研究加菲猫影视,我一起看了下。这个软件的前身叫南瓜影视,之前很多人研究,不过自从它换皮又上了服务器校验之后,我便很少看到有人研究了。此次教程便以去广告为主,搭配简简的
https://bbs.binmt.cc/thread-76889-1-1.html
理论上来说,可以白嫖一阵子了。
一般来说,以前的去广告都是修改xml为主,我这次便想挑战一下,用xposed写一个去广告插件。那么,教程开始了。

二、过程:

---

这个软件广告是真的多,而且还有一些是少儿不宜的。
先来看一下最终的效果图

它总共有八处广告,我一一来述。


1、启动广告
先看看广告长什么样子

启动广告采用的是activity纪录分析法,从中可以看出软件的activity的过程是由SplashActivity->AdActivity->HomepageActivity,由此可见,在AdActivity中必然有一个方法会启动HomepageActivity。

打开jadx-gui,很快就发现了调用的方法
代码如下:

  1. public void b2() {
  2.         ARouter.getInstance().build("/homepage/activity").withTransition(R.anim.anim_activity_enter_alpha, R.anim.anim_activity_exit_alpha).navigation(this);
  3.     }
复制代码



按x查找用例

发现都是在本类中调用,稍微分析了下,发现一个可以方法,代码如下:

  1. public void p1() {
  2.         SplashBean splashBean = this.T;
  3.         if (splashBean == null) {
  4.             return;
  5.         }
  6.         if (splashBean.getPicUrl() == null) { //getPicUrl为空时,跳转到home页
  7.             if (u3()) {
  8.                 b2();
  9.             }
  10.             finish();
  11.             return;
  12.         }
  13.         TextView textView = this.mTvWebUel;
  14.         if (textView != null) {
  15.             textView.setVisibility(8);
  16.             w.b("AdActivity", splashBean.getPicUrl());
  17.             AdPresenter adPresenter = (AdPresenter) this.Q;
  18.             String picUrl = splashBean.getPicUrl();
  19.             j.b(picUrl, "it.picUrl");
  20.             ImageView imageView = this.mIvAd;
  21.             if (imageView != null) {
  22.                 adPresenter.u(picUrl, imageView);
  23.             } else {
  24.                 j.q("mIvAd");
  25.                 throw null;
  26.             }
  27.         } else {
  28.             j.q("mTvWebUel");
  29.             throw null;
  30.         }
  31.     }
复制代码




跳转到getPicUrl方法看看,返回值是字符串也就是广告的url


  1. public String getPicUrl() {
  2.         return this.picUrl;
  3.     }
复制代码



编写xpoesd模块,直接让其返回值为空即可

  1. //去除启动广告
  2. XposedHelpers.findAndHookMethod("com.video.test.javabean.SplashBean", classLoader, "getPicUrl", new XC_MethodReplacement() {
  3.                     @Override
  4.                     protected Object replaceHookedMethod(MethodHookParam methodHookParam) throws Throwable {
  5.                         return null;
  6.                     }
  7.                 });
复制代码



---

**2.主页弹窗**
在解决启动广告后,我们进入主页。映入眼帘的就是两个弹窗广告
长这个样子

这个广告也同样是activity纪录分析法,这个弹窗是在HomepageActivity界面弹窗,那我们不妨搜一下dialog,因为一般这种弹窗都是属于dialog,果不其然,又发现了一个可疑的方法

  1. public void C0(List<HomeDialogBean> list) {
  2.         if (!(list == null || list.isEmpty())) { 当传入的List参数不为空时,弹出主页弹窗,而这个List就是弹窗广告的图片url,但是因为晚上在写教程的软件死活不弹,我也没办法给你们验证
  3.             ArrayList arrayList = new ArrayList();
  4.             for (HomeDialogBean homeDialogBean : list) {
  5.                 HomeNoticeDialogFragment homeNoticeDialogFragment = null;
  6.                 homeDialogBean.getActivityType();
  7.                 if (homeDialogBean.getActivityType() == 2) {
  8.                     homeNoticeDialogFragment = HomeNoticeDialogFragment.b0.a(homeDialogBean);
  9.                 }
  10.                 if (homeNoticeDialogFragment != null) {
  11.                     arrayList.add(homeNoticeDialogFragment);
  12.                     homeNoticeDialogFragment.q3(new b(arrayList));
  13.                     homeNoticeDialogFragment.h3(new BaseHomeDialogFragment.a(arrayList) { // from class: e.m.a.r.l.b

  14.                         /* renamed from: b  reason: collision with root package name */
  15.                         public final /* synthetic */ List f15178b;

  16.                         {
  17.                             this.f15178b = r2;
  18.                         }

  19.                         @Override // com.video.test.ui.widget.BaseHomeDialogFragment.a
  20.                         public final void a(BaseHomeDialogFragment baseHomeDialogFragment) {
  21.                             HomepageActivity.this.u4(this.f15178b, baseHomeDialogFragment);
  22.                         }
  23.                     });
  24.                 }
  25.             }
  26.             if (!arrayList.isEmpty()) {
  27.                 ((BaseHomeDialogFragment) arrayList.get(0)).F2(I3(), "dialog0");
  28.             }
  29.         }
  30.     }
复制代码




从上面的逻辑可以看出来,如果List的值为空,那它就不会弹弹窗,我们可以把List置空,当然也可以直接把方法置空,这并不会影响软件的使用
代码如下:


  1. //去除主页弹窗广告
  2. XposedHelpers.findAndHookMethod("com.video.test.module.homepage.HomepageActivity", classLoader, "C0", List.class, new XC_MethodReplacement() {
  3.                     @Override
  4.                     protected Object replaceHookedMethod(MethodHookParam methodHookParam) throws Throwable {
  5.                         return null;
  6.                     }
  7.                 });
复制代码



---

**3.轮播图广告**
老样子先看看长什么样子

这个需要我们先用小黄鸟抓个包,过滤一下ad,这几个都是关键的url请求
这里的响应都是密文,所以我们直接用简简帖子里的来解密,可以得知轮播图广告弹窗的url就是bannerInfo


在代码中搜索url中的Ad/bannerInfo,结果只有一个,而且是retrofit2的接口类,这就比较麻烦,没办法直接进行hook,只能找到关键的实例去修改

多次按x查找用例,因为层级有点多,我这里做了一个堆栈流程图,你们可以参考一下

最终聚焦一下这个s方法,代码如下:


  1. public void s(List<? extends BannerBean> list) {
  2.         j.f(list, "list");
  3.         if (!list.isEmpty()) {
  4.             int size = list.size();
  5.             ArrayList arrayList = new ArrayList(size);
  6.             ArrayList arrayList2 = new ArrayList(size);
  7.             for (BannerBean bannerBean : list) {
  8.                 String slidePic = bannerBean.getSlidePic();
  9.                 j.b(slidePic, "bannerBean.slidePic");
  10.                 arrayList.add(slidePic);
  11.                 String a2 = h0.a(bannerBean.getBannerContent());
  12.                 j.b(a2, "StringUtils.emptyIfNull(bannerBean.bannerContent)");
  13.                 arrayList2.add(a2);
  14.                 String str = this.f8643d;
  15.                                                                 //这里向f方法里传入三个参数,分别是广告图片url、广告id、广告文字
  16.                 w.f(str, "picUrls == " + bannerBean.getSlidePic() + " vodId == " + bannerBean.getVodId() + " bannerContent : " + bannerBean.getBannerContent());
  17.             }
  18.             ((e.m.a.r.j0.a) this.f8265b).f0(arrayList, arrayList2, list);
  19.             return;
  20.         }
  21.         ((e.m.a.r.j0.a) this.f8265b).d2();
  22.     }
复制代码



最终这些数据又转为List传入f0方法中,f0传入的三个参数也就分别代表了广告图片url、广告id、广告文字,这三个数据要同时进行修改,不然会报错,这里我们就去除两个广告,然后对其中一个广告的url和文字进行修改(从轮播图中我们可以知道,第一、第二、第四个都是广告)
注意索引!
xposed代码如下:

  1. //去除轮播图广告
  2. XposedHelpers.findAndHookMethod("com.video.test.module.videotype.BaseVideoTypeListFragment", classLoader, "f0",List.class,List.class,List.class,
  3.                 new XC_MethodHook() {
  4.                     @Override
  5.                     protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
  6.                         super.beforeHookedMethod(param);
  7.                         List URL = (List) param.args[0];
  8.                         URL.set(0,"https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fc-ssl.duitang.com%2Fuploads%2Fitem%2F201810%2F22%2F20181022224306_ydqyt.thumb.1000_0.jpg&refer=http%3A%2F%2Fc-ssl.duitang.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1641197983&t=178238b2c2ce9ef7398dcc9876b54e42");
  9.                         URL.remove(1);
  10.                         URL.remove(3);
  11.                         param.args[0] = URL;
  12.                         List content = (List) param.args[1];
  13.                         content.set(0,"正己修改");
  14.                         content.remove(1);
  15.                         content.remove(3);
  16.                         param.args[1] = content;
  17.                         List layout = (List) param.args[2];
  18.                         layout.remove(1);
  19.                         layout.remove(3);
  20.                         param.args[2] = layout;
  21.                     }
  22.                 });
复制代码




效果图:


---

**4.公告广告**
就是在轮播图下面的公告广告,同样是通过请求的url定位,直接分析有点混乱,我还是做个流程图,不得不说接口类找实例真麻烦

分析一下重写的w2代码:


  1. public void w2(List<HomePageNoticeBean> list) {
  2.                                 //当list为空时
  3.         if (list == null || list.isEmpty()) {
  4.             this.mSwitcherNotice.d();  //开发者助手抓布局时发现id刚好为SwitcherNotice
  5.             this.mSwitcherNotice.setVisibility(8);  // 隐藏布局
  6.             return;
  7.         }
  8.         if (this.R == null) {
  9.             this.R = new ViewSwitcher.ViewFactory() { // from class: e.m.a.r.i0.b
  10.                 @Override // android.widget.ViewSwitcher.ViewFactory
  11.                 public final View makeView() {
  12.                     return VideoRecommendFragment.this.z3();
  13.                 }
  14.             };
  15.         }
  16.         if (this.S == null) {
  17.             this.S = new a();
  18.         }
  19.         this.mSwitcherNotice.setFactory(this.R);
  20.         this.mSwitcherNotice.setTextBinder(this.S);
  21.         this.S.d(list);
  22.         this.mSwitcherNotice.c();
  23.     }
复制代码




由此可知,只需将传入的参数置空即可,xposed代码如下:


  1. //去除公告广告

  2. XposedHelpers.findAndHookMethod("com.video.test.module.videorecommend.VideoRecommendFragment", classLoader, "w2", List.class, new XC_MethodHook() {
  3.                     @Override
  4.                     protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
  5.                         super.beforeHookedMethod(param);
  6.                         param.args[0] = null;
  7.                     }
  8.                 });
复制代码



---

**5.横幅广告**
老样子,搜索url中的关键词(这里说一下,我抓包的那张截图中横幅广告的标记和公告广告的标记写反了),所以横幅广告应该搜索
Ad/noticeInfo

这里主要看一下com.video.test.module.videorecommend.VideoRecommendPresenter.z的代码:


  1. public /* synthetic */ void y(List list) throws Exception {
  2.         if (list.isEmpty()) { //当传入的lsit为空时,执行q0的方法
  3.             ((m) this.f8265b).q0();
  4.             return;
  5.         }
  6.         ((m) this.f8265b).a3(list);
  7.         ((m) this.f8265b).h1();
  8.     }
复制代码




q0的方法重写之后就是一个很明显的隐藏布局的代码


  1. public void q0() {
  2.         this.mRvModule.setVisibility(8);
  3.     }
复制代码



所以xpoesd代码如下:


  1. //去除主页notice广告

  2. XposedHelpers.findAndHookMethod("com.video.test.module.videorecommend.VideoRecommendPresenter", classLoader, "y", List.class, new XC_MethodHook() {
  3.                     @Override
  4.                     protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
  5.                         super.beforeHookedMethod(param);
  6.                         param.args[0] = null;
  7.                     }
  8.                 });
复制代码



---

**6.页面中间广告**
先看一下长什么样子

搜索字符串/Ad/barsIndexAdInfo,堆栈图

在j方法中注意传入的第一个参数,当他不为2时都会显示广告,分别是在加载顶栏的热门、电影、电视剧、综艺、动漫所加载的广告对应的值(可以打印一下进行验证)


  1. public final g.b.m<AdInfoBean> j(int i2, Context context) {
  2.         String str;
  3.         if (i2 == 1) {
  4.             str = m.a.l();
  5.         } else if (i2 == 3) {
  6.             str = m.a.j();
  7.         } else if (i2 == 4) {
  8.             str = m.a.n();
  9.         } else if (i2 == 5) {
  10.             str = m.a.a();
  11.         } else if (i2 != 6) {
  12.             g.b.m<AdInfoBean> B = g.b.m.B(AdInfoBean.EMPTY_INSTANCE);
  13.             j.b(B, "Observable.just(AdInfoBean.EMPTY_INSTANCE)");
  14.             return B;
  15.         } else {
  16.             str = m.a.p();
  17.         }
  18.         g.b.m<AdInfoBean> F = this.a.n(i2).e0(this.a.m(context, str), a.a).F(b.a);
  19.         j.b(F, "mModel.getAd(pid)\n      \u2026InfoBean.EMPTY_INSTANCE }");
  20.         return F;
  21.     }
复制代码




所以我们只需要将第一个参数写死即可


  1. //去除中间广告

  2. XposedHelpers.findAndHookMethod("com.video.test.module.videotype.BaseVideoTypeListPresenter", classLoader, "j", int.class,Context.class, new XC_MethodHook() {
  3.                     @Override
  4.                     protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
  5.                         super.beforeHookedMethod(param);
  6.                         param.args[0] = 2;
  7.                     }
  8.                 });
复制代码



---

**7.播放页广告**
看一下

根据抓包搜索字符串Ad/barsPlayAdInfo,堆栈图

代码如下:


  1. public void g1(AdInfoBean adInfoBean) {
  2.         if (adInfoBean != null) { //当传入的参数为空,隐藏布局
  3.             e.m.a.p.b.d(this).load(adInfoBean.getAdPic()).listener(new l(adInfoBean)).centerCrop().into(this.mIvAd);
  4.             ImageView imageView = this.mIvAd;
  5.             imageView.setTag(imageView.getId(), adInfoBean);
  6.             return;
  7.         }
  8.         this.mIvAd.setVisibility(8);
  9.     }
复制代码



所以xposed代码如下:


  1. //去除播放页广告,自定义类参数

  2. Class<?> personClass = XposedHelpers.findClass("com.video.test.javabean.AdInfoBean",classLoader);
  3. XposedHelpers.findAndHookMethod("com.video.test.module.player.PlayerActivity", classLoader, "g1", personClass,new XC_MethodHook() {
  4.                     @Override
  5.                     protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
  6.                         super.beforeHookedMethod(param);
  7.                         param.args[0] = null;
  8.                     }
  9.                 });
复制代码



---

**8.个人页广告**
这个就当给一些新手同学留个小问题,效果如下:
不要直接修改xml哦,尝试去推导堆栈,然后找到关键方法进行hook


---

三、尾声

啥时候MT能支持一下MD语法,转换挺头疼的

写个教程真的废时间呀,第一次尝试去hook接口类的实例,真的很麻烦,也有可能是还有其他更好的方法俺还不会,如果有大佬有其他更好的思路,请赐教
已有3人评分好评 金币 理由
417758 + 1 + 1 先评分再看
武大郎 + 1 + 1 帖子就不看了!
yuanyxh + 1 + 1 很给力!

查看全部评分 总评分:好评 +3  金币 +3 

萌新
回复

使用道具 举报

28

主题

644

帖子

3676

积分

大学生

Rank: 5Rank: 5

金币
1590
好评
17
信誉
103
QQ
发表于 2021-12-4 19:25:08 | 显示全部楼层  来自 香港
正己 发表于 2021-12-4 19:06
不支持MD语法,差评

我的沙发又没了,大神赔我
“其实最让人焦虑的,不是忙,也不是累,而是没有什么特别感兴趣的东西,觉得世间一切,怎样都可以,也没有什么特别想见的人,想动的心,明知道自己该努力了,却又不知道,该往哪里用力”
回复

使用道具 举报

63

主题

2700

帖子

1万

积分

博士生

萌新

Rank: 7Rank: 7Rank: 7

金币
641
好评
136
信誉
118

考神MT论坛帅哥MT论坛最佳新人MT论坛活跃会员

QQ
发表于 2021-12-4 19:06:54 | 显示全部楼层  来自 云南昆明
不支持MD语法,差评
萌新
回复

使用道具 举报

36

主题

3649

帖子

1万

积分

博士生

Rank: 7Rank: 7Rank: 7

金币
2165
好评
101
信誉
192

MT论坛最佳新人考神MT论坛帅哥MT论坛新人MT论坛活跃会员MT论坛侠客

发表于 2021-12-4 19:15:45 来自手机  | 显示全部楼层  来自 湖北鄂州
正己大佬的沙发下边我坐了
回复

使用道具 举报

11

主题

3326

帖子

1万

积分

博士生

Rank: 7Rank: 7Rank: 7

金币
3255
好评
10
信誉
100

MT论坛最佳新人MT论坛帅哥考神MT论坛新人MT论坛活跃会员

发表于 2021-12-4 19:29:45 来自手机  | 显示全部楼层  来自 福建福州
好东西。。
回复

使用道具 举报

102

主题

4113

帖子

9319

积分

硕士生

Rank: 6Rank: 6

金币
402
好评
7
信誉
100
发表于 2021-12-4 19:29:50 来自手机  | 显示全部楼层  来自 广东中山
看看     
回复

使用道具 举报

12

主题

217

帖子

1996

积分

高中生

Rank: 4

金币
103
好评
1
信誉
100
发表于 2021-12-4 19:33:29 来自手机  | 显示全部楼层  来自 广东
回复

使用道具 举报

20

主题

4473

帖子

1万

积分

博士生

Rank: 7Rank: 7Rank: 7

金币
512
好评
25
信誉
100

MT论坛最佳新人考神MT论坛活跃会员

发表于 2021-12-4 19:54:23 来自手机  | 显示全部楼层  来自 广东佛山
蒸鸡大佬300集教程更新了
回复

使用道具 举报

2

主题

222

帖子

493

积分

初中生

Rank: 3Rank: 3

金币
284
好评
0
信誉
100

MT论坛新人考神MT论坛帅哥

发表于 2021-12-4 19:57:22 来自手机  | 显示全部楼层  来自 广西
66666666666666666
回复

使用道具 举报

98

主题

2658

帖子

1万

积分

博士生

Rank: 7Rank: 7Rank: 7

金币
1733
好评
35
信誉
107
发表于 2021-12-4 19:58:51 来自手机  | 显示全部楼层  来自 广东广州
学习学习
回复

使用道具 举报

83

主题

3383

帖子

1万

积分

博士生

white hawk

Rank: 7Rank: 7Rank: 7

金币
2427
好评
57
信誉
100

考神MT论坛帅哥MT论坛最佳新人MT论坛活跃会员MT论坛新人

发表于 2021-12-4 20:05:13 来自手机  | 显示全部楼层  来自 新疆乌鲁木齐
本帖最后由 白鹰 于 2021-12-4 20:08 编辑

正己   三百集
回复

使用道具 举报

0

主题

497

帖子

3702

积分

大学生

Rank: 5Rank: 5

金币
389
好评
1
信誉
100
发表于 2021-12-4 20:10:41 来自手机  | 显示全部楼层  来自 广西
看看隐藏
回复

使用道具 举报

0

主题

557

帖子

2073

积分

大学生

Rank: 5Rank: 5

金币
1077
好评
0
信誉
100

MT论坛新人考神MT论坛帅哥

发表于 2021-12-4 20:12:09 来自手机  | 显示全部楼层  来自 福建泉州
学习学习一下
回复

使用道具 举报

0

主题

397

帖子

1056

积分

高中生

Rank: 4

金币
597
好评
0
信誉
100
发表于 2021-12-4 20:13:21 来自手机  | 显示全部楼层  来自 广东湛江
学习贴,谢分享
回复

使用道具 举报

9

主题

111

帖子

318

积分

初中生

Rank: 3Rank: 3

金币
55
好评
0
信誉
100

MT论坛新人MT论坛帅哥考神

发表于 2021-12-4 20:13:50 来自手机  | 显示全部楼层  来自 江苏南通
查看隐藏
回复

使用道具 举报

发表回复

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表