Add GetOrFindPrimaryProcess to correctly group process/threads

This commit is contained in:
Daniel
2019-04-26 15:17:44 +02:00
parent 78a0b3c1fb
commit 6495b4fe5f
4 changed files with 77 additions and 21 deletions

View File

@@ -2,7 +2,6 @@ package windowskext
import (
"encoding/binary"
"fmt"
"net"
"github.com/tevino/abool"
@@ -23,7 +22,7 @@ type VerdictRequest struct {
remoteIP [4]uint32 /* Destination Address */
localPort uint16 /* Source Port */
remotePort uint16 /* Destination port */
compartmentId uint32
compartmentID uint32
interfaceIndex uint32
subInterfaceIndex uint32
packetSize uint32

View File

@@ -94,13 +94,27 @@ func CleanProcessStorage(thresholdDuration time.Duration) {
defer processesLock.Unlock()
threshold := time.Now().Add(-thresholdDuration).Unix()
// clean primary processes
for _, p := range processes {
p.Lock()
if p.FirstCommEstablished < threshold && p.CommCount == 0 {
if !p.Virtual && p.LastCommEstablished < threshold && p.CommCount == 0 {
go p.Delete()
}
p.Unlock()
}
// clean virtual processes
for _, p := range processes {
p.Lock()
if p.Virtual {
_, parentIsAlive := processes[p.ParentPid]
if !parentIsAlive {
go p.Delete()
}
}
p.Unlock()
}
}
// SetDBController sets the database controller and allows the package to push database updates on a save. It must be set by the package that registers the "network" database.

View File

@@ -65,7 +65,7 @@ func GetProcessByPacket(pkt packet.Packet) (process *Process, direction bool, er
return nil, direction, ErrConnectionNotFound
}
process, err = GetOrFindProcess(pid)
process, err = GetOrFindPrimaryProcess(pid)
if err != nil {
return nil, direction, err
}
@@ -114,7 +114,7 @@ func GetProcessByEndpoints(localIP net.IP, localPort uint16, remoteIP net.IP, re
return nil, ErrConnectionNotFound
}
process, err = GetOrFindProcess(pid)
process, err = GetOrFindPrimaryProcess(pid)
if err != nil {
return nil, err
}

View File

@@ -4,8 +4,8 @@ package process
import (
"fmt"
"path/filepath"
"runtime"
"strings"
"sync"
"time"
@@ -45,6 +45,7 @@ type Process struct {
FirstCommEstablished int64
LastCommEstablished int64
CommCount uint
Virtual bool // This process is merged into another process
}
// ProfileSet returns the assigned profile set.
@@ -88,8 +89,54 @@ func (p *Process) RemoveCommunication() {
}
}
// GetOrFindPrimaryProcess returns the highest process in the tree that matches the given PID.
func GetOrFindPrimaryProcess(pid int) (*Process, error) {
process, err := loadProcess(pid)
if err != nil {
return nil, err
}
for {
parentProcess, err := loadProcess(process.ParentPid)
if err != nil {
log.Tracef("process: could not get parent (%d): %s", process.Pid, err)
return process, nil
}
// parent process does not match, we reached the top of the tree of matching processes
if process.Path != parentProcess.Path {
// save to storage
process.Save()
// return primary process
return process, nil
}
// mark as virtual
process.Lock()
process.Virtual = true
process.Unlock()
// save to storage
process.Save()
// continue up to process tree
process = parentProcess
}
}
// GetOrFindProcess returns the process for the given PID.
func GetOrFindProcess(pid int) (*Process, error) {
p, err := loadProcess(pid)
if err != nil {
return nil, err
}
// save to storage
p.Save()
return p, nil
}
func loadProcess(pid int) (*Process, error) {
process, ok := GetProcessFromStorage(pid)
if ok {
return process, nil
@@ -116,7 +163,7 @@ func GetOrFindProcess(pid int) (*Process, error) {
var uids []int32
uids, err = pInfo.Uids()
if err != nil {
log.Warningf("process: failed to get UID: %s", err)
log.Warningf("process: failed to get UID for p%d: %s", pid, err)
} else {
new.UserID = int(uids[0])
}
@@ -125,7 +172,7 @@ func GetOrFindProcess(pid int) (*Process, error) {
// Username
new.UserName, err = pInfo.Username()
if err != nil {
log.Warningf("process: failed to get Username: %s", err)
log.Warningf("process: failed to get Username for p%d: %s", pid, err)
}
// TODO: User Home
@@ -134,7 +181,7 @@ func GetOrFindProcess(pid int) (*Process, error) {
// PPID
ppid, err := pInfo.Ppid()
if err != nil {
log.Warningf("process: failed to get PPID: %s", err)
log.Warningf("process: failed to get PPID for p%d: %s", pid, err)
} else {
new.ParentPid = int(ppid)
}
@@ -142,8 +189,10 @@ func GetOrFindProcess(pid int) (*Process, error) {
// Path
new.Path, err = pInfo.Exe()
if err != nil {
log.Warningf("process: failed to get Path: %s", err)
log.Warningf("process: failed to get Path for p%d: %s", pid, err)
}
// Executable Name
_, new.ExecName = filepath.Split(new.Path)
// Current working directory
// net yet implemented for windows
@@ -155,13 +204,16 @@ func GetOrFindProcess(pid int) (*Process, error) {
// Command line arguments
new.CmdLine, err = pInfo.Cmdline()
if err != nil {
log.Warningf("process: failed to get Cmdline: %s", err)
log.Warningf("process: failed to get Cmdline for p%d: %s", pid, err)
}
// Name
new.Name, err = pInfo.Name()
if err != nil {
log.Warningf("process: failed to get Name: %s", err)
log.Warningf("process: failed to get Name for p%d: %s", pid, err)
}
if new.Name == "" {
new.Name = new.ExecName
}
// TODO: App Icon
@@ -239,16 +291,7 @@ func GetOrFindProcess(pid int) (*Process, error) {
// }
// }
// }
// Executable Information
// FIXME: use os specific path seperator
splittedPath := strings.Split(new.Path, "/")
new.ExecName = splittedPath[len(splittedPath)-1]
}
// save to storage
new.Save()
return new, nil
}