• 替换Srun3000解决掉网问题


      上次写了篇使用WebBorwser封装网页的博客,收到了不少宝贵意见,后来又懒得去改进,所以也没有新的文章。最近,由于学校宿舍也装校园网了,不再是用Dr.Com,我满怀心喜地试用了Srun3000,结果发现会出现连接上就一两秒掉网现象,并且提示说我的网络出现问题,与服务器连接断开,怒了!我试过各种办法,当然不包括换系统(我用的Win7),还是不行,网卡驱动也都是正常的。于是我试着用Fiddler抓了次HTTP包,发现了问题所在。

      原来,srun3000会在发送了连接的包后,又自动发了个注销的包,所以导致我网络中断,并且它在提示错误后就马上自动退出了,导致我产生了程序产生致命错误的假象……好吧,先上个图,看下srun3000的“罪证”:

      先后发的两条数据,第一条便是登录,第二条便是注销(为什么会自动注销,我用ollydbg跟进看了一会,由于汇编太难看了,而且我又比较懒,所以没分析出来),这导致了我网络的中断。为了验证我的想法,我使用Fiddler手动把登录的包重发了一次,果然能正常上网了,而且到第二天都没有掉过。所以大家可以看到我这篇文章,同样使用客户端的方式,基于HTTP协议来开发一个代替Srun3000的软件。

      1、功能:连接、注销、程序开机启动、自动登录、记住密码、连接后自动最小化

      2、界面:WPF窗口、通知栏图标、软件功能设置、异步连接断开

      3、效果:

      4、基本原理:

      从抓到的数据来看,连接和断开都使用的是POST,只需要根据它的格式依照Post数据过去就可以实现连接和断开。

      连接:

    POST http://172.30.16.53/cgi-bin/srun_portal HTTP/1.1
    Content-Type: application/x-www-form-urlencoded
    User-Agent: my session
    Host: 172.30.16.53
    Content-Length: 138
    Pragma: no-cache
    
    action=login&username=******&password=******&drop=0&type=2&n=23&ip=0&mbytes=0&minutes=0&ac_id=3&mac=**:**:**:**:**:**&nas_ip=172.30.12.244

      断开:

    POST http://172.30.16.53/cgi-bin/srun_portal HTTP/1.1
    Content-Type: application/x-www-form-urlencoded
    User-Agent: my session
    Host: 172.30.16.53
    Content-Length: 87
    Pragma: no-cache
    
    action=logout&ac_id=3&username=******&mac=**:**:**:**:**:**&type=2&nas_ip=172.30.12.244

      为了安全起见,我把上面的username、password、mac三个字段的值都用“*”号代替了。

      5、核心代码

      现在我在C#客户端只需要分别使用HttpWebRequest仿照进行请求就行了,我贴上连接的核心代码:

    连接核心代码
     1         private Func<string> ConnectDelegate = Connect;       // 连接委托
     2         // 连接执行函数
     3         private string Connect()
     4         {
     5             try
     6             {
     7                 var settings = Properties.Settings.Default;
     8                 Uri uri = new Uri("http://" + settings.GateIP + settings.RelativeUri);
     9                 // 新建请求
    10                 var request = HttpWebRequest.Create(uri);
    11                 request.Method = "POST";
    12                 request.ContentType = "application/x-www-form-urlencoded";
    13                 // 请求体
    14                 var body = Encoding.ASCII.GetBytes(
    15                     "action=login&username=" + UserName +
    16                     "&password=" + Password +
    17                     "&drop=0&type=2&n=23&ip=0&mbytes=0&minutes=0&ac_id=3&mac=" + _MacAddress +
    18                     "&nas_ip=" + settings.NasIP
    19                     );
    20                 request.ContentLength = body.Length;
    21                 request.Timeout = 5000;
    22                 var requestStream = request.GetRequestStream();
    23                 requestStream.Write(body, 0, body.Length);
    24                 requestStream.Close();
    25                 // 发送请求并接收结果
    26                 string responseBody;
    27                 var response = request.GetResponse();
    28                 var responseStream = response.GetResponseStream();
    29                 using (StreamReader reader = new StreamReader(responseStream))
    30                     responseBody = reader.ReadToEnd();
    31                 if (responseBody.Contains("login_ok"))
    32                 {
    33                     _State = ConnectionState.Connected;
    34                     return "连接成功!";
    35                 }
    36                 else if (responseBody.Contains("online_num_error"))
    37                 {
    38                     //var ping = new System.Net.NetworkInformation.Ping();
    39                     //ping.Send("www.baidu.com");
    40                     _State = ConnectionState.Connected;
    41                     return "已经连接上,请不要重复登录!";
    42                 }
    43                 else if (responseBody.Contains("username_error"))
    44                     return "帐号错误,请重新输入!";
    45                 else if (responseBody.Contains("password_error"))
    46                     return "密码错误,请重新输入!";
    47                 else
    48                     return "连接失败:" + responseBody;
    49             }
    50             catch (HttpListenerException ex)
    51             {
    52                 return "HTTP请求出错,请检查网络是否正常!错误代码:" + ex.ErrorCode;                
    53             }
    54             catch (Exception ex)
    55             {
    56                 return "连接失败!错误详情:" + ex.Message;
    57             }
    58         }    

       基本情况就是通过POST请求获取返回体,然后根据返回体的内容判断连接状态,这些返回数据牲也是使用Fiddler抓取的,比如“login_ok”、“online_num_error”、“username_error”、“password_error”、“logout_ok”等。当然这仅仅只是数据通信的部分,还有其它与界面相关的处理就不多说了,另外断开操作与连接操作也非常相似,也就不贴了。经过我的观察,由于Srun3000并没有在线检测机制,它只是通知认证网关把相应的MAC地址放行,而且认证服务器也不管回收离线地址(需要Srun3000自己去POST logout请求),所以我也不用去ping了,也不用写心跳包了,so easy。

      接下来,我顺便贴上修改注册表使程序开机启动的代码:

    开机启动
     1         private void AutoStartupChanged()
     2         {
     3             RegistryKey HKLM = Registry.LocalMachine;
     4             // 确认当前状态
     5             string name = AppDomain.CurrentDomain.FriendlyName;
     6             name = name.Substring(0, name.LastIndexOf('.'));
     7             var run =  HKLM.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Run");
     8             bool hasValue = run.GetValue(name) != null;
     9             try
    10             {
    11                 if (!hasValue && AutoStartup)                  // 添加启动
    12                 {
    13                     run = HKLM.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Run", true);
    14                     run.SetValue(name, AppDomain.CurrentDomain.BaseDirectory + name + ".exe");
    15                 }
    16                 else if (hasValue && !AutoStartup)             // 删除启动
    17                 {
    18                     run = HKLM.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Run", true);
    19                     run.DeleteValue(name);
    20                 }
    21             }
    22             catch (System.Exception ex)
    23             {
    24                 Message = "操作失败:" + ex.Message;
    25             }
    26         }

       主要也就是使用了SOFTWARE\Microsoft\Windows\CurrentVersion\Run下面的项来增加删除开机启动,这里不采用Windows服务来写的原因是,我想让这个软件成为“绿色”可携带的版本。

      其它也就不多说了,此软件目前为止用了一个星期,效果不错,没掉过线也。

    转载请注明原址:http://www.cnblogs.com/lekko/archive/2013/01/02/2841840.html

  • 相关阅读:
    反弹连接的shellcode
    md5反查网站
    一种新的Heap区溢出技术分析
    ckeditor漏洞
    Fedora Core 4下的一些小问题
    MYCCL特征码定位器详细使用之内存定位
    dedecms5.7最新注入和上传漏洞
    脱壳方法汇总
    一种小堆(heap)溢出的另类利用方法
    对付非法操作! 系统做了如下记录!
  • 原文地址:https://www.cnblogs.com/lekko/p/2841840.html
Copyright © 2020-2023  润新知