# 关掉机房助手 + 恢复被改的功能 —— 单文件版

**一个文件装下全部内容**：6 段代码 + 操作步骤 + 排错表。
**这台机器 `Win+R`（运行）已被禁用，所以全程只有双击和右键，不用敲任何命令。**

**耗时**：约 3 分钟。**需要**：管理员账户。

---

## 第 0 步：把 6 段代码存成 6 个文件

1. 双击桌面「计算机」→ 地址栏输入 `C:\Users\Public` → 回车；
2. 里面没有 `tool` 文件夹就新建一个，命名为 `tool`；
3. 打开「记事本」，把下面每一段代码**整段**粘进去，
   「文件 → 另存为」→ 保存类型选「所有文件」→ 编码选 **ANSI** →
   文件名一栏**连双引号一起**照抄本文给出的那一行。

**6 个文件名与完整路径（一字不差地抄进「文件名」框）**：

```
"C:\Users\Public\tool\01-recon.vbs"
"C:\Users\Public\tool\02-kill.vbs"
"C:\Users\Public\tool\03-restore.vbs"
"C:\Users\Public\tool\04-restore-hosts.bat"
"C:\Users\Public\tool\05-verify.vbs"
"C:\Users\Public\tool\06-dump-password.vbs"
```

> **文件名全用英文小写 + 连字符**，不用中文、不用空格，避免编码和路径上的特殊情况。
> **双引号必须有**：不加引号，记事本会给你存成 `01-recon.vbs.txt`，双击就不执行了。
> **编码必须是 ANSI**：存成 UTF-8 脚本会报「语法错误」。
> **文件名一个字都不能改**：序号、连字符、扩展名都要原样（`02-kill.vbs` 不是 `02_kill.vbs`）。

> 为什么不能放桌面或 `C:\Users\Public` 根下：助手会监视那些位置并删掉 `.bat`/`.vbs`，
> `C:\Users\Public\tool` 这个子目录它不监视。

## 第 1 步：侦察（只读，不用管理员）

**文件名**：`01-recon.vbs`

**另存为时，「文件名」一栏抄这一行（含英文双引号）**：

```
"C:\Users\Public\tool\01-recon.vbs"
```

**运行方式**：双击

**完整代码**（`01-recon.vbs`）：

```vbscript
Option Explicit
' 1-recon.vbs -- double-click. Read-only, no admin needed.
' Output: C:\Users\Public\tool\recon.txt (opened in Notepad)
Dim fso, out, wmi, p, s, cnt, fn

fn = "C:\Users\Public\tool\recon.txt"
Set fso = CreateObject("Scripting.FileSystemObject")
If Not fso.FolderExists("C:\Users\Public\tool") Then fso.CreateFolder "C:\Users\Public\tool"
Set out = fso.CreateTextFile(fn, True)
Set wmi = GetObject("winmgmts:")

out.WriteLine "RECON  " & Now
out.WriteLine ""

out.WriteLine "=== 1. TARGET PROCESSES (expect 2-3, 0 = assistant not running)"
cnt = 0
For Each p In wmi.ExecQuery("Select Name,ProcessId,ExecutablePath from Win32_Process")
  If IsTarget(LCase(p.Name), p.ExecutablePath) Then
    out.WriteLine "  HIT  " & p.Name & "  pid=" & p.ProcessId
    out.WriteLine "       " & p.ExecutablePath
    cnt = cnt + 1
  End If
Next
out.WriteLine "  total = " & cnt
out.WriteLine ""

out.WriteLine "=== 2. SERVICE"
For Each s In wmi.ExecQuery("Select Name,State,StartMode,PathName from Win32_Service Where Name='zmserv'")
  out.WriteLine "  " & s.State & " / " & s.StartMode
  out.WriteLine "  " & s.PathName
Next
out.WriteLine "  (no line above = service does not exist)"
out.WriteLine ""

out.WriteLine "=== 3. HOSTS"
On Error Resume Next
out.WriteLine "  size = " & fso.GetFile("C:\Windows\System32\drivers\etc\hosts").Size & "   (824 = stock, 4000+ = blocked list)"
Err.Clear
out.WriteLine "  hosts-bak exist = " & fso.FileExists("C:\Windows\System32\drivers\etc\hosts-bak")
out.WriteLine "  hosts2   exist = " & fso.FileExists("C:\Windows\System32\drivers\etc\hosts2")
On Error GoTo 0
out.WriteLine ""

out.WriteLine "=== 4. INSTALL DIRS"
out.WriteLine "  C:\f40967408 (12.97) = " & fso.FolderExists("C:\f40967408")
out.WriteLine "  C:\q40967584 (13.1)  = " & fso.FolderExists("C:\q40967584")
out.WriteLine "  C:\windows\jf        = " & fso.FolderExists("C:\windows\jf")
out.WriteLine ""
out.WriteLine "DONE"
out.Close
CreateObject("WScript.Shell").Run "notepad """ & fn & """", 1, False

Function AllInRange(t, lo, hi)
  Dim i, ch
  AllInRange = False
  For i = 1 To Len(t)
    ch = Asc(Mid(t, i, 1))
    If ch < lo Or ch > hi Then Exit Function
  Next
  AllInRange = True
End Function

Function IsTarget(b, pth)
  Dim base
  IsTarget = False
  base = LCase(b)
  If Right(base, 4) = ".exe" Then base = Left(base, Len(base) - 4)
  If base = "jfglzsn" Or base = "zmserv" Or base = "przs" Then
    IsTarget = True
    Exit Function
  End If
  If Len(base) = 5 And AllInRange(base, 105, 114) Then IsTarget = True
  If Len(base) = 4 And AllInRange(base, 97, 106) Then
    If InStr(LCase(pth & ""), "\program files (x86)\") > 0 Then IsTarget = True
  End If
End Function
```

