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

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

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

起因

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

实践

查找启动Activity

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

1162d5c783f4

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

1162d5c783f4

反编译classes.dex

在这里所用到的反编译工具都是可以在网上找到,工具为dex2jar和jd-gui,大家自行搜索下载。

找到了启动的Activity后呢,我们就要将apk给反编译,把里面的classes.dex文件提取出来,首先将微博国际版的apk后缀改为.zip,然后打开

1162d5c783f4

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

1162d5c783f4

转换过程

1162d5c783f4

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

1162d5c783f4

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

1162d5c783f4

查找广告

使用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分钟才出现一次广告,比起那些每次打开都会出现广告的好多了,但是也阻挡不了我干掉广告。

1162d5c783f4

显示广告条件

我们来看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方法的执行结果。

1162d5c783f4

通过上面分析,我们知道了所需要的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);

}

}

}

}

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

1162d5c783f4

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

去除广告

我们只需要将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);

}

}

}

}

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

1162d5c783f4

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

总结

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

Github

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/375885.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux命令:vim文件操作命令、新建用户,查看用户列表,chown命令

命令 简单说明 :w 保存编辑后的文件内容,但不退出vim编辑器。这个命令的作用是把内存缓冲区中的数据写到启动vim时指定的文件中。 :w! 强制写文件,即强制覆盖原有文件。如果原有文件的访问权限不允许写入文件,例如,原有的文件…

cocos2d-x android 环境搭配,cocos2d-x Android环境配置问题和解决方法

1.前提:下载安装Cygwin,并已经在cygwin\home\admin(计算机用户名)下的.bash_profile中完成如下配置:NDK_ROOT /cygdrive/d/cocos2dxdev/andrid-ndk-r8e//NDK安装位置export NDK_ROOT问题:运行cygwin.exe.录入如下的第一行数据后,没…

栈的应用--括号匹配的检验

算法中设置一个栈,每次读入一个括号,若是右括号,则或者与置于栈顶的括号匹配,或者是不合法的情况,若是左括号,则入栈。若算法结束,栈是空的,则括号合法。 括号匹配函数 Status bra…

node.js 初体验

node.js 初体验 2011-10-31 22:56 by 聂微东, 174545 阅读, 118 评论, 收藏, 编辑 PS: ~ 此篇文章的进阶内容在为《Nodejs初阶之express》 ~ 2014/09/24 更新《Express 4.X 启航指南》 欢迎阅读和评论:) 最近写的文章收到许多朋友的反馈,感谢大家的支持和建议&#…

Linux内核3.0移植并基于Initramfs根文件系统启动

Linux内核移植与启动 Target borad:FL2440 Bootloader:U-boot-2010.09 交叉编译器:buildroot-2012.08 1.linux内核基础知识 首先,磨刀不误砍柴工。在动手进行linux内核移植之前,我们有必要对linux内核进行一定的了解。…

操作系统上机作业--实现shell(2)(多进程)

sh2.c: 实现shell程序,要求在第1版的基础上,添加如下功能 • 实现文件重定向 • $ echo hello >log • $ cat log • Hello 实现思路: 和sh1.c相比,主要是修改了cmd函数的实现过程。通过循环找出重定向符号"&g…

操作系统上机作业--根据莱布尼兹级数计算PI(1)(多线程)

pi1.c: 使用2个线程根据莱布尼兹级数计算PI • 莱布尼兹级数公式: 1 - 1/3 1/5 - 1/7 1/9 - ... PI/4 • 主线程创建1个辅助线程 • 主线程计算级数的前半部分 • 辅助线程计算级数的后半部分 • 主线程等待辅助线程运行結束后,将前半部分和后半部分相加实现思路&#xff1…

操作系统上机作业--根据莱布尼兹级数计算PI(2)(多线程)

pi2.c: 使用N个线程根据莱布尼兹级数计算PI • 与上一题类似,但本题更加通用化,能适应N个核心,需要使用线程参数来实现 • 主线程创建N个辅助线程 • 每个辅助线程计算一部分任务,并将结果返回 • 主线程等待N个辅助线程…

数组以及冒泡排序

