使用Xposed去除微博国际版的启动广告

本文同步更新于旺仔的个人博客,访问可能有点慢,多刷新几次。

前面有篇文章已经介绍了如何创建Xposed模块的文章了,这篇就让我们来实现一个简单的去除启动广告的功能吧。

起因

为什么要是要去掉微博国际版的开屏广告呢,因为广告烦人啊,而且我打开微博的时间也是偶尔才会打开的,每次一打开就能看到广告,所以就想把这个开屏广告给删掉,奇怪的是,打开一次后,再关掉再打开是没有广告的,要隔一段时候才会出现广告,这个原因会在下面解释。

实践

查找启动Activity

首先我们先拿到微博国际版的apk,apk的版本是2.5.7-5。

然后拉到Android Studio里面,然后点击AndroidManifest.xml文件,然后搜索android.intent.category.LAUNCHER,找到启动的Activity,在这里我们找到Activity是com.weico.international.activity.LogoActivity

反编译classes.dex

在这里所用到的反编译工具都是可以在网上找到,工具为dex2jarjd-gui,大家自行搜索下载。
找到了启动的Activity后呢,我们就要将apk给反编译,把里面的classes.dex文件提取出来,首先将微博国际版的apk后缀改为.zip,然后打开

然后将里面的两个dex文件,拷贝出来,放到dex2jar目录里面,然后拖两个文件到dex2jar.bat上面,让其转换成jar文件

转换过程

转换完成之后会出现classes_dex2jar.jarclasses2_dex2jar.jar两个文件

然后我们用jd-gui打开这两个jar文件,然后找到LogoActivity

查找广告

使用jd-gui打开LogoActivity之后,我们就要在里面查找广告相关的内容了,我们搜索ad,最后找到loginOrGlance方法和openGDTAD方法。
通过下面代码可以看出,真正显示广告的是openGDTAD方法,而loginOrGlance方法则是判断当前启动是否需要显示广告,这下找到源头就好办了。

  
  private void loginOrGlance()
  {
    if (!Setting.getInstance().loadBoolean("first_open_guide"))
    {
      Setting.getInstance().saveBoolean("first_open_guide", true);
      startActivityForResult(new Intent(this.me, GuideActivity.class), 1025);
      return;
    }
    if (AccountsStore.getCurAccount() != null)
    {
      if (Setting.getInstance().loadInt("display_ad") == 1)
      {
        if (System.currentTimeMillis() - Setting.getInstance().loadLong("ad_display_time") > ProcessMonitor.repeatedTime)
        {
          openGDTAD();
          return;
        }
        initMainTabActivity();
        return;
      }
      initMainTabActivity();
      return;
    }
    initGuestActivity();
  }
  // 加载广告
  private void openGDTAD()
  {
    getWindow().getDecorView().postDelayed(new Runnable()
    {
      public void run()
      {
        WIActions.startActivityWithAction(new Intent(LogoActivity.this.me, NewSplashActivity.class), Constant.Transaction.GROW_FADE);
        LogoActivity.this.finish();
      }
    }
    , 600L);
  }

广告间隔出现原因

前面我们说过启动一次出现广告后,要隔一段时候才会重新出现广告,上面的代码System.currentTimeMillis() - Setting.getInstance().loadLong("ad_display_time") > ProcessMonitor.repeatedTime,这里就是原因,当前时间跟上一次显示广告的时间相差超过ProcessMonitor.repeatedTime的值的时候,就会出现广告。
我们来看一下repeatedTime的值是多少,进到ProcessMonitor类里面,值为1800000毫秒,也就是30分钟才出现一次广告,比起那些每次打开都会出现广告的好多了,但是也阻挡不了我干掉广告。

显示广告条件

我们来看loginOrGlance方法里面的广告相关代码

if (Setting.getInstance().loadInt("display_ad") == 1)
{
    if (System.currentTimeMillis() - Setting.getInstance().loadLong("ad_display_time") > ProcessMonitor.repeatedTime)
    {
      openGDTAD();
      return;
  }
  initMainTabActivity();
  return;
}
initMainTabActivity();
return;

可以看出,首先先判断display_ad的值是否为1,如果不为1,就直接调用启动主界面的initMainTabActivity()方法。
如果为1,在继续判断上一次显示广告的时间ad_display_time是否超过30分钟,如果超过就显示,没有超过就启动主界面。
所以,显示广告有两个条件

  • display_ad的值为1
  • 上一次显示广告的时间和现在的时间相差30分钟

Hook方法

这里我们来介绍一下Hook所用到的一下Xposed里面的方法
findAndHookMethod方法,其参数对应为加载的类(Class<?>) + 方法名 + 参数类型(根据所Hook方法的参数的类型,即有多少个写多少个,加上.class) + XC_MethodHook回调接口。
XC_MethodHook中定义了回调方法:
beforeHookedMethod(MethodHookParam param):被hook方法调用前执行,调用param.setResult可以跳过被Hook的方法。
afterHookedMethod(MethodHookParam param) : 被Hook方法调用后执行,调用param.setResult更改被hook方法的执行结果。

