TUST的抓包之旅(2)----- 校园网套餐余量

这篇文章是对于上一篇文章TUST抓包之旅(1)的补充,上一篇文章我们实现了一键登录校园网,并做了快捷瓷片。那么这篇文章主要是介绍如何获取到校园网登录成功的相关信息。

1.闲聊

我把相关的功能整合到我开发的小天盒子里了,所以这系列文章也是记录对于小天盒子的新创意的解决方案,也是我在开发道路上的不断摸索,当然方案可能比较笨拙,但是毕竟是小白,所以也情有可原吧。

首先我们看我们的官方页面


校园网官方页面

可以看到这里有三个数据,使用时间,已使用流量和账户余额,那么我们可以试着把这个数据抓下来。

然后写在我们的APP上,如下,


小天盒子.png

2.抓包

下面就是抓包咯,我们分析一下登录流程。
打开Chrome开发者工具,还是访问我们http://59.67.0.245/a30.htm网页,点击登录之后我们的NetWork选项卡下显示如下

页面显示.png

就这样,我们可以看到返回了59.67.0.245这个网页,一个js,一个jpg,一个notice.htm,那他们都是代表什么意思呢?

第一个肯定是59.67.0.245这个地址,也就是当前你看到的这个页面的文件,其余的是他上面的内容或者他的调用,
我们打开第一个


59.67.0.245

,选择preview选项卡来查看他的源码,下面的分析流程就是找到他的html代码。
我们定位到html的body部分的内容

<table border="0" width="100%" cellspacing="1" cellpadding="0" class="font1">
    <tr>
        <td height="120" width="99%" align="center">
<span id="PageTips"><script language="javascript">DispTFM(0)</script><br>
<script language="javascript">DispTFM(1)</script><br>
<script language="javascript">DispTFM(2)</script><br>
<script language="javascript">DispTFM(3)</script></span>
        </td>
    </tr>
    <tr>
        <td height="60" width="99%">
        <p align="center">
        <input id="LogoutButton" type="button" onClick="javascript:wc()" name="logout" value="注 销 (Logout)" class="btn">
        </td>
    </tr>
</table>

这段代码也很好找,我们根据注销两个字来找就行,那这里其实是一个table,而且对比上面我们放的图片


校园网官方页面

这里的

<span id="PageTips"><script language="javascript">DispTFM(0)</script><br>
<script language="javascript">DispTFM(1)</script><br>
<script language="javascript">DispTFM(2)</script><br>
<script language="javascript">DispTFM(3)</script></span>

其实就是上面的3行文字,有同学可能就会说了,你这明明四行代码,其实最后一行是没执行,是一个外网映射地址,那么关键是我们要找到DispTFM这个函数。

Ctrl+F搜一下,或者直接凭眼力找一下,代码也不长,找到这么一段代码

function DispTFM(sele){
    switch(sele){
        case 0:
            document.write("已使用时间 Used time : "+time +" Min");
            break;
        case 1:
            document.write("已使用流量 Used flux : "+flow1/1024+flow3+flow0/1024+" MByte");
            break;
        case 2:
            if(fsele==1)document.write("余额 Balance : "+"RMB"+fee1/10000);
            break;
        case 3:
            if(xsele==1)document.write("外网映射地址 External network IP address mapping : "+xip);
            break;
    }
}

这样子就很明显了,所有的东西都在这里写着呢,那这些变量我们在上面的图片也发现过,这里所有的量和计算公式都有

time='7877      ';flow='5929650   ';fsele=1;fee='111000    ';xsele=0;xip='000.000.000.000.';
flow0=flow%1024;flow1=flow-flow0;flow0=flow0*1000;flow0=flow0-flow0%1024;fee1=fee-fee%100;
flow3='.';

OK,抓包搞定,到这里我们需要的数据都已经搞到了,那么我们可以在Android上面搞了。(当然我只是以我们学校的网页为例,其他学校大同小异,注意观察推断就好了)

3.APP开发

当然上面一篇文章的代码写的有些不尽人意,这一次我们把他修改一下,我们把检查网络并登录这个地方,让它返回表单,然后直接通过HttpUtil来post访问。

  HttpUtil.post(UrlData.net_post_url, CheckWifi_then_login_util.LoginNetWork(NetWorkActivity.this)).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        Toast.makeText(NetWorkActivity.this,R.string.fail,Toast.LENGTH_SHORT).show();
                        finish();
                    }
                });
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                final String s = response.body().string();
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        if(s.contains(FormData.Drcom_pc_Login_success)){
                            LoadInfo();
                        }else{         
                          Toast.makeText(NetWorkActivity.this,R.string.wrong,Toast.LENGTH_SHORT).show();
                        }
                    }
                });
            }
        });

登录成功(如何检测登录成功,就是判断网页中是否有登录成功的信息)之后开始加载信息

注意这里:我们要考虑Cookies的问题,当我们请求登陆之后产生cookies,然后系统使用cookies来验证你的身份,那么我们要给Okhttp配置CookieJar

首先定义CookieJar


public class JavaNetCookieJar implements CookieJar {
    private final List<Cookie> allCookies=new ArrayList<Cookie>();

