android DNS检测

前段时间心血来潮,突然想研究一下dns检测是什么实现的,于是拿wifi管家开刀了,下面是分析结果: 

首先入口函数:

protected boolean arQ() {
        String v0_2;
        String v4_1;
        int v12 = 2;
        int v11 = 3;
        int v4 = ((int)(this.fNS / 2));
        int v5 = new n(ai.fNh).a("DnsLocalDetecter", PiSessionManagerUD.amB().kH());
        boolean v0 = v5 == 0 ? true : false;
        boolean v3 = this.mCurrentSessionItem == null || this.mCurrentSessionItem.fOA == 4098 || this.mCurrentSessionItem.fOA == 4100 ? false : true;
        if((v0) && (v3)) {
            String v5_1 = "http://tools.3g.qq.com/wifi/ssl";
            String v6 = "baidu.com";
            String v3_1 = "http://m.taobao.com";
            String v7 = "https://m.taobao.com";
            a v8 = this.av(v5_1, v4);
            a v9 = this.av(v3_1, v4);
            try {
                v4_1 = URLEncoder.encode(v5_1, "UTF-8");
                v0_2 = URLEncoder.encode(v3_1, "UTF-8");
            }
            catch(Exception v0_1) {
                v0_2 = v3_1;
                v4_1 = v5_1;
            }
 
            if((TextUtils.isEmpty(((CharSequence)v4_1))) || (TextUtils.isEmpty(v4_1.toLowerCase()))) {
                v4_1 = v5_1;
            }
 
            if((TextUtils.isEmpty(((CharSequence)v0_2))) || (TextUtils.isEmpty(v0_2.toLowerCase()))) {
                v0_2 = v3_1;
            }
 
            if(!v8.fNY && !TextUtils.isEmpty(v8.bVW) && ((v8.bVW.toLowerCase().contains(v4_1.toLowerCase())) || (v8.bVW.toLowerCase().contains(((CharSequence)v5_1))))) {
                this.fNV = "Redirect baidu RedirectUrl = " + v8.bVW + ", taobao RedirectUrl = " + v9.bVW;
                this.bc(v12, 0);
                return 1;
            }
 
            if(!v8.fNY && !TextUtils.isEmpty(v8.bVW) && !v8.bVW.toLowerCase().contains(((CharSequence)v6))) {
                this.fNV = "baidu: " + v8.bVW;
                this.bc(v11, v11);
                return 1;
            }
 
            if(!v9.fNY && !TextUtils.isEmpty(v9.bVW) && ((v9.bVW.toLowerCase().contains(v0_2.toLowerCase())) || (v9.bVW.toLowerCase().contains(((CharSequence)v3_1))))) {
                this.fNV = "Redirect baidu RedirectUrl = " + v8.bVW + ", taobao RedirectUrl = " + v9.bVW;
                this.bc(v12, 0);
                return 1;
            }
 
            if(!v9.fNY && !TextUtils.isEmpty(v9.bVW) && !v9.bVW.toLowerCase().startsWith(v3_1) && !v9.bVW.toLowerCase().startsWith(v7)) {
                this.fNV = "taobao: " + v9.bVW;
                this.bc(v11, v11);
                return 1;
            }
 
            if(!v8.fNY && !v9.fNY && !TextUtils.isEmpty(v8.bVW) && !TextUtils.isEmpty(v9.bVW) && (TextUtils.equals(v8.bVW.toLowerCase(), v9.bVW.toLowerCase()))) {
                this.fNV = "baidu and taobao has the same redirectUrl, url = " + v9.bVW;
                this.bc(v11, v11);
                return 1;
            }
 
            this.fNV = "safe";
            this.bc(v12, 0);
        }
        else {
            this.fNV = "isNetAvalible = " + v0 + ", isConnected = " + v3 + ", retCode = " + v5;
            this.bc(v12, 0);
        }
 
        return 1;
}

