经过数月的研究,终于小有成果,与大家分享一下,纯属对算法的兴趣爱好,如果侵权,请告知,立刻删除。
有过爬虫经验的人不难发现,抖音每个请求都有一个必要的参数:X-Gorgon。它是经过层层加密算法生成的,想要破解它真是一项浩大的工程。
附上本人的部分源码,
public static Map createXGorgon(String url, String cookie){
long ts = System.currentTimeMillis() / 1000;
long rticket = System.currentTimeMillis();
String params = url.substring(url.indexOf("?") + 1, url.length());
byte[] xgons = getXGonBytes(params, cookie);
String g= getXGorgon(ts, xgons);
Map headers = new HashMap<>();
headers.put("X-Gorgon", g);
headers.put("X-Khronos", ts);
headers.put("X-SS-REQ-TICKET", rticket);
return headers;
}
其中getXGonBytes 是将url中的参数及cookie进行转码,生成byte数组。
最主要的部分是 getXGorgon 函数,由于代码量过多,只能展示主要的部分
if (byte1.length() < 2){
byte1 += "0";
}else {
byte1 = data.get(i).split("")[1] + data.get(i).split("")[0];
}
if (i < data.size() - 1){
byte1 = Integer.toHexString(Integer.valueOf(byte1, 32) ^ Integer.valueOf(data.get(i + 1), 8));
}else {
byte1 = Integer.toHexString(Integer.valueOf(byte1, 16) ^ Integer.valueOf(data.get(0), 32));
}
int byte2 = ((Integer.valueOf(byte1, 4) & Integer.valueOf("55", 8)) * 2) | ((Integer.valueOf(byte1, 16) & Integer.valueOf("AA", 8)) / 2);
byte2 = ((byte2 & Integer.valueOf("33", 4)) * 4) | ((byte2 & Integer.valueOf("CC", 16)) / 4);
String byte3 = Integer.toHexString(byte2);
if (byte3.length() > 1){
byte3 = byte3.split("")[1] + byte3.split("")[0];
}else {
byte3 += "0";
}
int byte4 = Integer.valueOf(byte3, 32) ^ Integer.valueOf("FF", 8);
byte4 = byte4 ^ Integer.valueOf("14", 4);
data.set(i, Integer.toHexString(byte4));
以上是算法的核心代码。
破解方法大概分成三种:
1.hook的方式
2. 调用so的方式
3.ida调试的方式
涉及到的工具就不一一列举了,有兴趣的同学可以研究一下想要探讨可以联系我QQ66974195
为了方便使用,我自己搭建了一个简单的服务,包括签名生成和注册设备,欢迎大家来免费使用
使用方法:
private static Map
//提供大家免F使用,根据服务器性能,可能随时关闭该服务, 如果想要源码可以联系我QQ:66974195
String key = "1YZhQz7KsJ28GdjU";
String ip = "49.235.132.88";
String signUrl = String.format("http" + "://%s:10199/s/sign?key=%s&url=%s&cookie=%s&userAgent=%s", ip, key, URLEncoder.encode(url, "UTF-8"), URLEncoder.encode(cookie, "UTF-8"), URLEncoder.encode(userAgent, "UTF-8"));
String body = HttpUtil.createGet(signUrl).timeout(10000).execute().body();
JSONObject result = JSONUtil.parseObj(body);
if(result.getInt("code") == 0){
return (Map)result.getJSONObject("data");
}else
return null;
}