## 第 2 步：停止监控（要管理员）

**文件名**：`02-kill.vbs`

**另存为时，「文件名」一栏抄这一行（含英文双引号）**：

```
"C:\Users\Public\tool\02-kill.vbs"
```

**运行方式**：双击

**完整代码**（`02-kill.vbs`）：

```vbscript
Option Explicit
' 2-kill.vbs -- double-click. It asks for admin by itself.
'   1) stop service zmserv (WMI, no external program)
'   2) wait until zmserv.exe PROCESS is really gone
'   3) kill every target in ONE WMI pass (the judge revives them in 3 s)
' Output: C:\Users\Public\tool\kill.txt
Const LOGF = "C:\Users\Public\tool\kill.txt"

Dim fso, sh, wmi, p, rc, i, ok, killed, remain, judgeName, judgePid, svc

Set fso = CreateObject("Scripting.FileSystemObject")
Set sh = CreateObject("WScript.Shell")
If Not fso.FolderExists("C:\Users\Public\tool") Then fso.CreateFolder "C:\Users\Public\tool"

If Not IsAdmin() Then
  CreateObject("Shell.Application").ShellExecute "wscript.exe", """" & WScript.ScriptFullName & """", "", "runas", 1
  WScript.Quit 0
End If

Set wmi = GetObject("winmgmts:")
L "START " & Now

L "=== 1. stop service"
Set svc = Nothing
On Error Resume Next
Err.Clear
Set svc = wmi.Get("Win32_Service.Name='zmserv'")
If Err.Number <> 0 Then
  L "  service not found, skip"
  Err.Clear
Else
  rc = svc.StopService()
  L "  StopService rc=" & rc
  If rc = 5 Then
    MsgBox "No administrator rights. Double-click again and click Yes.", 16, "2-kill"
    WScript.Quit 1
  End If
End If
On Error GoTo 0

L "=== 2. wait for zmserv.exe to exit"
ok = False
For i = 1 To 20
  If ProcCount("zmserv.exe") = 0 Then
    ok = True
    L "  gone after check " & i
    Exit For
  End If
  WScript.Sleep 500
Next
If Not ok Then
  L "  zmserv.exe still alive after 10 s -- ABORT (do not kill, it would power off)"
  MsgBox "Service process did not exit. Aborted on purpose.", 16, "2-kill"
  WScript.Quit 2
End If

L "=== 3. one WMI pass"
judgeName = ""
judgePid = 0
For Each p In wmi.ExecQuery("Select Name,ProcessId from Win32_Process")
  If IsTarget(LCase(p.Name), "") Then
    If judgeName = "" And LCase(p.Name) <> "jfglzsn.exe" And LCase(p.Name) <> "zmserv.exe" Then
      judgeName = p.Name
      judgePid = p.ProcessId
    End If
  End If
Next
L "  judge = " & judgeName & " pid=" & judgePid

killed = 0
For Each p In wmi.ExecQuery("Select Name,ProcessId from Win32_Process")
  If IsTarget(LCase(p.Name), "") Then
    rc = 999
    On Error Resume Next
    Err.Clear
    rc = p.Terminate()
    If Err.Number <> 0 Then
      rc = "err " & Err.Number
      Err.Clear
    End If
    On Error GoTo 0
    L "  kill " & p.Name & " pid=" & p.ProcessId & " rc=" & rc
    killed = killed + 1
  End If
Next
L "  killed = " & killed

L "=== 4. recheck after 5 s"
WScript.Sleep 5000
remain = 0
For Each p In wmi.ExecQuery("Select Name,ProcessId from Win32_Process")
  If IsTarget(LCase(p.Name), "") Then
    L "  still alive: " & p.Name & " pid=" & p.ProcessId
    remain = remain + 1
  End If
Next
L "  remain = " & remain
L "DONE"

If remain = 0 Then
  MsgBox "OK. killed=" & killed & "  remain=0" & vbCrLf & vbCrLf & "judge was " & judgeName & vbCrLf & vbCrLf & "Next: double-click 3-restore.vbs", 64, "2-kill OK"
Else
  MsgBox "Still alive: " & remain & ". See kill.txt", 48, "2-kill FAILED"
  WScript.Quit 3
End If

Sub L(t)
  Dim ff
  Set ff = fso.OpenTextFile(LOGF, 8, True)
  ff.WriteLine t
  ff.Close
End Sub

Function IsAdmin()
  IsAdmin = True
  On Error Resume Next
  Err.Clear
  sh.RegWrite "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\__probe", 1, "REG_DWORD"
  If Err.Number <> 0 Then IsAdmin = False
  Err.Clear
  sh.RegDelete "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\__probe"
  Err.Clear
  On Error GoTo 0
End Function

Function ProcCount(nm)
  Dim q
  ProcCount = 0
  For Each q In wmi.ExecQuery("Select ProcessId from Win32_Process Where Name='" & nm & "'")
    ProcCount = ProcCount + 1
  Next
End Function

Function AllInRange(t, lo, hi)
  Dim i, ch
  AllInRange = False
  For i = 1 To Len(t)
    ch = Asc(Mid(t, i, 1))
    If ch < lo Or ch > hi Then Exit Function
  Next
  AllInRange = True
End Function

Function IsTarget(b, pth)
  Dim base
  IsTarget = False
  base = LCase(b)
  If Right(base, 4) = ".exe" Then base = Left(base, Len(base) - 4)
  If base = "jfglzsn" Or base = "zmserv" Or base = "przs" Then
    IsTarget = True
    Exit Function
  End If
  If Len(base) = 5 And AllInRange(base, 105, 114) Then IsTarget = True
  If Len(base) = 4 And AllInRange(base, 97, 106) Then
    If InStr(LCase(pth & ""), "\program files (x86)\") > 0 Then IsTarget = True
  End If
End Function
```

