zoukankan      html  css  js  c++  java
  • 【VC++开发实战】迅雷晒密及批量查询流量程序

    迅雷第一次登录是不需要验证码的,就很方便了。首先还是要解决登录的问题,也不是那么容易解决的,这个是在POST是提交的表单【u=joneeky%40qq.com&p=cf1e22e61d987c37c5c07facb1169b03&verifycode=%2153P&login_enable=0&login_hour=720】,要先分析这个表单“u=”后面是账号,邮箱格式和话要把“@”换为“%40”;“p=”后面是进过加密的密码,这就是关键;“verify=”后面是动态生成的验证码,这种验证码是不需要去输入的,提交的时候会自动完成;再后面的东西就是固定的了,不需要管。
        先分析一下“verify=”后面的数据是怎么来的。这种内部生成的验证码都是以“!”感叹号开头的,也就是里面的“%21”,后面3个则是大写字母和数字随机组合。每一次进入迅雷登录页面(http://i.xunlei.com/login.html)后,当你输入完账号光标离开输入账号的编辑框时,这个验证码就是已经设置好的,抓包看了一下,就是每一次输入完账号,会有一个这样的GET请求【/check?u=joneeky%40qq.com&cachetime=1337413954326】,“u=”后面是我的账号,“cachetime=”后面就是请求的时间,精确到毫秒,一看这种133开头的时间就是计算机被制造出来到现在所发生的时间,这种时间可以用 time 函数获取,它接受一个time_t指针类型的参数,其实就是long指针类型,这样就可以获取前面10位,后面3位是毫秒,可以用 GetLocalTime 函数得到。提交这个表单,成功后会返回Cookies,大致这样【check_result=0:!TPR】,验证码就在cookies里面,就是“!TPR”,我是用 CinternetSession::GetCookie 得到Cookies的。
        有了验证码和密码,就可以算出“p=”后面的了密钥。经过大量实验,发现密钥是一个这样的公式【p=MD5(MD5(MD5(密码))+验证码)】,就是密码两次MD5加密,然后结合验证码再MD5一次。至于MD5算法怎么样的,就自己找吧。
        提交一个登录请求后,成功了会返回很多行Cookies,如果里面有“nickname”这样的cookie就说明登录成功,否则是失败了。要用 CHttpFile::QueryInfo 来获取Cookies了,但是我发现MFC里封装的 CHttpFile::QueryInfo 函数有BUG,只能得到第一行Cookie, 这样就没有办法判断有没有登录成功了。原先我想过直接调用API函数 HttpQueryInfo ,但是发现CHttpFile::m_hFile 是protected成员,不能访问(微弱真贱)。然后在网上找到了 CHttpFile::QueryInfo 的代码,微软写的 HttpQueryInfo 最后一个参数永远是0,这样就只能得到索引位0的Cookie了,也就是第一行,我只要把这个参数改为函数传进去的index就行了,要改这个函数无非是重载它了,重载前要先继承一下 CHttpFile 类,代码就在最下面给出吧。
        登录成功后就可以获取流量了,在这个页面【http://dynamic.i.xunlei.com/user】,这个地方:

     

     我试过直接拿到这个页面的html源码是不可以的,因为数据是通过ajax显示出来的,必须要拿到ajax的数据,是一个这样的GET请求【/ajax?c=user&a=lixiangaosu&cachetime=1337416140406】,后面的时间上面说过了。返回的数据大致是这样的:

     

    “used_capacity”就是已使用的流量,一看就知道单位是字节(bit),转换成G的话要除以3次1024,最后精确到百分位。

    ---------------------完-------------------

    重载 CHttpFile::QueryInfo 数代码如下:

    class CMyHttpFile: public CHttpFile
    {
    public:
     BOOL QueryInfo(DWORD dwInfoLevel, CString &str, LPDWORD lpdwIndex) const
     {
      ASSERT(dwInfoLevel <= HTTP_QUERY_MAX);
      ASSERT_VALID(this);
      ASSERT(m_hFile != NULL);

      BOOL bRet;
      DWORD dwLen = 0;

      str.Empty();
      if(HttpQueryInfo(m_hFile, dwInfoLevel, NULL, &dwLen, lpdwIndex))
      {
       bRet = TRUE;
      }
      else 
      {
       LPTSTR pstr = str.GetBufferSetLength(dwLen);
       bRet = HttpQueryInfo(m_hFile, dwInfoLevel, pstr, &dwLen, lpdwIndex);
       if (bRet)
       {
        str.ReleaseBuffer(dwLen);
       }
       else
       {
        str.ReleaseBuffer(0);
       }
      }
      return bRet;
     }
    };

    ------------------------------

     这是我已经做好的程序,源码下载地址(VC6.0工程):http://dl.dbank.com/c0i0ydhsnj

    Keep it simple!
    作者:N3verL4nd
    知识共享,欢迎转载。
  • 相关阅读:
    富文本编辑器layedit,调用setContent方法会报错
    sqlserver2008事务日志已满
    解决asp.net上传文件时文件太大导致的错误
    完美版js金钱正则表达式校验
    jQuery实现清空table表格除首行外的所有数据
    textArea中的maxlength是无效的 解决办法
    jquery根据name属性查找
    fileupload页面跳转找不到原页面的解决方法
    xml获取属性值的方法
    读FCL源码系列之List<T>---让你知其所以然---内含疑问求大神指点
  • 原文地址:https://www.cnblogs.com/lgh1992314/p/5834895.html
Copyright © 2011-2022 走看看