你的位置: 阿强工作间 -> 软件开发日记 -> 阿强农场助手开发过程

推荐开发日记

站内搜索

人气排行
 
阿强农场助手开发过程

作 者:阿强 日 期:2009-11-15 0:50:56 
 

【2009.6.26】
    一段时间前,猫猫鱼介绍我玩我校内网的开心农场,叫我去校内网注册了一个帐号,可是,我注册了老是收不到激活邮件,喜欢的用户名都被试光了。后来猫猫鱼替我注册了一个帐号,但我并不是很喜欢那个带着数字的ID,校内网需要登录也麻烦。后来某天登了一下那个黄钻号,看一下黄钻有几级,偶的发现QQ空间也有农场,但目前只有黄钻或被黄钻邀请才能开通。我赶忙把QQ农场应用添加起,又邀请猫猫鱼和我的另一个号开通了农场。才开始开通的时候觉得等级涨得很快,在那个新手任务的提示下,一会儿就涨到了3级了,但是,过后就涨起就非慢非慢了,除一窝草才涨两点经验,栽一窝庄稼等10多个小时收获了才得十多点经验,而升一级要n * 200点经验。一天每块地都转遍了,手都点痛了,浪费好多时间,都还不见升级。想了一下,反正是要浪费时间,还不如花几天时间写一个辅助软件来自动照看农场,一劳永逸。 

    写这个软件,第一要解决的问题就是登录问题。QQ的每一栏目,都是要验证码才能登录的,暂时不花时间去研究咋个识别QQ验证码,直接把它DOWN下载原样显示。然后就是模拟登录提交的表单问题了。提交的表单中,包含QQ号、加密后的QQ密码、验证码和一些附加的表单变化。QQ密码的加密算法也整了我好一阵子。大略看了一下QQ登录的JS,发现QQ密码加密是用的这样的一个函数: 