## 第 3 步：恢复设置（要管理员）

**文件名**：`03-restore.vbs`

**另存为时，「文件名」一栏抄这一行（含英文双引号）**：

```
"C:\Users\Public\tool\03-restore.vbs"
```

**运行方式**：双击

**完整代码**（`03-restore.vbs`）：

```vbscript
Option Explicit
' 3-restore.vbs -- double-click. It asks for admin by itself.
' Restores USB storage, browser download policy, firewall, IE home page,
' and removes the Run entries the assistant added.
' Output: C:\Users\Public\tool\soft.txt
Const LOGF = "C:\Users\Public\tool\soft.txt"

Dim fso, sh, i, csName, csList, rc

Set fso = CreateObject("Scripting.FileSystemObject")
Set sh = CreateObject("WScript.Shell")
If Not fso.FolderExists("C:\Users\Public\tool") Then fso.CreateFolder "C:\Users\Public\tool"

If Not IsAdmin() Then
  CreateObject("Shell.Application").ShellExecute "wscript.exe", """" & WScript.ScriptFullName & """", "", "runas", 1
  WScript.Quit 0
End If

L "START " & Now

L "=== 1. USB storage Start=3"
csList = Array("CurrentControlSet", "ControlSet001", "ControlSet002", "ControlSet003")
For Each csName In csList
  rw "HKLM\SYSTEM\" & csName & "\Services\usbstor\Start", 3, "REG_DWORD", csName
Next

L "=== 2. browser downloads"
rw "HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3\1803", 0, "REG_DWORD", "IE Z3 1803"
rw "HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3\2200", 0, "REG_DWORD", "IE Z3 2200"
rw "HKCU\Software\Microsoft\Internet Explorer\Restrictions\NoBrowserSaveAs", 0, "REG_DWORD", "IE SaveAs"
rw "HKCU\Software\Policies\Microsoft\Edge\DownloadRestrictions", 0, "REG_DWORD", "Edge DL"
rw "HKCU\Software\Policies\Microsoft\Edge\SaveAs", 1, "REG_DWORD", "Edge SaveAs"
rw "HKCU\Software\Policies\Microsoft\Edge\DeveloperToolsAvailability", 0, "REG_DWORD", "Edge Dev"
rw "HKCU\Software\Policies\Google\Chrome\DownloadRestrictions", 0, "REG_DWORD", "Chrome DL"
rw "HKCU\Software\Policies\Google\Chrome\SaveAs", 1, "REG_DWORD", "Chrome SaveAs"
rw "HKCU\Software\Policies\Google\Chrome\DeveloperToolsAvailability", 0, "REG_DWORD", "Chrome Dev"
rw "HKCU\Software\Policies\Mozilla\Firefox\DisableDownloads", 0, "REG_DWORD", "FF DL"
rw "HKCU\Software\Policies\Mozilla\Firefox\BlockAboutDownloads", 0, "REG_DWORD", "FF BlockDL"
rw "HKCU\Software\Policies\Mozilla\Firefox\DeveloperToolsAvailability", 0, "REG_DWORD", "FF Dev"

L "=== 3. firewall"
rw "HKLM\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\EnableFirewall", 1, "REG_DWORD", "Std"
rw "HKLM\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\DomainProfile\EnableFirewall", 1, "REG_DWORD", "Domain"
rw "HKLM\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\PublicProfile\EnableFirewall", 1, "REG_DWORD", "Public"
x "netsh advfirewall set allprofiles state on", "netsh firewall on"
x "net start MpsSvc", "start MpsSvc (2182 = already running)"
x "net start BFE", "start BFE (may fail, ignore)"

L "=== 4. IE home page"
rw "HKCU\Software\Microsoft\Internet Explorer\Main\Start Page", "about:blank", "REG_SZ", "HKCU Start Page"
rw "HKCU\Software\Microsoft\Internet Explorer\Main\Default_Page_URL", "about:blank", "REG_SZ", "HKCU Default_Page"
rw "HKLM\SOFTWARE\Microsoft\Internet Explorer\Main\Start Page", "about:blank", "REG_SZ", "HKLM Start Page"

L "=== 5. remove Run entries"
rd "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run", "prozs"
rd "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run", "jfglzsn"
rd "HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Run", "prozs"
rd "HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Run", "jfglzsn"
rd "HKCU\Software\Microsoft\Windows\CurrentVersion\Run", "prozs"
rd "HKCU\Software\Microsoft\Windows\CurrentVersion\Run", "jfglzsn"

L "=== 6. self check"
L "  usbstor Start = " & rv("HKLM\SYSTEM\CurrentControlSet\Services\usbstor\Start") & "  (want 3)"
L "  IE Z3 1803    = " & rv("HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings\Zones\3\1803") & "  (want 0)"
L "  Chrome DL     = " & rv("HKCU\Software\Policies\Google\Chrome\DownloadRestrictions") & "  (want 0)"
L "  EnableFirewall= " & rv("HKLM\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\EnableFirewall") & "  (want 1)"
L "DONE"

MsgBox "Done. USB storage, downloads, firewall, Run entries restored." & vbCrLf & vbCrLf & _
       "Next: right-click 4-restore-hosts.bat -> Run as administrator", 64, "3-restore OK"

Sub L(t)
  Dim ff
  Set ff = fso.OpenTextFile(LOGF, 8, True)
  ff.WriteLine t
  ff.Close
End Sub

Sub rw(k, v, kind, label)
  Dim rc
  rc = "ok"
  On Error Resume Next
  Err.Clear
  sh.RegWrite k, v, kind
  If Err.Number <> 0 Then rc = "err " & Err.Number
  Err.Clear
  On Error GoTo 0
  L "  " & label & " rc=" & rc
End Sub

Sub rd(k, nm)
  Dim rc
  rc = "ok"
  On Error Resume Next
  Err.Clear
  sh.RegDelete k & "\" & nm
  If Err.Number <> 0 Then rc = "none"
  Err.Clear
  On Error GoTo 0
  L "  del " & nm & " rc=" & rc
End Sub

Function rv(k)
  Dim v
  On Error Resume Next
  v = sh.RegRead(k)
  If Err.Number <> 0 Then v = "<missing>"
  Err.Clear
  On Error GoTo 0
  rv = v
End Function

Sub x(cmd, label)
  Dim rc
  rc = 999
  On Error Resume Next
  Err.Clear
  rc = sh.Run(cmd, 0, True)
  If Err.Number <> 0 Then rc = "err " & Err.Number
  Err.Clear
  On Error GoTo 0
  L "  " & label & " rc=" & rc
End Sub

Function IsAdmin()
  IsAdmin = True
  On Error Resume Next
  Err.Clear
  sh.RegWrite "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\__probe", 1, "REG_DWORD"
  If Err.Number <> 0 Then IsAdmin = False
  Err.Clear
  sh.RegDelete "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\__probe"
  Err.Clear
  On Error GoTo 0
End Function
```

