leakhunt/bin/admin_setup.ps1
acbot 57b5e43d0e Initial commit — leak-hunt project complete
Five bugs identified and patched in retail Asheron's Call client:
- v3b: palette refcount over-increment (3-byte NOP at two sites)
- v5: RenderSurface PurgeResource no-op stub (vtable slot 2 thunk)
- v11: two dangling-pointer crash guards (NULL-check + reorder)
- v14: CEnvCell::Destroy ClipPlaneList leak (18-byte JMP to cleanup thunk)
- v22: unpacker stale-pointer SEH guard (whole-function __try/__except)

All five ship in leakfix.dll (117 KB, SHA d282f23c…) which is loaded
by acclient.exe at process start via PE import table patching by
tools/install_leakfix.py.

Controlled 15-client fleet soak: unpatched control died at 26h with
palette exhaustion; all 14 patched clients survived past that point
and reached ≥5-day uptime.

Residual ~15 MB/h growth traced to d3d9.dll's internal slab allocator
(260KB surface backing buffers retained after Release). See REPORT.md
§10 for the full investigation; conclusion is that it's unfixable from
outside d3d9.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-23 21:07:58 +02:00

91 lines
4.3 KiB
PowerShell

#requires -Version 5.1
<#
admin_setup.ps1 — one-time, ADMIN-ELEVATED setup for the leak hunt.
RUN THIS FROM AN ELEVATED POWERSHELL. It does three things:
1. Installs the Windows SDK "Windows Desktop Debuggers" feature
(~250 MB), giving us standalone cdb.exe, umdh.exe, gflags.exe
under C:\Program Files (x86)\Windows Kits\10\Debuggers\.
2. Configures WER LocalDumps for acclient.exe so any future crash
(OOM/AV/heap-corruption) auto-saves a full-memory dump to
artifacts\crashdumps\.
3. Sets gflags +ust on acclient.exe (per-image-file flag in HKLM)
so future acclient spawns tag every heap allocation with its
call stack — required for Phase 5 attribution.
NOTE: currently-running acclient processes will NOT pick up the
gflags +ust setting. Only processes started after this runs will
have stack tagging. Pre-existing leakers continue to leak, just
without UST tags on their heap entries.
After this finishes, you can close the elevated shell. The
non-elevated session keeps running.
#>
$ErrorActionPreference = 'Continue' # don't crash window on first error
$log = 'C:\Users\acbot\leakhunt\artifacts\soak\admin_setup.log'
Start-Transcript -Path $log -Force | Out-Null
try {
if (-not ([Security.Principal.WindowsPrincipal]::new(
[Security.Principal.WindowsIdentity]::GetCurrent())).IsInRole(
[Security.Principal.WindowsBuiltInRole]::Administrator)) {
Write-Host "ERROR: not elevated. Aborting." -ForegroundColor Red
Stop-Transcript | Out-Null
Read-Host 'press enter to close'
exit 1
}
Write-Host "=== admin_setup.ps1 started @ $(Get-Date -Format o) ===" -ForegroundColor Cyan
# ---- 1. Install Windows SDK Debuggers feature ----------------------------
$sdk = "$env:TEMP\winsdk\winsdksetup.exe"
if (-not (Test-Path $sdk)) {
Write-Host "SDK installer not present; downloading..." -ForegroundColor Yellow
New-Item -ItemType Directory -Path "$env:TEMP\winsdk" -Force | Out-Null
Invoke-WebRequest -Uri "https://go.microsoft.com/fwlink/?linkid=2272610" `
-OutFile $sdk -UseBasicParsing
}
Write-Host "[1/3] Installing Windows SDK Debuggers feature (silent)..." -ForegroundColor Cyan
$args = @('/features','OptionId.WindowsDesktopDebuggers','/quiet','/norestart')
$p = Start-Process -FilePath $sdk -ArgumentList $args -Wait -PassThru
if ($p.ExitCode -ne 0) {
Write-Warning "SDK setup exit code: $($p.ExitCode) (non-zero — see %TEMP%\winsdk\ logs)"
}
$cdb = 'C:\Program Files (x86)\Windows Kits\10\Debuggers\x86\cdb.exe'
$umdh = 'C:\Program Files (x86)\Windows Kits\10\Debuggers\x86\umdh.exe'
$gflags = 'C:\Program Files (x86)\Windows Kits\10\Debuggers\x86\gflags.exe'
foreach ($t in @($cdb, $umdh, $gflags)) {
if (Test-Path $t) { Write-Host " OK $t" -ForegroundColor Green }
else { Write-Host " MISSING $t" -ForegroundColor Red }
}
# ---- 2. WER LocalDumps for acclient.exe ----------------------------------
Write-Host "[2/3] Configuring WER LocalDumps for acclient.exe..." -ForegroundColor Cyan
$dumpDir = 'C:\Users\acbot\leakhunt\artifacts\crashdumps'
New-Item -ItemType Directory -Path $dumpDir -Force | Out-Null
$werKey = 'HKLM:\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps\acclient.exe'
New-Item -Path $werKey -Force | Out-Null
New-ItemProperty -Path $werKey -Name 'DumpFolder' -Value $dumpDir -PropertyType ExpandString -Force | Out-Null
New-ItemProperty -Path $werKey -Name 'DumpType' -Value 2 -PropertyType DWord -Force | Out-Null # 2 = Full
New-ItemProperty -Path $werKey -Name 'DumpCount' -Value 25 -PropertyType DWord -Force | Out-Null
Get-ItemProperty -Path $werKey | Format-List DumpFolder, DumpType, DumpCount
# ---- 3. gflags +ust on acclient.exe --------------------------------------
Write-Host "[3/3] Enabling gflags +ust on acclient.exe (FUTURE spawns only)..." -ForegroundColor Cyan
if (Test-Path $gflags) {
& $gflags /i acclient.exe +ust
} else {
Write-Warning "gflags.exe not found at $gflags — SDK install may have failed. Skipping +ust."
}
Write-Host "=== admin_setup.ps1 finished @ $(Get-Date -Format o) ===" -ForegroundColor Cyan
Write-Host "You can close this elevated window now." -ForegroundColor Green
} catch {
Write-Host "FATAL: $($_ | Out-String)" -ForegroundColor Red
}
Stop-Transcript | Out-Null
Read-Host 'press enter to close'