2026-07-18 21:37:15 +03:00
2026-07-18 21:37:15 +03:00
2026-07-18 21:37:15 +03:00
2026-07-18 21:37:15 +03:00
2026-07-18 21:37:15 +03:00
2026-07-18 21:37:15 +03:00
2026-07-18 21:37:15 +03:00
2026-07-18 21:37:15 +03:00
2026-07-18 21:37:15 +03:00
2026-07-18 21:37:15 +03:00
2026-07-18 21:37:15 +03:00
2026-07-18 21:37:15 +03:00
2026-07-18 21:37:15 +03:00
2026-07-18 21:37:15 +03:00
2026-07-18 21:37:15 +03:00
2026-07-18 21:37:15 +03:00
2026-07-18 21:37:15 +03:00
2026-07-18 21:37:15 +03:00
2026-07-18 21:37:15 +03:00
2026-07-18 21:37:15 +03:00
2026-07-18 21:37:15 +03:00
2026-07-18 21:37:15 +03:00
2026-07-18 21:37:15 +03:00
2026-07-18 21:37:15 +03:00
2026-07-18 21:37:15 +03:00
2026-07-18 21:37:15 +03:00
2026-07-18 21:37:15 +03:00
2026-07-18 21:37:15 +03:00
2026-07-18 21:37:15 +03:00
2026-07-18 21:37:15 +03:00
2026-07-18 21:37:15 +03:00
2026-07-18 21:37:15 +03:00
2026-07-18 21:37:15 +03:00
2026-07-18 21:37:15 +03:00
2026-07-18 21:37:15 +03:00
2026-07-18 21:37:15 +03:00
2026-07-18 21:37:15 +03:00
2026-07-18 21:37:15 +03:00
2026-07-18 21:37:15 +03:00
2026-07-18 21:37:15 +03:00
2026-07-18 21:37:15 +03:00
2026-07-18 21:37:15 +03:00
2026-07-18 21:37:15 +03:00
2026-07-18 21:37:15 +03:00
2026-07-18 21:37:15 +03:00
2026-07-18 21:37:15 +03:00
2026-07-18 21:37:15 +03:00
2026-07-18 21:37:15 +03:00
2026-07-18 21:37:15 +03:00
2026-07-18 21:37:15 +03:00
2026-07-18 21:37:15 +03:00
2026-07-18 21:37:15 +03:00
2026-07-18 21:37:15 +03:00
2026-07-18 21:37:15 +03:00
2026-07-18 21:37:15 +03:00
2026-07-18 21:37:15 +03:00
2026-07-18 21:37:15 +03:00
2026-07-18 21:37:15 +03:00
2026-07-18 21:37:15 +03:00
2026-07-18 21:37:15 +03:00
2026-07-18 21:37:15 +03:00
2026-07-18 21:37:15 +03:00

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):

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, log.go, cyclic.go, fiddling.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, process.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)

  • ServePipe(name) / DialPipe(name) over CreateNamedPipe (PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED) / CreateFile, both returning a *Tube.

PE analysis (pe.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, 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, imports.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, 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, 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)

  • OpenPEForWrite, SetSectionCharacteristics/MakeSectionExecutable/ MakeSectionWritable, DisableTLSCallbacks, PatchBytes/ PatchBytesAtOffset, RecalculateChecksum.

Minidump (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)

  • 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_lfh.go, heap_segment.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)

  • 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, shellcode_exec_windows.go)

  • ShellcodeWinExec(cmd): position-independent x64 shellcode resolving kernel32 via the PEB (source: shellcode/asm/winexec_x64.asm).
  • ExecuteShellcode: runs a template locally for validation.

CLI (cmd/winpwn, cmd/pwninit)

  • 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 — worked examples and a function-by-function reference.
  • USAGE_RU.md — condensed reference (Russian).
  • ROADMAP.md — implementation status and planned work.
S
Description
pwntools for Windows in Golang
Readme
9.5 MiB
Languages
Go 85.6%
C 10.2%
Assembly 4.2%