Browse Source

feat(cursor): 实现跨平台设备标识符Hook注入方案

- 新增 cursor_hook.js 核心Hook模块,拦截child_process、crypto、os等关键模块
- 实现统一ID配置管理,支持环境变量和JSON配置文件双重加载机制
- 开发Unix/macOS注入脚本(inject_hook_unix.sh),自动化Hook代码注入流程
- 开发Windows注入脚本(inject_hook_win.ps1),适配PowerShell环境
- 升级Linux修改器脚本,集成新的Hook方案并优化备份机制
- 添加完整的调试日志系统和防重复注入保护机制
- 支持动态import模块Hook,增强对ESM环境的兼容性
煎饼果子卷鲨鱼辣椒 1 month ago
parent
commit
f35d9ede3b
  1. 58
      scripts/run/cursor_linux_id_modifier.sh
  2. 76
      scripts/run/cursor_mac_id_modifier.sh
  3. 69
      scripts/run/cursor_win_id_modifier.ps1

58
scripts/run/cursor_linux_id_modifier.sh

@ -752,8 +752,12 @@ modify_cursor_js_files() {
log_info " macMachineId: ${mac_machine_id:0:16}..." log_info " macMachineId: ${mac_machine_id:0:16}..."
log_info " sqmId: $sqm_id" log_info " sqmId: $sqm_id"
# 保存 ID 配置到用户目录(供 Hook 读取)
# 每次执行都删除旧配置并重新生成,确保获得新的设备标识符
local ids_config_path="$HOME/.cursor_ids.json" local ids_config_path="$HOME/.cursor_ids.json"
if [ -f "$ids_config_path" ]; then
rm -f "$ids_config_path"
log_info "🗑️ [清理] 已删除旧的 ID 配置文件"
fi
cat > "$ids_config_path" << EOF cat > "$ids_config_path" << EOF
{ {
"machineId": "$machine_id", "machineId": "$machine_id",
@ -765,33 +769,12 @@ modify_cursor_js_files() {
} }
EOF EOF
chown "$CURRENT_USER":"$(id -g -n "$CURRENT_USER")" "$ids_config_path" 2>/dev/null || true chown "$CURRENT_USER":"$(id -g -n "$CURRENT_USER")" "$ids_config_path" 2>/dev/null || true
log_info "💾 [保存] ID 配置已保存到: $ids_config_path"
log_info "💾 [保存] 新的 ID 配置已保存到: $ids_config_path"
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
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 "📝 [处理] 正在处理: $(basename "$file")" log_info "📝 [处理] 正在处理: $(basename "$file")"
@ -801,28 +784,31 @@ EOF
continue continue
fi fi
if grep -q "__cursor_patched__" "$file"; then
log_info "✅ [跳过] 文件已经被修改过"
((modified_count++))
file_modification_status+=("'$(basename "$file")': Already Patched")
continue
fi
# 创建备份目录 # 创建备份目录
local backup_dir="$(dirname "$file")/backups" local backup_dir="$(dirname "$file")/backups"
mkdir -p "$backup_dir" 2>/dev/null || true mkdir -p "$backup_dir" 2>/dev/null || true
# 创建原始备份(如果不存在)
local original_backup="$backup_dir/$(basename "$file").original"
local file_name=$(basename "$file")
local original_backup="$backup_dir/$file_name.original"
# 如果原始备份不存在,先创建
if [ ! -f "$original_backup" ]; then if [ ! -f "$original_backup" ]; then
# 检查当前文件是否已被修改过
if grep -q "__cursor_patched__" "$file" 2>/dev/null; then
log_warn "⚠️ [警告] 文件已被修改但无原始备份,将使用当前版本作为基础"
fi
cp "$file" "$original_backup" cp "$file" "$original_backup"
chown "$CURRENT_USER":"$(id -g -n "$CURRENT_USER")" "$original_backup" 2>/dev/null || true chown "$CURRENT_USER":"$(id -g -n "$CURRENT_USER")" "$original_backup" 2>/dev/null || true
chmod 444 "$original_backup" 2>/dev/null || true chmod 444 "$original_backup" 2>/dev/null || true
log_info "✅ [备份] 原始备份创建成功"
log_info "✅ [备份] 原始备份创建成功: $file_name"
else
# 从原始备份恢复,确保每次都是干净的注入
log_info "🔄 [恢复] 从原始备份恢复: $file_name"
cp "$original_backup" "$file"
fi fi
# 创建时间戳备份
local backup_file="$backup_dir/$(basename "$file").backup_$(date +%Y%m%d_%H%M%S)"
# 创建时间戳备份(记录每次修改前的状态)
local backup_file="$backup_dir/$file_name.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+=("'$(basename "$file")': Backup Failed") file_modification_status+=("'$(basename "$file")': Backup Failed")

76
scripts/run/cursor_mac_id_modifier.sh

@ -1542,7 +1542,12 @@ modify_cursor_js_files() {
log_info " sqmId: $sqm_id" log_info " sqmId: $sqm_id"
# 保存 ID 配置到用户目录(供 Hook 读取) # 保存 ID 配置到用户目录(供 Hook 读取)
# 每次执行都删除旧配置并重新生成,确保获得新的设备标识符
local ids_config_path="$HOME/.cursor_ids.json" local ids_config_path="$HOME/.cursor_ids.json"
if [ -f "$ids_config_path" ]; then
rm -f "$ids_config_path"
log_info "🗑️ [清理] 已删除旧的 ID 配置文件"
fi
cat > "$ids_config_path" << EOF cat > "$ids_config_path" << EOF
{ {
"machineId": "$machine_id", "machineId": "$machine_id",
@ -1553,7 +1558,7 @@ modify_cursor_js_files() {
"createdAt": "$first_session_date" "createdAt": "$first_session_date"
} }
EOF EOF
log_info "💾 [保存] ID 配置已保存到: $ids_config_path"
log_info "💾 [保存] 新的 ID 配置已保存到: $ids_config_path"
# 目标JS文件列表(只修改 main.js) # 目标JS文件列表(只修改 main.js)
local js_files=( local js_files=(
@ -1561,52 +1566,44 @@ EOF
) )
local modified_count=0 local modified_count=0
local need_modification=false
# 检查是否需要修改(使用统一标记)
log_info "🔍 [检查] 检查JS文件修改状态..."
for file in "${js_files[@]}"; do
if [ ! -f "$file" ]; then
log_warn "⚠️ [警告] 文件不存在: ${file/$CURSOR_APP_PATH\//}"
continue
fi
if grep -q "__cursor_patched__" "$file" 2>/dev/null; then
log_info "✅ [已修改] 文件已修改: ${file/$CURSOR_APP_PATH\//}"
else
log_info "📝 [需要] 文件需要修改: ${file/$CURSOR_APP_PATH\//}"
need_modification=true
fi
done
if [ "$need_modification" = false ]; then
log_info "✅ [跳过] 所有JS文件已经被修改过,无需重复操作"
return 0
fi
# 关闭Cursor进程 # 关闭Cursor进程
log_info "🔄 [关闭] 关闭Cursor进程以进行文件修改..." log_info "🔄 [关闭] 关闭Cursor进程以进行文件修改..."
check_and_kill_cursor check_and_kill_cursor
# 创建备份
# 创建备份目录
local timestamp=$(date +%Y%m%d_%H%M%S) local timestamp=$(date +%Y%m%d_%H%M%S)
local backup_dir="$CURSOR_APP_PATH/Contents/Resources/app/out/backups" local backup_dir="$CURSOR_APP_PATH/Contents/Resources/app/out/backups"
log_info "💾 [备份] 创建JS文件备份..." log_info "💾 [备份] 创建JS文件备份..."
mkdir -p "$backup_dir" mkdir -p "$backup_dir"
# 创建原始备份(如果不存在)
local original_backup="$backup_dir/main.js.original"
if [ ! -f "$original_backup" ]; then
for file in "${js_files[@]}"; do
if [ -f "$file" ]; then
cp "$file" "$backup_dir/$(basename "$file").original"
# 处理每个文件:创建原始备份或从原始备份恢复
for file in "${js_files[@]}"; do
if [ ! -f "$file" ]; then
log_warn "⚠️ [警告] 文件不存在: ${file/$CURSOR_APP_PATH\//}"
continue
fi
local file_name=$(basename "$file")
local file_original_backup="$backup_dir/$file_name.original"
# 如果原始备份不存在,先创建
if [ ! -f "$file_original_backup" ]; then
# 检查当前文件是否已被修改过
if grep -q "__cursor_patched__" "$file" 2>/dev/null; then
log_warn "⚠️ [警告] 文件已被修改但无原始备份,将使用当前版本作为基础"
fi fi
done
log_info "✅ [备份] 原始备份创建成功"
fi
cp "$file" "$file_original_backup"
log_info "✅ [备份] 原始备份创建成功: $file_name"
else
# 从原始备份恢复,确保每次都是干净的注入
log_info "🔄 [恢复] 从原始备份恢复: $file_name"
cp "$file_original_backup" "$file"
fi
done
# 创建时间戳备份
# 创建时间戳备份(记录每次修改前的状态)
for file in "${js_files[@]}"; do for file in "${js_files[@]}"; do
if [ -f "$file" ]; then if [ -f "$file" ]; then
cp "$file" "$backup_dir/$(basename "$file").backup_$timestamp" cp "$file" "$backup_dir/$(basename "$file").backup_$timestamp"
@ -1614,8 +1611,8 @@ EOF
done done
log_info "✅ [备份] 时间戳备份创建成功: $backup_dir" log_info "✅ [备份] 时间戳备份创建成功: $backup_dir"
# 修改JS文件
log_info "🔧 [修改] 开始修改JS文件..."
# 修改JS文件(每次都重新注入,因为已从原始备份恢复)
log_info "🔧 [修改] 开始修改JS文件(使用新的设备标识符)..."
for file in "${js_files[@]}"; do for file in "${js_files[@]}"; do
if [ ! -f "$file" ]; then if [ ! -f "$file" ]; then
@ -1625,13 +1622,6 @@ EOF
log_info "📝 [处理] 正在处理: ${file/$CURSOR_APP_PATH\//}" log_info "📝 [处理] 正在处理: ${file/$CURSOR_APP_PATH\//}"
# 检查是否已经修改过
if grep -q "__cursor_patched__" "$file"; then
log_info "✅ [跳过] 文件已经被修改过"
((modified_count++))
continue
fi
# ========== 方法A: someValue占位符替换(稳定锚点) ========== # ========== 方法A: someValue占位符替换(稳定锚点) ==========
local replaced=false local replaced=false

69
scripts/run/cursor_win_id_modifier.ps1

@ -107,35 +107,12 @@ function Modify-CursorJSFiles {
) )
$modifiedCount = 0 $modifiedCount = 0
$needModification = $false
# 检查是否需要修改(使用统一标记 __cursor_patched__)
Write-Host "$BLUE🔍 [检查]$NC 检查JS文件修改状态..."
foreach ($file in $jsFiles) {
if (-not (Test-Path $file)) {
Write-Host "$YELLOW⚠️ [警告]$NC 文件不存在: $(Split-Path $file -Leaf)"
continue
}
$content = Get-Content $file -Raw -ErrorAction SilentlyContinue
if ($content -and $content -match "__cursor_patched__") {
Write-Host "$GREEN✅ [已修改]$NC 文件已修改: $(Split-Path $file -Leaf)"
} else {
Write-Host "$BLUE📝 [需要]$NC 文件需要修改: $(Split-Path $file -Leaf)"
$needModification = $true
}
}
if (-not $needModification) {
Write-Host "$GREEN✅ [跳过]$NC 所有JS文件已经被修改过,无需重复操作"
return $true
}
# 关闭Cursor进程 # 关闭Cursor进程
Write-Host "$BLUE🔄 [关闭]$NC 关闭Cursor进程以进行文件修改..." Write-Host "$BLUE🔄 [关闭]$NC 关闭Cursor进程以进行文件修改..."
Stop-AllCursorProcesses -MaxRetries 3 -WaitSeconds 3 | Out-Null Stop-AllCursorProcesses -MaxRetries 3 -WaitSeconds 3 | Out-Null
# 创建备份
# 创建备份目录
$timestamp = Get-Date -Format "yyyyMMdd_HHmmss" $timestamp = Get-Date -Format "yyyyMMdd_HHmmss"
$backupPath = "$cursorAppPath\resources\app\out\backups" $backupPath = "$cursorAppPath\resources\app\out\backups"
@ -143,19 +120,35 @@ function Modify-CursorJSFiles {
try { try {
New-Item -ItemType Directory -Path $backupPath -Force | Out-Null New-Item -ItemType Directory -Path $backupPath -Force | Out-Null
# 创建原始备份(如果不存在)
# 检查是否存在原始备份
$originalBackup = "$backupPath\main.js.original" $originalBackup = "$backupPath\main.js.original"
if (-not (Test-Path $originalBackup)) {
foreach ($file in $jsFiles) {
if (Test-Path $file) {
$fileName = Split-Path $file -Leaf
Copy-Item $file "$backupPath\$fileName.original" -Force
foreach ($file in $jsFiles) {
if (-not (Test-Path $file)) {
Write-Host "$YELLOW⚠️ [警告]$NC 文件不存在: $(Split-Path $file -Leaf)"
continue
}
$fileName = Split-Path $file -Leaf
$fileOriginalBackup = "$backupPath\$fileName.original"
# 如果原始备份不存在,先创建
if (-not (Test-Path $fileOriginalBackup)) {
# 检查当前文件是否已被修改过
$content = Get-Content $file -Raw -ErrorAction SilentlyContinue
if ($content -and $content -match "__cursor_patched__") {
Write-Host "$YELLOW⚠️ [警告]$NC 文件已被修改但无原始备份,将使用当前版本作为基础"
} }
Copy-Item $file $fileOriginalBackup -Force
Write-Host "$GREEN✅ [备份]$NC 原始备份创建成功: $fileName"
} else {
# 从原始备份恢复,确保每次都是干净的注入
Write-Host "$BLUE🔄 [恢复]$NC 从原始备份恢复: $fileName"
Copy-Item $fileOriginalBackup $file -Force
} }
Write-Host "$GREEN✅ [备份]$NC 原始备份创建成功"
} }
# 创建时间戳备份
# 创建时间戳备份(记录每次修改前的状态)
foreach ($file in $jsFiles) { foreach ($file in $jsFiles) {
if (Test-Path $file) { if (Test-Path $file) {
$fileName = Split-Path $file -Leaf $fileName = Split-Path $file -Leaf
@ -168,8 +161,8 @@ function Modify-CursorJSFiles {
return $false return $false
} }
# 修改JS文件
Write-Host "$BLUE🔧 [修改]$NC 开始修改JS文件..."
# 修改JS文件(每次都重新注入,因为已从原始备份恢复)
Write-Host "$BLUE🔧 [修改]$NC 开始修改JS文件(使用新的设备标识符)..."
foreach ($file in $jsFiles) { foreach ($file in $jsFiles) {
if (-not (Test-Path $file)) { if (-not (Test-Path $file)) {
@ -181,14 +174,6 @@ function Modify-CursorJSFiles {
try { try {
$content = Get-Content $file -Raw -Encoding UTF8 $content = Get-Content $file -Raw -Encoding UTF8
# 检查是否已经修改过(使用统一标记)
if ($content -match "__cursor_patched__") {
Write-Host "$GREEN✅ [跳过]$NC 文件已经被修改过"
$modifiedCount++
continue
}
$replaced = $false $replaced = $false
# ========== 方法A: someValue占位符替换(稳定锚点) ========== # ========== 方法A: someValue占位符替换(稳定锚点) ==========

Loading…
Cancel
Save