Browse Source

feat(cursor): 实现A+B混合方案绕过设备识别

- 引入someValue占位符替换方案,提供稳定跨版本兼容性
- 新增IIFE运行时劫持技术,从源头拦截UUID生成
- 统一三平台(Linux/macOS/Windows)修改逻辑与标识符生成方式
- 添加修改状态检查与跳过已修改文件功能
- 优化日志输出格式并增加emoji可视化提示
- 完善备份策略与错误恢复机制
- 更新注入代码结构以提高兼容性与稳定性
v0.0.210
煎饼果子卷鲨鱼辣椒 1 month ago
parent
commit
21daea3332
  1. 276
      scripts/run/cursor_linux_id_modifier.sh
  2. 163
      scripts/run/cursor_mac_id_modifier.sh
  3. 155
      scripts/run/cursor_win_id_modifier.ps1

276
scripts/run/cursor_linux_id_modifier.sh

@ -651,12 +651,15 @@ find_cursor_js_files() {
} }
# 修改Cursor的JS文件 # 修改Cursor的JS文件
# 🔧 修改Cursor内核JS文件实现设备识别绕过(A+B混合方案 - IIFE + someValue替换)
# 方案A: someValue占位符替换 - 稳定锚点,不依赖混淆后的函数名
# 方案B: IIFE运行时劫持 - 劫持crypto.randomUUID从源头拦截
modify_cursor_js_files() { modify_cursor_js_files() {
log_info "开始修改Cursor的JS文件..."
log_info "🔧 [内核修改] 开始修改Cursor内核JS文件实现设备识别绕过..."
log_info "💡 [方案] 使用A+B混合方案:someValue占位符替换 + IIFE运行时劫持"
# 先查找需要修改的JS文件 # 先查找需要修改的JS文件
if ! find_cursor_js_files; then if ! find_cursor_js_files; then
# find_cursor_js_files 内部会打印错误日志
return 1 return 1
fi fi
@ -665,15 +668,59 @@ modify_cursor_js_files() {
return 1 return 1
fi fi
# 生成新的设备标识符(使用固定格式确保兼容性)
local new_uuid=$(generate_uuid)
local machine_id=$(openssl rand -hex 32)
local device_id=$(generate_uuid)
local mac_machine_id=$(openssl rand -hex 32)
local sqm_id=$(generate_uuid)
local session_id=$(generate_uuid)
log_info "🔑 [生成] 已生成新的设备标识符"
log_info " machineId: ${machine_id:0:16}..."
log_info " deviceId: ${device_id:0:16}..."
log_info " macMachineId: ${mac_machine_id:0:16}..."
local modified_count=0 local modified_count=0
local file_modification_status=() # 记录每个文件的修改状态
local file_modification_status=()
# 检查是否需要修改(使用统一标记)
log_info "🔍 [检查] 检查JS文件修改状态..."
local need_modification=false
for file in "${CURSOR_JS_FILES[@]}"; do
if [ ! -f "$file" ]; then
log_warn "⚠️ [警告] 文件不存在: $file"
continue
fi
# 检查是否已经被修改过(使用统一标记 __cursor_patched__)
if grep -q "__cursor_patched__" "$file" 2>/dev/null; then
log_info "✅ [已修改] 文件已修改: $(basename "$file")"
else
log_info "📝 [需要] 文件需要修改: $(basename "$file")"
need_modification=true
fi
done
if [ "$need_modification" = false ]; then
log_info "✅ [跳过] 所有JS文件已经被修改过,无需重复操作"
return 0
fi
for file in "${CURSOR_JS_FILES[@]}"; do for file in "${CURSOR_JS_FILES[@]}"; do
log_info "处理文件: $file"
log_info "📝 [处理] 正在处理: $(basename "$file")"
if [ ! -f "$file" ]; then if [ ! -f "$file" ]; then
log_error "文件不存在: $file,跳过处理。" log_error "文件不存在: $file,跳过处理。"
file_modification_status+=("'$file': Not Found")
file_modification_status+=("'$(basename "$file")': Not Found")
continue
fi
# 检查是否已经修改过
if grep -q "__cursor_patched__" "$file"; then
log_info "✅ [跳过] 文件已经被修改过"
((modified_count++))
file_modification_status+=("'$(basename "$file")': Already Patched")
continue continue
fi fi
@ -681,189 +728,112 @@ modify_cursor_js_files() {
local backup_file="${file}.backup_$(date +%Y%m%d_%H%M%S)" local backup_file="${file}.backup_$(date +%Y%m%d_%H%M%S)"
if ! cp "$file" "$backup_file"; then if ! cp "$file" "$backup_file"; then
log_error "无法创建文件备份: $file" log_error "无法创建文件备份: $file"
file_modification_status+=("'$file': Backup Failed")
file_modification_status+=("'$(basename "$file")': Backup Failed")
continue continue
fi fi
chown "$CURRENT_USER":"$(id -g -n "$CURRENT_USER")" "$backup_file" || log_warn "设置备份文件所有权失败: $backup_file"
chmod 444 "$backup_file" || log_warn "设置备份文件权限失败: $backup_file"
chown "$CURRENT_USER":"$(id -g -n "$CURRENT_USER")" "$backup_file" 2>/dev/null || true
chmod 444 "$backup_file" 2>/dev/null || true
# 确保文件对当前执行用户(root)可写
# 确保文件对当前执行用户可写
chmod u+w "$file" || { chmod u+w "$file" || {
log_error "无法修改文件权限(写): $file" log_error "无法修改文件权限(写): $file"
file_modification_status+=("'$file': Permission Error (Write)")
# 尝试恢复备份(如果可能)
file_modification_status+=("'$(basename "$file")': Permission Error")
cp "$backup_file" "$file" 2>/dev/null || true cp "$backup_file" "$file" 2>/dev/null || true
continue continue
} }
local modification_applied=false
local replaced=false
# --- 开始尝试各种修改模式 ---
# ========== 方法A: someValue占位符替换(稳定锚点) ==========
# 这些字符串是固定的占位符,不会被混淆器修改,跨版本稳定
# 模式1:精确修改 x-cursor-checksum (最常见的目标之一)
if grep -q 'i.header.set("x-cursor-checksum' "$file"; then
log_debug "找到 x-cursor-checksum 设置代码,尝试修改..."
# 使用更健壮的 sed,处理不同的空格和变量名可能性
if sed -i -E 's/(i|[\w$]+)\.header\.set\("x-cursor-checksum",\s*e\s*===\s*void 0\s*\?\s*`\$\{p\}(\$\{t\})`\s*:\s*`\$\{p\}\2\/(\$\{e\})`/i.header.set("x-cursor-checksum",e===void 0?`${p}${t}`:`${p}${t}\/${p}`)/' "$file"; then
# 验证修改是否真的发生 (避免 sed 没匹配但返回0)
if ! grep -q 'i.header.set("x-cursor-checksum",e===void 0?`${p}${t}`:`${p}${t}\/${e}`)' "$file"; then
log_info "成功修改 x-cursor-checksum 设置代码"
modification_applied=true
else
log_warn "sed 命令执行成功,但似乎未修改 x-cursor-checksum (可能模式不匹配当前版本)"
fi
else
log_error "修改 x-cursor-checksum 设置代码失败 (sed 命令执行错误)"
fi
# 替换 someValue.machineId
if grep -q 'someValue\.machineId' "$file"; then
sed -i "s/someValue\.machineId/${machine_id}/g" "$file"
log_info " ✓ [方案A] 替换 someValue.machineId"
replaced=true
fi fi
# 模式2:注入 randomUUID 到特定函数 (如果模式1未应用)
if [ "$modification_applied" = false ] && grep -q "IOPlatformUUID" "$file"; then
log_debug "未修改 checksum 或未找到,尝试注入 randomUUID..."
# 尝试注入 a$ 函数
if grep -q "function a\$(" "$file" && ! grep -q "return crypto.randomUUID()" "$file"; then
if sed -i 's/function a\$(t){switch/function a\$(t){try { return require("crypto").randomUUID(); } catch(e){} switch/' "$file"; then
# 验证修改
if grep -q "return require(\"crypto\").randomUUID()" "$file"; then
log_info "成功注入 randomUUID 调用到 a\$ 函数"
modification_applied=true
else
log_warn "sed 注入 a$ 失败(可能模式不匹配)"
fi
else
log_error "修改 a\$ 函数失败 (sed 命令执行错误)"
fi
# 尝试注入 v5 函数 (如果 a$ 没成功)
elif [ "$modification_applied" = false ] && grep -q "async function v5(" "$file" && ! grep -q "return crypto.randomUUID()" "$file"; then
if sed -i 's/async function v5(t){let e=/async function v5(t){try { return require("crypto").randomUUID(); } catch(e){} let e=/' "$file"; then
# 验证修改
if grep -q "return require(\"crypto\").randomUUID()" "$file"; then
log_info "成功注入 randomUUID 调用到 v5 函数"
modification_applied=true
else
log_warn "sed 注入 v5 失败(可能模式不匹配)"
fi
else
log_error "修改 v5 函数失败 (sed 命令执行错误)"
fi
fi
# 替换 someValue.macMachineId
if grep -q 'someValue\.macMachineId' "$file"; then
sed -i "s/someValue\.macMachineId/${mac_machine_id}/g" "$file"
log_info " ✓ [方案A] 替换 someValue.macMachineId"
replaced=true
fi fi
# 模式3:通用注入 (如果上述模式都未应用,并且没有标记)
if [ "$modification_applied" = false ] && ! grep -q "// Cursor ID Modifier Injection" "$file"; then
log_debug "特定修改模式未生效或不适用,尝试通用注入..."
# 生成唯一标识符以避免冲突
local timestamp=$(date +%s)
local new_uuid=$(generate_uuid)
local machine_id=$(generate_uuid) # 使用 UUID
local device_id=$(generate_uuid)
local mac_machine_id=$(openssl rand -hex 32) # 伪造 MAC 相关 ID
# 创建注入代码块
local inject_universal_code="
// Cursor ID Modifier Injection - $timestamp
const originalRequire_$timestamp = typeof require === 'function' ? require : null;
if (originalRequire_$timestamp) {
require = function(module) {
try {
const result = originalRequire_$timestamp(module);
if (module === 'crypto' && result && result.randomUUID) {
const originalRandomUUID_$timestamp = result.randomUUID;
result.randomUUID = function() { return '$new_uuid'; };
console.log('Cursor Modifier: Patched crypto.randomUUID');
}
if (module === 'os' && result && result.networkInterfaces) {
const originalNI_$timestamp = result.networkInterfaces;
result.networkInterfaces = function() { return { lo: [{ address: '127.0.0.1', netmask: '255.0.0.0', family: 'IPv4', mac: '00:00:00:00:00:00', internal: true, cidr: '127.0.0.1/8' }]}; };
console.log('Cursor Modifier: Patched os.networkInterfaces');
}
return result;
} catch (e) {
console.error('Cursor Modifier: Error in require patch for module:', module, e);
// 如果原始 require 失败,可能需要返回一个空对象或抛出异常
// 尝试调用原始 require,即使它可能已在 try 块中失败
try { return originalRequire_$timestamp(module); } catch (innerE) { return {}; }
}
};
} else { console.warn('Cursor Modifier: Original require not found.'); }
// Override potential global functions or properties if they exist
try { if (typeof global !== 'undefined' && global.getMachineId) global.getMachineId = function() { return '$machine_id'; }; } catch(e){}
try { if (typeof global !== 'undefined' && global.getDeviceId) global.getDeviceId = function() { return '$device_id'; }; } catch(e){}
try { if (typeof global !== 'undefined' && global.macMachineId) global.macMachineId = '$mac_machine_id'; } catch(e){}
try { if (typeof process !== 'undefined' && process.env) process.env.VSCODE_MACHINE_ID = '$machine_id'; } catch(e){}
console.log('Cursor Modifier: Universal patches applied (UUID: $new_uuid)');
// End Cursor ID Modifier Injection - $timestamp
"
# 将变量替换进代码
inject_universal_code=${inject_universal_code//\$new_uuid/$new_uuid}
inject_universal_code=${inject_universal_code//\$machine_id/$machine_id}
inject_universal_code=${inject_universal_code//\$device_id/$device_id}
inject_universal_code=${inject_universal_code//\$mac_machine_id/$mac_machine_id}
inject_universal_code=${inject_universal_code//\$timestamp/$timestamp} # 确保时间戳替换
# 将代码注入到文件开头
local temp_inject_file=$(mktemp)
echo "$inject_universal_code" > "$temp_inject_file"
cat "$file" >> "$temp_inject_file"
if mv "$temp_inject_file" "$file"; then
log_info "完成通用注入修改"
modification_applied=true
else
log_error "通用注入失败 (无法移动临时文件)"
rm -f "$temp_inject_file" # 清理注入文件
fi
elif [ "$modification_applied" = false ]; then
log_info "文件 '$file' 似乎已被修改过 (包含注入标记),跳过通用注入。"
# 即使未应用新修改,也认为"成功"处理(避免恢复备份)
modification_applied=true # 标记为已处理,防止恢复备份
# 替换 someValue.devDeviceId
if grep -q 'someValue\.devDeviceId' "$file"; then
sed -i "s/someValue\.devDeviceId/${device_id}/g" "$file"
log_info " ✓ [方案A] 替换 someValue.devDeviceId"
replaced=true
fi
# 替换 someValue.sqmId
if grep -q 'someValue\.sqmId' "$file"; then
sed -i "s/someValue\.sqmId/${sqm_id}/g" "$file"
log_info " ✓ [方案A] 替换 someValue.sqmId"
replaced=true
fi fi
# --- 结束修改尝试 ---
# 替换 someValue.sessionId(新增锚点)
if grep -q 'someValue\.sessionId' "$file"; then
sed -i "s/someValue\.sessionId/${session_id}/g" "$file"
log_info " ✓ [方案A] 替换 someValue.sessionId"
replaced=true
fi
# ========== 方法B: IIFE运行时劫持(crypto.randomUUID) ==========
# 使用IIFE包装,兼容webpack打包的bundle文件,无需import语法
# 劫持crypto.randomUUID从源头拦截所有UUID生成
local inject_code=";(function(){/*__cursor_patched__*/var _cr=require('crypto'),_orig=_cr.randomUUID;_cr.randomUUID=function(){return'${new_uuid}';};if(typeof globalThis!=='undefined'){globalThis.__cursor_machine_id='${machine_id}';globalThis.__cursor_mac_machine_id='${mac_machine_id}';globalThis.__cursor_dev_device_id='${device_id}';globalThis.__cursor_sqm_id='${sqm_id}';}try{var _os=require('os'),_origNI=_os.networkInterfaces;_os.networkInterfaces=function(){var r=_origNI.call(_os);for(var k in r){if(r[k]){for(var i=0;i<r[k].length;i++){if(r[k][i].mac){r[k][i].mac='00:00:00:00:00:00';}}}}return r;};}catch(e){}console.log('[Cursor ID Modifier] 设备标识符已劫持 - 煎饼果子(86) 公众号【煎饼果子卷AI】');})();"
# 注入代码到文件开头
local temp_file=$(mktemp)
echo "$inject_code" > "$temp_file"
cat "$file" >> "$temp_file"
# 根据修改结果处理
if [ "$modification_applied" = true ]; then
if mv "$temp_file" "$file"; then
log_info " ✓ [方案B] IIFE运行时劫持代码已注入"
if [ "$replaced" = true ]; then
log_info "✅ [成功] A+B混合方案修改成功(someValue替换 + IIFE劫持)"
else
log_info "✅ [成功] 方案B修改成功(IIFE劫持)"
fi
((modified_count++)) ((modified_count++))
file_modification_status+=("'$file': Success")
file_modification_status+=("'$(basename "$file")': Success")
# 恢复文件权限为只读 # 恢复文件权限为只读
chmod u-w,go-w "$file" || log_warn "设置文件只读权限失败: $file"
# 设置文件所有者
chown "$CURRENT_USER":"$(id -g -n "$CURRENT_USER")" "$file" || log_warn "设置 JS 文件所有权失败: $file"
chmod u-w,go-w "$file" 2>/dev/null || true
chown "$CURRENT_USER":"$(id -g -n "$CURRENT_USER")" "$file" 2>/dev/null || true
else else
log_error "未能成功应用任何修改到文件: $file"
file_modification_status+=("'$file': Failed")
log_error "IIFE注入失败 (无法移动临时文件)"
rm -f "$temp_file"
file_modification_status+=("'$(basename "$file")': Inject Failed")
# 恢复备份 # 恢复备份
log_info "正在从备份恢复文件: $file"
if cp "$backup_file" "$file"; then
chmod u-w,go-w "$file" || log_warn "恢复备份后设置只读权限失败: $file"
chown "$CURRENT_USER":"$(id -g -n "$CURRENT_USER")" "$file" || log_warn "恢复备份后设置所有权失败: $file"
else
log_error "从备份恢复文件失败: $file"
# 文件可能处于不确定状态
fi
cp "$backup_file" "$file" 2>/dev/null || true
fi fi
# 清理备份文件
rm -f "$backup_file"
# 清理备份文件(可选保留)
# rm -f "$backup_file"
done # 文件循环结束 done # 文件循环结束
# 报告每个文件的状态 # 报告每个文件的状态
log_info "JS 文件处理状态汇总:"
log_info "📊 [统计] JS 文件处理状态汇总:"
for status in "${file_modification_status[@]}"; do for status in "${file_modification_status[@]}"; do
log_info "- $status"
log_info " - $status"
done done
if [ "$modified_count" -eq 0 ]; then if [ "$modified_count" -eq 0 ]; then
log_error "未能成功修改任何JS文件。请检查日志以获取详细信息。"
log_error "❌ [失败] 未能成功修改任何JS文件。"
return 1 return 1
fi fi
log_info "成功修改或确认了 $modified_count 个JS文件。"
log_info "🎉 [完成] 成功修改 $modified_count 个JS文件"
log_info "💡 [说明] 使用A+B混合方案:"
log_info " • 方案A: someValue占位符替换(稳定锚点,跨版本兼容)"
log_info " • 方案B: IIFE运行时劫持(crypto.randomUUID + os.networkInterfaces)"
return 0 return 0
} }

163
scripts/run/cursor_mac_id_modifier.sh

@ -1420,9 +1420,12 @@ backup_config() {
fi fi
} }
# 🔧 修改Cursor内核JS文件实现设备识别绕过(新增核心功能)
# 🔧 修改Cursor内核JS文件实现设备识别绕过(A+B混合方案 - IIFE + someValue替换)
# 方案A: someValue占位符替换 - 稳定锚点,不依赖混淆后的函数名
# 方案B: IIFE运行时劫持 - 劫持crypto.randomUUID从源头拦截
modify_cursor_js_files() { modify_cursor_js_files() {
log_info "🔧 [内核修改] 开始修改Cursor内核JS文件实现设备识别绕过..." log_info "🔧 [内核修改] 开始修改Cursor内核JS文件实现设备识别绕过..."
log_info "💡 [方案] 使用A+B混合方案:someValue占位符替换 + IIFE运行时劫持"
echo echo
# 检查Cursor应用是否存在 # 检查Cursor应用是否存在
@ -1431,15 +1434,21 @@ modify_cursor_js_files() {
return 1 return 1
fi fi
# 生成新的设备标识符
# 生成新的设备标识符(使用固定格式确保兼容性)
local new_uuid=$(uuidgen | tr '[:upper:]' '[:lower:]') local new_uuid=$(uuidgen | tr '[:upper:]' '[:lower:]')
local machine_id="auth0|user_$(openssl rand -hex 16)"
local machine_id=$(openssl rand -hex 32)
local device_id=$(uuidgen | tr '[:upper:]' '[:lower:]') local device_id=$(uuidgen | tr '[:upper:]' '[:lower:]')
local mac_machine_id=$(openssl rand -hex 32) local mac_machine_id=$(openssl rand -hex 32)
local sqm_id=$(uuidgen | tr '[:upper:]' '[:lower:]')
# 生成一个固定的session_id用于替换someValue.sessionId
local session_id=$(uuidgen | tr '[:upper:]' '[:lower:]')
log_info "🔑 [生成] 已生成新的设备标识符" log_info "🔑 [生成] 已生成新的设备标识符"
log_info " machineId: ${machine_id:0:16}..."
log_info " deviceId: ${device_id:0:16}..."
log_info " macMachineId: ${mac_machine_id:0:16}..."
# 目标JS文件列表
# 目标JS文件列表(按优先级排序)
local js_files=( local js_files=(
"$CURSOR_APP_PATH/Contents/Resources/app/out/vs/workbench/api/node/extensionHostProcess.js" "$CURSOR_APP_PATH/Contents/Resources/app/out/vs/workbench/api/node/extensionHostProcess.js"
"$CURSOR_APP_PATH/Contents/Resources/app/out/main.js" "$CURSOR_APP_PATH/Contents/Resources/app/out/main.js"
@ -1449,7 +1458,7 @@ modify_cursor_js_files() {
local modified_count=0 local modified_count=0
local need_modification=false local need_modification=false
# 检查是否需要修改
# 检查是否需要修改(使用统一标记)
log_info "🔍 [检查] 检查JS文件修改状态..." log_info "🔍 [检查] 检查JS文件修改状态..."
for file in "${js_files[@]}"; do for file in "${js_files[@]}"; do
if [ ! -f "$file" ]; then if [ ! -f "$file" ]; then
@ -1457,12 +1466,12 @@ modify_cursor_js_files() {
continue continue
fi fi
if ! grep -q "return crypto.randomUUID()" "$file" 2>/dev/null; then
# 检查是否已经被修改过(使用统一标记 __cursor_patched__)
if grep -q "__cursor_patched__" "$file" 2>/dev/null; then
log_info "✅ [已修改] 文件已修改: ${file/$CURSOR_APP_PATH\//}"
else
log_info "📝 [需要] 文件需要修改: ${file/$CURSOR_APP_PATH\//}" log_info "📝 [需要] 文件需要修改: ${file/$CURSOR_APP_PATH\//}"
need_modification=true need_modification=true
break
else
log_info "✅ [已修改] 文件已修改: ${file/$CURSOR_APP_PATH\//}"
fi fi
done done
@ -1477,15 +1486,16 @@ modify_cursor_js_files() {
# 创建备份 # 创建备份
local timestamp=$(date +%Y%m%d_%H%M%S) local timestamp=$(date +%Y%m%d_%H%M%S)
local backup_app="/tmp/Cursor.app.backup_js_${timestamp}"
local backup_dir="/tmp/Cursor_JS_Backup_${timestamp}"
log_info "💾 [备份] 创建Cursor应用备份..."
if ! cp -R "$CURSOR_APP_PATH" "$backup_app"; then
log_error "❌ [错误] 创建备份失败"
return 1
fi
log_info "✅ [备份] 备份创建成功: $backup_app"
log_info "💾 [备份] 创建JS文件备份..."
mkdir -p "$backup_dir"
for file in "${js_files[@]}"; do
if [ -f "$file" ]; then
cp "$file" "$backup_dir/$(basename "$file")"
fi
done
log_info "✅ [备份] 备份创建成功: $backup_dir"
# 修改JS文件 # 修改JS文件
log_info "🔧 [修改] 开始修改JS文件..." log_info "🔧 [修改] 开始修改JS文件..."
@ -1499,93 +1509,80 @@ modify_cursor_js_files() {
log_info "📝 [处理] 正在处理: ${file/$CURSOR_APP_PATH\//}" log_info "📝 [处理] 正在处理: ${file/$CURSOR_APP_PATH\//}"
# 检查是否已经修改过 # 检查是否已经修改过
if grep -q "return crypto.randomUUID()" "$file" || grep -q "// Cursor ID 修改工具注入" "$file"; then
if grep -q "__cursor_patched__" "$file"; then
log_info "✅ [跳过] 文件已经被修改过" log_info "✅ [跳过] 文件已经被修改过"
((modified_count++)) ((modified_count++))
continue continue
fi fi
# 方法1: 查找IOPlatformUUID相关函数
if grep -q "IOPlatformUUID" "$file"; then
log_info "🔍 [发现] 找到IOPlatformUUID关键字"
# 针对不同的函数模式进行修改
if grep -q "function a\$" "$file"; then
if sed -i.tmp 's/function a\$(t){switch/function a\$(t){return crypto.randomUUID(); switch/' "$file"; then
log_info "✅ [成功] 修改a$函数成功"
((modified_count++))
continue
fi
fi
# 通用注入方法 - ES模块兼容版本
local inject_code="
// Cursor ID 修改工具注入 - $(date) - ES模块兼容版本
import crypto from 'crypto';
// 保存原始函数引用
const originalRandomUUID_$(date +%s) = crypto.randomUUID;
// 重写crypto.randomUUID方法
crypto.randomUUID = function() {
return '${new_uuid}';
};
# ========== 方法A: someValue占位符替换(稳定锚点) ==========
# 这些字符串是固定的占位符,不会被混淆器修改,跨版本稳定
local replaced=false
// 覆盖所有可能的系统ID获取函数 - ES模块兼容版本
globalThis.getMachineId = function() { return '${machine_id}'; };
globalThis.getDeviceId = function() { return '${device_id}'; };
globalThis.macMachineId = '${mac_machine_id}';
# 替换 someValue.machineId
if grep -q 'someValue\.machineId' "$file"; then
sed -i.tmp "s/someValue\.machineId/${machine_id}/g" "$file"
log_info " ✓ [方案A] 替换 someValue.machineId"
replaced=true
fi
// 确保在不同环境下都能访问
if (typeof window !== 'undefined') {
window.getMachineId = globalThis.getMachineId;
window.getDeviceId = globalThis.getDeviceId;
window.macMachineId = globalThis.macMachineId;
}
# 替换 someValue.macMachineId
if grep -q 'someValue\.macMachineId' "$file"; then
sed -i.tmp "s/someValue\.macMachineId/${mac_machine_id}/g" "$file"
log_info " ✓ [方案A] 替换 someValue.macMachineId"
replaced=true
fi
// 确保模块顶层执行
console.log('Cursor设备标识符已成功劫持 - ES模块版本 煎饼果子(86) 关注公众号【煎饼果子卷AI】一起交流更多Cursor技巧和AI知识(脚本免费、关注公众号加群有更多技巧和大佬)');
"
# 替换 someValue.devDeviceId
if grep -q 'someValue\.devDeviceId' "$file"; then
sed -i.tmp "s/someValue\.devDeviceId/${device_id}/g" "$file"
log_info " ✓ [方案A] 替换 someValue.devDeviceId"
replaced=true
fi
# 替换变量
inject_code=${inject_code//\$\{new_uuid\}/$new_uuid}
inject_code=${inject_code//\$\{machine_id\}/$machine_id}
inject_code=${inject_code//\$\{device_id\}/$device_id}
inject_code=${inject_code//\$\{mac_machine_id\}/$mac_machine_id}
# 替换 someValue.sqmId
if grep -q 'someValue\.sqmId' "$file"; then
sed -i.tmp "s/someValue\.sqmId/${sqm_id}/g" "$file"
log_info " ✓ [方案A] 替换 someValue.sqmId"
replaced=true
fi
# 注入代码到文件开头
echo "$inject_code" > "${file}.new"
cat "$file" >> "${file}.new"
mv "${file}.new" "$file"
# 替换 someValue.sessionId(新增锚点)
if grep -q 'someValue\.sessionId' "$file"; then
sed -i.tmp "s/someValue\.sessionId/${session_id}/g" "$file"
log_info " ✓ [方案A] 替换 someValue.sessionId"
replaced=true
fi
log_info "✅ [成功] 通用注入方法修改成功"
((modified_count++))
# ========== 方法B: IIFE运行时劫持(crypto.randomUUID) ==========
# 使用IIFE包装,兼容webpack打包的bundle文件,无需import语法
# 劫持crypto.randomUUID从源头拦截所有UUID生成
local inject_code=";(function(){/*__cursor_patched__*/var _cr=require('crypto'),_orig=_cr.randomUUID;_cr.randomUUID=function(){return'${new_uuid}';};if(typeof globalThis!=='undefined'){globalThis.__cursor_machine_id='${machine_id}';globalThis.__cursor_mac_machine_id='${mac_machine_id}';globalThis.__cursor_dev_device_id='${device_id}';globalThis.__cursor_sqm_id='${sqm_id}';}try{var _os=require('os'),_origNI=_os.networkInterfaces;_os.networkInterfaces=function(){var r=_origNI.call(_os);for(var k in r){if(r[k]){for(var i=0;i<r[k].length;i++){if(r[k][i].mac){r[k][i].mac='00:00:00:00:00:00';}}}}return r;};}catch(e){}console.log('[Cursor ID Modifier] 设备标识符已劫持 - 煎饼果子(86) 公众号【煎饼果子卷AI】');})();"
# 方法2: 查找其他设备ID相关函数
elif grep -q "function t\$()" "$file" || grep -q "async function y5" "$file"; then
log_info "🔍 [发现] 找到设备ID相关函数"
# 注入代码到文件开头
echo "$inject_code" > "${file}.new"
cat "$file" >> "${file}.new"
mv "${file}.new" "$file"
# 修改MAC地址获取函数
if grep -q "function t\$()" "$file"; then
sed -i.tmp 's/function t\$(){/function t\$(){return "00:00:00:00:00:00";/' "$file"
log_info "✅ [成功] 修改MAC地址获取函数"
fi
log_info " ✓ [方案B] IIFE运行时劫持代码已注入"
# 修改设备ID获取函数
if grep -q "async function y5" "$file"; then
sed -i.tmp 's/async function y5(t){/async function y5(t){return crypto.randomUUID();/' "$file"
log_info "✅ [成功] 修改设备ID获取函数"
fi
# 清理临时文件
rm -f "${file}.tmp"
((modified_count++))
if [ "$replaced" = true ]; then
log_info "✅ [成功] A+B混合方案修改成功(someValue替换 + IIFE劫持)"
else else
log_warn "⚠️ [警告] 未找到已知的设备ID函数模式,跳过此文件"
log_info "✅ [成功] 方案B修改成功(IIFE劫持)"
fi fi
((modified_count++))
done done
if [ $modified_count -gt 0 ]; then if [ $modified_count -gt 0 ]; then
log_info "🎉 [完成] 成功修改 $modified_count 个JS文件" log_info "🎉 [完成] 成功修改 $modified_count 个JS文件"
log_info "💾 [备份] 原始文件备份位置: $backup_app"
log_info "💾 [备份] 原始文件备份位置: $backup_dir"
log_info "💡 [说明] 使用A+B混合方案:"
log_info " • 方案A: someValue占位符替换(稳定锚点,跨版本兼容)"
log_info " • 方案B: IIFE运行时劫持(crypto.randomUUID + os.networkInterfaces)"
return 0 return 0
else else
log_error "❌ [失败] 没有成功修改任何文件" log_error "❌ [失败] 没有成功修改任何文件"

155
scripts/run/cursor_win_id_modifier.ps1

@ -24,10 +24,13 @@ function Generate-RandomString {
return $result return $result
} }
# 修改Cursor内核JS文件实现设备识别绕过(从macOS版本移植)
# 🔧 修改Cursor内核JS文件实现设备识别绕过(A+B混合方案 - IIFE + someValue替换)
# 方案A: someValue占位符替换 - 稳定锚点,不依赖混淆后的函数名
# 方案B: IIFE运行时劫持 - 劫持crypto.randomUUID从源头拦截
function Modify-CursorJSFiles { function Modify-CursorJSFiles {
Write-Host "" Write-Host ""
Write-Host "$BLUE🔧 [内核修改]$NC 开始修改Cursor内核JS文件实现设备识别绕过..." Write-Host "$BLUE🔧 [内核修改]$NC 开始修改Cursor内核JS文件实现设备识别绕过..."
Write-Host "$BLUE💡 [方案]$NC 使用A+B混合方案:someValue占位符替换 + IIFE运行时劫持"
Write-Host "" Write-Host ""
# Windows版Cursor应用路径 # Windows版Cursor应用路径
@ -56,15 +59,28 @@ function Modify-CursorJSFiles {
Write-Host "$GREEN✅ [发现]$NC 找到Cursor安装路径: $cursorAppPath" Write-Host "$GREEN✅ [发现]$NC 找到Cursor安装路径: $cursorAppPath"
# 生成新的设备标识符
# 生成新的设备标识符(使用固定格式确保兼容性)
$newUuid = [System.Guid]::NewGuid().ToString().ToLower() $newUuid = [System.Guid]::NewGuid().ToString().ToLower()
$machineId = "auth0|user_$(Generate-RandomString -Length 32)"
$randomBytes = New-Object byte[] 32
$rng = [System.Security.Cryptography.RNGCryptoServiceProvider]::new()
$rng.GetBytes($randomBytes)
$machineId = [System.BitConverter]::ToString($randomBytes) -replace '-',''
$rng.Dispose()
$deviceId = [System.Guid]::NewGuid().ToString().ToLower() $deviceId = [System.Guid]::NewGuid().ToString().ToLower()
$macMachineId = Generate-RandomString -Length 64
$randomBytes2 = New-Object byte[] 32
$rng2 = [System.Security.Cryptography.RNGCryptoServiceProvider]::new()
$rng2.GetBytes($randomBytes2)
$macMachineId = [System.BitConverter]::ToString($randomBytes2) -replace '-',''
$rng2.Dispose()
$sqmId = [System.Guid]::NewGuid().ToString().ToLower()
$sessionId = [System.Guid]::NewGuid().ToString().ToLower()
Write-Host "$GREEN🔑 [生成]$NC 已生成新的设备标识符" Write-Host "$GREEN🔑 [生成]$NC 已生成新的设备标识符"
Write-Host " machineId: $($machineId.Substring(0,16))..."
Write-Host " deviceId: $($deviceId.Substring(0,16))..."
Write-Host " macMachineId: $($macMachineId.Substring(0,16))..."
# 目标JS文件列表(Windows路径)
# 目标JS文件列表(Windows路径,按优先级排序
$jsFiles = @( $jsFiles = @(
"$cursorAppPath\resources\app\out\vs\workbench\api\node\extensionHostProcess.js", "$cursorAppPath\resources\app\out\vs\workbench\api\node\extensionHostProcess.js",
"$cursorAppPath\resources\app\out\main.js", "$cursorAppPath\resources\app\out\main.js",
@ -74,7 +90,7 @@ function Modify-CursorJSFiles {
$modifiedCount = 0 $modifiedCount = 0
$needModification = $false $needModification = $false
# 检查是否需要修改
# 检查是否需要修改(使用统一标记 __cursor_patched__)
Write-Host "$BLUE🔍 [检查]$NC 检查JS文件修改状态..." Write-Host "$BLUE🔍 [检查]$NC 检查JS文件修改状态..."
foreach ($file in $jsFiles) { foreach ($file in $jsFiles) {
if (-not (Test-Path $file)) { if (-not (Test-Path $file)) {
@ -83,12 +99,11 @@ function Modify-CursorJSFiles {
} }
$content = Get-Content $file -Raw -ErrorAction SilentlyContinue $content = Get-Content $file -Raw -ErrorAction SilentlyContinue
if ($content -and $content -notmatch "return crypto\.randomUUID\(\)") {
if ($content -and $content -match "__cursor_patched__") {
Write-Host "$GREEN✅ [已修改]$NC 文件已修改: $(Split-Path $file -Leaf)"
} else {
Write-Host "$BLUE📝 [需要]$NC 文件需要修改: $(Split-Path $file -Leaf)" Write-Host "$BLUE📝 [需要]$NC 文件需要修改: $(Split-Path $file -Leaf)"
$needModification = $true $needModification = $true
break
} else {
Write-Host "$GREEN✅ [已修改]$NC 文件已修改: $(Split-Path $file -Leaf)"
} }
} }
@ -134,88 +149,72 @@ function Modify-CursorJSFiles {
try { try {
$content = Get-Content $file -Raw -Encoding UTF8 $content = Get-Content $file -Raw -Encoding UTF8
# 检查是否已经修改过
if ($content -match "return crypto\.randomUUID\(\)" -or $content -match "// Cursor ID 修改工具注入") {
# 检查是否已经修改过(使用统一标记)
if ($content -match "__cursor_patched__") {
Write-Host "$GREEN✅ [跳过]$NC 文件已经被修改过" Write-Host "$GREEN✅ [跳过]$NC 文件已经被修改过"
$modifiedCount++ $modifiedCount++
continue continue
} }
# ES模块兼容的JavaScript注入代码
$timestampVar = [DateTimeOffset]::Now.ToUnixTimeSeconds()
$injectCode = @"
// Cursor ID 修改工具注入 - $(Get-Date) - ES模块兼容版本
import crypto from 'crypto';
// 保存原始函数引用
const originalRandomUUID_${timestampVar} = crypto.randomUUID;
// 重写crypto.randomUUID方法
crypto.randomUUID = function() {
return '${newUuid}';
};
// 覆盖所有可能的系统ID获取函数 - ES模块兼容版本
globalThis.getMachineId = function() { return '${machineId}'; };
globalThis.getDeviceId = function() { return '${deviceId}'; };
globalThis.macMachineId = '${macMachineId}';
// 确保在不同环境下都能访问
if (typeof window !== 'undefined') {
window.getMachineId = globalThis.getMachineId;
window.getDeviceId = globalThis.getDeviceId;
window.macMachineId = globalThis.macMachineId;
}
// 确保模块顶层执行
console.log('Cursor设备标识符已成功劫持 - ES模块版本 煎饼果子(86) 关注公众号【煎饼果子卷AI】一起交流更多Cursor技巧和AI知识(脚本免费、关注公众号加群有更多技巧和大佬)');
"@
$replaced = $false
# 方法1: 查找IOPlatformUUID相关函数
if ($content -match "IOPlatformUUID") {
Write-Host "$BLUE🔍 [发现]$NC 找到IOPlatformUUID关键字"
# ========== 方法A: someValue占位符替换(稳定锚点) ==========
# 这些字符串是固定的占位符,不会被混淆器修改,跨版本稳定
# 针对不同的函数模式进行修改
if ($content -match "function a\$") {
$content = $content -replace "function a\$\(t\)\{switch", "function a`$(t){return crypto.randomUUID(); switch"
Write-Host "$GREEN✅ [成功]$NC 修改a`$函数成功"
$modifiedCount++
continue
}
# 替换 someValue.machineId
if ($content -match 'someValue\.machineId') {
$content = $content -replace 'someValue\.machineId', $machineId
Write-Host " $GREEN✓$NC [方案A] 替换 someValue.machineId"
$replaced = $true
}
# 通用注入方法
$content = $injectCode + $content
Write-Host "$GREEN✅ [成功]$NC 通用注入方法修改成功"
$modifiedCount++
# 替换 someValue.macMachineId
if ($content -match 'someValue\.macMachineId') {
$content = $content -replace 'someValue\.macMachineId', $macMachineId
Write-Host " $GREEN✓$NC [方案A] 替换 someValue.macMachineId"
$replaced = $true
} }
# 方法2: 查找其他设备ID相关函数
elseif ($content -match "function t\$\(\)" -or $content -match "async function y5") {
Write-Host "$BLUE🔍 [发现]$NC 找到设备ID相关函数"
# 修改MAC地址获取函数
if ($content -match "function t\$\(\)") {
$content = $content -replace "function t\$\(\)\{", "function t`$(){return `"00:00:00:00:00:00`";"
Write-Host "$GREEN✅ [成功]$NC 修改MAC地址获取函数"
}
# 修改设备ID获取函数
if ($content -match "async function y5") {
$content = $content -replace "async function y5\(t\)\{", "async function y5(t){return crypto.randomUUID();"
Write-Host "$GREEN✅ [成功]$NC 修改设备ID获取函数"
}
# 替换 someValue.devDeviceId
if ($content -match 'someValue\.devDeviceId') {
$content = $content -replace 'someValue\.devDeviceId', $deviceId
Write-Host " $GREEN✓$NC [方案A] 替换 someValue.devDeviceId"
$replaced = $true
}
$modifiedCount++
# 替换 someValue.sqmId
if ($content -match 'someValue\.sqmId') {
$content = $content -replace 'someValue\.sqmId', $sqmId
Write-Host " $GREEN✓$NC [方案A] 替换 someValue.sqmId"
$replaced = $true
} }
else {
Write-Host "$YELLOW⚠️ [警告]$NC 未找到已知的设备ID函数模式,使用通用注入"
$content = $injectCode + $content
$modifiedCount++
# 替换 someValue.sessionId(新增锚点)
if ($content -match 'someValue\.sessionId') {
$content = $content -replace 'someValue\.sessionId', $sessionId
Write-Host " $GREEN✓$NC [方案A] 替换 someValue.sessionId"
$replaced = $true
} }
# ========== 方法B: IIFE运行时劫持(crypto.randomUUID) ==========
# 使用IIFE包装,兼容webpack打包的bundle文件,无需import语法
# 劫持crypto.randomUUID从源头拦截所有UUID生成
$injectCode = ";(function(){/*__cursor_patched__*/var _cr=require('crypto'),_orig=_cr.randomUUID;_cr.randomUUID=function(){return'$newUuid';};if(typeof globalThis!=='undefined'){globalThis.__cursor_machine_id='$machineId';globalThis.__cursor_mac_machine_id='$macMachineId';globalThis.__cursor_dev_device_id='$deviceId';globalThis.__cursor_sqm_id='$sqmId';}try{var _os=require('os'),_origNI=_os.networkInterfaces;_os.networkInterfaces=function(){var r=_origNI.call(_os);for(var k in r){if(r[k]){for(var i=0;i<r[k].length;i++){if(r[k][i].mac){r[k][i].mac='00:00:00:00:00:00';}}}}return r;};}catch(e){}console.log('[Cursor ID Modifier] 设备标识符已劫持 - 煎饼果子(86) 公众号【煎饼果子卷AI】');})();"
# 注入代码到文件开头
$content = $injectCode + "`n" + $content
Write-Host " $GREEN✓$NC [方案B] IIFE运行时劫持代码已注入"
# 写入修改后的内容 # 写入修改后的内容
Set-Content -Path $file -Value $content -Encoding UTF8 -NoNewline Set-Content -Path $file -Value $content -Encoding UTF8 -NoNewline
Write-Host "$GREEN✅ [完成]$NC 文件修改完成: $(Split-Path $file -Leaf)"
if ($replaced) {
Write-Host "$GREEN✅ [成功]$NC A+B混合方案修改成功(someValue替换 + IIFE劫持)"
} else {
Write-Host "$GREEN✅ [成功]$NC 方案B修改成功(IIFE劫持)"
}
$modifiedCount++
} catch { } catch {
Write-Host "$RED❌ [错误]$NC 修改文件失败: $($_.Exception.Message)" Write-Host "$RED❌ [错误]$NC 修改文件失败: $($_.Exception.Message)"
@ -233,7 +232,9 @@ console.log('Cursor设备标识符已成功劫持 - ES模块版本 煎饼果子(
Write-Host "" Write-Host ""
Write-Host "$GREEN🎉 [完成]$NC 成功修改 $modifiedCount 个JS文件" Write-Host "$GREEN🎉 [完成]$NC 成功修改 $modifiedCount 个JS文件"
Write-Host "$BLUE💾 [备份]$NC 原始文件备份位置: $backupPath" Write-Host "$BLUE💾 [备份]$NC 原始文件备份位置: $backupPath"
Write-Host "$BLUE💡 [说明]$NC JavaScript注入功能已启用,实现设备识别绕过"
Write-Host "$BLUE💡 [说明]$NC 使用A+B混合方案:"
Write-Host " • 方案A: someValue占位符替换(稳定锚点,跨版本兼容)"
Write-Host " • 方案B: IIFE运行时劫持(crypto.randomUUID + os.networkInterfaces)"
return $true return $true
} else { } else {
Write-Host "$RED❌ [失败]$NC 没有成功修改任何文件" Write-Host "$RED❌ [失败]$NC 没有成功修改任何文件"

Loading…
Cancel
Save