1
2
3
4
5
6 import os
7 import json
8 import codecs
9 import calendar
10 import datetime
11
12 from lib.cuckoo.common.abstracts import Report
13 from lib.cuckoo.common.exceptions import CuckooReportError
14
16 if isinstance(obj, datetime.datetime):
17 if obj.utcoffset() is not None:
18 obj = obj - obj.utcoffset()
19 return calendar.timegm(obj.timetuple()) + obj.microsecond / 1000000.0
20 raise TypeError("%r is not JSON serializable" % obj)
21
23 """Saves analysis results in JSON format."""
24
26 """Temporarily removes calls from the report by replacing them with
27 empty lists."""
28 if self.calls:
29 self.calls = None
30 return
31
32 self.calls = []
33 for process in results.get("behavior", {}).get("processes", []):
34 self.calls.append(process["calls"])
35 process["calls"] = []
36
38 """Restores calls that were temporarily removed in the report by
39 replacing the calls with the original values."""
40 if not self.calls:
41 return
42
43 for process in results.get("behavior", {}).get("processes", []):
44 process["calls"] = self.calls.pop(0)
45
46 - def run(self, results):
47 """Writes report.
48 @param results: Cuckoo results dict.
49 @raise CuckooReportError: if fails to write report.
50 """
51 indent = self.options.get("indent", 4)
52 encoding = self.options.get("encoding", "utf-8")
53
54
55
56 if "json.calls" in self.task["options"]:
57 self.calls = int(self.task["options"]["json.calls"])
58 else:
59 self.calls = self.options.get("calls", True)
60
61 self.erase_calls(results)
62
63 try:
64 path = os.path.join(self.reports_path, "report.json")
65
66 with codecs.open(path, "w", "utf-8") as report:
67 json.dump(results, report, default=default, sort_keys=False,
68 indent=int(indent), encoding=encoding)
69 except (UnicodeError, TypeError, IOError) as e:
70 raise CuckooReportError("Failed to generate JSON report: %s" % e)
71 finally:
72 self.restore_calls(results)
73