## 第 4 步：还原 hosts（要管理员）

**文件名**：`04-restore-hosts.bat`

**另存为时，「文件名」一栏抄这一行（含英文双引号）**：

```
"C:\Users\Public\tool\04-restore-hosts.bat"
```

**运行方式**：右键 → 以管理员身份运行

**完整代码**（`04-restore-hosts.bat`）：

```bat
@echo off
rem ============================================================
rem  04_restore_hosts.bat  --  restore the stock Windows 7 hosts
rem  Run AS ADMINISTRATOR (right click - Run as administrator)
rem  Source of truth: C:\Windows\System32\drivers\etc\hosts-bak
rem  Also deletes hosts2, otherwise the watchdog copies the
rem  blocklist back within 15 seconds.
rem ============================================================
set ETCDIR=C:\Windows\System32\drivers\etc
set BAK=%ETCDIR%\hosts-bak

echo [1/5] clear read-only / hidden / system on hosts
attrib -r -h -s "%ETCDIR%\hosts"

if not exist "%BAK%" goto NOBAK

echo [2/5] copy hosts-bak over hosts
copy /y "%BAK%" "%ETCDIR%\hosts" >nul
if errorlevel 1 goto COPYFAIL

echo [3/5] delete hosts2 (watchdog source copy)
if exist "%ETCDIR%\hosts2" del /f /q "%ETCDIR%\hosts2"

echo [4/5] flush DNS cache
ipconfig /flushdns >nul

echo [5/5] verify - no line printed below means STOCK file
findstr /v /b "#" "%ETCDIR%\hosts"
echo.
for %%f in ("%ETCDIR%\hosts") do echo   hosts = %%~zf bytes  (expect 824)
echo Done.
pause
exit /b 0

:NOBAK
echo ERROR: %BAK% not found.
echo Restore manually: copy a stock Win7 hosts (824 bytes) to %ETCDIR%\hosts,
echo then delete %ETCDIR%\hosts2 and run: ipconfig /flushdns
pause
exit /b 1

:COPYFAIL
echo ERROR: copy failed. Clear attributes first:
echo   attrib -r -h -s %ETCDIR%\hosts
pause
exit /b 1
```

