手机毒霸去广告功能分析二:广告View的识别

Android 抛弃原生WebView,使用腾讯X5内核、并加入广告拦截。 大家都不知道原生的WebView 存在各种坑。各种适配问题。 最近在使用,总会出现DNS被拦截的情况。预览了各个大神的论坛与博客。 发现可以更改WebView内核。找到了比较火的两个。 分别是:腾讯X5内核 和 crosswalk crosswalk : 据说很强大,但缺点就是会让你的APK包增大很多。(我还没试过,都是看大神们的博客说的) 大家可以参考这篇...... 阅读详情

手机毒霸对于广告View的判定规则分析

@安卓安全小分队 2013/2/5

 

上次我们提到手机毒霸获得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失效了。广告拦截更加无从谈起。

在VS2019里把JSBSim飞行模型集成到你的C++项目里(附完整配置流程和常见错误解决) 本文详细介绍了如何在Visual Studio 2019中将JSBSim飞行模型集成到C++项目中,包括环境准备、源码编译、项目配置和常见错误解决方案。通过实战技巧和优化建议,帮助开发者高效实现高精度飞行仿真功能,提升开发效率。 阅读详情

相关推荐

手把手教你用Boot-Repair快速修复Ubuntu启动分区缺失(附详细命令行步骤)

本文详细介绍了如何使用Boot-Repair工具快速修复Ubuntu启动分区缺失问题,包括诊断、应急准备、自动修复和手动命令操作。通过grub rescue模式下的关键命令和Boot-Repair的图形界面操作,帮助用户高效解决启动分区故障,确保系统恢复正常运行。

weixin_29229989的博客 564

WebView 拦截广告 简单实现

