手机毒霸去广告功能分析二:广告View的识别
手机毒霸对于广告View的判定规则分析
上次我们提到手机毒霸获得root权限之后,生成一个root进程,然后通过进程注入的方式将广告应用中的广告检测出来,并且清除之。这次我们将详细介绍手机毒霸(v1.6.0)是如何找到广告View的。
一、广告View判定规则分析
接着上次的说,注入代码勾住了ActivityThread中的mH的mCallback回调【@】,拦截了RESUME_ACTIVITY(107)和PAUSE_ACTIVITY(101)消息。直接看dex2jar反编译ksremote.jar后的代码。
@com.ijinshan.remotejar.e
if (paramMessage.what == 107)
{
if (com.ijinshan.hookutil.b.a)
Log.d("HookActivityThread", "RESUME_ACTIVITY");
f.a(paramMessage.obj); //这里就是在Activity resume之前做的事情
KsRemoteCtrl.a(107);
break;
}
if (paramMessage.what == 101)
{
f.b(paramMessage.obj);
break;
}
顺藤摸瓜看看f.a(paramMessage.obj);做了些什么。
@ com.ijinshan.remotejar.f
public static void a(Object paramObject) {//paramObjects实际是IBinder类型的token
if ((a != null) && (e != null)) {
Object localObject = a.get(paramObject);//根据token拿到ActivityClientRecord
if (localObject != null) {
Activity localActivity = c(localObject);//根据ActivityClientRecord拿到Activity
if (localActivity != null) {
//根据Activity拿到com.ijinshan.duba.a.b对象
com.ijinshan.duba.a.b localb = (com.ijinshan.duba.a.b)e.get(localActivity);
if (localb != null) localb.d();//接下来要跟这个函数
}
}
}
d();
}
其实上面的com.ijinshan.duba.a.b类是一个比较重要的类,它负责检测广告。我们接下去看它的d()方法。
@ com.ijinshan.duba.a.b
public void d()
{
if (com.ijinshan.hookutil.b.a)
Log.e(a, this.c.toString() + " onResume");
// com.ijinshan.remotejar.d.b()返回了主线程的一个Handler
com.ijinshan.remotejar.d.b().postDelayed(this.h, 1000L);
}
接下来要看这个h是一个什么样的Runnable了。这个成员h是com.ijinshan.duba.a.c类型的。
@com.ijinshan.duba.a.c
public void run()
{
if (!a.h());
while (true)
{
return;
if (!b.a(this.a).isFinishing())
{
b.b(this.a);
…
boolean bool = this.a.a(b.a(this.a));//这里如果找到广告View就返回true
…
if (bool)
b.a(this.a, true);
else if (b.a(this.a).getClass().toString().indexOf("qsbk.app.logic.TopActivity") > -1)
d.b().postDelayed(b.c(this.a), 500L);
}
}
}
boolean bool = this.a.a(b.a(this.a));这句看上去比较复杂,我们掰开来瞧瞧。
拆成Activity activity = b.a(this.a); boolean bool = this.a.a(activity);
this.a是com.ijinshan.duba.a.b类型。b.a(this.a)的b类也是com.ijinshan.duba.a.b,b.a方法返回一个Activity。this.a.a(activity);就是在这个activity中搜索看是否存在广告View。
@ com.ijinshan.duba.a.b
public boolean a(Activity paramActivity) {
int i = 0;
FrameLayout localFrameLayout = (FrameLayout)paramActivity.getWindow().getDecorView();//获得当前Activity的DecorView
if (localFrameLayout != null) {
localFrameLayout.getClass();
bool = false;
while (i < localFrameLayout.getChildCount()) {//从根开始遍历所有view
if (a("---", localFrameLayout, localFrameLayout.getChildAt(i)))//接着看a方法
bool = true;
i++;
}
}
boolean bool = false;
return bool;
}
这里这个a方法太复杂了,但是非常重要。dex2jar反编译出来的逻辑出现了较大误差,还是用smali吧。
对这个a()函数做一下总结:整个广告匹配过程中一共使用了3种规则:
1. 类名规则:当前View对象的类名如果与黑名单中的类名匹配,那么就认定为广告。
2. WebView规则:当前View对象是WebView并且满足一定的规则,那么就认定为广告。
3. 排除规则:当ViewGroup对象的类名如含有” com.android.internal.policy.impl.PhoneWindow”, 那么就肯定不是广告。
a()函数的算法大体如下:
首先判断当前View是不是ViewGroup。
1. 非ViewGroup情况下,只用类名规则匹配
2. ViewGroup情况下,以此用类名规则和WebView规则匹配,如果还未匹配上,则用排除规则排除PhoneWindow的情况。接下来就是遍历当前ViewGroup的所有子View,然后递归调用a()。
一旦出现命中,则广告View的位置上将被加上adclose View。这个adclose View就是给用户点击来移除广告用的。
以下给出类名规则和WebView规则的细节。(排除规则上述代码中已有)
类名规则:
@com.ijinshan.duba.a.a
public static boolean b(String paramString)
{
if (paramString.startsWith("class "))
paramString = paramString.substring(6); //将View的类名移除开头”class ”
boolean bool;
//过滤掉肯定不是广告的类名。请看下面a(paramString.getBytes()函数的具体实现。
if (a(paramString.getBytes()))【@】
bool = false;
while (true)
{
return bool;
synchronized (f)
{
if ((j == null) || (j.size() == 0))
{
bool = false;
continue;
}
if (TextUtils.isEmpty(paramString))
{
bool = false;
continue;
}
String[] arrayOfString = d.a(paramString, ".");//将View的类名按照”.”拆分成字符串数组
if (arrayOfString.length >= 2)//必须要有包名。【@】
{
String str1 = arrayOfString[0] + "." + arrayOfString[1];
//这里j就是广告View的类名黑名单,它是一个二级Map。
List localList = (List)j.get(str1);
if ((localList != null) && (!localList.isEmpty()))
{
Iterator localIterator = localList.iterator();
while (true)
if (localIterator.hasNext())
{
String str2 = (String)localIterator.next();
if (paramString.contains(str2)) //匹配上了。命中!
{
if (b.a)
Log.e("ad", "IsAdViewCls clsSign " + str2 + " || clsName " + paramString + " return true");
bool = true;
break;
}
}
}
}
bool = false;
}
}
}
总的来说就两步:先过滤掉一些金山认为肯定不含广告的包名,然后到黑名单中去匹配。至于这个黑名单怎么来的。这里我不想展开了。这里只想简单的说这个黑名单是通过IPC从手机毒霸的主进程哪里获得的。至于哪些包名是金山认为肯定不含广告的包名呢?请大家看下面的函数。
@com.ijinshan.duba.a.a
//过滤掉肯定不是广告的类名。
public static boolean a(byte[] paramArrayOfByte)
{
boolean bool = true;
if ((paramArrayOfByte.length >= 6) && (paramArrayOfByte[0] == 106) && (paramArrayOfByte[bool] == 97) && (paramArrayOfByte[2] == 118) && (paramArrayOfByte[3] == 97) && (paramArrayOfByte[4] == 46) && (paramArrayOfByte[5] == 108));
while (true)
{
return bool;
if (((paramArrayOfByte.length < 7) || (paramArrayOfByte[0] != 100) || (paramArrayOfByte[bool] != 97) || (paramArrayOfByte[2] != 108) || (paramArrayOfByte[3] != 118) || (paramArrayOfByte[4] != 105) || (paramArrayOfByte[5] != 107) || (paramArrayOfByte[6] != 46)) && ((paramArrayOfByte.length < 8 || (paramArrayOfByte[0] != 97) || (paramArrayOfByte[bool] != 110) || (paramArrayOfByte[2] != 100) || (paramArrayOfByte[3] != 114) || (paramArrayOfByte[4] != 111) || (paramArrayOfByte[5] != 105) || (paramArrayOfByte[6] != 100) || (paramArrayOfByte[7] != 46) || ((paramArrayOfByte.length >= 15) && (paramArrayOfByte[8] == 99) && (paramArrayOfByte[9] == 111) && (paramArrayOfByte[10] == 109) && (paramArrayOfByte[11] == 109) && (paramArrayOfByte[12] == 111) && (paramArrayOfByte[13] == 110) && (paramArrayOfByte[14] == 46))) && ((paramArrayOfByte.length < 13) || (paramArrayOfByte[0] != 99) || (paramArrayOfByte[bool] != 111) || (paramArrayOfByte[2] != 109) || (paramArrayOfByte[3] != 46) || (paramArrayOfByte[4] != 97) || (paramArrayOfByte[5] != 110) || (paramArrayOfByte[6] != 100) || (paramArrayOfByte[7] != 114) || (paramArrayOfByte[8] != 111) || (paramArrayOfByte[9] != 105) || (paramArrayOfByte[10] != 100) || (paramArrayOfByte[11] != 46) || (paramArrayOfByte[12] != 114)) && ((paramArrayOfByte.length < 13) || (paramArrayOfByte[0] != 99) || (paramArrayOfByte[bool] != 111) || (paramArrayOfByte[2] != 109) || (paramArrayOfByte[3] != 46) || (paramArrayOfByte[4] != 105) || (paramArrayOfByte[5] != 106) || (paramArrayOfByte[6] != 105) || (paramArrayOfByte[7] != 110) || (paramArrayOfByte[8] != 115) || (paramArrayOfByte[9] != 104) || (paramArrayOfByte[10] != 97) || (paramArrayOfByte[11] != 110) || (paramArrayOfByte[12] != 46)))
bool = false;
}
}
是不是觉得有点恶心?dex2jar反编译也有点问题。不过仔细整理一下,其实逻辑很简单:
"java.l"打头的类名、“dalvik.”打头的类名、“android.”打头但不是 “androd.common.”打头的类名、“com.android.r”打头的类名和“com.ijinshan.”打头的类名都不会被认为是广告。
WebView规则:
@com.ijinshan.duba.a.b
private boolean b(WebView paramWebView)
{
Object localObject = a(paramWebView); //调用下面的函数
if ((com.ijinshan.hookutil.b.a) && (localObject != null))
Log.e(a, "getWebViewClient: " + localObject.toString());
//判断WebViewClient对象类名
//这里貌似是特别针对万普世纪(com.waps)的广告。
if ((localObject != null) && (localObject.getClass().toString().contains("com.waps")));
for (boolean bool = true; ; bool = false)
return bool;
}
public Object a(WebView paramWebView)
{
try
{
//反射得到当前WebView的getWebViewClient方法。
Method localMethod = Class.forName(KSCONST.decrypt("android.webkit.WebView")).getDeclaredMethod(KSCONST.decrypt("getWebViewClient"), new Class[0]);
localMethod.setAccessible(true);
//调用getWebViewClient()
Object localObject2 = localMethod.invoke(paramWebView, new Object[0]);
localObject1 = localObject2;
return localObject1;
}
catch (Exception localException)
{
while (true)
{
localException.printStackTrace();
Object localObject1 = null;
}
}
}
二、总结
经过了上面的介绍,我相信大家基本上对于手机毒霸是如何判定一个View是广告的原理已经有了较清楚的了解。总的来说就是通过View的类名匹配。手机毒霸存有一个黑名单。如果一个View的类名跟这个黑名单匹配上,那么这个View就被认作是广告View。寻找广告View的过程则是从Activity的根View上树形遍历所有的View。
三、如何躲避手机毒霸的查杀
细心的读者可能已经发现了,我在文中加了三处【@】。这三处也是躲避手机毒霸查杀的入口点。
1. 既然"java.l"打头的类名、“dalvik.”打头的类名、“android.”打头但不是 “androd.common.”打头的类名、“com.android.r”打头的类名和“com.ijinshan.”打头的类名都不会被认为是广告。那么如果一个广告SDK的View的package名就以这些打头手机毒霸不就放过去了么。
2. 既然一个View的类名必须含有包名,那么如果将广告View写在默认包里不就可以躲过去了么。因为arrayOfString的长度必须要大于等于2才行。
String[] arrayOfString = d.a(paramString, ".");//将View的类名按照”.”拆分成字符串数组
3. 这点放在最后说,是因为相对有点工作量,并且还需要对我们的上一篇博客《手机毒霸去广告功能分析报告》有一个比较详尽的了解。广告View之所以被检测到是因为手机毒霸Hook了AndroidThread.mH的mCallback。广告SDK可以在每次显示广告前检查mCallback有没有被修改,如果发现mCallback被修改了,把它改回去就可以了。这样就从根本上使的手机毒霸的HOOK失效了。广告拦截更加无从谈起。
@安卓安全小分队 2013/2/5
更多内容请关注 http://blog.sina.com.cn/u/3194858670 以及 sina微博@ 安卓安全小分队
相关推荐
#### 二、金山毒霸广告弹窗的类型 1. **产品推荐**:包括但不限于垃圾清理、隐私清理等功能的推广。 2. **游戏保护模式提示**:开启或退出游戏时,金山毒霸会弹出提示窗口。 3. **重要信息推送**:通常指新闻资讯类...
综上所述,本资源涉及的是一个专门为手机设计的WAP导航网站模板,它模拟了“手机毒霸网址大全”的功能,提供了一种便捷的方式帮助用户快速访问常用网站。同时,该资源是通过百度网盘分享的形式提供的,用户可以下载...
4. **广告拦截**:手机毒霸在这方面的表现最佳,能识别并拦截多种类型的广告。360手机卫士可以扫描出问题软件,但无法拦截内置广告。腾讯手机管家能拦截同类竞品软件的信息。 5. **骚扰拦截**:360手机卫士提供了...
**金山毒霸WiFi共享功能详解** 金山毒霸是一款知名的网络安全软件,它除了提供基础的病毒查杀、系统优化等功能外,还内置了实用的WiFi共享工具。这项功能使得用户能够将电脑的网络连接转化为WiFi热点,让其他设备...
- **手机金山毒霸**:适合不太熟悉技术的用户,安装后可以直接选择屏蔽广告的功能。 - **LBE安全大师**:适合有一定技术基础的用户,可以细致地为每个应用设置权限,如禁止联网、获取位置信息等。需要注意的是,...
6. **漏洞扫描功能**:金山毒霸网络版的全网漏洞扫描功能可以集中扫描并修复所有客户机的系统漏洞,通过Proxy(代理)下载补丁的方式有效降低了网络带宽占用,提升了系统的整体安全性。 7. **综合服务价值**:除了...
金山毒霸作为一款知名的杀毒及系统优化软件,除了基本的安全防护功能外,还提供了一系列实用工具,其中包括广告过滤功能,该功能也可以用来禁止访问指定网站。 #### 一、金山毒霸简介 金山毒霸是一款由金山软件...
《金山毒霸》是一款功能强大的杀毒软件,其丰富的设置选项和使用技巧使得用户能够更加高效、智能地保护自己的电脑安全。以下将详细介绍几个关键的使用技巧,帮助你充分利用这款软件。 1. 多种查杀方式:金山毒霸...
【标题】"用vc++做的仿金山毒霸界面"是一个示例项目,展示了如何使用Microsoft Visual C++(简称VC++)编程环境来实现一个类似金山毒霸的用户界面。这个项目对于初学者或者想要深入理解Windows GUI编程的人来说,是...
例如,手机金山毒霸等安全应用提供了广告过滤功能,用户只需开启此功能即可自动拦截大部分广告。另一款更高级的工具是LBE安全大师,它允许用户对每个应用的权限进行精细化控制,包括阻止应用联网,防止其获取用户...
新毒霸轻桌面是一款由金山软件开发的桌面管理工具,旨在提供便捷的桌面整理和优化功能。然而,有时用户可能想要卸载或禁用它,尤其是当他们觉得它不再需要或者影响了系统的性能。以下是一些关于如何卸载或管理新毒霸...
标题中的"C盘清理工具(取代金山毒霸VIP)"指出,这是一个专用于清理C盘空间的软件,其功能可替代金山毒霸VIP的清理模块。在Windows操作系统中,C盘通常是系统盘,随着时间推移,安装的软件、系统更新、日志文件等会...
毒霸网址大全里的天气专栏的相关城市代码列表。map.put("北京","101010100"); map.put("海淀","101010200"); map.put("朝阳","101010300"); map.put("顺义","101010400"); map.put("怀柔","101010500"); map....
"Linux为毒霸升级.pdf" 本文档主要讲述了如何使用 Linux 系统来升级毒霸杀毒软件,解决了单位办公自动化中遇到的安全问题。文章分为三步骤,分别是统一杀毒软件版本、建立病毒库的镜像和共享病毒库。 第一步,统一...
金山毒霸是一款知名的杀毒软件,其用户界面设计通常具有清晰的布局、直观的操作和丰富的功能,因此,通过实现这个项目,开发者能够学习到如何创建一个高效且用户友好的安全软件界面。 【压缩包子文件的文件列表】中...
这类联盟初期可能因经验不足,在防止作弊、定价和盈利分析方面存在挑战,可能导致广告效果不佳。例如,金山早期的毒霸点击广告曾因效果问题调整为安装计费模式。 2. 以推广他人产品为主的联盟,它们自身不生产产品...
金山毒霸网路安全套装 用户手册.pdf
项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松copy复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(随意编程),有任何使用问题欢迎随时与我联系,我会及时为您解惑,...