From e5003b64902ce5e54a79711a7287aeff915b3fe2 Mon Sep 17 00:00:00 2001 From: emilien Date: Sun, 25 Jul 2021 15:06:22 +0200 Subject: [PATCH 1/3] Handle SMS bases in mmssms.db instead of bugle_db --- mvt/android/modules/adb/base.py | 13 ++++++++ mvt/android/modules/adb/sms.py | 54 ++++++++++++++++++++++++--------- 2 files changed, 52 insertions(+), 15 deletions(-) diff --git a/mvt/android/modules/adb/base.py b/mvt/android/modules/adb/base.py index aa0c0a7..8b09864 100644 --- a/mvt/android/modules/adb/base.py +++ b/mvt/android/modules/adb/base.py @@ -112,6 +112,19 @@ class AndroidExtraction(MVTModule): :returns: Output of command """ return self._adb_command(f"su -c {command}") + + def _adb_check_file_exists(self, file): + """Verify that a file exists. + :param file: Path of the file + :returns: Boolean indicating whether the file exists or not + """ + + # Connect to the device over adb. + self._adb_connect() + # Check if we have root, if not raise an Exception. + self._adb_root_or_die() + + return bool(self._adb_command_as_root(f"[ ! -f {file} ] || echo 1")) def _adb_download(self, remote_path, local_path, progress_callback=None, retry_root=True): """Download a file form the device. diff --git a/mvt/android/modules/adb/sms.py b/mvt/android/modules/adb/sms.py index dcaccac..62b8007 100644 --- a/mvt/android/modules/adb/sms.py +++ b/mvt/android/modules/adb/sms.py @@ -13,6 +13,29 @@ from mvt.common.utils import convert_timestamp_to_iso, check_for_links log = logging.getLogger(__name__) SMS_PATH = "data/data/com.google.android.apps.messaging/databases/bugle_db" +SMS_PATH_2 = "data/data/com.android.providers.telephony/databases/mmssms.db" +sql_command_1 = """ +SELECT + ppl.normalized_destination AS number, + p.timestamp AS timestamp, +CASE WHEN m.sender_id IN +(SELECT _id FROM participants WHERE contact_id=-1) +THEN 2 ELSE 1 END incoming, p.text AS text +FROM messages m, conversations c, parts p, + participants ppl, conversation_participants cp +WHERE (m.conversation_id = c._id) + AND (m._id = p.message_id) + AND (cp.conversation_id = c._id) + AND (cp.participant_id = ppl._id); +""" +sql_command_2 = """ +SELECT + address AS number, + date_sent AS timestamp, + type as incoming, + body AS text +FROM sms; +""" class SMS(AndroidExtraction): """This module extracts all SMS messages containing links.""" @@ -47,23 +70,16 @@ class SMS(AndroidExtraction): def _parse_db(self, db_path): """Parse an Android bugle_db SMS database file. :param db_path: Path to the Android SMS database file to process + :param sql_command: SQL command to execute """ conn = sqlite3.connect(db_path) cur = conn.cursor() - cur.execute(""" - SELECT - ppl.normalized_destination AS number, - p.timestamp AS timestamp, - CASE WHEN m.sender_id IN - (SELECT _id FROM participants WHERE contact_id=-1) - THEN 2 ELSE 1 END incoming, p.text AS text - FROM messages m, conversations c, parts p, - participants ppl, conversation_participants cp - WHERE (m.conversation_id = c._id) - AND (m._id = p.message_id) - AND (cp.conversation_id = c._id) - AND (cp.participant_id = ppl._id); - """) + + if (self.SMS_DB_TYPE == 1): + cur.execute(sql_command_1) + elif (self.SMS_DB_TYPE == 2): + cur.execute(sql_command_2) + names = [description[0] for description in cur.description] for item in cur: @@ -85,7 +101,15 @@ class SMS(AndroidExtraction): log.info("Extracted a total of %d SMS messages containing links", len(self.results)) def run(self): + # Checking the SMS database path try: - self._adb_process_file(os.path.join("/", SMS_PATH), self._parse_db) + if (self._adb_check_file_exists(os.path.join("/", SMS_PATH))): + self.SMS_DB_TYPE = 1 + self._adb_process_file(os.path.join("/", SMS_PATH), self._parse_db) + elif (self._adb_check_file_exists(os.path.join("/", SMS_PATH_2))): + self.SMS_DB_TYPE = 2 + self._adb_process_file(os.path.join("/", SMS_PATH_2), self._parse_db) + else: + self.log.error("No SMS database found") except Exception as e: self.log.error(e) From 47df94fa12abc107b78108e5cd54f2f29e984ed0 Mon Sep 17 00:00:00 2001 From: emilien Date: Sun, 25 Jul 2021 15:13:23 +0200 Subject: [PATCH 2/3] fix typo --- mvt/android/modules/adb/sms.py | 1 - 1 file changed, 1 deletion(-) diff --git a/mvt/android/modules/adb/sms.py b/mvt/android/modules/adb/sms.py index 62b8007..21676ba 100644 --- a/mvt/android/modules/adb/sms.py +++ b/mvt/android/modules/adb/sms.py @@ -70,7 +70,6 @@ class SMS(AndroidExtraction): def _parse_db(self, db_path): """Parse an Android bugle_db SMS database file. :param db_path: Path to the Android SMS database file to process - :param sql_command: SQL command to execute """ conn = sqlite3.connect(db_path) cur = conn.cursor() From 632409c81d2207e451a680a14d26101b5118bd20 Mon Sep 17 00:00:00 2001 From: Nex Date: Fri, 30 Jul 2021 18:08:52 +0200 Subject: [PATCH 3/3] Using consistent constant names --- mvt/android/modules/adb/base.py | 2 +- mvt/android/modules/adb/sms.py | 21 +++++++++++---------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/mvt/android/modules/adb/base.py b/mvt/android/modules/adb/base.py index cccce7e..2ddb95d 100644 --- a/mvt/android/modules/adb/base.py +++ b/mvt/android/modules/adb/base.py @@ -124,7 +124,7 @@ class AndroidExtraction(MVTModule): self._adb_connect() # Check if we have root, if not raise an Exception. self._adb_root_or_die() - + return bool(self._adb_command_as_root(f"[ ! -f {file} ] || echo 1")) def _adb_download(self, remote_path, local_path, progress_callback=None, retry_root=True): diff --git a/mvt/android/modules/adb/sms.py b/mvt/android/modules/adb/sms.py index f00108c..eab9031 100644 --- a/mvt/android/modules/adb/sms.py +++ b/mvt/android/modules/adb/sms.py @@ -13,9 +13,8 @@ from .base import AndroidExtraction log = logging.getLogger(__name__) -SMS_PATH = "data/data/com.google.android.apps.messaging/databases/bugle_db" -SMS_PATH_2 = "data/data/com.android.providers.telephony/databases/mmssms.db" -sql_command_1 = """ +SMS_BUGLE_PATH = "data/data/com.google.android.apps.messaging/databases/bugle_db" +SMS_BUGLE_QUERY = """ SELECT ppl.normalized_destination AS number, p.timestamp AS timestamp, @@ -29,7 +28,9 @@ WHERE (m.conversation_id = c._id) AND (cp.conversation_id = c._id) AND (cp.participant_id = ppl._id); """ -sql_command_2 = """ + +SMS_MMSSMS_PATH = "data/data/com.android.providers.telephony/databases/mmssms.db" +SMS_MMSMS_QUERY = """ SELECT address AS number, date_sent AS timestamp, @@ -76,9 +77,9 @@ class SMS(AndroidExtraction): cur = conn.cursor() if (self.SMS_DB_TYPE == 1): - cur.execute(sql_command_1) + cur.execute(SMS_BUGLE_QUERY) elif (self.SMS_DB_TYPE == 2): - cur.execute(sql_command_2) + cur.execute(SMS_MMSMS_QUERY) names = [description[0] for description in cur.description] @@ -103,12 +104,12 @@ class SMS(AndroidExtraction): def run(self): # Checking the SMS database path try: - if (self._adb_check_file_exists(os.path.join("/", SMS_PATH))): + if (self._adb_check_file_exists(os.path.join("/", SMS_BUGLE_PATH))): self.SMS_DB_TYPE = 1 - self._adb_process_file(os.path.join("/", SMS_PATH), self._parse_db) - elif (self._adb_check_file_exists(os.path.join("/", SMS_PATH_2))): + self._adb_process_file(os.path.join("/", SMS_BUGLE_PATH), self._parse_db) + elif (self._adb_check_file_exists(os.path.join("/", SMS_MMSSMS_PATH))): self.SMS_DB_TYPE = 2 - self._adb_process_file(os.path.join("/", SMS_PATH_2), self._parse_db) + self._adb_process_file(os.path.join("/", SMS_MMSSMS_PATH), self._parse_db) else: self.log.error("No SMS database found") except Exception as e: