Skip to content

Commit

Permalink
chg: [all] parsers and analysers are now classes
Browse files Browse the repository at this point in the history
  • Loading branch information
cvandeplas committed Aug 28, 2024
1 parent 9571217 commit 94ee149
Show file tree
Hide file tree
Showing 77 changed files with 3,172 additions and 2,714 deletions.
36 changes: 34 additions & 2 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,11 @@
"cwd": "${workspaceFolder}/"
},
{
"name": "Python Debugger: analyse list",
"name": "Python Debugger: analysers list",
"type": "debugpy",
"request": "launch",
"program": "${workspaceFolder}/sysdiagnose.py",
"args": "analyse list",
"args": "analysers",
"cwd": "${workspaceFolder}/"
},
{
Expand All @@ -53,6 +53,14 @@
"args": "-c 1 analyse timeliner",
"cwd": "${workspaceFolder}/"
},
{
"name": "Python Debugger: analyse demo_analyser",
"type": "debugpy",
"request": "launch",
"program": "${workspaceFolder}/sysdiagnose.py",
"args": "-c 1 analyse demo_analyser",
"cwd": "${workspaceFolder}/"
},
{
"name": "Python Debugger: analyse apps 1",
"type": "debugpy",
Expand Down Expand Up @@ -93,6 +101,22 @@
"args": "-c 1 analyse timeliner",
"cwd": "${workspaceFolder}/"
},
{
"name": "Python Debugger: analyse yarascan",
"type": "debugpy",
"request": "launch",
"program": "${workspaceFolder}/sysdiagnose.py",
"args": "-c 1 analyse yarascan",
"cwd": "${workspaceFolder}/"
},
{
"name": "Python Debugger: list parsers",
"type": "debugpy",
"request": "launch",
"program": "${workspaceFolder}/sysdiagnose.py",
"args": "parsers",
"cwd": "${workspaceFolder}/"
},
{
"name": "Python Debugger: parse demo_parser",
"type": "debugpy",
Expand Down Expand Up @@ -133,6 +157,14 @@
"args": "-c 2 parse networkextension",
"cwd": "${workspaceFolder}/"
},
{
"name": "Python Debugger: parse psthread",
"type": "debugpy",
"request": "launch",
"program": "${workspaceFolder}/sysdiagnose.py",
"args": "-c 1 parse psthread",
"cwd": "${workspaceFolder}/"
},
{
"name": "Python Debugger: parse ps",
"type": "debugpy",
Expand Down
60 changes: 27 additions & 33 deletions analysers/apps.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,30 @@
# For Python3
# Author: Emiliern Le Jamtel

import os
import json
import re
from utils.base import BaseAnalyserInterface
from parsers.accessibility_tcc import AccessibilityTccParser
from parsers.brctl import BrctlParser
from parsers.itunesstore import iTunesStoreParser
from parsers.logarchive import LogarchiveParser

analyser_description = 'Get list of Apps installed on the device'
analyser_format = 'json'

uses_parsers = ['accessibility_tcc', 'brctl', 'itunesstore', 'logarchive'] # not used yet, but just interesting to keep track
class AppsAnalyser(BaseAnalyserInterface):
description = 'Get list of Apps installed on the device'
format = 'json'

# TODO this code is terribly slow. I would expect this is due to all the if key in lookups. It took 49 seconds for case 1
def __init__(self, config: dict, case_id: str):
super().__init__(__file__, config, case_id)

# TODO this code is terribly slow. I would expect this is due to all the if key in lookups. It took 49 seconds for case 1
def execute(self):
'''
Go through all json files in the folder and generate the json list of apps
'''
apps = {}
# TODO add a check to see if the files exist, and if necessary, call the parsers (or ask the user to call them), or maybe using a flag in the function call

def analyse_path(case_folder: str, output_file: str = 'apps.json') -> bool:
'''
Go through all json files in the folder and generate the json list of apps
'''

apps = {}
# TODO add a check to see if the files exist, and if necessary, call the parsers (or ask the user to call them), or maybe using a flag in the function call

with open(os.path.join(case_folder, 'accessibility_tcc.json'), 'r') as f:
json_data = json.load(f)
json_data = AccessibilityTccParser(self.config, self.case_id).get_result()
if json_data and not json_data.get('error'):
for entry in json_data['access']:
if entry['client'] not in apps:
Expand All @@ -35,8 +37,7 @@ def analyse_path(case_folder: str, output_file: str = 'apps.json') -> bool:
except KeyError:
apps[entry['client']]['services'] = [entry['service']]

with open(os.path.join(case_folder, 'brctl.json'), 'r') as f:
json_data = json.load(f)
json_data = BrctlParser(self.config, self.case_id).get_result()
if json_data and not json_data.get('error'):
# directly going to the list of apps
for entry in json_data['app_library_id']:
Expand All @@ -50,8 +51,7 @@ def analyse_path(case_folder: str, output_file: str = 'apps.json') -> bool:

apps[entry]['found'].append('brctl')

with open(os.path.join(case_folder, 'itunesstore.json'), 'r') as f:
json_data = json.load(f)
json_data = iTunesStoreParser(self.config, self.case_id).get_result()
if json_data and not json_data.get('error'):
# directly going to the list of apps
for entry in json_data['application_id']:
Expand All @@ -60,19 +60,17 @@ def analyse_path(case_folder: str, output_file: str = 'apps.json') -> bool:
else:
apps[entry['bundle_id']]['found'].append('itunesstore')

re_bundle_id_pattern = r'(([a-zA-Z0-9-_]+\.)+[a-zA-Z0-9-_]+)'
# list files in here
with open(os.path.join(case_folder, 'logarchive.json'), 'r') as f:
for line in f: # jsonl format
re_bundle_id_pattern = r'(([a-zA-Z0-9-_]+\.)+[a-zA-Z0-9-_]+)'
# list files in here
json_entries = LogarchiveParser(self.config, self.case_id).get_result()
for entry in json_entries:
try:
entry = json.loads(line)
# skip empty entries
if entry['subsystem'] == '':
continue
except KeyError: # last line of the native logarchive.json file
continue
except json.decoder.JSONDecodeError: # last lines of the native logarchive.json file
except KeyError: # last line of the native logarchive.jsonl file
continue

# extract app/bundle id or process name from the subsystem field
if not re.search(r'^' + re_bundle_id_pattern + r'$', entry['subsystem']):
# extract foo.bar.hello from the substing if it is in that format
Expand Down Expand Up @@ -101,8 +99,4 @@ def analyse_path(case_folder: str, output_file: str = 'apps.json') -> bool:
if 'logarchive' not in apps[entry['subsystem']]['found']:
apps[entry['subsystem']]['found'].append('logarchive')

with open(output_file, 'w') as f:
json.dump(apps, f, indent=4, sort_keys=True)
print(f"Apps list written to {output_file}")
# print(json.dumps(apps, indent=4))
return
return apps
30 changes: 19 additions & 11 deletions analysers/demo_analyser.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,26 @@
# For Python3
# DEMO - Skeleton

import json
from utils.base import BaseAnalyserInterface


analyser_description = "Do something useful (DEMO)"
analyser_format = "json"
class DemoAnalyser(BaseAnalyserInterface):
description = "Do something useful (DEMO)"
# format = "json" # by default json

def __init__(self, config: dict, case_id: str):
super().__init__(__file__, config, case_id)

def analyse_path(case_folder: str, output_file: str = "demo-analyser.json") -> bool:
"""
Generate the timeline and save it to filename
"""
print("DO SOMETHING HERE")
with open(output_file, 'w') as f:
json.dump({"Hello": "World"}, f, indent=4)
return
def execute(self):
"""
This method is responsible for executing the functionality of the class.
Load parsers here, and use the parser.get_result() to get the data.
By doing so you will get the parser output even if it never ran before.
"""
print("DO SOMETHING HERE")

# json_data = p_fooparser.get_result()

result = {'foo': 'bar'}
return result
Loading

0 comments on commit 94ee149

Please sign in to comment.