一:原理 WebView有个setWebViewClient()方法,new一个WebViewClient()的匿名类,里面有两个待重写的方法。其中一个为每次访问前都会回调的方法,在这里面如果待访问的url里面和我们定义的广告url相同,就不访问该url,其余正常。 二:实现 webView.setWebViewClient(new WebViewClient() { private Map<String, Boolean> loadedUrls = ne

kicinio的博客 1629

WSL中使用VMD图形化界面

【代码】WSL中使用VMD图形化界面。

handsome213的博客 841

smali语法中文版

表中的vx、vy、vz表示某个Dalvik寄存器。根据不同指令可以访问16、256或64K寄存器。 表中lit4、lit8、lit16、lit32、lit64表示字面值(直接赋值),数字是值所占用位的长度。 long和double型的值占用两个寄存器,例:一个在v0寄存器的double值实际占用v0,v1两个寄存器。 boolean值的存储实际是1和0,1为真、0为假;boolean型的值实际是转成int型的值进行操作。 所有例子的字节序都采用高位存储格式,例:0F00 0A00的编译为0F, 00, 0A

qq_18477271的博客 2429

从CAD到Web:高效转换STEP/IGES模型为GLB格式的实践指南

本文详细介绍了如何将工业设计中的STEP/IGES模型高效转换为Web友好的GLB格式。通过PythonOCC和gltf-pipeline等工具链,实现从CAD到Web的无缝转换,大幅提升模型加载速度和展示效果。文章包含实战案例、优化技巧和常见问题解决方案,帮助开发者快速掌握3D模型转换技术。

weixin_29072299的博客 509

ABAP BAPI_PRODORD_CHANGE函数详解:如何高效重读生产订单主数据

本文深入解析ABAP BAPI_PRODORD_CHANGE函数在生产订单主数据高效处理中的应用。通过详细讲解函数架构、主数据重读机制及实战代码示例,帮助开发人员掌握生产订单数据的精准读取与更新技术,提升SAP系统集成与自动化处理效率。

weixin_29207149的博客 471

屏蔽电信流氓广告造成的诡异的问题--Android WebView 长时间不能载入页面

发如今家里的时候用Android App里的WebView打开站点非常慢,会有十几秒甚至更长时间的卡住。 可是在电脑上打开相同的网页却非常快。 查找这个问题的过程比較曲折,记录下来。 抓取Android网络数据 为了调试这个问题,首先要抓取Android的网络包数据。開始时,是想用Wireshark来抓包的,可是非常麻烦,tcpdump在手机要root权限。 于是转换思路,能不能...

weixin_33882452的博客 238

【在 WSL2 GUI 中使用 pulseaudio 播放声音】

最近在搞一个Linux项目,由于WSL2中需要用到声音外放,无奈只能潜心研究。后来就使用了一种折中的方式替代,那就是pulseaudio。目前来讲WSL2对硬件外设的支持还是不太友好,关于USB的支持我之前在其他文章中已经论述过了,这里不讨论。1、Windows11别忘记打开声音2、可能有一定延迟,因为是通过网络传输的。3、效果的话只能见仁见智了,如果不能满足要求就安装一个实实在在的Ubuntu吧!

jiexijihe945的博客 4532

金山手机毒霸工作原理

本文章由Jack_Jia编写,转载请注明出处。   文章链接:http://blog.youkuaiyun.com/jiazhijun/article/details/8804402 作者:Jack_Jia    邮箱: 309zhijun@163.com 一、序言        金山手机毒霸(http://m.duba.com/)是金山网络推出的首款Android A

novelly的专栏 817

[QMT和ptrade量化交易小白入门]-125、菜场大妈加上四大现金行业指数风控,最大回撤从22%减少了一半

群里面有人建议,在菜场大妈策略的基础上,加入申万的行业指数(银行,钢铁,有色,煤炭)测算其宽度,当这四大行业其中有一个高就会清仓(用来控制回撤)。这背后的逻辑是,在存量资金博弈的市场环境中,资金总量相对固定,当银行、钢铁、有色、煤炭等大市值周期行业因基本面改善(如涨价、政策催化)或避险需求而走强时,会吸引大量资金涌入,导致其他板块(尤其是小市值股票)面临流动性虹吸。经过回测,对比上一个版本发现确实是可以降低一半的回撤,最大回撤从22.3%降到了11.4%,而且有很多时间是空仓等待。

木头大左的博客 241

ABAP 系统里使用 SAP Joule 辅助编程的前提条件

只是说这些大语言模型是针对互联网上能够挖掘到的所有数据进行训练,不像 SAP Joule 那样术业有专攻,仅仅深耕 SAP 技术和业务领域,因此大伙儿对 SAP Joule 的期望值,也远远高于通过大语言模型。SAP Joule 从 ABAP Development Tool 的 Chat 窗口中接收到的对话请求,都会路由到 SAP BTP 上的 AI Foundation.在上述 ABAP 环境中启用 SAP Joule,需要购买额外的 license:8019124.

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 799

乐安全内嵌广告屏蔽原理

一、原理 分析完了手机毒霸去广告功能的原理,接下来我们来看看“乐安全”是如何去内嵌广告的。对手机毒霸去广告功能感兴趣的读者可以看一下我们之前发的三篇技术博客: 手机毒霸去广告功能分析一:总体分析 http://blog.sina.com.cn/s/blog_be6dacae01018hjg.html 手机毒霸去广告功能分析二:广告View的识别 http://blog

android_squad的专栏 2910

PDN分析实战:电源完整性设计与Altium PDN Analyzer全流程指南

电源完整性(PI)是嵌入式硬件系统稳定运行的基础能力,其核心在于控制电流密度与电压降两大物理量。基于欧姆定律与热-电耦合原理,PDN分析将抽象的电源噪声问题转化为可量化、可定位的几何与电气参数优化过程。该技术显著提升系统抗干扰能力、降低复位与ADC漂移等隐性故障率,并直接支撑EMC合规性设计。典型应用场景包括电机驱动板、Wi-Fi模块、STM32/ESP32等资源受限型MCU供电网络验证。本文以Altium Designer为工具平台,结合IPC-2152标准与真实工程案例,详解从功率预算、模型构建到瓶颈定

weixin_28949937的博客 229

我也被Boolean.getBoolean()骗了

https://blog.youkuaiyun.com/vi_error/article/details/77334518

csl0l0的专栏 275

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

smali语法总结

我们知道android中java文件先被编译成由java字节码组成的class文件,最终会被编译打包成.dex文件,文件中是可以运行于dalvik虚拟机的字节码。这些字节码不具有可读性, 可以从这些字节码反编译得到的更具有可读性的smali文件。具体方式可以参阅开源项目smali,下面是一些smali的语法 类型标记,和jni中的表示是一样的| java中的类型 | smali中对应的表示 |

临江仙的技术文章 2717

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

smali指令设置空的静态方法采坑与解决

如果直接删除会导致如下错误.method public static a()V方法直接删除会导致如下错误a non-abstract method must have at least 1 instruction 修改为 .locals 2 .prologue .line 902 const/4 v0,0x1 return-void 如果只保留void,则提示A register...

情随事迁个人博客 1153

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

Android中X5WebView详解

今日科技快讯据路透社报道,推特(Twitter)公司周五宣布,它已经禁止总部位于莫斯科的卡巴斯基实验室在其社交平台上打广告,称这家网络安全公司的商业模式与其广告规则存在冲...

郭霖 1万+

webview屏蔽页面

遇到的问题: 1. webview load url 之后,看到有个中国移动的广告浮窗,乍一看挺可爱的,为什么会出来呢? 2. 点击进去看到这个html页面,点击设置 3. 令人气愤的是,这三个选项都不是我想要的啊 4. 令人无奈的只要通过流量浏览网页,就会出现这个弹窗,这个没人管吗?很不雅观啊 解决方式 1. 方法一:onLoadResource()//这个方式无效,...

shuijianbaozi的博客 2111

击溃360手机卫士的三大防护

360作为国内专业的安全公司,在安全界的水平是有目共睹的,我们抛开它在经营与病毒防治上的一些极端措施,就其产品技术性而言,是广大安全爱好者应该学习的。今天我与大家探讨下在Android平台上360手机卫士这款产品其本身的安全性,并将自己研究时的一点小成果拿出来与大家分享。Android手持设备的私密性注定了这是一个敏感话题,在开始本文前,我郑重声明:本文的宗旨是让大家看到Android平台的可能的

菲菲家的吴先森 2910

android广告拦截原理,WebView 广告拦截浅析

前言查豆瓣 使用的是 WebView 加载页面,在豆瓣的移动页面中存在两到三个的广告轮播图,比较影响阅读体验。所以开始着手看看怎么屏蔽掉广告。在 WebView 中有以下三个方法可以考虑:fun onPageFinished(view: WebView, url: String)fun shouldInterceptRequest(view: WebView, request: WebResour...

weixin_29027285的博客 1073

android webview 广告过滤,使用webView屏蔽广告(实操版)

本帖最后由 wushaominkk 于 2021-1-12 10:55 编辑快过年了,准备刷一波剧,发现以前写的【Android】利用爬虫将电影网站打包成一个APP(8.26更新)这个已经失效了,准备再搞一波.这次不写界面了太麻烦,直接用webView嵌套网页.嵌套进去发现广告贼特多,各种悬浮页面根本无法用.在浏览器上输入网址按F12调整手机模式1610417623(1).jpg (97.53 K...

weixin_32736961的博客 1612

smali语言程序流程控制语法

选择结构(if-else)smali条件跳转分支语法``` if-<条件> v0 v1,:cond_** // 如果v0<条件>v1成立,则跳转到:cond_**处的代码。 if-eq vA, vB, :cond_1f //如果vA等于vB则程序跳转到:cond_1f处的代码执,行。 ``` 条件有如下 条件关键字 意思 if-eq 如果等于 if-ne 如果不等于

Ceryool的博客 1万+
上一篇: 机毒霸去广告功能分析三:java代码(dex)注入
下一篇: Android网络防火墙实现初探
鲶鱼团队
博客等级 码龄14年 36粉丝 33原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值