## 第 5 步：验证（只读，不用管理员）

**文件名**：`05-verify.vbs`

**另存为时，「文件名」一栏抄这一行（含英文双引号）**：

```
"C:\Users\Public\tool\05-verify.vbs"
```

**运行方式**：双击

**完整代码**（`05-verify.vbs`）：

```vbscript
Option Explicit
' 5-verify.vbs -- double-click. Read-only. Tells you whether it worked.
' Output: C:\Users\Public\tool\verify.txt (opened in Notepad)
Dim fso, out, wmi, p, s, sh, v, cnt, fn, sz, ok, pass, fail

fn = "C:\Users\Public\tool\verify.txt"
Set fso = CreateObject("Scripting.FileSystemObject")
Set sh = CreateObject("WScript.Shell")
If Not fso.FolderExists("C:\Users\Public\tool") Then fso.CreateFolder "C:\Users\Public\tool"
Set out = fso.CreateTextFile(fn, True)
Set wmi = GetObject("winmgmts:")

pass = 0
fail = 0

out.WriteLine "VERIFY  " & Now
out.WriteLine ""

cnt = 0
For Each p In wmi.ExecQuery("Select Name,ProcessId from Win32_Process")
  If IsTarget(LCase(p.Name)) Then
    out.WriteLine "  [proc] alive: " & p.Name & " pid=" & p.ProcessId
    cnt = cnt + 1
  End If
Next
chk (cnt = 0), "no assistant process"

ok = -1
For Each s In wmi.ExecQuery("Select Name,State from Win32_Service Where Name='zmserv'")
  out.WriteLine "  [svc] " & s.State
  If LCase(s.State) = "running" Then ok = 0
  If LCase(s.State) = "stopped" Then ok = 1
Next
If ok = -1 Then
  out.WriteLine "  [svc] not installed (1060)"
  ok = 1
End If
chk (ok = 1), "service not running"

sz = -1
On Error Resume Next
Err.Clear
sz = fso.GetFile("C:\Windows\System32\drivers\etc\hosts").Size
Err.Clear
On Error GoTo 0
out.WriteLine "  [hosts] " & sz & " bytes, hosts2 exist=" & fso.FileExists("C:\Windows\System32\drivers\etc\hosts2")
chk (sz > 0 And sz < 2000), "hosts restored (~824)"

v = rv("HKLM\SYSTEM\CurrentControlSet\Services\usbstor\Start")
out.WriteLine "  [usb] Start = " & v & "  (3 = ok, 4 = disabled)"
chk (CStr(v) = "3"), "USB storage enabled"

v = rv("HKLM\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\EnableFirewall")
out.WriteLine "  [fw] EnableFirewall = " & v
chk (CStr(v) = "1"), "firewall on"

ok = rvcount("HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run") + rvcount("HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Run")
out.WriteLine "  [run] prozs/jfglzsn entries = " & ok
chk (ok = 0), "no autostart entries"

out.WriteLine ""
out.WriteLine "PASS " & pass & "   FAIL " & fail
out.Close

If fail = 0 Then
  sh.Popup "ALL PASS (" & pass & " checks)", 6, "5-verify CLEAN", 64
Else
  sh.Popup fail & " check(s) failed, see verify.txt", 8, "5-verify PROBLEM", 48
End If
sh.Run "notepad """ & fn & """", 1, False

Sub chk(cond, label)
  If cond Then
    pass = pass + 1
    out.WriteLine "    -> PASS : " & label
  Else
    fail = fail + 1
    out.WriteLine "    -> FAIL : " & label
  End If
End Sub

Function rv(k)
  Dim t
  On Error Resume Next
  t = sh.RegRead(k)
  If Err.Number <> 0 Then t = "<missing>"
  Err.Clear
  On Error GoTo 0
  rv = t
End Function

Function rvcount(base)
  Dim t
  rvcount = 0
  On Error Resume Next
  t = sh.RegRead(base & "\prozs")
  If Err.Number = 0 Then rvcount = rvcount + 1
  Err.Clear
  t = sh.RegRead(base & "\jfglzsn")
  If Err.Number = 0 Then rvcount = rvcount + 1
  Err.Clear
  On Error GoTo 0
End Function

Function AllInRange(t, lo, hi)
  Dim i, ch
  AllInRange = False
  For i = 1 To Len(t)
    ch = Asc(Mid(t, i, 1))
    If ch < lo Or ch > hi Then Exit Function
  Next
  AllInRange = True
End Function

Function IsTarget(b)
  Dim base
  IsTarget = False
  base = LCase(b)
  If Right(base, 4) = ".exe" Then base = Left(base, Len(base) - 4)
  If base = "jfglzsn" Or base = "zmserv" Or base = "przs" Then
    IsTarget = True
    Exit Function
  End If
  If Len(base) = 5 And AllInRange(base, 105, 114) Then IsTarget = True
End Function
```

