Google参数解密(11-11)
Google翻译参数解密(11-11)
一.请求过程
文件地址:https://translate.google.com.hk/translate/releases/twsfe_w_20201102_RC00/r/js/translate_m_zh-CN.js:formatted 22573
其中uv
函数调用aF
函数,结果生成请求链接
变量说明:
-
aF 为函数
aF = function(a, b, c, d, e, f) { c = c.toString(); c += $E(d); d = d.toString(); var g = "POST"; b += "?" + c; 2E3 > b.length + d.length && (g = "GET", b += "&" + d, d = ""); ++a.j; return Tj(b, function(h) { --a.j; e(h) }, g, d, void 0, f) }
-
变量参数
2.1
a
为对象
2.2 b
为需要翻译语言标识
"auto" // 自动识别
2.3 c
为翻译目标语言标识
"zh-CN" // 中文
2.4 d
变量与c
变量相同
2.5 e
需要翻译的内容
ซิลิโคนสีเงา
2.6 p
为变量数组
["at", "bd", "ex", "ld", "md", "qca", "rw", "rm", "sos", "ss", "t"]
2.7 f
与m
为函数
2.8 h
为未定义
2.9 l
为变量数组
2.10 void 0
为未定义
通过代码调试发现aF(a, r, u, B, t(a.m, a, g, p), void 0)
返回的内容就是整个请求参数,并且此过程就是tk
值生成
二.过程解析
1.aF
函数处理机制
/*
a:Object webapp 表明平台
b: String /translate_a/single
c:Object 0: "client" 其他请求参数
1: "sl"
2: "tl"
3: "hl"
4: "dt"
5: "otf"
6: "ssel"
7: "tsel"
8: "kc"
d:Object 存储查询内容
e:function
f:undefined
*/
aF = function(a, b, c, d, e, f) {
// 将请求参数组成请求链接
// client=webapp&sl=auto&tl=zh-CN&hl=zh-CN&dt=at&dt=bd&dt=ex&dt=ld&dt=md&dt=qca&dt=rw&dt=rm&dt=sos&dt=ss&dt=t&otf=1&ssel=0&tsel=0&kc=1
c = c.toString();
// d 查询内容
c += $E(d);
d = d.toString();
var g = "POST";
b += "?" + c;
2E3 > b.length + d.length && (g = "GET",
b += "&" + d,
d = "");
++a.j;
return Tj(b, function(h) {
--a.j;
e(h)
}, g, d, void 0, f)
}
2.$E
函数处理机制
将查询内容进行wu
调用
$E = function(a) {
a = a.Kb("q").join("");
return wu(a)
}
3.Kb
函数处理机制
使用a.Kb("q")
将查询内容生成查询内容的数组,并使用join
函数将查询内容组合赋值a
4.wu
函数处理机制
// a 为查询内容 'Hello'
vu = null;
wu = function(a) {
// 条件为true
if (null !== vu)
var b = vu; // 执行这步
else {
b = tu(String.fromCharCode(84));
var c = tu(String.fromCharCode(75));
b = [b(), b()];
b[1] = c();
b = (vu = window[b.join(c())] || "") || ""
}
// 注意函数执行完到这里,会产生 b = 445860.98157186
// 这是 b 的值是打开翻译网站生成的。详细内容看下面图片
// String.fromCharCode(116) 获取ASCII码 116对应的字符
// 函数 tu 返回一个函数,如果执行返回函数。就会返回第一次传入的内容
var d = tu(String.fromCharCode(116)); // t
c = tu(String.fromCharCode(107)); // k
d = [d(), d()]; // [t,t]
d[1] = c(); // [t,k]
// c = "&tk="
c = "&" + d.join("") + "=";
// b = 445860.98157186 进行切,并生成数组[整数部分字符串,小数部分字符串]
d = b.split(".");
// 获取整数部分内容,并将内容强制转化成 int
b = Number(d[0]) || 0;
// 处理查询内容,并生成 e
for (var e = [], f = 0, g = 0; g < a.length; g++) {
var h = a.charCodeAt(g);
128 > h ? e[f++] = h : (2048 > h ? e[f++] = h >> 6 | 192 : (55296 == (h & 64512) && g + 1 < a.length && 56320 == (a.charCodeAt(g + 1) & 64512) ? (h = 65536 + ((h & 1023) << 10) + (a.charCodeAt(++g) & 1023),
e[f++] = h >> 18 | 240,
e[f++] = h >> 12 & 63 | 128) : e[f++] = h >> 12 | 224,
e[f++] = h >> 6 & 63 | 128),
e[f++] = h & 63 | 128)
}
a = b;
// 将上一步的e在进行处理生成a
for (f = 0; f < e.length; f++)
a += e[f],
a = uu(a, "+-a^+6");
a = uu(a, "+-3^+b+-f");
a ^= Number(d[1]) || 0;
0 > a && (a = (a & 2147483647) + 2147483648);
a %= 1E6;
// 生成加密结果 &tk=618649.1031485
return c + (a.toString() + "." + (a ^ b))
}
5.tu
函数处理机制
var tu = function(a) {
return function() {
return a
}
}
6.uu
函数处理机制
将参数进行处理,并返回a
uu = function(a, b) {
for (var c = 0; c < b.length - 2; c += 3) {
var d = b.charAt(c + 2);
d = "a" <= d ? d.charCodeAt(0) - 87 : Number(d);
d = "+" == b.charAt(c + 1) ? a >>> d : a << d;
a = "+" == b.charAt(c) ? a + d & 4294967295 : a ^ d
}
return a
}
具体步骤如下:
- 将请求参数请求函数
aF
- 函数
aF
将调用函数$E
,并将查询对象传入当作参数 - 取出查询内容的值,并将其作为参数传入
wu
- 函数进行一系列的操作生成加密内容
- 将函数加密内容与函数
aF
中的变量c
组成完整的请求链接,完成请求
三.加密代码实现
1.python代码
#!/usr/bin/env python3
# -*- coding:utf-8 -*-
# Author LQ6H
import execjs.runtime_names
def Init_JS():
with open('google.js','r',encoding='utf-8') as f:
js = execjs.compile(f.read())
return js
def wu(keyword):
c = '/translate_a/single?client=webapp&sl=auto&tl=zh-CN&hl=zh-CN&dt=at&dt=bd&dt=ex&dt=ld&dt=md&dt=qca&dt=rw&dt=rm&dt=sos&dt=ss&dt=t&otf=1&pc=1&ssel=0&tsel=0&kc=2'
js = Init_JS()
# 打开翻译网页内容,第一步获取内容
ttk = '445860.98157186'
# 将 tk内容与c 拼接生成请求url
tk = js.call('params',keyword,ttk)
print(tk)
print(c + tk)
wu('ซิลิโคนสีเงา')
2.js代码
function uu (a,b) {
for (var c = 0; c < b.length - 2; c += 3) {
var d = b.charAt(c + 2);
d = "a" <= d ? d.charCodeAt(0) - 87 : Number(d);
d = "+" == b.charAt(c + 1) ? a >>> d : a << d;
a = "+" == b.charAt(c) ? a + d & 4294967295 : a ^ d
}
return a
}
function params(a,ttk) {
var c = "&tk=";
var d = ttk.split(".");
var b = Number(d[0]) || 0;
for (var e = [], f = 0, g = 0; g < a.length; g++) {
var h = a.charCodeAt(g);
128 > h ? e[f++] = h : (2048 > h ? e[f++] = h >> 6 | 192 : (55296 == (h & 64512) && g + 1 < a.length && 56320 == (a.charCodeAt(g + 1) & 64512) ? (h = 65536 + ((h & 1023) << 10) + (a.charCodeAt(++g) & 1023),
e[f++] = h >> 18 | 240,
e[f++] = h >> 12 & 63 | 128) : e[f++] = h >> 12 | 224,
e[f++] = h >> 6 & 63 | 128),
e[f++] = h & 63 | 128)
}
a = b;
for (f = 0; f < e.length; f++)
a += e[f],
a = uu(a, "+-a^+6");
a = uu(a, "+-3^+b+-f");
a ^= Number(d[1]) || 0;
0 > a && (a = (a & 2147483647) + 2147483648);
a %= 1E6;
return c + (a.toString() + "." + (a ^ b))
}