# winpwn

Pwntools-style exploitation toolkit for Windows pwn/CTF tasks, written in Go.

pwntools targets Linux. winpwn targets the Windows equivalents: SEH instead of
signals, PE instead of ELF, msvcrt/ntdll instead of glibc, the Windows Debug
API instead of ptrace/GDB. Go is used for direct WinAPI access
(`golang.org/x/sys/windows`) and goroutine-based concurrent I/O.

## Install / import

Library (used from a solve script):

```go
import "winpwn"

func main() {
    t, err := winpwn.Spawn("./target.exe")
    if err != nil {
        log.Fatal(err)
    }
    if err := t.SendLineAfter([]byte("Input: "), payload); err != nil {
        log.Fatal(err)
    }
    t.Interactive()
}
```

The module is used locally via a `replace` directive; it is not published.

CLI (quick-answer wrapper):

```
go install ./cmd/winpwn
go install ./cmd/pwninit
```

## Components

**Core** ([context.go](context.go), [log.go](log.go), [cyclic.go](cyclic.go),
[fiddling.go](fiddling.go), [packing.go](packing.go))
- `Context`: global `Arch`, `LogLevel`, `Timeout`, `Newline` (pwntools' `context`).
- `Info`/`Success`/`Warn`/`Error`: leveled logger to stderr, gated by `Context.LogLevel`.
- `Cyclic`/`CyclicN`/`CyclicFind`/`CyclicFindN`: de Bruijn pattern generation and
  offset lookup. Matches pwntools' `cyclic`/`cyclic_find` output.
- `Hexdump`/`Enhex`/`Unhex`/`Xor`.
- `P16`/`P32`/`P64`, `U16`/`U32`/`U64`: little-endian pack/unpack.

**Tubes** ([tube.go](tube.go), [process.go](process.go), [remote.go](remote.go))
- `Spawn` (local process) and `Remote` (TCP) return a `*Tube`.
- `Send`/`SendLine`/`SendAfter`/`SendLineAfter`/`Recv`/`RecvUntil`/`RecvLine`/
  `RecvRegex`/`RecvPred`/`Interactive`/`Close`.
- Every method returns `error`; the library never calls `os.Exit`/`log.Fatal`.
- `SetTimeout` overrides `Context.Timeout` per tube (0 = block forever).

**Named pipes** ([pipe_windows.go](pipe_windows.go))
- `ServePipe(name)` / `DialPipe(name)` over `CreateNamedPipe`
  (`PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED`) / `CreateFile`, both returning a
  `*Tube`.

**PE analysis** ([pe.go](pe.go), [sections.go](sections.go))
- `OpenPE`, `ImageBase`, `EntryPoint`, `Is64Bit` (PE32 and PE32+).
- Per-section `IsReadable`/`Writable`/`Executable`/`IsRWX`, `VirtualAddress`
  (RVA), `Offset` (`PointerToRawData`, file offset), `Entropy`,
  `LikelyPackedSections`.
- `SearchBytes`: byte-pattern search across sections (analogue of `elf.search()`).

**Checksec** ([checksec.go](checksec.go), [authenticode_windows.go](authenticode_windows.go))
- `(*PEFile).Checksec()`: ASLR, HighEntropyVA, DEP, CFG (cross-checked against
  Load Config `GuardFlags`), SafeSEH (x86 only, gated by `SEHApplicable`),
  GS-cookie heuristic, Authenticode presence, .NET/CLR.
- `VerifyAuthenticodeSignature`: signature verification via `WinVerifyTrust`
  (Windows-only, no network calls).

**Imports / exports** ([exports.go](exports.go), [imports.go](imports.go),
[imported_libs_windows.go](imported_libs_windows.go))
- `ListExports`/`GetExport` with forwarder resolution.
- `ListImports`/`FindImport` walking the IAT thunk arrays.
- `ImportedLibs`: distinct imported DLLs, each `LoadLibrary`'d to report its live
  image base (system DLL bases are randomized per boot, not per process, so the
  address is valid machine-wide until reboot).

**Live-process PE** ([procmem_windows.go](procmem_windows.go), [symbols_windows.go](symbols_windows.go))
- `OpenPEFromProcess(pid, base)`: every PE accessor works against process memory
  (`ReadProcessMemory`), not just a disk file.
- `ResolveModuleBase(pid, name)`: walks `PEB->Ldr->InMemoryOrderModuleList`.
- `SpawnSuspended`/`ResumeMainThread`: launch with `CREATE_SUSPENDED`.
  `ResolveModuleBase` returns null until the loader runs post-resume.
- `ProcessSymbols` (`NewProcessSymbols`): `Base`, `Symbol`, `Modules`,
  `AllSymbols`. `SymbolVA`/`ListLoadedModules` for one-off lookups.

**ROP gadgets** ([gadgets.go](gadgets.go), [rop.go](rop.go))
- `NewROP(path)`: shells out to `rp-win.exe` (a Windows build of rp++), resolved
  from `RP_WIN_EXE` or `C:\tools\rp-win\rp-win.exe`. Run with `--allow-branches`,
  so results include JOP transit gadgets (indirect `jmp reg`/`call reg`) as well
  as ret-terminated ones.
- `NewROPExternal(path, toolPath)`: explicit tool path.
- `Find(pattern)`: ranked matches, index 0 is the cleanest usable gadget.
  `Search`/`SearchRegex`: `(results, error)` form.
- `Disassemble(addr, count)`: native decode via `golang.org/x/arch/x86/x86asm`
  for verifying a chain in-script.

**Patching** ([patch.go](patch.go))
- `OpenPEForWrite`, `SetSectionCharacteristics`/`MakeSectionExecutable`/
  `MakeSectionWritable`, `DisableTLSCallbacks`, `PatchBytes`/
  `PatchBytesAtOffset`, `RecalculateChecksum`.

**Minidump** ([minidump.go](minidump.go))
- `OpenMinidump(path)`: parses `MINIDUMP_HEADER`/`MINIDUMP_DIRECTORY` directly
  (no `dbghelp.dll`). `Modules()` (loaded modules + base addresses),
  `Exception()` (faulting thread/code/address/parameters), `RawStream(type)` for
  any other stream. Works without `GOOS=windows`.

**Debugger** ([debugger_windows.go](debugger_windows.go))
- `Attach(pid)`: wraps the Windows Debug API
  (`DebugActiveProcess`/`WaitForDebugEvent`/`ContinueDebugEvent`/
  `Get/SetThreadContext`), resolved via `LazyDLL`.
- `Events()`: typed event channel (`EventBreakpoint`/`EventException`/
  `EventCreateProcess`/`EventLoadDll`/`EventExitProcess`/...).
- `SetBreakpoint`/`RemoveBreakpoint`: software INT3; `Continue` handles the
  restore/single-step/re-arm sequence internally.
- `GetContext`/`SetContext` (registers), `ReadMemory`/`WriteMemory`.
- No GUI-debugger (x64dbg/WinDbg) integration; `Attach` uses the same Win32 API.

**Heap struct parsing** ([heap.go](heap.go), [heap_lfh.go](heap_lfh.go),
[heap_segment.go](heap_segment.go), [heap_windows.go](heap_windows.go))
- Works against any `io.ReaderAt` (`*ProcessMemory`, `*Debugger`, or a test
  buffer). Only `ListProcessHeaps` requires a live process (walks the PEB).
- NT Heap: `ReadHeap`, `DecodeHeapEntry` (XOR-decoding), `WalkAllHeapEntries`,
  `SummariseEntries`, `AdjacentBusyPairs`, `EntriesInRange`, `EntriesWithUserData`.
- NT Heap LFH: `ReadLFHBuckets`, `FindLFHBucket`, `ActiveSubsegment`,
  `ReadLFHSubsegment`, `CalibrateLFHFirstBlockOffset`, `BlockAddress`, `SlotOf`.
- Segment Heap: `ReadSegmentHeap` (VS/LFH context summaries).
- `AdjacentAddressPairs`/`FindAdjacentPair`: adjacency detection from leaked
  addresses, no chunk-header decode required.
- Offsets confirmed on build 10.0.26100; verify on other builds. VS chunk headers
  and LFH `EncodedOffsets` are XOR-encoded and not decoded — calibrate against a
  known address instead.

**Spray** ([spray.go](spray.go))
- `SprayAndFind`: spray up to N times, check each attempt against all prior
  samples (plus an optional seed) via a caller-supplied relation, return the
  first match. Covers both equality (UAF reuse) and distance (adjacency) checks.

**Shellcraft** ([shellcraft.go](shellcraft.go), [shellcode_exec_windows.go](shellcode_exec_windows.go))
- `ShellcodeWinExec(cmd)`: position-independent x64 shellcode resolving kernel32
  via the PEB (source: [shellcode/asm/winexec_x64.asm](shellcode/asm/winexec_x64.asm)).
- `ExecuteShellcode`: runs a template locally for validation.

**CLI** ([cmd/winpwn](cmd/winpwn/main.go), [cmd/pwninit](cmd/pwninit/main.go))
- `winpwn`: `checksec`, `cyclic`, `hex`/`unhex`, `hexdump`, `rop`, `bytes`,
  `disasm`, `exports`, `imports`, `heap`.
- `pwninit`: prints recon (arch, checksec, sections, imported libs) and scaffolds
  a `go.mod` + minimal `main.go` for a new task.

## Documentation

- [USAGE.md](USAGE.md) — worked examples and a function-by-function reference.
- [USAGE_RU.md](USAGE_RU.md) — condensed reference (Russian).
- [ROADMAP.md](ROADMAP.md) — implementation status and planned work.
