mirror of
https://github.com/mvt-project/mvt.git
synced 2024-06-30 16:18:54 +00:00
Small clean ups and type hints of mvt-android
This commit is contained in:
parent
14bbbd9e45
commit
efceb777f0
|
@ -71,15 +71,7 @@ def download_apks(ctx, all_apks, virustotal, output, from_file, serial):
|
||||||
log.critical("You need to specify an output folder with --output!")
|
log.critical("You need to specify an output folder with --output!")
|
||||||
ctx.exit(1)
|
ctx.exit(1)
|
||||||
|
|
||||||
if not os.path.exists(output):
|
download = DownloadAPKs(results_path=output, all_apks=all_apks)
|
||||||
try:
|
|
||||||
os.makedirs(output)
|
|
||||||
except Exception as e:
|
|
||||||
log.critical("Unable to create output folder %s: %s", output, e)
|
|
||||||
ctx.exit(1)
|
|
||||||
|
|
||||||
download = DownloadAPKs(output_folder=output, all_apks=all_apks,
|
|
||||||
log=logging.getLogger(DownloadAPKs.__module__))
|
|
||||||
if serial:
|
if serial:
|
||||||
download.serial = serial
|
download.serial = serial
|
||||||
download.run()
|
download.run()
|
||||||
|
|
|
@ -9,6 +9,7 @@ import os
|
||||||
import sys
|
import sys
|
||||||
import tarfile
|
import tarfile
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
from typing import Callable
|
||||||
|
|
||||||
from rich.prompt import Prompt
|
from rich.prompt import Prompt
|
||||||
|
|
||||||
|
@ -38,7 +39,7 @@ class CmdAndroidCheckBackup(Command):
|
||||||
self.backup_archive = None
|
self.backup_archive = None
|
||||||
self.backup_files = []
|
self.backup_files = []
|
||||||
|
|
||||||
def init(self):
|
def init(self) -> None:
|
||||||
if os.path.isfile(self.target_path):
|
if os.path.isfile(self.target_path):
|
||||||
self.backup_type = "ab"
|
self.backup_type = "ab"
|
||||||
with open(self.target_path, "rb") as handle:
|
with open(self.target_path, "rb") as handle:
|
||||||
|
@ -77,7 +78,7 @@ class CmdAndroidCheckBackup(Command):
|
||||||
log.critical("Invalid backup path, path should be a folder or an Android Backup (.ab) file")
|
log.critical("Invalid backup path, path should be a folder or an Android Backup (.ab) file")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
def module_init(self, module):
|
def module_init(self, module: Callable) -> None:
|
||||||
if self.backup_type == "folder":
|
if self.backup_type == "folder":
|
||||||
module.from_folder(self.target_path, self.backup_files)
|
module.from_folder(self.target_path, self.backup_files)
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
from typing import Callable
|
||||||
from zipfile import ZipFile
|
from zipfile import ZipFile
|
||||||
|
|
||||||
from mvt.common.command import Command
|
from mvt.common.command import Command
|
||||||
|
@ -31,7 +32,7 @@ class CmdAndroidCheckBugreport(Command):
|
||||||
self.bugreport_archive = None
|
self.bugreport_archive = None
|
||||||
self.bugreport_files = []
|
self.bugreport_files = []
|
||||||
|
|
||||||
def init(self):
|
def init(self) -> None:
|
||||||
if os.path.isfile(self.target_path):
|
if os.path.isfile(self.target_path):
|
||||||
self.bugreport_format = "zip"
|
self.bugreport_format = "zip"
|
||||||
self.bugreport_archive = ZipFile(self.target_path)
|
self.bugreport_archive = ZipFile(self.target_path)
|
||||||
|
@ -44,7 +45,7 @@ class CmdAndroidCheckBugreport(Command):
|
||||||
for file_name in subfiles:
|
for file_name in subfiles:
|
||||||
self.bugreport_files.append(os.path.relpath(os.path.join(root, file_name), parent_path))
|
self.bugreport_files.append(os.path.relpath(os.path.join(root, file_name), parent_path))
|
||||||
|
|
||||||
def module_init(self, module):
|
def module_init(self, module: Callable) -> None:
|
||||||
if self.bugreport_format == "zip":
|
if self.bugreport_format == "zip":
|
||||||
module.from_zip(self.bugreport_archive, self.bugreport_files)
|
module.from_zip(self.bugreport_archive, self.bugreport_files)
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
from typing import Callable
|
||||||
|
|
||||||
from tqdm import tqdm
|
from tqdm import tqdm
|
||||||
|
|
||||||
|
@ -36,23 +37,22 @@ class DownloadAPKs(AndroidExtraction):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, output_folder=None, all_apks=False, log=None,
|
def __init__(self, results_path: str = "", all_apks: bool = False,
|
||||||
packages=None):
|
packages: list = []):
|
||||||
"""Initialize module.
|
"""Initialize module.
|
||||||
:param output_folder: Path to the folder where data should be stored
|
:param results_path: Path to the folder where data should be stored
|
||||||
:param all_apks: Boolean indicating whether to download all packages
|
:param all_apks: Boolean indicating whether to download all packages
|
||||||
or filter known-goods
|
or filter known-goods
|
||||||
:param packages: Provided list of packages, typically for JSON checks
|
:param packages: Provided list of packages, typically for JSON checks
|
||||||
"""
|
"""
|
||||||
super().__init__(log=log)
|
super().__init__(results_path=results_path, log=log)
|
||||||
|
|
||||||
self.packages = packages
|
self.packages = packages
|
||||||
self.all_apks = all_apks
|
self.all_apks = all_apks
|
||||||
self.output_folder_apk = None
|
self.results_path_apks = None
|
||||||
self.output_folder = output_folder
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_json(cls, json_path):
|
def from_json(cls, json_path: str) -> Callable:
|
||||||
"""Initialize this class from an existing apks.json file.
|
"""Initialize this class from an existing apks.json file.
|
||||||
|
|
||||||
:param json_path: Path to the apks.json file to parse.
|
:param json_path: Path to the apks.json file to parse.
|
||||||
|
@ -62,7 +62,7 @@ class DownloadAPKs(AndroidExtraction):
|
||||||
packages = json.load(handle)
|
packages = json.load(handle)
|
||||||
return cls(packages=packages)
|
return cls(packages=packages)
|
||||||
|
|
||||||
def pull_package_file(self, package_name, remote_path):
|
def pull_package_file(self, package_name: str, remote_path: str) -> None:
|
||||||
"""Pull files related to specific package from the device.
|
"""Pull files related to specific package from the device.
|
||||||
|
|
||||||
:param package_name: Name of the package to download
|
:param package_name: Name of the package to download
|
||||||
|
@ -76,7 +76,7 @@ class DownloadAPKs(AndroidExtraction):
|
||||||
if "==/" in remote_path:
|
if "==/" in remote_path:
|
||||||
file_name = "_" + remote_path.split("==/")[1].replace(".apk", "")
|
file_name = "_" + remote_path.split("==/")[1].replace(".apk", "")
|
||||||
|
|
||||||
local_path = os.path.join(self.output_folder_apk,
|
local_path = os.path.join(self.results_path_apks,
|
||||||
f"{package_name}{file_name}.apk")
|
f"{package_name}{file_name}.apk")
|
||||||
name_counter = 0
|
name_counter = 0
|
||||||
while True:
|
while True:
|
||||||
|
@ -84,7 +84,7 @@ class DownloadAPKs(AndroidExtraction):
|
||||||
break
|
break
|
||||||
|
|
||||||
name_counter += 1
|
name_counter += 1
|
||||||
local_path = os.path.join(self.output_folder_apk,
|
local_path = os.path.join(self.results_path_apks,
|
||||||
f"{package_name}{file_name}_{name_counter}.apk")
|
f"{package_name}{file_name}_{name_counter}.apk")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -105,11 +105,9 @@ class DownloadAPKs(AndroidExtraction):
|
||||||
|
|
||||||
return local_path
|
return local_path
|
||||||
|
|
||||||
def get_packages(self):
|
def get_packages(self) -> None:
|
||||||
"""Use the Packages adb module to retrieve the list of packages.
|
"""Use the Packages adb module to retrieve the list of packages.
|
||||||
We reuse the same extraction logic to then download the APKs.
|
We reuse the same extraction logic to then download the APKs.
|
||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
self.log.info("Retrieving list of installed packages...")
|
self.log.info("Retrieving list of installed packages...")
|
||||||
|
|
||||||
|
@ -120,12 +118,11 @@ class DownloadAPKs(AndroidExtraction):
|
||||||
|
|
||||||
self.packages = m.results
|
self.packages = m.results
|
||||||
|
|
||||||
def pull_packages(self):
|
def pull_packages(self) -> None:
|
||||||
"""Download all files of all selected packages from the device."""
|
"""Download all files of all selected packages from the device.
|
||||||
log.info("Starting extraction of installed APKs at folder %s", self.output_folder)
|
"""
|
||||||
|
log.info("Starting extraction of installed APKs at folder %s",
|
||||||
if not os.path.exists(self.output_folder):
|
self.results_path)
|
||||||
os.mkdir(self.output_folder)
|
|
||||||
|
|
||||||
# If the user provided the flag --all-apks we select all packages.
|
# If the user provided the flag --all-apks we select all packages.
|
||||||
packages_selection = []
|
packages_selection = []
|
||||||
|
@ -139,7 +136,7 @@ class DownloadAPKs(AndroidExtraction):
|
||||||
if not package.get("system", False):
|
if not package.get("system", False):
|
||||||
packages_selection.append(package)
|
packages_selection.append(package)
|
||||||
|
|
||||||
log.info("Selected only %d packages which are not marked as system",
|
log.info("Selected only %d packages which are not marked as \"system\"",
|
||||||
len(packages_selection))
|
len(packages_selection))
|
||||||
|
|
||||||
if len(packages_selection) == 0:
|
if len(packages_selection) == 0:
|
||||||
|
@ -148,9 +145,9 @@ class DownloadAPKs(AndroidExtraction):
|
||||||
|
|
||||||
log.info("Downloading packages from device. This might take some time ...")
|
log.info("Downloading packages from device. This might take some time ...")
|
||||||
|
|
||||||
self.output_folder_apk = os.path.join(self.output_folder, "apks")
|
self.results_path_apks = os.path.join(self.results_path, "apks")
|
||||||
if not os.path.exists(self.output_folder_apk):
|
if not os.path.exists(self.results_path_apks):
|
||||||
os.mkdir(self.output_folder_apk)
|
os.mkdirs(self.results_path_apks)
|
||||||
|
|
||||||
counter = 0
|
counter = 0
|
||||||
for package in packages_selection:
|
for package in packages_selection:
|
||||||
|
@ -172,14 +169,12 @@ class DownloadAPKs(AndroidExtraction):
|
||||||
|
|
||||||
log.info("Download of selected packages completed")
|
log.info("Download of selected packages completed")
|
||||||
|
|
||||||
def save_json(self):
|
def save_json(self) -> None:
|
||||||
"""Save the results to the package.json file."""
|
json_path = os.path.join(self.results_path, "apks.json")
|
||||||
json_path = os.path.join(self.output_folder, "apks.json")
|
|
||||||
with open(json_path, "w", encoding="utf-8") as handle:
|
with open(json_path, "w", encoding="utf-8") as handle:
|
||||||
json.dump(self.packages, handle, indent=4)
|
json.dump(self.packages, handle, indent=4)
|
||||||
|
|
||||||
def run(self) -> None:
|
def run(self) -> None:
|
||||||
"""Run all steps of fetch-apk."""
|
|
||||||
self.get_packages()
|
self.get_packages()
|
||||||
self._adb_connect()
|
self._adb_connect()
|
||||||
self.pull_packages()
|
self.pull_packages()
|
||||||
|
|
Loading…
Reference in New Issue
Block a user