    @Override
    public synchronized void saveFromResponse(HttpUrl url, List<Cookie> cookies) {
        allCookies.addAll(cookies);
        Log.d("cookies", "saveFromResponse: "+allCookies);
    }

    @Override
    public synchronized List<Cookie> loadForRequest(HttpUrl url) {
        List<Cookie> result = new ArrayList<Cookie>();
        for (Cookie cookie : allCookies) {
            if (cookie.matches(url)) {
                result.add(cookie);
            }
        }
        Log.d("cookies", "loadForRequest: "+result);
        return result;
    }
}

然后我们使用CookieJar
看一下我们HttpUtil里的post方法

 //post
    public static Call post(String url,FormBody formBody){
        OkHttpClient.Builder builder = new OkHttpClient.Builder().connectTimeout(5, TimeUnit.SECONDS);//设置连接超时时间;
        OkHttpClient okHttpClient = builder.cookieJar(new JavaNetCookieJar()).build();
        return okHttpClient.newCall(new Request.Builder().post(formBody).url(url).build());
    }

这里我们可以看到设置了cookiejar,这样系统就会给我们自动保存好cookie,下次访问就可以做身份验证了。

上面说到请求成功之后开始进行加载信息,我们来看一下加载信息的方法

 private void LoadInfo() {
       HttpUtil.get(UrlData.net_get_url).enqueue(new Callback() {
           @Override
           public void onFailure(Call call, IOException e) {
               runOnUiThread(new Runnable() {
                   @Override
                   public void run() {
                       Toast.makeText(NetWorkActivity.this, R.string.get_data_use_fail,Toast.LENGTH_SHORT).show();
                   }
               });
           }

           @Override
           public void onResponse(Call call, Response response) throws IOException {
               final String s = response.body().string();
               runOnUiThread(new Runnable() {
                   @Override
                   public void run() {
                       if(s.contains(FormData.Drcom_pc_get_success)){
                           //成功
                           Toast.makeText(NetWorkActivity.this,R.string.success,Toast.LENGTH_SHORT).show();
                           //解析展示
                           Jsoup_and_show(s);
                       }else{
                           //获取数据失败
                           Toast.makeText(NetWorkActivity.this,R.string.get_data_use_fail,Toast.LENGTH_SHORT).show();
                       }
                   }
               });
           }
       });
    }

同样也是一个请求,这次我们是一个get请求,请求的地址就是59.67.0.245,那么因为我们使用cookiejar来管理了cookie,所以我们直接在登录成功之后抓取成功页面数据,如果抓取成功,那么就开始进行 Jsoup_and_show(s)方法,使用jsoup进行解析和展示。

Jsoup这个东西是什么呢?
它是在java中解析html网页源码的很棒的工具,有了jsoup,我们可以很便捷的解析出请求网页的内容,那么这款工具也很有名气,想了解更多的童鞋不如去研究研究,那么在Android中使用包括这么几个步骤:

1.Gradle

配置依赖:

compile 'org.jsoup:jsoup:1.10.2'

2.开始使用

这里我直接演示了怎么搞到数据了,当然jsoup还有好多方法,童鞋们可以去体验一下。

 private void Jsoup_and_show(String s) {
         /*通过返回的值构建Document对象*/
        Document document = Jsoup.parse(s);
         /*取得script下面的JS变量
          在这个地方我解释一下:刚才我们得到的网页源码中有很多的JS部分,
         也就是<script>标签,那么我们的需要的也就是那几个定义的变量和他的值,
          参考上面的图,我们会发现它们在第二个script标签里,那么我们在这里取得第二个标签(下标为1)
        getElementsByTag方法就是通过标志取得信息的方法
        */
        Element e = document.getElementsByTag("script").get(1);
        /*
        取得成功的e就是一个script标签,那么里面的数据我做了一个字符串截取,把有用的部分拿下来了,
      然后使用一个getNumber方法来获取其中的数据
        */
        List<String> numbers = PatternUtil.getNumber(e.data().toString().substring(e.data().toString().indexOf("time"),e.data().toString().indexOf("xsele")));
        String time = numbers.get(0);
        String flow = numbers.get(1);
        String fee = numbers.get(3);

        //官方换算公式
        int flow0=Integer.parseInt(flow)%1024;
        int flow1=Integer.parseInt(flow)-flow0;
        flow0=flow0*1000;
        flow0=flow0-flow0%1024;
        int fee1=Integer.parseInt(fee)-Integer.parseInt(fee)%100;
        String flow3=".";
       //最后是展示
        String use_time = time;
        String use_data = flow1/1024+flow3+flow0/1024;
        String use_fee =  ""+fee1/10000;
    }

下面是一个getNumber()方法,主要是正则表达式

  /********************
     * 提取字符串里的数字,并且转换为List表返回
     * **********************/
    public static List<String> getNumber(String a){
        Pattern p = Pattern.compile("\\d+");
        Matcher m = p.matcher(a);
        List<String> list = new ArrayList<>();
        while (m.find()){
            list.add(m.group());
        }
        return list;
    }

这样我们就拿到基本的数据了,展示就不需要我多说了吧。

4.总结

这里主要是研究了抓包,和包解析,利用抓包我们可以做更多有意思的事情,很神奇吧。

不说了,刚刷机,去体验一下新系统。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容