您的位置:首页 > 编程语言 > C语言/C++

【VC++开发实战】迅雷晒密及批量查询流量程序

2013-10-09 12:04 561 查看
迅雷第一次登录是不需要验证码的,就很方便了。首先还是要解决登录的问题,也不是那么容易解决的,这个是在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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: