//go:build windows package winpwn import ( "strings" "golang.org/x/sys/windows" ) // ImportedLibs returns the distinct DLLs listed in this PE's import table, // each loaded into the current process (via LoadLibrary -- already-loaded // system DLLs just hand back their existing mapping and a bumped refcount, // which is immediately released again) to report its current live image // base. // // This is useful on Windows specifically because a system DLL's base is // randomized once per boot, not once per process: every process on the // machine sees kernel32.dll/ntdll.dll/etc. at the same address until the // next reboot. So the base reported here is a real, reusable value for // planning an exploit against this machine -- not a property of some // already-running target you'd otherwise have to leak from first. func (p *PEFile) ImportedLibs() ([]ImportedLib, error) { imports, err := p.ListImports() if err != nil { return nil, err } seen := make(map[string]bool, len(imports)) var out []ImportedLib for _, im := range imports { key := strings.ToLower(im.DLL) if im.DLL == "" || seen[key] { continue } seen[key] = true h, err := windows.LoadLibrary(im.DLL) if err != nil { out = append(out, ImportedLib{Name: im.DLL, Err: err}) continue } out = append(out, ImportedLib{Name: im.DLL, Base: uint64(h)}) windows.FreeLibrary(h) } return out, nil }