## 第 6 步：抓注册表里存的密码（只读，不用管理员，随时可做）

**文件名**：`06-dump-password.vbs`

**另存为时，「文件名」一栏抄这一行（含英文双引号）**：

```
"C:\Users\Public\tool\06-dump-password.vbs"
```

**运行方式**：双击

**完整代码**（`06-dump-password.vbs`）：

```vbscript
Option Explicit
' 06-dump-password.vbs  --  double-click, read-only, NO admin needed.
'
' Dumps every registry value the classroom assistant keeps under
'     HKCU\Software          (usually: n, dtmm, czmm)
'     HKCU\Software\jfglzs   (if present)
' plus a few related scheduling keys, into
'     C:\Users\Public\tool\pass.txt
' and opens it in notepad.
'
' NOTHING is decrypted or cracked here - it is a pure dump for later analysis.
' Running it does not touch files, services or processes of the assistant.

Const OUTD = "C:\Users\Public\tool"
Const HKCU = &H80000001
Dim LOGF
LOGF = OUTD & "\pass.txt"

Dim fso, sh, reg, o, total
Set fso = CreateObject("Scripting.FileSystemObject")
Set sh  = CreateObject("WScript.Shell")
Set reg = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\default:StdRegProv")

If Not fso.FolderExists(OUTD) Then fso.CreateFolder OUTD
Set o = fso.CreateTextFile(LOGF, True, False)

Sub W(ByVal s)
    o.WriteLine s
End Sub

' Dump all values of one HKCU subkey. Returns number of values found.
Function DumpKey(ByVal subkey, ByVal title)
    Dim names, types, i, n, cnt
    cnt = 0
    W "[" & title & "]  HKCU\" & subkey
    On Error Resume Next
    reg.EnumValues HKCU, subkey, names, types
    If Err.Number <> 0 Or Not IsArray(names) Then
        Err.Clear
        W "  (key not present or empty)"
        On Error GoTo 0
        DumpKey = 0
        Exit Function
    End If
    On Error GoTo 0
    For i = 0 To UBound(names)
        W "  " & names(i) & " = " & ValOf(subkey, names(i), types(i))
        cnt = cnt + 1
    Next
    If cnt = 0 Then W "  (empty)"
    W ""
    DumpKey = cnt
End Function

' Read one value and render it: strings as-is, dwords as hex+dec, binary as hex.
Function ValOf(ByVal subkey, ByVal name, ByVal typ)
    Dim s, d, b, i, r, x
    On Error Resume Next
    If typ = 1 Then
        reg.GetStringValue HKCU, subkey, name, s
        If Err.Number = 0 Then ValOf = """" & s & """" Else ValOf = "<read error>"
    ElseIf typ = 4 Then
        reg.GetDWORDValue HKCU, subkey, name, d
        If Err.Number = 0 Then
            ValOf = "0x" & Hex(d) & " (" & d & ")"
        Else
            ValOf = "<read error>"
        End If
    ElseIf typ = 3 Then
        reg.GetBinaryValue HKCU, subkey, name, b
        If Err.Number = 0 And IsArray(b) Then
            r = ""
            For i = 0 To UBound(b)
                x = Hex(b(i))
                If Len(x) = 1 Then x = "0" & x
                r = r & LCase(x)
            Next
            ValOf = "0x" & r
        Else
            ValOf = "<read error>"
        End If
    Else
        reg.GetStringValue HKCU, subkey, name, s
        If Err.Number = 0 Then
            ValOf = "(" & typ & ") """ & s & """"
        Else
            Err.Clear
            reg.GetDWORDValue HKCU, subkey, name, d
            If Err.Number = 0 Then ValOf = "(" & typ & ") 0x" & Hex(d) Else ValOf = "(" & typ & ") <unreadable>"
        End If
    End If
    Err.Clear
    On Error GoTo 0
End Function

' Read one value with a clear marker when it does not exist.
Function RegRead(ByVal subkey, ByVal name)
    Dim v
    On Error Resume Next
    v = sh.RegRead("HKCU\" & subkey & "\" & name)
    If Err.Number <> 0 Then
        Err.Clear
        RegRead = "<not present>"
    Else
        RegRead = CStr(v)
    End If
    On Error GoTo 0
End Function

' ---------------- main ----------------
W "=== REGISTRY DUMP  " & Now
W "computer = " & sh.ExpandEnvironmentStrings("%COMPUTERNAME%") & _
  "   user = " & sh.ExpandEnvironmentStrings("%USERNAME%")
W ""

Dim vn, vd, vc, found
vn = RegRead("Software", "n")
vd = RegRead("Software", "dtmm")
vc = RegRead("Software", "czmm")
found = 0
If vn <> "<not present>" Then found = found + 1
If vd <> "<not present>" Then found = found + 1
If vc <> "<not present>" Then found = found + 1

W "[A] known names (read one by one)"
W "  HKCU\Software\n      = " & vn
W "  HKCU\Software\dtmm   = " & vd
W "  HKCU\Software\czmm   = " & vc
W ""
W "  found_known = " & found
W ""

W "[B] everything under HKCU\Software"
total = DumpKey("Software", "all values")
W ""

W "[C] everything under HKCU\Software\jfglzs"
total = total + DumpKey("Software\jfglzs", "all values")
W ""

W "[note] HKCU\Software holds many unrelated values too."
W "       The assistant's own ones are usually: n, dtmm, czmm"
W "       n = the exit-password hash written by set.exe"
W ""
W "value_count = " & (total + found)
W ""
W "=== DONE"
o.Close

sh.Run "notepad.exe """ & LOGF & """", 1, False
WScript.Sleep 400
MsgBox "Dumped " & total & " registry values." & vbCrLf & vbCrLf & _
       "File: " & LOGF, vbInformation, "06-dump-password"
```

