diff --git a/mvt/android/modules/adb/__init__.py b/mvt/android/modules/adb/__init__.py index aad18b4..831f91c 100644 --- a/mvt/android/modules/adb/__init__.py +++ b/mvt/android/modules/adb/__init__.py @@ -6,6 +6,7 @@ from .chrome_history import ChromeHistory from .dumpsys_accessibility import DumpsysAccessibility from .dumpsys_activities import DumpsysActivities +from .dumpsys_battery_history import DumpsysBatteryHistory from .dumpsys_batterystats import DumpsysBatterystats from .dumpsys_full import DumpsysFull from .dumpsys_packages import DumpsysPackages @@ -23,5 +24,6 @@ from .whatsapp import Whatsapp ADB_MODULES = [ChromeHistory, SMS, Whatsapp, Processes, Getprop, Settings, DumpsysAccessibility, DumpsysBatterystats, DumpsysProcstats, - DumpsysPackages, DumpsysReceivers, DumpsysActivities, - DumpsysFull, Packages, RootBinaries, Logcat, Files] + DumpsysBatteryHistory, DumpsysPackages, DumpsysReceivers, + DumpsysActivities, DumpsysFull, Packages, RootBinaries, Logcat, + Files] diff --git a/mvt/android/modules/adb/dumpsys_battery_history.py b/mvt/android/modules/adb/dumpsys_battery_history.py new file mode 100644 index 0000000..3d7a8dd --- /dev/null +++ b/mvt/android/modules/adb/dumpsys_battery_history.py @@ -0,0 +1,80 @@ +# Mobile Verification Toolkit (MVT) +# Copyright (c) 2021 The MVT Project Authors. +# Use of this software is governed by the MVT License 1.1 that can be found at +# https://license.mvt.re/1.1/ + +import logging +import os + +from .base import AndroidExtraction + +log = logging.getLogger(__name__) + + +class DumpsysBatteryHistory(AndroidExtraction): + """This module extracts stats on battery consumption by processes.""" + + def __init__(self, file_path=None, base_folder=None, output_folder=None, + serial=None, fast_mode=False, log=None, results=[]): + super().__init__(file_path=file_path, base_folder=base_folder, + output_folder=output_folder, fast_mode=fast_mode, + log=log, results=results) + + def check_indicators(self): + for result in self.results: + ioc = self.indicators.check_app_id(result["package"]) + if ioc: + result["matched_indicators"] = ioc + self.detected.append(result) + continue + + def process_process_history(self, output): + for line in output.split("\n")[1:]: + if line.strip() == "": + break + + time_elapsed, rest = line.strip().split(" ", 1) + + start = line.find(" 100 ") + if start == -1: + continue + + line = line[start+5:] + + event = "" + if line.startswith("+job"): + event = "start_job" + elif line.startswith("-job"): + event = "end_job" + elif line.startswith("+running +wake_lock="): + event = "wake" + else: + continue + + if event in ["start_job", "end_job"]: + uid = line[line.find("=")+1:line.find(":")] + service = line[line.find(":")+1:].strip('"') + package = service.split("/")[0] + else: + uid = line[line.find("=")+1:line.find(":")] + service = line[line.find("*walarm*:")+9:line.find(" ")].strip('"') + package = service.split("/")[0] + + + self.results.append({ + "time_elapsed": time_elapsed, + "event": event, + "uid": uid, + "package": package, + "service": service, + }) + + self.log.info("Extracted %d records from process history", len(self.results)) + + def run(self): + self._adb_connect() + + output = self._adb_command("dumpsys batterystats --history") + self.process_process_history(output) + + self._adb_disconnect() diff --git a/mvt/android/modules/adb/dumpsys_batterystats.py b/mvt/android/modules/adb/dumpsys_batterystats.py index 1160761..3d01f50 100644 --- a/mvt/android/modules/adb/dumpsys_batterystats.py +++ b/mvt/android/modules/adb/dumpsys_batterystats.py @@ -33,14 +33,4 @@ class DumpsysBatterystats(AndroidExtraction): log.info("Records from dumpsys batterystats stored at %s", stats_path) - history = self._adb_command("dumpsys batterystats --history") - if self.output_folder: - history_path = os.path.join(self.output_folder, - "dumpsys_batterystats_history.txt") - with open(history_path, "w", encoding="utf-8") as handle: - handle.write(history) - - log.info("History records from dumpsys batterystats stored at %s", - history_path) - self._adb_disconnect()