最近很流行的一款微信小游戏《海盗来了》,用来打发时间还不错,就是建岛和转盘太慢了,于是用Fiddler抓了下包,分析了下请求报文,发现所有的请求都需要sign签名,尝试了几次都得不到签名值,于是搞了个安卓模拟器,把小游戏的源码拷出来分析了下。
以下是我解包出来并且解码后的海盗来了game.js 源码:gamezip
发现请求的签名算法就是普通的字典排序,拼成URL后把&符号去掉,再进行MD5签名!
例如:sign=md5(uid=666t=666secret=666)
试了下,还是可以用的,但请求的频率不宜过高,我的一个号就是这样被封了,所以。。。
Talk is cheap, show you the code :
解释一下,这里用到了一个RelynSpider类,是我自己的爬虫框架,就不贴出来了,其实就是简单的POST请求即可(POST的时候,User-Agent记得跟微信一样)~~
public class RelynPirate {
private static RelynSpider relynSpider = new RelynSpider();
public static void start(String encryptedCode, String uid, String userId, String island) {
String url = "https://pirate-api.hortor002.com/game/entry/wxgame";
Map<String, Object> map = new HashMap<String, Object>();
Map<String, String> dataMap = new HashMap<String, String>();
String t = String.valueOf(System.currentTimeMillis()).substring(0, 10);
String resp = "";
String sign = "";
String param = "";
map.put("encryptedCode", encryptedCode);
resp = relynSpider.postWechat(url, map);
System.out.println("HTML >> " + resp);
resp = resp.substring(resp.indexOf("secret/":/"") + 9);
String secret = resp.substring(0, resp.indexOf("/""));
System.out.println("secret >> " + secret);
// 基础登录
url = "https://pirate-api.hortor002.com/game/basic/login";
dataMap = new HashMap<String, String>();
dataMap.put("userId", userId);
dataMap.put("isWxGame", "true");
dataMap.put("t", t);
dataMap.put("secret", secret);
param = RelynSpider.formatUrlMap(dataMap, false, false);
System.out.println("param >> " + param);
param = param.replaceAll("&", ""); // 把&去掉
sign = RelynSpider.md5(param);
System.out.println("sign >> " + sign);
map = new HashMap<String, Object>();
map.put("userId", userId);
map.put("isWxGame", "true");
map.put("t", t);
map.put("secret", secret);
map.put("sign", sign);
resp = relynSpider.postWechat(url, map);
System.out.println("HTML >> " + resp);
// 领取并赠送能量
url = "https://pirate-api.hortor002.com/game/friend/donate";
dataMap = new HashMap<String, String>();
dataMap.put("uid", uid);
dataMap.put("fid", "0");
dataMap.put("isWxGame", "true");
dataMap.put("t", t);
dataMap.put("secret", secret);
param = RelynSpider.formatUrlMap(dataMap, false, false);
System.out.println("param >> " + param);
param = param.replaceAll("&", ""); // 把&去掉
sign = RelynSpider.md5(param);
System.out.println("sign >> " + sign);
map = new HashMap<String, Object>();
map.put("uid", uid);
map.put("fid", "0");
map.put("isWxGame", "true");
map.put("t", t);
map.put("secret", secret);
map.put("sign", sign);
resp = relynSpider.postWechat(url, map);
System.out.println("HTML >> " + resp);
// 金矿
url = "https://pirate-api.hortor002.com/game/island/collect";
dataMap = new HashMap<String, String>();
dataMap.put("uid", uid);
dataMap.put("isWxGame", "true");
dataMap.put("t", t);
dataMap.put("secret", secret);
param = RelynSpider.formatUrlMap(dataMap, false, false);
System.out.println("param >> " + param);
param = param.replaceAll("&", ""); // 把&去掉
sign = RelynSpider.md5(param);
System.out.println("sign >> " + sign);
map = new HashMap<String, Object>();
map.put("uid", uid);
map.put("isWxGame", "true");
map.put("t", t);
map.put("secret", secret);
map.put("sign", sign);
resp = relynSpider.postWechat(url, map);
System.out.println("HTML >> " + resp);
// 转盘
int length = 100;
while (length > 34) {
// 这里的等待5秒是我被封号后加上去的,可根据实际情况适当调整
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
url = "https://pirate-api.hortor002.com/game/roller/roll";
dataMap = new HashMap<String, String>();
dataMap.put("uid", uid);
dataMap.put("bet", "1");
dataMap.put("isWxGame", "true");
dataMap.put("t", t);
dataMap.put("secret", secret);
param = RelynSpider.formatUrlMap(dataMap, false, false);
System.out.println("param >> " + param);
param = param.replaceAll("&", ""); // 把&去掉
sign = RelynSpider.md5(param);
System.out.println("sign >> " + sign);
map = new HashMap<String, Object>();
map.put("uid", uid);
map.put("bet", "1");
map.put("isWxGame", "true");
map.put("t", t);
map.put("secret", secret);
map.put("sign", sign);
resp = relynSpider.postWechat(url, map);
System.out.println("HTML >> " + resp);
length = resp.length();
System.out.println("length >> " + length);
if (length > 600) {
if (resp.indexOf("stealIslands/":null") != -1) {
resp = resp.substring(resp.indexOf("uid/":") + 5);
String puid = resp.substring(0, resp.indexOf(","));
// 攻击
System.out.println("[*] 攻击");
url = "https://pirate-api.hortor002.com/game/pvp/attack";
dataMap = new HashMap<String, String>();
dataMap.put("uid", uid);
dataMap.put("puid", puid);
dataMap.put("building", "3");
dataMap.put("isWxGame", "true");
dataMap.put("t", t);
dataMap.put("secret", secret);
param = RelynSpider.formatUrlMap(dataMap, false, false);
System.out.println("param >> " + param);
param = param.replaceAll("&", ""); // 把&去掉
sign = RelynSpider.md5(param);
System.out.println("sign >> " + sign);
map = new HashMap<String, Object>();
map.put("uid", uid);
map.put("puid", puid);
map.put("building", "3");
map.put("isWxGame", "true");
map.put("t", t);
map.put("secret", secret);
map.put("sign", sign);
resp = relynSpider.postWechat(url, map);
System.out.println("HTML >> " + resp);
} else {
// 盗窃
System.out.println("[*] 盗窃");
url = "https://pirate-api.hortor002.com/game/pvp/steal";
dataMap = new HashMap<String, String>();
dataMap.put("uid", uid);
dataMap.put("idx", "1");
dataMap.put("isWxGame", "true");
dataMap.put("t", t);
dataMap.put("secret", secret);
param = RelynSpider.formatUrlMap(dataMap, false, false);
System.out.println("param >> " + param);
param = param.replaceAll("&", ""); // 把&去掉
sign = RelynSpider.md5(param);
System.out.println("sign >> " + sign);
map = new HashMap<String, Object>();
map.put("uid", uid);
map.put("idx", "1");
map.put("isWxGame", "true");
map.put("t", t);
map.put("secret", secret);
map.put("sign", sign);
resp = relynSpider.postWechat(url, map);
System.out.println("HTML >> " + resp);
}
}
}
// 许愿瓶
// url = "https://pirate-api.hortor002.com/game/annual/open-lucky-box";
// dataMap = new HashMap<String, String>();
// dataMap.put("uid", uid);
// dataMap.put("useFree", "false");
// dataMap.put("isWxGame", "true");
// dataMap.put("t", t);
// dataMap.put("secret", secret);
// param = formatUrlMap(dataMap, false, false);
// System.out.println("param >> " + param);
// param = param.replaceAll("&", ""); //把&去掉
// sign = md5(param);
// System.out.println("sign >> " + sign);
// map = new HashMap<String, Object>();
// map.put("uid", uid);
// map.put("useFree", "false");
// map.put("isWxGame", "true");
// map.put("t", t);
// map.put("secret", secret);
// map.put("sign", sign);
// resp = relynSpider.postWechat(url, map);
// System.out.println("HTML >> " + resp);
// 建造
for (int building = 0; building < 5; building++) {
for (int level = 1; level < 6; level++) {
url = "https://pirate-api.hortor002.com/game/island/build";
dataMap = new HashMap<String, String>();
dataMap.put("uid", uid);
dataMap.put("island", island);
dataMap.put("building", String.valueOf(building));
dataMap.put("level", String.valueOf(level));
dataMap.put("t", t);
dataMap.put("secret", secret);
param = RelynSpider.formatUrlMap(dataMap, false, false);
System.out.println("param >> " + param);
param = param.replaceAll("&", ""); // 把&去掉
sign = RelynSpider.md5(param);
System.out.println("sign >> " + sign);
map = new HashMap<String, Object>();
map.put("uid", uid);
map.put("island", island);
map.put("building", building);
map.put("level", level);
map.put("t", t);
map.put("secret", secret);
map.put("sign", sign);
resp = relynSpider.postWechat(url, map);
System.out.println("HTML >> " + resp);
}
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
// 下面这三个参数,抓包下就能看到啦
encryptedCode = ";
uid = "";
userId = "";
island = ""; //这个是目前要建的岛屿序号,从0开始的
start(encryptedCode, uid, userId, island);
}