Fix download of APKs that require root privileges

Some system APKs are stored in directories that require root privileges, such as /system/product.
This commit is contained in:
Adam Lawson 2021-07-20 12:43:54 +01:00
parent 425d83e0a0
commit cb6bde5b8c
2 changed files with 29 additions and 2 deletions

View File

@ -135,7 +135,7 @@ class DownloadAPKs(AndroidExtraction):
try:
with PullProgress(unit='B', unit_divisor=1024, unit_scale=True,
miniters=1) as pp:
self._adb_download(remote_path, local_path,
self._adb_download(remote_path, local_path, package_name,
progress_callback=pp.update_to)
except Exception as e:
log.exception("Failed to pull package file from %s: %s",

View File

@ -111,7 +111,7 @@ class AndroidExtraction(MVTModule):
"""
return self._adb_command(f"su -c {command}")
def _adb_download(self, remote_path, local_path, progress_callback=None):
def _adb_download(self, remote_path, local_path, package_name, progress_callback=None):
"""Download a file form the device.
:param remote_path: Path to download from the device
:param local_path: Path to where to locally store the copy of the file
@ -119,8 +119,35 @@ class AndroidExtraction(MVTModule):
"""
try:
self.device.pull(remote_path, local_path, progress_callback)
except AdbCommandFailureException:
self._adb_download_root(remote_path, local_path, package_name, progress_callback)
except AdbCommandFailureException as e:
raise Exception(f"Unable to download file {remote_path}: {e}")
def _adb_download_root(self, remote_path, local_path, package_name, progress_callback=None):
try:
# Check if we have root, if not raise an Exception.
self._adb_root_or_die()
# We create a temporary local file.
new_remote_path = f"/sdcard/Download/{package_name}"
# We copy the file from the data folder to /sdcard/.
cp = self._adb_command_as_root(f"cp {remote_path} {new_remote_path}")
if cp.startswith("cp: ") and "No such file or directory" in cp:
raise Exception(f"Unable to process file {remote_path}: File not found")
elif cp.startswith("cp: ") and "Permission denied" in cp:
raise Exception(f"Unable to process file {remote_path}: Permission denied")
# We download from /sdcard/ to the local temporary file.
self._adb_download(new_remote_path, local_path, package_name)
# Delete the copy on /sdcard/.
self._adb_command(f"rm -f {new_remote_path}")
except AdbCommandFailureException as e:
raise Exception(f"Unable to download file {remote_path}: {e}")
def _adb_process_file(self, remote_path, process_routine):
"""Download a local copy of a file which is only accessible as root.