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(&params), 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

  1. Re-run the lookup; if the target process was exiting, retry on a live process.
  2. Run witr elevated (Administrator) so the handle has PROCESS_VM_READ on the target.
  3. Verify the target and witr bitness/architecture match (x64 vs x86, ARM64).
  4. Check whether the process is protected (e.g. protected process light); fall back to the snapshot-based lookup (getInfoFromSnapshot) or skip detail collection.
  5. Confirm the paramsOffset derivation matches the target OS build.

Example fix

// before
if !readProcessMemory(handle, pebPtr, unsafe.Pointer(&params), unsafe.Sizeof(params)) {
    return fmt.Errorf("failed to read ProcessParameters struct")
}
// after
if !readProcessMemory(handle, pebPtr, unsafe.Pointer(&params), 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

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.