|
|
@ -1935,192 +1935,6 @@ EOF |
|
|
replaced=true |
|
|
replaced=true |
|
|
fi |
|
|
fi |
|
|
|
|
|
|
|
|
# ========== 方法B: b6 定点重写(机器码源函数,仅 main.js) ========== |
|
|
|
|
|
local b6_patched=false |
|
|
|
|
|
if [ "$(basename "$file")" = "main.js" ]; then |
|
|
|
|
|
if command -v python3 >/dev/null 2>&1; then |
|
|
|
|
|
local b6_result |
|
|
|
|
|
b6_result=$(python3 - "$file" "$machine_guid" "$machine_id" <<'PY' |
|
|
|
|
|
if True: |
|
|
|
|
|
import re, sys |
|
|
|
|
|
|
|
|
|
|
|
def diag(msg): |
|
|
|
|
|
print(f"[方案B][诊断] {msg}", file=sys.stderr) |
|
|
|
|
|
|
|
|
|
|
|
path, machine_guid, machine_id = sys.argv[1], sys.argv[2], sys.argv[3] |
|
|
|
|
|
|
|
|
|
|
|
with open(path, "r", encoding="utf-8") as f: |
|
|
|
|
|
data = f.read() |
|
|
|
|
|
|
|
|
|
|
|
# ✅ 1+3 融合:限定 out-build/vs/base/node/id.js 模块内做特征匹配 + 花括号配对定位函数边界 |
|
|
|
|
|
marker = "out-build/vs/base/node/id.js" |
|
|
|
|
|
marker_index = data.find(marker) |
|
|
|
|
|
if marker_index < 0: |
|
|
|
|
|
print("NOT_FOUND") |
|
|
|
|
|
diag(f"未找到模块标记: {marker}") |
|
|
|
|
|
raise SystemExit(0) |
|
|
|
|
|
|
|
|
|
|
|
window_end = min(len(data), marker_index + 200000) |
|
|
|
|
|
window = data[marker_index:window_end] |
|
|
|
|
|
|
|
|
|
|
|
def find_matching_brace(text, open_index, max_scan=20000): |
|
|
|
|
|
limit = min(len(text), open_index + max_scan) |
|
|
|
|
|
depth = 1 |
|
|
|
|
|
in_single = in_double = in_template = False |
|
|
|
|
|
in_line_comment = in_block_comment = False |
|
|
|
|
|
escape = False |
|
|
|
|
|
i = open_index + 1 |
|
|
|
|
|
while i < limit: |
|
|
|
|
|
ch = text[i] |
|
|
|
|
|
nxt = text[i + 1] if i + 1 < limit else "" |
|
|
|
|
|
|
|
|
|
|
|
if in_line_comment: |
|
|
|
|
|
if ch == "\n": |
|
|
|
|
|
in_line_comment = False |
|
|
|
|
|
i += 1 |
|
|
|
|
|
continue |
|
|
|
|
|
if in_block_comment: |
|
|
|
|
|
if ch == "*" and nxt == "/": |
|
|
|
|
|
in_block_comment = False |
|
|
|
|
|
i += 2 |
|
|
|
|
|
continue |
|
|
|
|
|
i += 1 |
|
|
|
|
|
continue |
|
|
|
|
|
|
|
|
|
|
|
if in_single: |
|
|
|
|
|
if escape: |
|
|
|
|
|
escape = False |
|
|
|
|
|
elif ch == "\\\\": |
|
|
|
|
|
escape = True |
|
|
|
|
|
elif ch == "'": |
|
|
|
|
|
in_single = False |
|
|
|
|
|
i += 1 |
|
|
|
|
|
continue |
|
|
|
|
|
if in_double: |
|
|
|
|
|
if escape: |
|
|
|
|
|
escape = False |
|
|
|
|
|
elif ch == "\\\\": |
|
|
|
|
|
escape = True |
|
|
|
|
|
elif ch == '"': |
|
|
|
|
|
in_double = False |
|
|
|
|
|
i += 1 |
|
|
|
|
|
continue |
|
|
|
|
|
if in_template: |
|
|
|
|
|
if escape: |
|
|
|
|
|
escape = False |
|
|
|
|
|
elif ch == "\\\\": |
|
|
|
|
|
escape = True |
|
|
|
|
|
elif ch == "`": |
|
|
|
|
|
in_template = False |
|
|
|
|
|
i += 1 |
|
|
|
|
|
continue |
|
|
|
|
|
|
|
|
|
|
|
if ch == "/" and nxt == "/": |
|
|
|
|
|
in_line_comment = True |
|
|
|
|
|
i += 2 |
|
|
|
|
|
continue |
|
|
|
|
|
if ch == "/" and nxt == "*": |
|
|
|
|
|
in_block_comment = True |
|
|
|
|
|
i += 2 |
|
|
|
|
|
continue |
|
|
|
|
|
|
|
|
|
|
|
if ch == "'": |
|
|
|
|
|
in_single = True |
|
|
|
|
|
i += 1 |
|
|
|
|
|
continue |
|
|
|
|
|
if ch == '"': |
|
|
|
|
|
in_double = True |
|
|
|
|
|
i += 1 |
|
|
|
|
|
continue |
|
|
|
|
|
if ch == "`": |
|
|
|
|
|
in_template = True |
|
|
|
|
|
i += 1 |
|
|
|
|
|
continue |
|
|
|
|
|
|
|
|
|
|
|
if ch == "{": |
|
|
|
|
|
depth += 1 |
|
|
|
|
|
elif ch == "}": |
|
|
|
|
|
depth -= 1 |
|
|
|
|
|
if depth == 0: |
|
|
|
|
|
return i |
|
|
|
|
|
|
|
|
|
|
|
i += 1 |
|
|
|
|
|
return None |
|
|
|
|
|
|
|
|
|
|
|
# 🔧 修复:避免 raw string + 单引号 + ['"] 字符组导致的语法错误;同时修正正则转义,提升 b6 特征匹配命中率 |
|
|
|
|
|
hash_re = re.compile(r"""createHash\(["']sha256["']\)""") |
|
|
|
|
|
sig_re = re.compile(r'^async function (\w+)\((\w+)\)') |
|
|
|
|
|
|
|
|
|
|
|
hash_matches = list(hash_re.finditer(window)) |
|
|
|
|
|
diag(f"marker_index={marker_index} window_len={len(window)} sha256_createHash={len(hash_matches)}") |
|
|
|
|
|
|
|
|
|
|
|
for idx, hm in enumerate(hash_matches, start=1): |
|
|
|
|
|
hash_pos = hm.start() |
|
|
|
|
|
func_start = window.rfind("async function", 0, hash_pos) |
|
|
|
|
|
if func_start < 0: |
|
|
|
|
|
if idx <= 3: |
|
|
|
|
|
diag(f"候选#{idx}: 未找到 async function 起点") |
|
|
|
|
|
continue |
|
|
|
|
|
|
|
|
|
|
|
open_brace = window.find("{", func_start) |
|
|
|
|
|
if open_brace < 0: |
|
|
|
|
|
if idx <= 3: |
|
|
|
|
|
diag(f"候选#{idx}: 未找到函数起始花括号") |
|
|
|
|
|
continue |
|
|
|
|
|
|
|
|
|
|
|
end_brace = find_matching_brace(window, open_brace, max_scan=20000) |
|
|
|
|
|
if end_brace is None: |
|
|
|
|
|
if idx <= 3: |
|
|
|
|
|
diag(f"候选#{idx}: 花括号配对失败(扫描上限内未闭合)") |
|
|
|
|
|
continue |
|
|
|
|
|
|
|
|
|
|
|
func_text = window[func_start:end_brace + 1] |
|
|
|
|
|
if len(func_text) > 8000: |
|
|
|
|
|
if idx <= 3: |
|
|
|
|
|
diag(f"候选#{idx}: 函数体过长 len={len(func_text)},已跳过") |
|
|
|
|
|
continue |
|
|
|
|
|
|
|
|
|
|
|
sm = sig_re.match(func_text) |
|
|
|
|
|
if not sm: |
|
|
|
|
|
if idx <= 3: |
|
|
|
|
|
diag(f"候选#{idx}: 未解析到函数签名(async function name(param))") |
|
|
|
|
|
continue |
|
|
|
|
|
name, param = sm.group(1), sm.group(2) |
|
|
|
|
|
|
|
|
|
|
|
# 特征校验:sha256 + hex digest + return param ? raw : hash |
|
|
|
|
|
has_digest = re.search(r"""\.digest\(["']hex["']\)""", func_text) is not None |
|
|
|
|
|
has_return = re.search(r'return\s+' + re.escape(param) + r'\?\w+:\w+\}', func_text) is not None |
|
|
|
|
|
if idx <= 3: |
|
|
|
|
|
diag(f"候选#{idx}: {name}({param}) len={len(func_text)} digest={has_digest} return={has_return}") |
|
|
|
|
|
if not has_digest: |
|
|
|
|
|
continue |
|
|
|
|
|
if not has_return: |
|
|
|
|
|
continue |
|
|
|
|
|
|
|
|
|
|
|
replacement = f'async function {name}({param}){{return {param}?"{machine_guid}":"{machine_id}";}}' |
|
|
|
|
|
abs_start = marker_index + func_start |
|
|
|
|
|
abs_end = marker_index + end_brace |
|
|
|
|
|
new_data = data[:abs_start] + replacement + data[abs_end + 1:] |
|
|
|
|
|
with open(path, "w", encoding="utf-8") as f: |
|
|
|
|
|
f.write(new_data) |
|
|
|
|
|
diag(f"命中并重写: {name}({param}) len={len(func_text)}") |
|
|
|
|
|
print("PATCHED") |
|
|
|
|
|
break |
|
|
|
|
|
else: |
|
|
|
|
|
diag("未找到满足特征的候选函数") |
|
|
|
|
|
print("NOT_FOUND") |
|
|
|
|
|
PY |
|
|
|
|
|
) |
|
|
|
|
|
if [ "$b6_result" = "PATCHED" ]; then |
|
|
|
|
|
log_info " ✓ [方案B] 已重写 b6 特征函数" |
|
|
|
|
|
b6_patched=true |
|
|
|
|
|
else |
|
|
|
|
|
log_warn "⚠️ [方案B] 未定位到 b6 特征函数" |
|
|
|
|
|
fi |
|
|
|
|
|
else |
|
|
|
|
|
log_warn "⚠️ [方案B] 未检测到 python3,跳过 b6 定点重写" |
|
|
|
|
|
fi |
|
|
|
|
|
fi |
|
|
|
|
|
|
|
|
|
|
|
# ========== 方法C: Loader Stub 注入 ========== |
|
|
# ========== 方法C: Loader Stub 注入 ========== |
|
|
local inject_code='// ========== Cursor Hook Loader 开始 ========== |
|
|
local inject_code='// ========== Cursor Hook Loader 开始 ========== |
|
|
|