---

## 运行顺序（必须按这个顺序）

| 顺序 | 文件（完整路径） | 怎么运行 | 预期结果 |
|---|---|---|---|
| 1 | `C:\Users\Public\tool\01-recon.vbs` | 双击 | 弹记事本，`total = 2` 或 `3` |
| 2 | `C:\Users\Public\tool\02-kill.vbs` | 双击 → UAC 点**是** | 弹 `2-kill OK`，`remain = 0` |
| 3 | `C:\Users\Public\tool\03-restore.vbs` | 双击 → UAC 点**是** | 弹 `3-restore OK` |
| 4 | `C:\Users\Public\tool\04-restore-hosts.bat` | **右键 → 以管理员身份运行** | 末行 `hosts = 824 bytes` |
| 5 | `C:\Users\Public\tool\05-verify.vbs` | 双击 | 弹 `ALL PASS (5 checks)` |
| 6 | `C:\Users\Public\tool\06-dump-password.vbs` | 双击 | 弹记事本，`pass.txt` 里有 `n = ...` |

> 只有 `.bat` 的右键菜单里有「以管理员身份运行」，`.vbs` 没有 —— 所以第 4 步右键，其余双击。
> `.vbs` 会自己弹 UAC 再以管理员身份重跑一遍，看到 UAC 一定点「是」（默认是「否」，按回车等于取消）。
> 第 6 步是**只读**的，任何时候都能跑，不改变任何东西；它只把注册表里的值抄到 `pass.txt`。

