-
Notifications
You must be signed in to change notification settings - Fork 50
/
procmon.py
94 lines (79 loc) · 3.14 KB
/
procmon.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# Copyright (C) 2016 Cuckoo Foundation.
# This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org
# See the file 'docs/LICENSE' for copying permission.
import logging
import os.path
import subprocess
import time
from threading import Thread
from lib.common.abstracts import Auxiliary
from lib.common.constants import ROOT
from lib.common.exceptions import CuckooPackageError
from lib.common.results import upload_to_host
class Procmon(Auxiliary, Thread):
"""Allow procmon to be run on the side."""
def __init__(self, options, config):
Thread.__init__(self)
Auxiliary.__init__(self, options, config)
self.enabled = config.procmon
self.startupinfo = subprocess.STARTUPINFO()
self.startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
bin_path = os.path.join(ROOT, "bin")
self.procmon_exe = os.path.join(bin_path, "procmon.exe")
self.procmon_pmc = os.path.join(bin_path, "procmon.pmc")
self.procmon_pml = os.path.join(bin_path, "procmon")
self.procmon_xml = os.path.join(bin_path, "procmon.xml")
def run(self) -> bool:
if not self.enabled:
return False
if not os.path.exists(self.procmon_exe) or not os.path.exists(self.procmon_pmc):
raise CuckooPackageError(
"In order to use the Process Monitor functionality it is "
"required to have Procmon setup with CAPE. Please run the "
"CAPE Community script which will automatically fetch all "
"related files to get you up-and-running."
)
# Start process monitor in the background.
subprocess.Popen(
(
self.procmon_exe,
"/AcceptEula",
"/Quiet",
"/Minimized",
"/BackingFile",
self.procmon_pml,
),
startupinfo=self.startupinfo,
shell=True,
)
# Try to avoid race conditions by waiting until at least something
# has been written to the log file.
while not os.path.exists(self.procmon_pml) or not os.path.getsize(self.procmon_pml):
time.sleep(0.1)
return True
def stop(self) -> bool:
try:
# Terminate process monitor.
subprocess.call((self.procmon_exe, "/Terminate"), startupinfo=self.startupinfo, shell=True)
# Convert the process monitor log into a readable XML file.
subprocess.call(
(
self.procmon_exe,
"/OpenLog",
f"{self.procmon_pml}.PML",
"/LoadConfig",
self.procmon_pmc,
"/SaveAs",
self.procmon_xml,
"/SaveApplyFilter",
),
startupinfo=self.startupinfo,
shell=True,
)
# Upload the XML file to the host.
upload_to_host(self.procmon_xml, "procmon.xml")
if self.enabled:
return True
return False
except Exception as e:
logging.error(e, exc_info=True)