Files
NomanNasirMinhas 28f02e2fd2 init
2026-08-16 19:28:23 +03:00

80 lines
2.1 KiB
Go

// Package runtime discovers live driver state: loaded kernel modules, device
// names, and named sections in the object manager namespace.
package runtime
import (
"strings"
"unsafe"
"golang.org/x/sys/windows"
)
// Module is a loaded kernel module.
type Module struct {
ImageBase uintptr
ImageSize uint32
Path string
}
// Modules returns the list of loaded kernel modules via
// NtQuerySystemInformation(SystemModuleInformation).
func Modules() ([]Module, error) {
size := uint32(1 << 20) // 1 MiB initial; grows on STATUS_INFO_LENGTH_MISMATCH
for {
buf := make([]byte, size)
err := windows.NtQuerySystemInformation(windows.SystemModuleInformation, unsafe.Pointer(&buf[0]), size, &size)
if err == nil {
return parseModules(buf), nil
}
if err != windows.STATUS_INFO_LENGTH_MISMATCH {
return nil, err
}
}
}
// parseModules decodes an RTL_PROCESS_MODULES buffer into a slice of Module.
func parseModules(buf []byte) []Module {
mods := (*windows.RTL_PROCESS_MODULES)(unsafe.Pointer(&buf[0]))
out := make([]Module, 0, mods.NumberOfModules)
base := unsafe.Pointer(&mods.Modules[0])
entrySize := unsafe.Sizeof(windows.RTL_PROCESS_MODULE_INFORMATION{})
for i := uint32(0); i < mods.NumberOfModules; i++ {
mi := (*windows.RTL_PROCESS_MODULE_INFORMATION)(unsafe.Pointer(uintptr(base) + uintptr(i)*entrySize))
out = append(out, Module{
ImageBase: mi.ImageBase,
ImageSize: mi.ImageSize,
Path: modulePath(mi),
})
}
return out
}
// modulePath extracts the null-terminated ANSI path from a module info entry.
func modulePath(mi *windows.RTL_PROCESS_MODULE_INFORMATION) string {
b := mi.FullPathName[:]
n := 0
for n < len(b) && b[n] != 0 {
n++
}
return string(b[:n])
}
// FindModule returns the loaded module whose file name matches name
// (case-insensitive), or ok=false if it is not loaded.
func FindModule(name string) (Module, bool) {
mods, err := Modules()
if err != nil {
return Module{}, false
}
for _, m := range mods {
base := m.Path
if i := strings.LastIndexAny(base, `\/`); i >= 0 {
base = base[i+1:]
}
if strings.EqualFold(base, name) {
return m, true
}
}
return Module{}, false
}