Skip to content

Commit 72ddaf1

Browse files
rick-slinjoachimmetz
authored andcommitted
expanded the number of parsed fields
1 parent 65f507a commit 72ddaf1

File tree

3 files changed

+95
-39
lines changed

3 files changed

+95
-39
lines changed

data/formatters/macos.yaml

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,18 @@
33
type: 'conditional'
44
data_type: 'apple:ips_recovery_logd'
55
message:
6-
- 'Application Name :{application_name}'
7-
- 'Application Version :{application_version}'
8-
- 'Bug Type :{bug_type}'
9-
- 'Device Model :{device_model}'
10-
- 'Incident Identifier :{incident_identifier}'
11-
- 'OS version :{os_version}'
6+
- 'Application Name: {application_name}'
7+
- 'Application Version: {application_version}'
8+
- 'Bug Type: {bug_type}'
9+
- 'Device Model: {device_model}'
10+
- 'Exception Type: {exception_type}'
11+
- 'Incident Identifier: {incident_identifier}'
12+
- 'OS Version: {os_version}'
13+
- 'Parent Process: {parent_process}'
14+
- 'Parent Process Identifier: {parent_process_identifier}'
15+
- 'Process Identifier: {process_identifier}'
16+
- 'Process Launch Time: {process_launch_time}'
17+
- 'User Identifier: {user_identifier}'
1218
short_message:
1319
- 'Bug Type :{bug_type}'
1420
- 'Device Model :{device_model}'

plaso/parsers/ips_plugins/recovery_logd.py

