元旦期间舍友迷恋上了QQ空间的一个游戏应用-猜歌王,玩得不亦乐乎。突然有一次,上铺告诉遇到一个人,猜歌都特别快,特别准,很明显用了外挂。
上面是背景。
对于这个游戏我的第一思路是模拟,对声音进行采样,提取特征,然后与歌曲库中歌曲对比,理论上是可行的,比如有一款APP叫做SoundHound……但是游戏辅助必然不是通过这种手段。
换个思路,根据经验,歌曲片段应该需要先缓存到本地,于是考虑拦截HTTP封包,对比歌曲库的地址来获取每首歌的歌名,于是乎,打开了火狐的Web控制台,希望能获得有用的东西。
[15:30:45.941] GET http://app100645222.imgcache.qzoneapp.com/app100645222/mp3/355/7355_4.mp3 [HTTP/1.1 200 OK 440ms]
[15:30:45.943] GET http://app100645222.imgcache.qzoneapp.com/app100645222/mp3/902/1079902_1.mp3 [HTTP/1.1 200 OK 466ms]
[15:30:45.945] GET http://app100645222.imgcache.qzoneapp.com/app100645222/mp3/478/718478_3.mp3 [HTTP/1.1 200 OK 524ms]
[15:30:45.947] GET http://app100645222.imgcache.qzoneapp.com/app100645222/mp3/179/101179_1.mp3 [HTTP/1.1 200 OK 389ms]
[15:30:45.949] GET http://app100645222.imgcache.qzoneapp.com/app100645222/mp3/783/727783_1.mp3 [HTTP/1.1 200 OK 463ms]
看到这样子的记录以后,大概有了眉目,但是仍然存在一个问题,需要采集大量的地址与歌曲名或者歌手的对应信息。无意间一个POST数据引起了我的注意。
请求网址:
http://app100645222.qzone.qzoneapp.com/contest/create.ngi
请求方法:
POST
查看其相应数据,一切大白于天下。
响应头
*****省略*****
响应主体
JSON格式化后:
{ "data": { "songs": [ { "id": "V2550379", "part": 4, "mode": 1, "answer": 2, "opts": [ "我要给你", "霸王命", "爱上你不是我的错", "365天" ], "name": "爱上你不是我的错", "singer": "多亮", "album_id": "198946", "album_name": "多原话", "url": "http://app100645222.imgcache.qzoneapp.com/app100645222/mp3/379/V2550379_4.mp3", "url_aux": "http://cdn.vanchu.net/app100645222/mp3/379/V2550379_4.mp3" }, { "id": "V2472634", "part": 6, "mode": 0, "answer": 0, "opts": [ "侧田", "胡歌", "俞灏明", "蔡旻佑" ], "name": "很想很想说再见", "singer": "侧田", "album_id": "191434", "album_name": "2012年12月新歌速递", "url": "http://app100645222.imgcache.qzoneapp.com/app100645222/mp3/634/V2472634_6.mp3", "url_aux": "http://cdn.vanchu.net/app100645222/mp3/634/V2472634_6.mp3" }, { "id": "V2550675", "part": 1, "mode": 1, "answer": 0, "opts": [ "SUPER GIRL 爱无畏", "无脸人", "我们都能幸福着", "呼呼" ], "name": "SUPER GIRL 爱无畏", "singer": "萧亚轩", "album_id": "198991", "album_name": "SUPER GIRL 爱无畏", "url": "http://app100645222.imgcache.qzoneapp.com/app100645222/mp3/675/V2550675_1.mp3", "url_aux": "http://cdn.vanchu.net/app100645222/mp3/675/V2550675_1.mp3" }, { "id": "V2634923", "part": 2, "mode": 1, "answer": 2, "opts": [ "霸王命", "十二生肖", "天机(feat.五月天阿信)", "忘了我也不错" ], "name": "天机(feat.五月天阿信)", "singer": "MP魔幻力量", "album_id": "205656", "album_name": "射手", "url": "http://app100645222.imgcache.qzoneapp.com/app100645222/mp3/923/V2634923_2.mp3", "url_aux": "http://cdn.vanchu.net/app100645222/mp3/923/V2634923_2.mp3" }, { "id": "V2550447", "part": 3, "mode": 0, "answer": 2, "opts": [ "萧亚轩", "A-Lin", "Popu Lady", "魏晨" ], "name": "一直一直爱", "singer": "Popu Lady", "album_id": "198961", "album_name": "一直一直爱", "url": "http://app100645222.imgcache.qzoneapp.com/app100645222/mp3/447/V2550447_3.mp3", "url_aux": "http://cdn.vanchu.net/app100645222/mp3/447/V2550447_3.mp3" } ], "status": { "stamina": 1, "staminaElapsedTime": 3012 } }, "ret": 0, "ver": "75", "t": 1357102078 }
响应主体是JSON格式,其中使用了Unicode编码。
将JSON格式数据视图化,可以看得很清楚了。
WebBrowser控件有 BeforeNavigate2 事件
BeforeNavigate2(Sender: TObject; const pDisp: IDispatch; var URL, Flags, TargetFrameName, PostData, Headers: OleVariant; var Cancel: WordBool);
但是经过试验,不能够拦截网页中Flash控件的POST。
利用HOOK对进程进行拦截,对数据包的JSON数据进行解析(注意GZIP压缩),然后获取answer值,0,1,2,3分别对应opts的四个选项。
至此游戏辅助的原型基本呈现。
题外话:经试验,QQ空间多个猜歌应用均存在相同漏洞。
上传的图像