有时一些直觉仍然非常有用。也许人们的直觉经过长时间的学习,有能力用现有的信息推断出结论,但你没有意识到你是如何推断出来的。是内隐记忆。
作者:小宗
这篇文章似乎是带着悲伤的心情写的。这几天没有什么特别的事情发生,但不知道为什么心里有一丝丝的难过。
上次提到自己修改hdget参数的问题,在firefox网络分析的地方重新发送请求,后来发现这次重新发送是没有cookies的(据说是为了安全,我可以做饼干吗?骗子不会被这么点小麻烦难住的),导致服务器不向我返回数据。. . 哎呀。. .
其实我一直不知道小米的getmode请求是做什么的,但是我知道mode应该和模数有关,但是模数是什么?拿模型有什么用?18号抓小米的时候突然发现验证码全是数字,那么验证码是不是某个数字取模返回值的结果?18日getmode请求的返回结果为:
getmode({"mod":2675})
18号,我的验证码是2080,所以模数的最后一位应该是0或者5。我首先想到的是时间戳,但是我的浏览器发送的所有时间戳都不是以0开头的。或者5最后(是我的运气),然后突然想到还有一个数字是小米的ID(谁让你把它放在这么明显的位置^_^),结果计算显示验证码确实是是小米的ID模2675,出错的概率是万分之一,所以我去看看验证码相关的功能
好了,现在来看看小米的代码getmode函数和调用的函数。
function getmode(json) { if (json.mod !== 0) { Util.countFk(json.mod); //json.mod就是返回的2675 if (window.getmodeTimer) { clearInterval(window.getmodeTimer) }; if (window.getmodeTimeout) { clearTimeout(window.getmodeTimeout) } }};//countFk函数,Util的方法countFk: function (mod) { if (!mod || mod === 0) { return false }; var uid = m.cookie(CONFIG.cookies.userid), //uid就是小米ID num = (uid % mod) .toString() .substr( - 4, 4);//取模哦 switch (num.length) { case 1: CONFIG.fkNum = _$[261] + num; //_$[261]=='000' this.formatFk(); break; case 2: CONFIG.fkNum = _$[262] + num; //_$[262]=='00' this.formatFk(); break; case 3: CONFIG.fkNum = _$[263] + num; //_$[263]=='0' this.formatFk(); break; case 4: CONFIG.fkNum = num; this.formatFk(); break } //就是把验证码放在了fkNum中 },
还有一个checkFk函数红米抢购页面代码,玩儿你没商量,对输入的验证码进行校验。基本内容是检查输入的验证码是否与fkNum相同。我知道大家都不喜欢看代码,所以就不贴了。
如前所述,抢购开始后,会发送几个请求,hdinfo、getmode和hdget。前两个已经介绍过了。我们来看看hdget请求返回的数据。
hdcontrol( {"stime":1395115250, //服务器时间"d22a51":5, //自动发hdget请求的时间(秒),不知道为什么取了这么一个名字"login":true, //是否登录了"pmstart":false,"status":{"miphone":{ //手机的抢购状态"hdstart":true, //抢购是否开始"hdstop":false, //抢购是否结束"hdurl":"", //抢购成功后自动跳转的URL"duration":null,//未知,想知道的自己去看小米源码,反正我不想看"reg":true}, //未知 //下面个miphone类似"mitv":{"hdstart":true,"hdstop":false,"hdurl":"","duration":null,"reg":true} }})
看一下hdcontrol的关键代码。
function hdcontrol(json) { //……………………………… var jsonStr = json.status,phoneUrl, powerUrl, tvUrl, //…………………………………… if (CONFIG.onSale.phone === true) { phoneUrl = jsonStr.miphone.hdurl }; //……………………………… if (CONFIG.proType === _$[71] && phoneUrl) { //判断抢购的东西和url是否为空 m.locationNext(phoneUrl) } else if (CONFIG.proType === _$[72] && powerUrl) //………………………………//抢其他东西的代码//……………………………… getPermit.hdStatus(json)};locationNext: function (str) { if (str == null || str == _$[66]) {//其实这个判断基本没有用,在调用前就判断过str是否为null或是‘’ _$[66]=='' window.location.reload() } else { //_$[67]=='http://t.hd.xiaomi.com/s/' location.href = _$[67] + str //不为空则页面跳转到。。。 } }
……………………………………………………这是小米的抢购页面,我该说什么。. . . . .
根据firefox的网络分析,抢购开始后,发送了多个请求。
1.高清信息;2. 获取模式;3.hget;
至于参数是什么,先不说。我最初截图了,但我没有重命名它。后来玩2048的时候截图给师姐看,结果被覆盖了。. . 臭臭害死人。
好,下面说一下结论。. . 结论是一个脚本
自己尝试另存为html后缀,同样,没有实际验证红米抢购页面代码,玩儿你没商量,就得等到25号才能验证。到时候我可能验证不了,因为我已经抢到了。如果它被视为作弊,别担心来找我。
小米抢购 小米抢购
该代码是18号之后写的,未实际验证
首先打开小米抢购页面,登录后,根据倒计时时间调整准系统时间后,刷新页面
填好下面几项
小米ID为小米个人中心里的那个ID号
在小米抢购页面的地址栏输入(区分大小写):javascript:alert(CONFIG.srcs.hdinfo)将显示的最后一串数字填入刷新时间(不要复制了多余的字符比如空格等),关掉对话框,不要再刷新页面
等到小米的抢购时间一到,立即点击“开始”按钮
只针对小米2014/03/04-2014/03/18的页面,对后续页面情况未知
不保证能100%抢到,但是该程序具有自动识别验证码的作用
本文件不做任何验证,出错不会有提示,请输入准确后再提交
该脚本之在FireFox下验证有效,其他浏览器未验证,应该也可以
没有像小米页面那样重发hdget,因为我觉得第一次没有抢到后面抢到的概率也不大
没有整理房间的,页面简陋,海涵
MadeBy zong
<script>var url; //保存hdget的urlvar miid; //保存小米IDvar time1; //最后一次刷新时间,因为我不知道服务器是否验证这个参数,所以还是用实际的var time2; //原本是想伪造一个时间戳2的,//后来想既然调整了系统时间和自动计算验证码,还是直接用Date类获得靠谱一些function hdcontrol(json){p=json.status.miphone.hdurl;if(p==null || p==""){alert("很遗憾,您可以多次刷新下面的页面来抢购\n");location.href=url;}else{location.href="http://t.hd.xiaomi.com/s/"+p;}return;}function getmode(json){ //参考自小米countfk,生成验证码var fk=(miid%json.mod).toString().substr(-4,4); switch (fk.length) {case 1:fk='000'+fk;break;case 2:fk='00'+fk;break;case 3:fk='0'+fk;break; } var script = document.createElement("script");url="http://tc.hd.xiaomi.com/hdget?product=phone&fk={{fk}}&_="+time1+new Date().getTime();url=url.replace('{{fk}}',fk.toString());script.src =url; script.id ="hdget";document.getElementById("body").appendChild(script)//正确加载后将执行hdcontrol函数,没有做错误处理,参考自小米页面}function hdinfo(json){var script = document.createElement("script");//生成请求germode的urlscript.src ="http://tc.hd.xiaomi.com/getmode?_="+time1+new Date().getTime();script.id ="getmode";document.getElementById("body").appendChild(script);//正确加载后将执行getmode函数,没有做错误处理,参考自小米页面return;}function buy(){time1=document.getElementById("time1").value;//保存第一个时间戳1miid=document.getElementById("miid").value;//保存小米IDvar script = document.createElement("script");//生成请求hdinfo的url,其实这条请求可以不发送script.src ="http://tc.hd.xiaomi.com/hdinfo?callback=hdinfo&_="+time1+new Date().getTime();script.id ="hdinfo";document.getElementById("body").appendChild(script);//正确加载后将执行hdinfo函数,没有做错误处理,参考自小米页面}//每条请求的返回值示例//hdinfo//hdinfo({"stime":1395115208,"d22a51":5,"login":true,"pmstart":false,"status":{"miphone":{"hdstart":true,"hdstop":false,"hdurl":"","duration":null,"reg":true},"mitv":{"hdstart":true,"hdstop":false,"hdurl":"","duration":null,"reg":true}}})//getmode//getmode({"mod":2675})//hdget//hdcontrol({"stime":1395115250,"d22a51":5,"login":true,"pmstart":false,"status":{"miphone":{"hdstart":true,"hdstop":false,"hdurl":"","duration":null,"reg":true},"mitv":{"hdstart":true,"hdstop":false,"hdurl":"","duration":null,"reg":true}}})</script>
好吧,我会做的,让我们做剩下的。. .