Lines changed: 75 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,18 @@ class AppleRecoveryLogdEvent(events.EventData):
1717
application_name (str): name of the application.
1818
application_version (str): version of the application.
1919
bug_type (str): type of bug.
20+
crash_reporter_key (str):
2021
device_model (str): model of the device.
2122
event_time (dfdatetime.DateTimeValues): date and time of the crash report.
23+
exception_type (str): type of the exception that caused the crash.
2224
incident_identifier (str): uuid for crash.
2325
os_version (str): version of the operating system.
26+
parent_process (str): parent process.
27+
parent_process_identifier (int): process identifier of the parent process.
28+
process_identifier (int): process identifier.
29+
process_launch_time (dfdatetime.DateTimeValues): date and time when the
30+
process started.
31+
user_identifier (int): user identifier of the process.
2432
"""
2533
DATA_TYPE = 'apple:ips_recovery_logd'
2634

@@ -30,10 +38,17 @@ def __init__(self):
3038
self.application_name = None
3139
self.application_version = None
3240
self.bug_type = None
41+
self.crash_reporter_key = None
3342
self.device_model = None
3443
self.event_time = None
44+
self.exception_type = None
3545
self.incident_identifier = None
3646
self.os_version = None
47+
self.parent_process = None
48+
self.parent_process_identifier = None
49+
self.process_identifier = None
50+
self.process_launch_time = None
51+
self.user_identifier = None
3752

3853

3954
class AppleRecoveryLogdIPSPlugin(interface.IPSPlugin):
@@ -48,7 +63,7 @@ class AppleRecoveryLogdIPSPlugin(interface.IPSPlugin):
4863
'app_name', 'app_version', 'bug_type', 'incident_id', 'os_version',
4964
'timestamp']
5065
REQUIRED_CONTENT_KEYS = [
51-
'pid', 'procLaunch', 'threads', 'usedImages']
66+
'captureTime', 'modelCode', 'os_version', 'pid', 'procLaunch', ]
5267

5368
_TWO_DIGITS = pyparsing.Word(pyparsing.nums, exact=2).setParseAction(
5469
lambda tokens: int(tokens[0], 10))
@@ -63,7 +78,7 @@ class AppleRecoveryLogdIPSPlugin(interface.IPSPlugin):
6378
_TWO_DIGITS.setResultsName('hours') + pyparsing.Suppress(':') +
6479
_TWO_DIGITS.setResultsName('minutes') + pyparsing.Suppress(':') +
6580
_TWO_DIGITS.setResultsName('seconds') + pyparsing.Suppress('.') +
66-
_TWO_DIGITS.setResultsName('hundredth') +
81+
_FOUR_DIGITS.setResultsName('fraction') +
6782
pyparsing.Word(
6883
pyparsing.nums + '+' + '-').setResultsName('timezone_delta'))
6984

@@ -72,58 +87,87 @@ def __init__(self):
7287
super(AppleRecoveryLogdIPSPlugin, self).__init__()
7388
self._event_data = None
7489

75-
# pylint: disable=unused-argument
76-
def Process(self, parser_mediator, ips_file=None, **unused_kwargs):
77-
"""Extracts information from an IPS log file.
78-
This is the main method that an IPS plugin needs to implement.
90+
def _ParseTimestampValue(self, parser_mediator, timestamp_text):
91+
"""Parses a timestamp string.
92+
7993
Args:
8094
parser_mediator (ParserMediator): parser mediator.
81-
ips_file (Optional[IpsFile]): database.
82-
Raises:
83-
ValueError: If the file value is missing.
84-
"""
85-
if ips_file is None:
86-
raise ValueError('Missing ips_file value')
87-
88-
# This will raise if unhandled keyword arguments are passed.
89-
super(AppleRecoveryLogdIPSPlugin, self).Process(parser_mediator)
90-
91-
event_data = AppleRecoveryLogdEvent()
92-
event_data.application_name = ips_file.header.get('app_name')
93-
event_data.application_version = ips_file.header.get('app_version')
94-
event_data.bug_type = ips_file.header.get('bug_type')
95-
event_data.device_model = ips_file.content.get('modelCode')
96-
event_data.incident_identifier = ips_file.header.get('incident_id')
97-
event_data.os_version = ips_file.header.get('os_version')
98-
99-
timestamp = ips_file.header.get('timestamp')
100-
101-
parsed_timestamp = self.TIMESTAMP_GRAMMAR.parseString(timestamp)
95+
timestamp_text (str): the timestamp to parse.
10296
97+
Returns:
98+
dfdatetime.TimeElements: date and time
99+
or None if not available.
100+
"""
103101
# dfDateTime takes the time zone offset as number of minutes relative from
104102
# UTC. So for Easter Standard Time (EST), which is UTC-5:00 the sign needs
105103
# to be converted, to +300 minutes.
104+
105+
parsed_timestamp = self.TIMESTAMP_GRAMMAR.parseString(timestamp_text)
106+
106107
try:
107108
time_delta_hours = int(parsed_timestamp['timezone_delta'][:3], 10)
108109
time_delta_minutes = int(parsed_timestamp['timezone_delta'][3:], 10)
109110
except (TypeError, ValueError):
110111
parser_mediator.ProduceExtractionWarning(
111112
'unsupported timezone offset value')
112-
return
113+
return None
113114

114115
time_zone_offset = (time_delta_hours * -60) + time_delta_minutes
115116

116117
try:
117-
event_data.event_time = dfdatetime_time_elements.TimeElements(
118+
milliseconds = round(parsed_timestamp['fraction']/10)
119+
120+
time_element_object = dfdatetime_time_elements.TimeElementsInMilliseconds(
118121
time_elements_tuple=(
119122
parsed_timestamp['year'], parsed_timestamp['month'],
120123
parsed_timestamp['day'], parsed_timestamp['hours'],
121-
parsed_timestamp['minutes'], parsed_timestamp['seconds']),
124+
parsed_timestamp['minutes'], parsed_timestamp['seconds'],
125+
milliseconds),
122126
time_zone_offset=time_zone_offset)
123127

124128
except (TypeError, ValueError):
125129
parser_mediator.ProduceExtractionWarning('unsupported date time value')
126-
return
130+
return None
131+
132+
return time_element_object
133+
134+
# pylint: disable=unused-argument
135+
def Process(self, parser_mediator, ips_file=None, **unused_kwargs):
136+
"""Extracts information from an IPS log file.
137+
This is the main method that an IPS plugin needs to implement.
138+
Args:
139+
parser_mediator (ParserMediator): parser mediator.
140+
ips_file (Optional[IpsFile]): database.
141+
Raises:
142+
ValueError: If the file value is missing.
143+
"""
144+
if ips_file is None:
145+
raise ValueError('Missing ips_file value')
146+
147+
# This will raise if unhandled keyword arguments are passed.
148+
super(AppleRecoveryLogdIPSPlugin, self).Process(parser_mediator)
149+
150+
event_data = AppleRecoveryLogdEvent()
151+
event_data.application_name = ips_file.header.get('app_name')
152+
event_data.application_version = ips_file.header.get('app_version')
153+
event_data.bug_type = ips_file.header.get('bug_type')
154+
event_data.device_model = ips_file.content.get('modelCode')
155+
event_data.exception_type = ips_file.content.get(
156+
'exception', {}).get('type')
157+
event_data.incident_identifier = ips_file.header.get('incident_id')
158+
event_data.os_version = ips_file.header.get('os_version')
159+
event_data.parent_process = ips_file.content.get('parentProc')
160+
event_data.parent_process_identifier = ips_file.content.get('parentPid')
161+
event_data.process_identifier = ips_file.content.get('pid')
162+
event_data.user_identifier = ips_file.content.get('userID')
163+
164+
event_timestamp = ips_file.content.get('captureTime')
165+
event_data.event_time = self._ParseTimestampValue(
166+
parser_mediator, event_timestamp)
167+
168+
launch_timestamp = ips_file.content.get('procLaunch')
169+
event_data.process_launch_time = self._ParseTimestampValue(
170+
parser_mediator, launch_timestamp)
127171

128172
parser_mediator.ProduceEventData(event_data)
129173

tests/parsers/ips_plugins/recovery_logd.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,15 @@ def testProcess(self):
2727
'application_version': '',
2828
'bug_type': '309',
2929
'device_model': 'iBridge2,14',
30-
'event_time': '2023-06-08T14:49:13+00:00',
30+
'exception_type': 'EXC_CRASH',
31+
'event_time': '2023-06-08T14:49:13.520+00:00',
3132
'incident_identifier': '9505C5CC-07DE-4E81-BCCE-60D07C96D1B1',
32-
'os_version': 'Bridge OS 7.5 (20P5058)'}
33+
'os_version': 'Bridge OS 7.5 (20P5058)',
34+
'parent_process': 'launchd',
35+
'parent_process_identifier': 1,
36+
'process_identifier': 74,
37+
'process_launch_time': '2023-06-08T14:49:12.507+00:00',
38+
'user_identifier': 501}
3339

3440
event_data = storage_writer.GetAttributeContainerByIndex('event_data', 0)
3541
self.CheckEventData(event_data, expected_event_values)

0 commit comments

Comments
 (0)