验证:补充独立光标可行性POC
This commit is contained in:
1 parent
b29b59c62f
commit
1439028833
49 files changed
+957
-1
No files matched your search
@@ -0,0 +1,73 @@
|
||||
"""Scoped VM100 interactive cursor exporter. No new network listener or system cursor theme."""
|
||||
import argparse
|
||||
import base64
|
||||
import json
|
||||
from pathlib import Path
|
||||
import runpy
|
||||
import sys
|
||||
|
||||
sys.stdout.reconfigure(encoding="utf-8", errors="replace")
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument("action", choices=["start", "status", "export", "stop"])
|
||||
parser.add_argument("--output", type=Path)
|
||||
args = parser.parse_args()
|
||||
root = Path(__file__).resolve().parent
|
||||
t = runpy.run_path(str(root / "pve_term_exec.py"))
|
||||
v = runpy.run_path(str(root / "pve_vm.py"))
|
||||
ticket, csrf = t["login"]()
|
||||
if v["api"]("/api2/json/nodes/starhe/qemu/100/status/current", ticket=ticket).get("status") != "running":
|
||||
sys.exit("VM100 is not running")
|
||||
command = r"$ErrorActionPreference='Stop'; $folder='C:\ProgramData\VDI\cursor-poc-20261103'; $task='VDICursorPOC'; "
|
||||
if args.action == "start":
|
||||
payload = base64.b64encode((root / "cursor-poc-host.ps1").read_bytes()).decode()
|
||||
command += r"""
|
||||
if(Get-ScheduledTask -TaskName $task -ErrorAction SilentlyContinue) { throw 'Probe already exists' }
|
||||
$user=(Get-CimInstance Win32_ComputerSystem).UserName
|
||||
if(-not $user) { throw 'No interactive user' }
|
||||
New-Item -ItemType Directory -Force $folder | Out-Null
|
||||
$acl=Get-Acl $folder
|
||||
$acl.SetAccessRule((New-Object Security.AccessControl.FileSystemAccessRule($user,'Modify','ContainerInherit,ObjectInherit','None','Allow')))
|
||||
Set-Acl $folder $acl
|
||||
Remove-Item "$folder\error.txt","$folder\state.json","$folder\shapes.json" -ErrorAction SilentlyContinue
|
||||
[IO.File]::WriteAllBytes("$folder\probe.ps1",[Convert]::FromBase64String('__PAYLOAD__'))
|
||||
$a=New-ScheduledTaskAction -Execute powershell.exe -Argument "-NoProfile -STA -ExecutionPolicy Bypass -WindowStyle Hidden -File $folder\probe.ps1"
|
||||
$p=New-ScheduledTaskPrincipal -UserId $user -LogonType Interactive -RunLevel Limited
|
||||
$s=New-ScheduledTaskSettingsSet -ExecutionTimeLimit (New-TimeSpan -Minutes 9)
|
||||
Register-ScheduledTask -TaskName $task -Action $a -Principal $p -Settings $s | Out-Null
|
||||
Start-ScheduledTask -TaskName $task
|
||||
Start-Sleep -Seconds 3
|
||||
if(Test-Path "$folder\error.txt") { throw (Get-Content "$folder\error.txt" -Raw) }
|
||||
if(-not(Test-Path "$folder\shapes.json")) { throw 'No fresh cursor export' }
|
||||
'Cursor probe started'
|
||||
""".replace("__PAYLOAD__", payload)
|
||||
elif args.action == "export":
|
||||
command += 'Get-Content "$folder\\shapes.json" -Raw'
|
||||
elif args.action == "status":
|
||||
command += r"""
|
||||
Get-Content "$folder\state.json" -Raw
|
||||
Get-Content "$folder\clicks.csv"
|
||||
Get-Content "$folder\states.csv"
|
||||
Get-Content "$folder\error.txt" -ErrorAction SilentlyContinue
|
||||
"""
|
||||
else:
|
||||
command += r"""
|
||||
Stop-ScheduledTask -TaskName $task -ErrorAction SilentlyContinue
|
||||
Unregister-ScheduledTask -TaskName $task -Confirm:$false -ErrorAction SilentlyContinue
|
||||
if(Test-Path "$folder\pid.txt") {
|
||||
$probePid=[int](Get-Content "$folder\pid.txt")
|
||||
$process=Get-CimInstance Win32_Process -Filter "ProcessId=$probePid"
|
||||
if($process.CommandLine -like '*cursor-poc-20261103*') { Stop-Process -Id $probePid -ErrorAction SilentlyContinue }
|
||||
}
|
||||
'Cursor probe stopped'
|
||||
"""
|
||||
out, error = v["agent"](ticket, csrf, ["powershell.exe", "-NoProfile", "-Command", command])
|
||||
if error or not out or out == "TIMEOUT":
|
||||
sys.exit(error or out or "Empty guest-agent result")
|
||||
if args.action == "export":
|
||||
data = json.loads(out.lstrip("\ufeff"))
|
||||
if args.output:
|
||||
args.output.parent.mkdir(parents=True, exist_ok=True)
|
||||
args.output.write_text(json.dumps(data, separators=(",", ":")), encoding="utf-8")
|
||||
print(json.dumps([{k: s[k] for k in ("name", "width", "height", "hotX", "hotY", "monochrome", "invertedPixels")} for s in data["shapes"]]))
|
||||
else:
|
||||
print(out)
|
||||
Reference in new issue
Block a user