| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192 |
- # -*- coding: utf-8 -*-
- """解析 webpack 稀疏数组,确定登录模块 P.b 引用哪个 RSA 公钥模块"""
- import re
- import sys
- import requests
- import urllib3
- urllib3.disable_warnings()
- s = requests.Session()
- s.verify = False
- t = s.get('https://newpc.996db.com/static/js/mainv2.6.01789526607.chunk.js', timeout=30).text
- def match_bracket(text, start):
- depth = 0
- for k in range(start, len(text)):
- c = text[k]
- if c in '([{':
- depth += 1
- elif c in ')]}':
- depth -= 1
- if depth == 0:
- return k
- return -1
- def split_top_array(arr_text):
- """[a,b,,c] → 顶层逗号切分(跳过空槽)"""
- items, depth, cur = [], 0, ''
- in_str = None
- for c in arr_text[1:-1]:
- if in_str:
- cur += c
- if c == in_str:
- in_str = None
- continue
- if c in '"\'':
- in_str = c
- cur += c
- continue
- if c in '([{':
- depth += 1
- elif c in ')]}':
- depth -= 1
- if c == ',' and depth == 0:
- items.append(cur)
- cur = ''
- continue
- cur += c
- items.append(cur)
- return items
- i = t.find('this.webpackJsonp996box||[]).push(')
- p1 = t.index('[', i) # [[33],[mods]]
- q1 = t.index(']', p1) # [33] 闭合(第一个子数组很短)
- r = t.index('[', q1) # mods 数组起点
- r_end = match_bracket(t, r)
- mods = split_top_array(t[r:r_end + 1])
- print(f'total slots: {len(mods)}, non-empty: {sum(1 for x in mods if x.strip())}')
- login_id = crypto_old_id = crypto_new_id = None
- for idx, item in enumerate(mods):
- if not item.strip():
- continue
- if 'AjCQvqNP' in item:
- crypto_old_id = idx
- print(f'crypto OLD-key module id={idx} size={len(item)} exports={re.findall(r"n\.d\(t,.(\w+).", item)}')
- if 'KuB+7dLm' in item:
- crypto_new_id = idx
- print(f'crypto NEW-key module id={idx} size={len(item)} exports={re.findall(r"n\.d\(t,.(\w+).", item)}')
- if 'function _e()' in item:
- login_id = idx
- imps = re.findall(r'(\w+)=n\((\d+)\)', item)
- print(f'LOGIN module id={idx} size={len(item)}')
- print(f' imports: {imps}')
- # 在登录模块里找 P 的绑定
- login_mod = mods[login_id] if login_id is not None else ''
- for m in re.finditer(r'(\w+)=n\.n?\((\d+)\)', login_mod):
- name, num = m.group(1), m.group(2)
- if name == 'P':
- print(f'\n*** P = n({num})')
- target = int(num)
- if target == crypto_old_id:
- print('*** P 指向 OLD 公钥模块 (b=old key)')
- elif target == crypto_new_id:
- print('*** P 指向 NEW 公钥模块 (a=new key)')
- else:
- print(f'*** P 指向模块 {target}(非公钥模块!)其内容片段:')
- if target < len(mods):
- print(mods[target][:600])
|