通过上面分析,我们知道了所需要的Hook的两个方法,这两个值居然是存到本地SharedPreferences里面,那么我们修改就更容易了。

  • 一个是Setting.getInstance().loadInt("display_ad"),既是Setting类里面的loadInt方法。
public int loadInt(String paramString)
{
    return this.mSharedPreferences.getInt(paramString, -1);
}
  • 一个是Setting.getInstance().loadLong("ad_display_time"),既是Setting类里面的loadLong方法。
public long loadLong(String paramString)
{
    return this.mSharedPreferences.getLong(paramString, -1L);
}

验证

首先我们来验证一下我们上面的两个条件是否正确,打开我们的Tutorial类,在handleLoadPackage方法里面实现我们的Hook。
我们先验证30分钟出现的条件,既然是要超过30分钟,那么我们只需要将loadLong("ad_display_time")返回的值改为-1L,也就是afterHookedMethod(MethodHookParam param)方法里面修改,就可以实现每次启动都能出现广告界面了


public class Tutorial implements IXposedHookLoadPackage {

    @Override
    public void handleLoadPackage(final XC_LoadPackage.LoadPackageParam lpparam) throws Throwable {
        // 只对微博国际版进行操作
        if (lpparam.packageName.equals("com.weico.international")) {
            try {
                // 获取Setting类
                Class<?> aClass = XposedHelpers.findClassIfExists("com.weico.international.activity.v4.Setting", lpparam.classLoader);
                if (aClass == null) {
                    return;
                }
                // Hook方法
                XposedHelpers.findAndHookMethod(aClass, "loadLong", String.class, new XC_MethodHook() {

                    @Override
                    protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                        String param1 = (String) param.args[0];
                        // 如果参数为ad_display_time的时候将返回值改为-1L
                        if (!TextUtils.isEmpty(param1) && param1.equals("ad_display_time")) {
                            Log.e("info", "com.weico.international---loadLong---ad_display_time");
                            param.setResult(-1L);
                        }
                    }
                });
            } catch (Throwable t) {
                XposedBridge.log("Hook出错" + t);
            }
        }
    }
}

接着运行重启手机,开机后,打开微博国际版。

可以看出,现在每次打开都会有广告,证明我们的猜测是正确的。

去除广告

我们只需要将Setting.getInstance().loadInt("display_ad")的返回值改为-1就能实现去除广告的效果了,下面看代码

public class Tutorial implements IXposedHookLoadPackage {

    @Override
    public void handleLoadPackage(final XC_LoadPackage.LoadPackageParam lpparam) throws Throwable {
        // 只对微博国际版进行操作
        if (lpparam.packageName.equals("com.weico.international")) {
            try {
                Class<?> aClass = XposedHelpers.findClassIfExists("com.weico.international.activity.v4.Setting", lpparam.classLoader);
                if (aClass == null) {
                    return;
                }
                // Hook loadInt方法
                XposedHelpers.findAndHookMethod(aClass, "loadInt", String.class, new XC_MethodHook() {

                    @Override
                    protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                        String param1 = (String) param.args[0];
                        // 如果参数为display_ad的时候将返回值改为-1
                        if (!TextUtils.isEmpty(param1) && param1.equals("display_ad")) {
                            Log.e("info", "com.weico.international---loadInt---display_ad");
                            param.setResult(-1);
                        }
                    }
                });
                // Hook loadLong方法
                XposedHelpers.findAndHookMethod(aClass, "loadLong", String.class, new XC_MethodHook() {

                    @Override
                    protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                        String param1 = (String) param.args[0];
                        // 如果参数为ad_display_time的时候将返回值改为当前时间
                        if (!TextUtils.isEmpty(param1) && param1.equals("ad_display_time")) {
                            Log.e("info", "com.weico.international---loadLong---ad_display_time");
                            param.setResult(System.currentTimeMillis());
                        }
                    }
                });
            } catch (Throwable t) {
                XposedBridge.log("Hook出错" + t);
            }
        }
    }
}

接着运行重启手机,开机后,打开微博国际版。

可以看出,再也没有广告了。

总结

这次使用Xposed实践,来去除微博国际版的启动广告,可以说是收获挺大的,Hook到所调用的方法,然后里面进行我们自己的操作,关键就是在于beforeHookedMethodafterHookedMethod这两个方法里面实现的操作。

Github

Github地址在此奉上:XposedRemoveAd,欢迎star

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 180,161评论 5 436
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 75,785评论 2 342
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 128,551评论 0 297
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 48,708评论 1 254
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 57,479评论 4 337
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 43,558评论 1 250
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 34,544评论 3 364
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 33,100评论 0 237
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 37,231评论 1 278
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 32,788评论 2 285
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 34,457评论 1 300
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 30,484评论 3 294
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 35,750评论 3 287
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 27,507评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 28,714评论 1 240
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 38,993评论 2 318
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 38,555评论 2 318