数组 1、概念:可以帮我一次声明多个同类型的变量,这些变量再内存中是连续存储的。 2、声明语法:数据类型[] 数组名 new 数据类型[数组长度] 数组长度:一次要声明的同类型的变量个数。是在定义这个数组的时候就确定了&#xf…

操作系统上机作业--多线程排序

sort.c: 多线程排序 • 主线程创建一个辅助线程 • 主线程使用选择排序算法对数组的前半部分排序 • 辅助线程使用选择排序算法对数组的后半部分排序 • 主线程等待辅助线程运行結束后,使用归并排序算法归并数组的前半部分和后半部分 实现思路: ARRAY_CO…

jdk5下载链接

查看jdk版本 java -versionJDK下载 最新版本http://www.oracle.com/technetwork/java/javase/downloads/index.htmlJDK下载 版本1.5.22http://www.oracle.com/technetwork/java/javasebusiness/downloads/java-archive-downloads-javase5-419410.html#jdk-1.5.0_22-oth-JPR JDK…

html的细节优化,网站页面优化细节详解

原标题:网站页面优化细节详解SEO页面优化是继SEO结构优化之后,另一个重要优化地方;页面标题在每个页面中的关键位置,出现目标关键词,这是我们做页面优化的基础思路,关键词位置,都有哪些呢?第一个是关键位置…

操作系统上机作业--使用条件变量解决生产者、计算者、消费者问题(多线程)

pc1.c: 使用条件变量解决生产者、计算者、消费者问题 /* • 系统中有3个线程:生产者、计算者、消费者 • 系统中有2个容量为4的缓冲区:buffer1、buffer2 • 生产者生产a、b、c、‘d、e、f、g、h八个字符,放入到buffer1 • 计算者从b…

程序各个段text,data,bss,stack,heap

网上找了一堆资料学习一下,了解这些, 有助于规化程序结构,优化代码; 使用gcc编译出来的程序,用size可以查看程序结构和大小, 如 1: #size hello 2: Text data bss dec hex filename 3: 778 200 4 982 3D6 hello 所以一个可执行的程序文件,结构分三部分: .text 代码段,用来存…

操作系统上机作业-- 使用信号量解决生产者、计算者、消费者问题(多线程)

pc2.c: 使用信号量解决生产者、计算者、消费者问题 • 功能和前面的实验相同,使用信号量解决 实现思路: 生产者、计算者、消费者三者之间的关系和上一个编程任务一样,不一样的是,将互斥量、条件变量封装起来作为信号量,处理方…

Singleton 单件

模式分类 从目的来看: -创建型(Creational)模式:负责对象创建 -结构型(Structural)模式:处理类与对象间的组合 -行为型(Behavioral)模式:类与对象交互中的职责…

10个利用Eclipse调试Java的常见技巧

http://www.open-open.com/news/view/1ad9099 阅读目录 1. Conditional Breakpoint2. Exception Breakpoint3. Watch Point4. Evaluation (Display or Inspect or Watch)5. Change Variable Values6. Stop in Main7. Environment Variables8. Drop to Frame9. Step Filter10. S…

操作系统上机作业--创建N个线程(多线程)

ring.c: 创建N个线程,它们构成一个环 • 创建N个线程:T1、T2、T3、… TN • T1向T2发送整数1 • T2收到后将整数加1 • T2向T3发送整数2 • T3收到后将整数加1 • T3向T4发送整数3 • … • TN收到后将整数加1 • TN向T1发送整数N 实…

台式计算机网线,台式电脑如何连接宽带_台式电脑如何连接网线

2017-03-11 21:36:28电脑直接拨号上网(有宽带账号和密码)或者自动获取IP(有帐号没密码)上方式设置见图2016-12-10 13:29:30右击网上邻居,点属性,创建一个新的连接,按照下一步下一步的步骤就可以了,然后成功之后输入你的宽带号码和…

栈的应用--汉诺塔

#include<stdio.h>void move(char x,int n,char y){printf("%d号盘 %c柱 ---> %c柱\n",n,x,y); }void hanoi(int n,char x,char y,char z){if(n1){move(x,1,z);}else{hanoi(n-1,x,z,y);move(x,n,z);hanoi(n-1,y,x,z);} }int main(){int n;char xX;char yY;c…