android DNS检测

来源:互联网 发布:照片字体识别软件 编辑:程序博客网 时间:2024/06/03 12:42

前段时间心血来潮,突然想研究一下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有问题,列出了所有情况,检测就结束了

 

 

原创粉丝点击