function preprocess(A){ 
    var B=""; 
    B+=A.verifycode.value; 
    B=B.toUpperCase(); 
    A.p.value=md5(md5_3(A.p.value)+B); 
    return true 
} 
其中A是表单对象,verifycode是验证码文本框对象,p是QQ密码框对象,初看这个函数,意思是就将QQ密码进行三次MD5加密,然后与大写后的验证码连接,再进行一次MD5加密,从而得到加密后的密码。我用抓包工具抓取了我一次登录的加密后的密码和验证码值,在一个MD5加密/解密的网站上将原始密码和验证码代入上面函数中的式子,但运算得到的结果却与抓包得到加密结果大相径廷。我看了一下MD5的代码,很烦锁,找不出问题出在哪儿。我一时有点茫然,不过突然想起一个妙招。管得它是用的什么加密算法,代码在那儿摆起,我何不直接使用它的代码来加密呢?我试了,直接在JS里调用它的md5()和md5_3()函数能够得到相同的结果。不过下面又有一个问题,如果让我的EXE应用程序与JS脚本通讯呢?我想起了Windows宿主脚本,以前我不会Win32编程的时候,就爱用VBS调用系统里的一些COM来干是一些控制系统的事情。我试了一下它对JS的支持情况,嘿嘿,支持得很好。不过wscript.exe是标准的Win32应用程序,要和它交互,只有通过它的WScript.Echo()弹出一个对话框来显示结果,这对于EXE应用程序还是不好处理。我又发现了一个与它有相同功能但是控制台的应用程序cscript.exe,调用WScript.Echo(),它便输出到控制台。这样,可以比较方便的在应用程序中通过命令行向它传递包含原始密码和验证码的参数,由它加密后输出到控制台,再从控制台输出的字符串中提取出加密结果。我们可以这样来实现一个JS,假设它的文件名是QQPwdEncode.js,我们首先将QQ密码加密用的JS中的md5()和md5_3()相关的代码通通复制过来,然后在最后加上如下代码: 
if (WScript.Arguments.Count() > 1) { 
var result = md5(md5_3(WScript.Arguments(0)) + WScript.Arguments(1).toUpperCase()); 
WScript.Echo(result); 
} 
将其保存,该JS的用法如下: 
在命令行中输入: cscript /Nologo QQPwdEncode.js [密码] [验证码] 
这样,它将输出加密后的QQ密码。 (后来发现,有的XP的Windows宿主脚本并不支持JS;同时也发现,那个md5_3()是对二进制数据进行3次MD5加密,而外面那个md5()是对文本进行加密的,于是我改写一个C++的MD5类实现了该算法) 
    密码加密搞定了,然后就是如何模拟登录提供的表单数据的问题了。我在网上搜了好多关于QQ网页登录文章,但没有一个实验成功了的。我用抓包工具对照了提交的数据与程序代码的期望,它们都是一致的。于是,我抓取了自己登录QQ农场整个过程的socket数据,又在应用程序中模拟了这过程中HTTP-REFERER和提交的所有数据(当然Cookies是自动添加的),但登录验证页面依旧返回提交的数据不正确。我实在找不出问题出在哪儿了,进行了最后的一赌,除了验证码和加密密码替换外,包中的其它数据完全重现,包括浏览器类型伪造为遨游,各个HEADER变量顺序完全相同,然后再提交到登录验证页,皇天不负有心人,终于返回成功了! 
    实现了登录,这个辅助软件的实现也就看到了希望。通过登录后,可以非常容易地读取自家的农场信息、好友列表、好友农场信息……我原以为实现了登录后面的事都水到渠成了。但事实却并不是想像中完美,另一个更大的难关出现的。要对农场进行操作,比如收获、除草之类,必需提交一组farmTime和farmKey,实验表明,farmTime与farmKey之前存在对应关系,farmKey由farmTime加密而来。在网上搜了关于farmKey的算法,有部分人研究过,却没有一个人解出来了的。通过反编译QQ农场的flash文件happyfarm.swf,可以从中找到farmKey的得来的相关代码,关于farmTime与farmKey的关系的探讨见http://dlsohocom.kpengidc.cn/viewthread.php?tid=27&extra=&page=1。实验现象是farmTime与farmKey是对应的,使用抓取的farmTime和farmKey可以通过验证,且有效期为1个小时。而跟踪反编译的flash代码最终却被带到一个从JPG图片随机取点的函数里去了。JPG图片上随机取的点与以秒为单位的时间有什么对应关系?显然,这是用来迷惑我们的。但farmTime和farmKey到底是什么关系呢,看了大半天的AS代码,都没找出来,我拿给老五去研究了,自今都还没给我结果。在百思不解,我突然又想起,既然QQ登录的加密算法我可以不去考虑,直接调用它的JS中的函数,那么flash中的函数是否可以被应用程序调用呢?搜索有关资料,flash可以提供外部接口给JS调用其中的函数,但只有提供了这样的接口的函数才能被调用。TX才没那么傻给你提供加密函数的外部接口。我对继续做这个辅助软件都快绝望了,我大睡了一觉后,又想起一个妙招,不去考虑farmKey是怎么算出来的,也不去考虑怎么去调用它的加密函数,直接截这个flash发的包。farmKey不是有一个小时有效期吗?截获一个farmKey不就够我的辅助软件用一个小时了吗?这个flash不是向服务器提交数据提交farmKey的吗?我在一个IE控件中登录农场,再访问这个happyfarm.swf这个flash,它一向服务器提交数据我就给它捕获,从捕获的包里提取出farmTime和farmKey不就行了?实时证明该方法是正确的。每隔半个小时我使用这样的方法捕获一次farmTime和farmKey,farmKey不就能让我持续用下去了吗? 
    难关均已解决,QQ农场辅助软件得以实现,《阿强QQ农场助手》终于出世。首版阿强农场助手于2009.6.26完成。 

阿强农场助手 测试版 [2009.6.26] 功能简介
==================================================
* 自动播种、收获、翻土
* 自动卖果、买种
* 自动除草、杀虫、浇水、偷果
* 收获时间预测,即使农场状态查询周期设置很长也可以按时收获
* 支持密码加密保存,方便下次登录;支持登录多个号
* 除草、杀虫、浇水三项获得经验记录,当达到300点,停止这三项活动,降低被TX发现而降级风险
* 自家和好友农场状态查询周期设置,设置适当可防止被TX发现而降级

【后记】
   
阿强农场助手最终版本为1.13(2009.11.14),网友们更喜爱超强农场助手而停止更新此作品。
    阿强餐厅助手是一款独立的餐厅辅助软件,该作品首版(0.90测试版)完成于2011.9.17
    超强农场助手是在阿强农场助手的基础上增加更丰富、灵活的配置选项,从而有更好的使用体验,超强农场助手首版(1.00试用版)于2009.9.24完成,在首版的基础上增加更精确的计时和农场状态保存,升级为评估版(2.00)。后来,随牧场的推出,超强农场助手加入了牧场辅助功能,超强农场助手更名为超强农牧助手(3.00)。超强农牧助手后来整合餐厅助手后更名为超强农牧餐助手(4.00),此作品最终版本为4.12。
    由于职业规划原因,以上软件作品均不再更新。

    
  


 网友评论 
 
昵称:验证码:
  对本文章看法: 好    不好