@@ -17,10 +17,10 @@ import (
1717
1818// ProcessInformation wrap basic process information and memory dump in a structure
1919type ProcessInformation struct {
20- PID uint32
21- ProcessName string
22- ProcessPath string
23- ProcessMemory []byte
20+ PID uint32
21+ ProcessName string
22+ ProcessPath string
23+ MemoryDump []byte
2424}
2525
2626// MemoryAnalysisRoutine analyse processes memory every 5 seconds
@@ -29,28 +29,34 @@ func MemoryAnalysisRoutine(pDump string, pQuarantine string, pKill bool, pAggres
2929 // list process information and memory
3030 procs := ListProcess (pVerbose )
3131
32- // dump process memory and quit the program
33- if len (pDump ) > 0 {
34- for _ , proc := range procs {
35- if err := WriteProcessMemoryToFile (pDump , proc .ProcessName + fmt .Sprint (proc .PID )+ ".dmp" , proc .ProcessMemory ); err != nil && pVerbose {
32+ // analyze process memory and executable
33+ for _ , proc := range procs {
34+ // dump processes memory and quit the program
35+ if len (pDump ) > 0 {
36+ if err := WriteProcessMemoryToFile (pDump , proc .ProcessName + fmt .Sprint (proc .PID )+ ".dmp" , proc .MemoryDump ); err != nil && pVerbose {
3637 log .Println ("[ERROR]" , err )
3738 }
3839 }
39- os .Exit (0 )
40- }
41-
42- // analyze process memory and executable
43- for _ , proc := range procs {
4440
4541 // parsing kill queue
4642 if StringInSlice (proc .ProcessPath , killQueue ) && pKill {
4743 log .Println ("[INFO]" , "KILLING PID" , proc .PID )
4844 KillProcessByID (proc .PID , pVerbose )
4945 } else {
50- MemoryAnalysis (proc , pQuarantine , pKill , pAggressive , pNotifications , pVerbose , rules )
46+ // analyzing process memory and cleaning memory buffer
47+ MemoryAnalysis (& proc , pQuarantine , pKill , pAggressive , pNotifications , pVerbose , rules )
48+ proc .MemoryDump = nil
49+
50+ // analyzing process executable
5151 FileAnalysis (proc .ProcessPath , pQuarantine , pKill , pAggressive , pNotifications , pVerbose , rules , "MEMORY" )
5252 }
5353 }
54+
55+ if len (pDump ) > 0 {
56+ log .Println ("[INFO] Processes memory dump completed - Exiting program." )
57+ os .Exit (0 )
58+ }
59+
5460 killQueue = nil
5561
5662 time .Sleep (5 * time .Second )
@@ -73,38 +79,53 @@ func ListProcess(verbose bool) (procsInfo []ProcessInformation) {
7379 }
7480
7581 if err == nil && procHandle > 0 {
76- procFilename , modules , err := GetProcessModulesHandles (procHandle )
77- if err == nil {
78- for _ , moduleHandle := range modules {
79- if moduleHandle != 0 {
80- moduleRawName , err := GetModuleFileNameEx (procHandle , moduleHandle , 512 )
81- if err != nil && verbose {
82- log .Println ("[ERROR]" , err )
83- }
84- moduleRawName = bytes .Trim (moduleRawName , "\x00 " )
85- modulePath := strings .Split (string (moduleRawName ), "\\ " )
86- moduleFileName := modulePath [len (modulePath )- 1 ]
87-
88- if procFilename == moduleFileName {
89- memdump := DumpModuleMemory (procHandle , moduleHandle , verbose )
90- if len (memdump ) > 0 {
91- proc := ProcessInformation {PID : procsIds [i ], ProcessName : procFilename , ProcessPath : string (moduleRawName ), ProcessMemory : memdump }
92- if ! StringInSlice (fmt .Sprintf ("%x" , md5 .Sum (memdump )), memoryscanHistory ) {
93- procsInfo = append (procsInfo , proc )
94- memoryscanHistory = append (memoryscanHistory , fmt .Sprintf ("%x" , md5 .Sum (memdump )))
95- }
96- }
97- }
82+ if proc , memdump , err := GetProcessMemory (procsIds [i ], procHandle , verbose ); err != nil && verbose {
83+ log .Println ("[ERROR]" , err )
84+ } else {
85+ if len (memdump ) > 0 {
86+ // return process memory only if it has changed since the last process scan
87+ if ! StringInSlice (fmt .Sprintf ("%x" , md5 .Sum (memdump )), memoryHashHistory ) {
88+ proc .MemoryDump = memdump
89+ procsInfo = append (procsInfo , proc )
90+ memoryHashHistory = append (memoryHashHistory , fmt .Sprintf ("%x" , md5 .Sum (memdump )))
9891 }
9992 }
10093 }
94+
10195 }
10296 windows .CloseHandle (procHandle )
10397 }
10498 }
10599 return procsInfo
106100}
107101
102+ // GetProcessMemory return a process memory dump based on its handle
103+ func GetProcessMemory (pid uint32 , handle windows.Handle , verbose bool ) (ProcessInformation , []byte , error ) {
104+
105+ procFilename , modules , err := GetProcessModulesHandles (handle )
106+ if err != nil {
107+ return ProcessInformation {}, nil , fmt .Errorf ("Unable to get PID %d memory: %s" , pid , err .Error ())
108+ }
109+
110+ for _ , moduleHandle := range modules {
111+ if moduleHandle != 0 {
112+ moduleRawName , err := GetModuleFileNameEx (handle , moduleHandle , 512 )
113+ if err != nil {
114+ return ProcessInformation {}, nil , err
115+ }
116+ moduleRawName = bytes .Trim (moduleRawName , "\x00 " )
117+ modulePath := strings .Split (string (moduleRawName ), "\\ " )
118+ moduleFileName := modulePath [len (modulePath )- 1 ]
119+
120+ if procFilename == moduleFileName {
121+ return ProcessInformation {PID : pid , ProcessName : procFilename , ProcessPath : string (moduleRawName )}, DumpModuleMemory (handle , moduleHandle , verbose ), nil
122+ }
123+ }
124+ }
125+
126+ return ProcessInformation {}, nil , fmt .Errorf ("Unable to get PID %d memory: no module corresponding to process name" , pid )
127+ }
128+
108129// KillProcessByID try to kill the specified PID
109130func KillProcessByID (procID uint32 , verbose bool ) (err error ) {
110131 hProc , err := GetProcessHandle (procID , windows .PROCESS_QUERY_INFORMATION | windows .PROCESS_TERMINATE )
0 commit comments