可以大概看到主要拿了两个网址作为检测的依据,第一个是http://tools.3g.qq.com/wifi/ssl,这个网址是腾讯自己的,会返回301响应,而且会重定向到baidu.com,另一个是https://m.taobao.com,这个会返回200的响应,然后就拿这两个Url分别进行请求,主要函数是this.av,下面看一下这个函数:

 private a av(String arg7, int arg8) {
        HttpURLConnection v2_4;
        HttpURLConnection v3;
        String v1 = null;
        a v0 = new a(this);
        v0.fNX = arg7;
        v0.bVW = v1;
        InputStream v2 = null;
        try {
            v3 = this.aw(arg7, arg8);
            if(v3 != null) {
                goto label_15;
            }
        }
        catch(Throwable v0_1) {
            v2 = ((InputStream)v1);
            v3 = ((HttpURLConnection)v1);
            goto label_85;
        }
        catch(Exception v2_1) {
            v2 = ((InputStream)v1);
            v3 = ((HttpURLConnection)v1);
            goto label_74;
        }
        catch(IOException v2_2) {
            v2 = ((InputStream)v1);
            v3 = ((HttpURLConnection)v1);
            goto label_62;
        }
        catch(SocketTimeoutException v2_3) {
            v2_4 = ((HttpURLConnection)v1);
            goto label_50;
        }
 
        try {
            v0.fNY = true;
            if(0 != 0) {
                goto label_11;
            }
 
            goto label_12;
        }
        catch(Exception v2_1) {
            goto label_102;
        }
        catch(IOException v2_2) {
            goto label_107;
        }
        catch(SocketTimeoutException v2_3) {
            goto label_115;
        }
        catch(Throwable v0_1) {
            goto label_93;
        }
 
        try {
        label_11:
            v2.close();
        label_12:
            if(v3 == null) {
                return v0;
            }
 
            v3.disconnect();
        }
        catch(IOException v1_1) {
        }
 
        return v0;
        try {
        label_15:
            int v4 = v3.getResponseCode();
            v2 = v3.getInputStream();
            if(v4 != 200) {
                goto label_27;
            }
        }
        catch(Throwable v0_1) {
        label_93:
            v2 = ((InputStream)v1);
            goto label_85;
        }
        catch(Exception v2_1) {
        label_102:
            v2 = ((InputStream)v1);
            goto label_74;
        }
        catch(IOException v2_2) {
        label_107:
            v2 = ((InputStream)v1);
            goto label_62;
        }
        catch(SocketTimeoutException v2_3) {
        label_115:
            v2_4 = v3;
            goto label_50;
        }
 
        try {
            v0.bVW = arg7;
            if(v2 != null) {
                goto label_21;
            }
 
            goto label_22;
        }
        catch(Exception v1_2) {
            goto label_105;
        }
        catch(IOException v1_1) {
            goto label_110;
        }
        catch(SocketTimeoutException v1_3) {
            goto label_47;
        }
        catch(Throwable v0_1) {
            goto label_96;
        }
 
        try {
        label_21:
            v2.close();
        label_22:
            if(v3 == null) {
                return v0;
            }
 
            v3.disconnect();
        }
        catch(IOException v1_1) {
        }
 
        return v0;
    label_27:
        if(v4 == 301 || v4 == 302) {
            if(v2 != null) {
                int v1_4 = -1;
                try {
                    v1 = n.a(v2, v1_4);
                label_34:
                    v0.bVW = this.a(v3, arg7, v1);
                    goto label_36;
                }
...
 
private HttpURLConnection aw(String arg4, int arg5) {
        HttpURLConnection v0_2;
        int v1_2;
        URLConnection v0_1;
        HttpURLConnection v1 = null;
        try {
            v0_1 = new URL(arg4).openConnection();
        }
        catch(Exception v0) {
            goto label_26;
        }
 
        try {
            v1_2 = uc.KF();
            goto label_5;
        }
        catch(Exception v1_1) {
        }
        catch(Exception v0) {
        label_26:
            v0_2 = ((HttpURLConnection)v1_2);
            return v0_2;
            try {
            label_5:
                if(v1_2 < 8) {
                    System.setProperty("http.keepAlive", "false");
                }
 
                ((HttpURLConnection)v0_1).setUseCaches(false);
                ((HttpURLConnection)v0_1).setRequestProperty("Pragma", "no-cache");
                ((HttpURLConnection)v0_1).setRequestProperty("Cache-Control", "no-cache");
                ((HttpURLConnection)v0_1).setInstanceFollowRedirects(false);
                ((HttpURLConnection)v0_1).setRequestMethod("GET");
                ((HttpURLConnection)v0_1).setReadTimeout(arg5);
                ((HttpURLConnection)v0_1).setConnectTimeout(arg5);
            }
            catch(Exception v1_1) {
            }
        }
 
        return v0_2;
    }

通过上面可以看到,主要是发送一个http请求,然后根据返回码进行处理,如果是200,那么bVW就是当前的urlbVWredirec url,后面会根据这个判断,很重要),如果是301302,那么说明发生了重定向,这种情况下就要获取重定向的url,有下面三种情况:

1. 如果responseheader里面有Location这个字段,那么重定向url就是它里面的内容

2. 如果responseheader里面有Refresh这个字段,那么重定向url就是它里面的部分内容

3. 如果responseurl为空,那么查找body里面是否有location.href这个字段,有的话重定向url就是它指向的内容

具体代码如下:

private String a(HttpURLConnection arg5, String arg6, String arg7) {
        String v1_3;
        String v0 = "";
        try {
            if(TextUtils.isEmpty(((CharSequence)v0))) {
                v0 = arg5.getHeaderField("Location");
            }

            if(!TextUtils.isEmpty(((CharSequence)v0))) {
                goto label_18;
            }

            try {
                String[] v1_2 = arg5.getHeaderField("Refresh").split(";");
                if(v1_2 == null) {
                    goto label_18;
                }

                if(v1_2.length != 2) {
                    goto label_18;
                }

                v0 = v1_2[1].trim();
                goto label_18;
            }
            catch(Exception v1_1) {
                try {
                    v1_1.printStackTrace();
                label_18:
                    if(TextUtils.isEmpty(((CharSequence)v0))) {
                        String v2 = arg6 != null ? new URL(arg6).getHost() : "";
                        v1_3 = arg5.getURL() != null ? arg5.getURL().getHost() : "";
                        if(!TextUtils.isEmpty(((CharSequence)v0))) {
                            goto label_58;
                        }

                        if(v2.compareTo(v1_3) == 0) {
                            goto label_58;
                        }

                        v0 = arg5.getURL().toExternalForm();
                        v1_3 = v0;
                        goto label_36;
                        return v0;
                    }
                    else {
                    }
                }
                catch(Throwable v1) {
                    return v0;
                }
            }
        }
        catch(Throwable v1) {
            return v0;
        }

    label_58:
        v1_3 = v0;
        try {
        label_36:
            if((TextUtils.isEmpty(((CharSequence)v1_3))) && !TextUtils.isEmpty(((CharSequence)arg7))) {
                v0 = n.pN(arg7);
                if(v0 == null) {
                    return v1_3;
                }

                return v0;
            }
        }
        catch(Throwable v0_1) {
            return v1_3;
        }

        return v1_3;
}

public static String pN(String arg3) {
        int v2;
        String v0 = "";
        if(v0 != null) {
            int v1 = arg3.indexOf("location.href=\"");
            if(v1 > 0) {
                v1 += "location.href=\"".length();
                v2 = arg3.indexOf("\"", v1);
                if(v2 > v1 && v2 > 0) {
                    v0 = arg3.substring(v1, v2);
                    if(v0 != null && !v0.trim().toLowerCase().startsWith("http")) {
                        v0 = "";
                    }
                }
            }

            if(!TextUtils.isEmpty(((CharSequence)v0))) {
                return v0;
            }

            v1 = arg3.indexOf("location.href=\'");
            if(v1 <= 0) {
                return v0;
            }

            v1 += "location.href=\'".length();
            v2 = arg3.indexOf("\'", v1);
            if(v2 <= v1) {
                return v0;
            }

            if(v2 <= 0) {
                return v0;
            }

            v0 = arg3.substring(v1, v2);
            if(v0 == null) {
                return v0;
            }

            if(v0.trim().toLowerCase().startsWith("http")) {
                return v0;
            }

            v0 = "";
        }

        return v0;
    }

获取到重定向的url,接下来返回入口函数,对这个重定向url进行处理,下面是处理代码:

           if((TextUtils.isEmpty(((CharSequence)v4_1))) || (TextUtils.isEmpty(v4_1.toLowerCase()))) {
                v4_1 = v5_1;
            }
 
            if((TextUtils.isEmpty(((CharSequence)v0_2))) || (TextUtils.isEmpty(v0_2.toLowerCase()))) {
                v0_2 = v3_1;
            }
 
            if(!v8.fNY && !TextUtils.isEmpty(v8.bVW) && ((v8.bVW.toLowerCase().contains(v4_1.toLowerCase())) || (v8.bVW.toLowerCase().contains(((CharSequence)v5_1))))) {
                this.fNV = "Redirect baidu RedirectUrl = " + v8.bVW + ", taobao RedirectUrl = " + v9.bVW;
                this.bc(v12, 0);
                return 1;
            }
 
            if(!v8.fNY && !TextUtils.isEmpty(v8.bVW) && !v8.bVW.toLowerCase().contains(((CharSequence)v6))) {
                this.fNV = "baidu: " + v8.bVW;
                this.bc(v11, v11);
                return 1;
            }
 
            if(!v9.fNY && !TextUtils.isEmpty(v9.bVW) && ((v9.bVW.toLowerCase().contains(v0_2.toLowerCase())) || (v9.bVW.toLowerCase().contains(((CharSequence)v3_1))))) {
                this.fNV = "Redirect baidu RedirectUrl = " + v8.bVW + ", taobao RedirectUrl = " + v9.bVW;
                this.bc(v12, 0);
                return 1;
            }
 
            if(!v9.fNY && !TextUtils.isEmpty(v9.bVW) && !v9.bVW.toLowerCase().startsWith(v3_1) && !v9.bVW.toLowerCase().startsWith(v7)) {
                this.fNV = "taobao: " + v9.bVW;
                this.bc(v11, v11);
                return 1;
            }
 
            if(!v8.fNY && !v9.fNY && !TextUtils.isEmpty(v8.bVW) && !TextUtils.isEmpty(v9.bVW) && (TextUtils.equals(v8.bVW.toLowerCase(), v9.bVW.toLowerCase()))) {
                this.fNV = "baidu and taobao has the same redirectUrl, url = " + v9.bVW;
                this.bc(v11, v11);
                return 1;
            }

首先解释一下相关变量的意义,fNY是一个boolean值,代表的是响应是否是301302这两个里面的一个,如果不是,那就是没有重定向,默认是safe.然后是bVW这个变量,这个就是之前获取到的重定向的url,最后是v11v12这两个变量代表检测结果,v11代表有危险,v12代表安全,所以看到返回v11的就是不安全的几种情况,比如http://tools.3g.qq.com/wifi/ssl本来应该重定向到baidu.com,如果重定向结果不是这个说明dns遭到篡改了,还有就是淘宝的那个url本来不应该重定向的,如果发生了重定向也说明dns有问题,列出了所有情况,检测就结束了

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值