pranshuparmar/witr · error
failed to read ProcessParameters struct
Error message
failed to read ProcessParameters struct
What it means
witr reads a target process's PEB via readProcessMemory to extract cwd, command line, exe path and environment on Windows. This error means the PEB address was readable but the rtlUserProcessParameters struct at that address could not be read, so no process detail could be collected. It is typically caused by the target process exiting mid-inspection, insufficient privileges, or cross-bitness/cross-architecture reading.
Source
Thrown at internal/proc/peb_windows.go:175
if pbi.PebBaseAddress == 0 {
return fmt.Errorf("PEB Base Address is 0")
}
// Read PEB
var pebPtr uintptr
paramsOffset := uintptr(0x20)
if unsafe.Sizeof(uintptr(0)) == 4 {
paramsOffset = 0x10
}
if !readProcessMemory(handle, pbi.PebBaseAddress+paramsOffset, unsafe.Pointer(&pebPtr), unsafe.Sizeof(pebPtr)) {
return fmt.Errorf("failed to read PEB ProcessParameters address")
}
var params rtlUserProcessParameters
if !readProcessMemory(handle, pebPtr, unsafe.Pointer(¶ms), unsafe.Sizeof(params)) {
return fmt.Errorf("failed to read ProcessParameters struct")
}
info.Cwd = readUnicodeString(handle, params.CurrentDirectoryPath)
info.CommandLine = readUnicodeString(handle, params.CommandLine)
info.Exe = readUnicodeString(handle, params.ImagePathName)
info.Env = readEnvironmentBlock(handle, params.Environment)
return nil
}
func readProcessMemory(handle syscall.Handle, addr uintptr, dest unsafe.Pointer, size uintptr) bool {
// lpNumberOfBytesRead is a SIZE_T* (pointer-sized: 8 bytes on x64). It MUST
// be uintptr, not uint32 — a uint32 here lets the kernel write 8 bytes into
// a 4-byte slot, corrupting adjacent memory and causing nondeterministic
// crashes far from this call site.
var read uintptr
ret, _, _ := procReadProcessMem.Call(
uintptr(handle),View on GitHub (pinned to dc4fa1da82)
Solutions
- Re-run the lookup; if the target process was exiting, retry on a live process.
- Run witr elevated (Administrator) so the handle has PROCESS_VM_READ on the target.
- Verify the target and witr bitness/architecture match (x64 vs x86, ARM64).
- Check whether the process is protected (e.g. protected process light); fall back to the snapshot-based lookup (getInfoFromSnapshot) or skip detail collection.
- Confirm the paramsOffset derivation matches the target OS build.
Example fix
// before
if !readProcessMemory(handle, pebPtr, unsafe.Pointer(¶ms), unsafe.Sizeof(params)) {
return fmt.Errorf("failed to read ProcessParameters struct")
}
// after
if !readProcessMemory(handle, pebPtr, unsafe.Pointer(¶ms), unsafe.Sizeof(params)) {
// degrade gracefully instead of failing the whole lookup
return partialInfo, nil // caller still gets PID/PPID/exe from snapshot
} Defensive patterns
Strategy: try-catch
Validate before calling
// Windows: check the process is still alive and accessible before detailed lookup
h, err := windows.OpenProcess(windows.PROCESS_QUERY_LIMITED_INFORMATION|windows.PROCESS_VM_READ, false, uint32(pid))
if err != nil { /* process gone or access denied */ }
windows.CloseHandle(h) Try / catch
p, err := GetProcessDetailedInfo(pid)
if err != nil {
if strings.Contains(err.Error(), "failed to read ProcessParameters struct") {
// degrade: fall back to snapshot-based info (PID/PPID/exe only)
p, err = getSnapshotInfo(pid)
}
} Prevention
- Run elevated when probing system or protected processes
- Re-check process liveness immediately before detailed reads
- Match process bitness/architecture between witr and the target
- Fall back to snapshot-based enumeration when VM reads fail
When it happens
Trigger: Calling GetProcessDetailedInfo on a Windows process where the second readProcessMemory call for the rtlUserProcessParameters struct fails — usually because the process terminated between the PEB read and this read, the handle lacks PROCESS_VM_READ rights, or the target is a protected/elevated process.
Common situations: Inspecting short-lived processes that exit during the scan; running witr without elevation while probing a service running as SYSTEM/protected light processes; 32-bit target inspected from a 64-bit build (or vice versa) making the params offset/size mismatch.
Related errors
AI-assisted analysis of pranshuparmar/witr@dc4fa1da82 (2026-09-01).
Data as JSON: /api/errors/daf4405fd7d1bc2d.
Report an issue: GitHub.