inital commit
This commit is contained in:
@@ -0,0 +1,174 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"overlord-client/cmd/agent/wire"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
var (
|
||||
modKernel32 = windows.NewLazySystemDLL("kernel32.dll")
|
||||
modPsapi = windows.NewLazySystemDLL("psapi.dll")
|
||||
procEnumProcesses = modPsapi.NewProc("EnumProcesses")
|
||||
procGetProcessMemoryInfo = modPsapi.NewProc("GetProcessMemoryInfo")
|
||||
procOpenProcess = modKernel32.NewProc("OpenProcess")
|
||||
procGetProcessImageFileNameW = modPsapi.NewProc("GetProcessImageFileNameW")
|
||||
)
|
||||
|
||||
type PROCESS_MEMORY_COUNTERS struct {
|
||||
CB uint32
|
||||
PageFaultCount uint32
|
||||
PeakWorkingSetSize uintptr
|
||||
WorkingSetSize uintptr
|
||||
QuotaPeakPagedPoolUsage uintptr
|
||||
QuotaPagedPoolUsage uintptr
|
||||
QuotaPeakNonPagedPoolUsage uintptr
|
||||
QuotaNonPagedPoolUsage uintptr
|
||||
PagefileUsage uintptr
|
||||
PeakPagefileUsage uintptr
|
||||
}
|
||||
|
||||
func listProcesses() ([]wire.ProcessInfo, error) {
|
||||
var pids [4096]uint32
|
||||
var bytesReturned uint32
|
||||
|
||||
ret, _, _ := procEnumProcesses.Call(
|
||||
uintptr(unsafe.Pointer(&pids[0])),
|
||||
uintptr(len(pids)*4),
|
||||
uintptr(unsafe.Pointer(&bytesReturned)),
|
||||
)
|
||||
|
||||
if ret == 0 {
|
||||
return nil, fmt.Errorf("EnumProcesses failed")
|
||||
}
|
||||
|
||||
numProcesses := int(bytesReturned / 4)
|
||||
processes := make([]wire.ProcessInfo, 0, numProcesses)
|
||||
|
||||
for i := 0; i < numProcesses; i++ {
|
||||
pid := int32(pids[i])
|
||||
if pid == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
handle, _, _ := procOpenProcess.Call(
|
||||
windows.PROCESS_QUERY_INFORMATION|windows.PROCESS_VM_READ,
|
||||
0,
|
||||
uintptr(pid),
|
||||
)
|
||||
|
||||
if handle == 0 {
|
||||
continue
|
||||
}
|
||||
defer windows.CloseHandle(windows.Handle(handle))
|
||||
|
||||
var filename [windows.MAX_PATH]uint16
|
||||
ret, _, _ := procGetProcessImageFileNameW.Call(
|
||||
handle,
|
||||
uintptr(unsafe.Pointer(&filename[0])),
|
||||
uintptr(len(filename)),
|
||||
)
|
||||
|
||||
name := "Unknown"
|
||||
if ret != 0 {
|
||||
name = syscall.UTF16ToString(filename[:])
|
||||
|
||||
for i := len(name) - 1; i >= 0; i-- {
|
||||
if name[i] == '\\' || name[i] == '/' {
|
||||
name = name[i+1:]
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var memCounters PROCESS_MEMORY_COUNTERS
|
||||
memCounters.CB = uint32(unsafe.Sizeof(memCounters))
|
||||
memory := uint64(0)
|
||||
|
||||
ret, _, _ = procGetProcessMemoryInfo.Call(
|
||||
handle,
|
||||
uintptr(unsafe.Pointer(&memCounters)),
|
||||
uintptr(memCounters.CB),
|
||||
)
|
||||
|
||||
if ret != 0 {
|
||||
memory = uint64(memCounters.WorkingSetSize)
|
||||
}
|
||||
|
||||
var pbi windows.PROCESS_BASIC_INFORMATION
|
||||
ppid := int32(0)
|
||||
err := windows.NtQueryInformationProcess(windows.Handle(handle), windows.ProcessBasicInformation, unsafe.Pointer(&pbi), uint32(unsafe.Sizeof(pbi)), nil)
|
||||
if err == nil {
|
||||
ppid = int32(pbi.InheritedFromUniqueProcessId)
|
||||
}
|
||||
|
||||
username := "System"
|
||||
var token windows.Token
|
||||
if err := windows.OpenProcessToken(windows.Handle(handle), windows.TOKEN_QUERY, &token); err == nil {
|
||||
defer token.Close()
|
||||
tokenUser, err := token.GetTokenUser()
|
||||
if err == nil {
|
||||
account, domain, _, err := tokenUser.User.Sid.LookupAccount("")
|
||||
if err == nil {
|
||||
if domain != "" {
|
||||
username = domain + "\\" + account
|
||||
} else {
|
||||
username = account
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
procType := "other"
|
||||
usernameLower := strings.ToLower(username)
|
||||
nameLower := strings.ToLower(name)
|
||||
|
||||
if pid <= 4 || nameLower == "system" || nameLower == "registry" {
|
||||
procType = "system"
|
||||
} else if strings.Contains(usernameLower, "system") ||
|
||||
strings.Contains(usernameLower, "local service") ||
|
||||
strings.Contains(usernameLower, "network service") ||
|
||||
usernameLower == "system" {
|
||||
procType = "service"
|
||||
} else {
|
||||
|
||||
currentUser, err := windows.GetCurrentProcessToken().GetTokenUser()
|
||||
if err == nil {
|
||||
tokenUser, err := token.GetTokenUser()
|
||||
if err == nil && tokenUser.User.Sid.Equals(currentUser.User.Sid) {
|
||||
procType = "own"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
processes = append(processes, wire.ProcessInfo{
|
||||
PID: pid,
|
||||
PPID: ppid,
|
||||
Name: name,
|
||||
CPU: 0.0,
|
||||
Memory: memory,
|
||||
Username: username,
|
||||
Type: procType,
|
||||
})
|
||||
}
|
||||
|
||||
return processes, nil
|
||||
}
|
||||
|
||||
func killProcess(pid int32) error {
|
||||
handle, err := windows.OpenProcess(windows.PROCESS_TERMINATE, false, uint32(pid))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer windows.CloseHandle(handle)
|
||||
|
||||
return windows.TerminateProcess(handle, 1)
|
||||
}
|
||||
Reference in New Issue
Block a user