import re, base64, urllib.parse html = open('/tmp/android_proxy.html', encoding='utf8', errors='ignore').read() mix = next(b for b in re.findall(r'', html) if '.split("")' in b) def eval_frags(expr): REVr = '.split("").reverse().join("")' out = []; i = 0 while i < len(expr): m = re.match(r'"([^"]*)"(\.split\(""\)\.reverse\(\)\.join\(""\))?', expr[i:]) if m: lit = m.group(1) is_rev = m.group(2) is not None out.append(lit[::-1] if is_rev else lit) i += m.end() while i < len(expr) and expr[i] in ' +': i += 1 else: i += 1 return ''.join(out) # 真实数据验证: assign = {} for st in [s.strip() for s in mix.split(';') if s.strip()]: m = re.match(r'^var\s+(\w+)\s*=\s*(.*)$', st) if not m: m = re.match(r'^(\w+)\s*=\s*(.*)$', st) if m: name = m.group(1); rhs = m.group(2).strip().rstrip(')').strip() if rhs in assign: assign[name] = assign[rhs] continue else: name = m.group(1); rhs = m.group(2).strip().rstrip(')').strip() if not rhs: assign[name] = ''; continue eval_body = rhs if eval_body.startswith('"'): eval_body = eval_body[1:] # strip leading quote (assignment's opening) # 还有末尾可能结尾在 .join("") 之后的 ) assign[name] = eval_frags(eval_body) continue print('assign:', {k: (v[:25]+'..' if len(v) > 25 else v) for k, v in assign.items()}) vals = [v for v in assign.values() if v] hex32 = [v for v in vals if re.match(r'^[a-f0-9]{32}$', v)] xKey = hex32[0] oldToken = next(h for h in hex32 if h != xKey) newToken = next(v for v in vals if re.search(r'%[0-9A-Fa-f]{2}', v) and not re.match(r'^[a-f0-9]{32}$', v) and not re.match(r'^[a-f0-9]{16}$', v) and v != xKey) xorConst = re.findall(r'"([a-f0-9]{16})"', html)[0] print(f'xKey={xKey} new={newToken[:26]} old={oldToken[:10]}.. c={xorConst}') def b64(s): return base64.b64decode(s.encode()).decode('latin1') def dec(e): b1 = b64(e[::-1]) k = xKey + xorConst x = ''.join(chr((ord(b1[i]) ^ ord(k[i % len(k)])) & 0xff) for i in range(len(b1))) b2 = b64(x) return urllib.parse.unquote(b2.replace('token=' + oldToken, 'token=' + newToken).replace(xKey, '')) opts = re.findall(r'