## `02-kill.vbs` 的输出怎么读

结果存在 `C:\Users\Public\tool\kill.txt`，关键几行：

| 行 | 含义 |
|---|---|
| `StopService rc=0` | 服务已停（`rc=1060` 也表示服务本来就不存在，可以继续） |
| `gone after check N` | 服务进程真的退出了，可以杀进程 |
| `judge = xxx.exe` | 识别到的裁判（5 个字母的那个） |
| `kill ... rc=0` | 该进程已被结束 |
| `killed = 2` / `3` | 结束的总数 |
| `remain = 0` | 5 秒后没有残留，成功 |

若出现 `zmserv.exe still alive after 10 s -- ABORT`：
**这是脚本主动放弃**，因为服务没停就杀进程会让机器约 80 秒后直接断电。重启一次再重试。

## `06-dump-password.vbs` 抓到了什么

输出 `C:\Users\Public\tool\pass.txt`，分三段：

| 段 | 内容 |
|---|---|
| A | 三个已知名字 `n` / `dtmm` / `czmm` 的值（没有就写 `<not present>`） |
| B | `HKCU\Software` 下全部值（名称、类型、内容） |
| C | `HKCU\Software\jfglzs` 下全部值（有的话） |

`n` 是助手设置的退出密码，但**存的不是明文**，而是一串 64 位十六进制。
把 `pass.txt` 交给我，我来分析每个值分别是什么、以及能不能还原。

## 出事了怎么办

| 现象 | 原因 | 处理 |
|---|---|---|
| 双击后没反应 | UAC 没点「是」 | 重新双击，点「是」（别按回车） |
| 文件变成 `xxx.vbs.txt` | 另存为时文件名没加双引号 | 删掉重存，文件名连同引号一起抄 |
| 提示「找不到文件 wscript」 | 文件关联被改 | 右键 `.vbs` → 打开方式 → `C:\Windows\System32\wscript.exe` |
| 屏幕被蓝底红字锁住 | 裁判发现文件被杀 | `Ctrl+Alt+Del` → 启动任务管理器 → 结束那个 5 字母进程 |
| 鼠标点哪都没反应 | 鼠标被限制在左上 500×100 | 只用键盘：`Ctrl+Alt+Del` → 任务管理器 |
| 机器突然断电 | 服务先死、进程后死，80 秒倒计时走完 | 重启后重来，严格按 1→2→3→4→5 |
| `remain` 不是 0 | 裁判被重新拉起 | 再双击一次 `02-kill.vbs` |
| 脚本报「语法错误」 | 保存成了 UTF-8 | 重新另存为，编码选 **ANSI** |

## 这套脚本不做什么

- 不删安装目录（`C:\f40967408`）、不删 `C:\windows\jf`、不删服务。
  这些属于「彻底清除」，不可逆，而且本套的目标只是「停掉 + 恢复可用」。
- 重启后助手会自己回来（服务是自启动、无 Run 键拉起），这是可预期的，等于留了退路。

## 关于提示文字是英文

VBScript 按系统 ANSI 读文件，脚本里写中文在不同编码下会变乱码甚至报错。
所以脚本内部的提示统一用英文；文件名同样统一用英文小写，避免零宽字符、全角符号、编码这类问题。


sk-8b1abb152e0d48dc8b969656
