def __init__(self): self.adb = Adb() self.fastboot = Fastboot() self.device = Device() #constant variables self.RECOVERY = "recovery" self.TWRP_SWITCH = "BDO" #BSDCO
def __init__(self): self.monitorManager = MonitorsManager() self.profileManager = ProfilesManager() self.adb = Adb() self.fastboot = Fastboot() self.partition = Partition() self.tool = Tool() self.session = object self.config_ini = config.Session() self.device_backup_path = "" self.device = Device()
def setUp(self): self.fastboot = Fastboot() self.adb = Adb() self.adb.reboot_bootloader()
class fastboot_testCase(unittest.TestCase): def setUp(self): self.fastboot = Fastboot() self.adb = Adb() self.adb.reboot_bootloader() def tearDown(self): self.fastboot.reboot() while len(self.adb.devices()) == 0: time.sleep(5) @unittest.skip("skip reboot test") def test_reboot(self): self.fastboot.reboot() result = True print "[!] waiting for phone to reboot..." for i in range(0, 5): if len(self.adb.devices()) == 0: time.sleep(10) result = False else: result = True break if i == 4: print "[!] Reboot time out" self.assertTrue(result, msg="fastboot reboot failed") @unittest.skip("skip reboot bootloader test") def test_reboot_bootloader(self): result = False self.fastboot.reboot_bootloader() devices = self.fastboot.devices() print "[!] waiting for phone to enter bootloader mode..." for i in range(0, 5): devices = self.fastboot.devices() if len(devices) != 0: result = True break else: time.sleep(10) if i == 4: print "[!] Reboot time out" self.assertTrue(result, msg="fastboot reboot-bootloader failed") def test_devices(self): result = False self.fastboot.reboot_bootloader() time.sleep(5) devices = self.fastboot.devices() if len(devices) > 0: result = True self.assertTrue(result, msg="fastboot devices did not detect any devices")
class SessionManager(object): def __init__(self): self.monitorManager = MonitorsManager() self.profileManager = ProfilesManager() self.adb = Adb() self.fastboot = Fastboot() self.partition = Partition() self.tool = Tool() self.session = object self.config_ini = config.Session() self.device_backup_path = "" self.device = Device() def create_session_dir(self, session_id, device_serial): """ Create new session directory with given session ID :param session_id: session id :return: nil """ try: id_path = os.path.join(SESSION_DIR, session_id.__str__()) is_session_dir_exist = os.path.isdir(id_path) if is_session_dir_exist: raise SessionDirError for directory in directories: new_session_path = os.path.join(id_path, directory) os.makedirs(new_session_path) self.config_ini.create(id_path, device_serial) except Exception as e: log.error("Unable to create session directory") self.create_session_dir(session_id, device_serial) def save_result(self, session_id, name, result, ext=""): """ save processing result into session directory :param session_id: :param name: :param result: :return: """ try: session = Session(session_id) file = open(os.path.join(session.report_dir, name + ext), "w") file.write(result) file.close() return True except Exception as e: return False def get_results(self, session_id): """ Get all json results from session's report directory :param session_id: :return: """ reports = {} # key: file name, value: json content current_session = Session(session_id) for file in os.listdir(current_session.report_dir): if file.endswith(".json"): with open(os.path.join(current_session.report_dir, file)) as data_file: reports[file.split(".")[0].replace("_", " ")] = json.load(data_file) return reports def end(self, session_id, device_backup_path, modules_config, device_serial): """ End sandbox analysis :param session_id: :return: """ self.session = Session(session_id) log_name = "end_status_%s" % session_id end_logger = logging.getLogger(log_name) end_logger.setLevel(logging.INFO) START_LOG = os.path.join(self.session.logs_dir, "end_status.log") fh = logging.FileHandler(START_LOG) fh.setLevel(logging.INFO) formatter = logging.Formatter("%(asctime)s - %(message)s") fh.setFormatter(formatter) end_logger.addHandler(fh) # get post-session monitor required data from device end_logger.info("Post-session information gathering") if modules_config: for module, params in modules_config.iteritems(): if params["module_type"] == "monitor": end_result = self.monitorManager.postSession( module, params, self.session, device_serial=device_serial ) log_file = os.path.join(self.session.logs_dir, module.replace(" ", "_") + ".post" + ".cap") file_handler = open(log_file, "w+") file_handler.write(end_result.__str__()) file_handler.close() # restore partitions end_logger.info("Restoring boot partition") self.restore_boot_partition(self.session, device_serial) end_logger.info("Restoring other partitions") self.partition.restore( twrp_path=self.tool.twrp, backup_src=self.session.partition_dir, backup_dest=device_backup_path, device_serial=device_serial, ) return True def start_logger(self, session_id): # initilize status logging log_name = "start_status_%s" % session_id self.start_logger = logging.getLogger(log_name) self.start_logger.setLevel(logging.INFO) self.START_LOG = os.path.join(self.session.logs_dir, "status.log") fh = logging.FileHandler(self.START_LOG) fh.setLevel(logging.INFO) formatter = logging.Formatter("%(asctime)s - %(message)s") fh.setFormatter(formatter) self.start_logger.addHandler(fh) def start(self, modules_config, session_id, apk_paths, duration, device_serial): """ Begin sandbox analysis. :param modules_config: parameters selected from configuration page :type modules_config: dictionary. configuration of modules from django session database :return: if analysis is successful or not """ # create session directory self.create_session_dir(session_id, device_serial) # session object self.session = Session(session_id) self.start_logger(session_id) # checking device temp folders are ready self.start_logger.info("Initilizing device %s", device_serial) self.start_logger.info("Checking device temp folders are ready") self.check_device_tmp_folders(device_serial) # create symbolic link for apks self.start_logger.info("Creating symbolic links for APKs") self.create_apk_symbolic_links(apk_paths) # backup device partitions self.start_logger.info("Backing up partitions") device_backup_path = self.backup_device_partitions(device_serial) # prepare device for session (haven't copy to device yet) self.start_logger.info("Preparing device partitions") is_partition_init = self.prepare_device_for_session(device_serial, modules_config) # install user profile self.start_logger.info("Installing user profile") self.install_user_profile(device_serial, modules_config) # copy daemons to device self.start_logger.info("Copying daemons onto device") self.copy_daemons_to_device(device_serial, modules_config) # push modified partition to device self.start_logger.info("Pushing modified partitions to device") self.push_modified_partition_to_device(device_serial, is_partition_init) # get baseline of the device (pre session) # depending on the monitor modules requirements self.start_logger.info("Pre-session initilizations") self.device_presession(device_serial, modules_config) # lastly, install the suspicious apk self.start_logger.info("Installing APK on device") package_name = self.install_apk(device_serial) while not package_name: package_name = self.install_apk(device_serial) # whitelist package name for monitoring self.whitelist_package_name(package_name, device_serial) # run profile simulation script self.start_logger.info("package name is %s" % package_name) self.start_logger.info("Running profile simulation") now = datetime.datetime.now() end_time = now + datetime.timedelta(minutes=duration) end_time_str = end_time.strftime("%H:%M:%S %d-%m-%Y") self.run_profile_simulation(duration, modules_config, device_serial, package_name, self.session) self.start_logger.info("Session end time: %s" % end_time_str) return (device_backup_path, self.START_LOG, end_time) def whitelist_package_name(self, package_name, device_serial): tmp_path = self.device.daemon_path(device_serial) whitelist_path = os.path.join(tmp_path, "whitelist.txt") add_whitelist_command = 'echo "%s" > %s' % (package_name, whitelist_path) result = self.adb.shell(add_whitelist_command, root=True, device_serial=device_serial) def check_device_tmp_folders(self, device_serial): """ Check android device for the temp folders declared in devices.ini :param device_serial: device serial no. :return: boolean result """ try: device_backup_path = self.device.backup_path(device_serial) device_daemon_path = self.device.daemon_path(device_serial) paths = [device_backup_path, device_daemon_path] for path in paths: check_path_command = "ls %s" % path result = self.adb.shell(check_path_command, device_serial=device_serial, root=True) if not result.std_output: log.error( "device %s is not ready for DroidPot! Ensure all tmp folders declared in devices.ini are present on the device" ) return False return True except Exception as e: log.error( "device %s is not ready for DroidPot! Ensure all tmp folders declared in devices.ini are present on the device" ) return False def run_profile_simulation(self, duration, modules_config, device_serial, package_name, session): # try: log.info("Running user simulation") if modules_config: for modules, params in modules_config.iteritems(): try: if params["module_type"] == "profile": simulation_option = params["simulation_option"] p = Process( target=run_simulation, args=(simulation_option, modules, duration, device_serial, package_name, session), ) p.start() break # break in case there's more than 1 profile selected except KeyError as e: pass # except Exception as e: # log.error("Unable to run profile simulation") # time.sleep(10) # self.run_profile_simulation(duration, modules_config,device_serial, package_name, session) def install_apk(self, device_serial): try: log.info("Installing sample apk") self.adb.wait_for_device(device_serial) apks = os.listdir(self.session.apk_dir) for apk in apks: apk_path = os.path.join(self.session.apk_dir, apk) if os.path.isfile(apk_path): log.info("Installing apk %s" % (apk_path)) get_current_packages_command = "pm list packages" result = self.adb.shell(get_current_packages_command, root=True, device_serial=device_serial) packages = result.std_output apk_realpath = os.path.realpath(apk_path) self.adb.push(source=apk_realpath, dest="/sdcard/tmp.apk", device_serial=device_serial) time.sleep(2) self.adb.shell("pm install -rt /sdcard/tmp.apk", root=True, device_serial=device_serial) time.sleep(2) self.adb.shell("rm -f /sdcard/tmp.apk", root=True, device_serial=device_serial) # os.remove(apk_path) result = self.adb.shell(get_current_packages_command, root=True, device_serial=device_serial) packages_after = result.std_output sample_package_name = "" for package in packages_after: if not packages.__contains__(package): sample_package_name = package.replace("package:", "") return sample_package_name # break # Note: ONLY 1 APK TO BE ANALYSIS AT A TIME. AFTER ANALYSIS SESSION, INSTALL THE NEXT APK except Exception as e: log.error("Unable to install APK onto device") print e time.sleep(10) return "" def device_presession(self, device_serial, modules_config): try: log.info("Getting device baseline") self.adb.wait_for_device(device_serial) time.sleep(10) if modules_config: for module, params in modules_config.iteritems(): if params["module_type"] == "monitor": baseline = self.monitorManager.preSession(module, params, self.session, device_serial) print "baseline file result is " print baseline # store baseline information into an analysis file log_file = os.path.join(self.session.logs_dir, module.replace(" ", "_") + ".pre" + ".cap") file_handler = open(log_file, "w+") file_handler.write(baseline.__str__()) file_handler.close() except Exception as e: log.error("Unable to get baseline of device") time.sleep(10) self.device_presession(device_serial, modules_config) def push_modified_partition_to_device(self, device_serial, is_partition_init): try: log.info("Modifying device's partitions") if is_partition_init: self.push_boot_partition(self.session, device_serial=device_serial) except Exception as e: log.error("Unable to push modified partition to device") time.sleep(10) self.push_modified_partition_to_device(device_serial, is_partition_init) def copy_daemons_to_device(self, device_serial, modules_config): try: log.info("Transferring daemons to device") if modules_config: for module, params in modules_config.iteritems(): # copy each module's daemons individually into device if params["module_type"] == "monitor": daemon = self.monitorManager.daemons(module, params) if daemon: self.copy_daemons(daemon, self.session) # check device ini for temp path preference dev_daemon_path = self.device.daemon_path(device_serial) self.push_daemons(self.session, dev_daemon_path, device_serial=device_serial) except Exception as e: log.error("Unable to install process monitors on device") time.sleep(10) self.copy_daemons_to_device(device_serial, modules_config) def install_user_profile(self, device_serial, modules_config): try: log.info("Installing profile on device") self.adb.wait_for_device(device_serial) if modules_config: for module, params in modules_config.iteritems(): if params["module_type"] == "profile": self.profileManager.setup_device(module, params, device_serial) break except Exception as e: log.error("Unable to install user profile onto device") time.sleep(10) self.install_user_profile(device_serial, modules_config) def prepare_device_for_session(self, device_serial, modules_config): try: is_partition_init = self.monitorManager.prepare(modules_config, self.session, device_serial) except Exception as e: log.error("Unable to prepare partitions for session") time.sleep(10) return self.prepare_device_for_session(device_serial, modules_config) return is_partition_init def backup_device_partitions(self, device_serial): try: log.info("Backing up device partitions") self.start_logger.info("Performing TWRP backup") device_backup_path = self.partition.backup( twrp_path=self.tool.twrp, backup_dest=self.session.partition_dir, device_serial=device_serial ) if device_backup_path: log.debug("Backup completed, extracting boot partition for modification") time.sleep(3) self.device_backup_path = device_backup_path is_boot_extracted = self.get_and_extract_boot_partition(self.session, device_serial=device_serial) while not is_boot_extracted: time.sleep(3) is_boot_extracted = self.get_and_extract_boot_partition(self.session, device_serial=device_serial) except Exception as e: log.error("Unable to perform backup") time.sleep(2) return self.backup_device_partitions(device_serial) return device_backup_path def create_apk_symbolic_links(self, apk_paths): try: log.info("Creating symbolic links for APKs") for apk_name, apk_realpath in apk_paths.iteritems(): os.symlink(apk_realpath, os.path.join(self.session.apk_dir, apk_name)) except Exception as e: log.error("Unable to create symbolic link for apks") time.sleep(10) self.create_apk_symbolic_links(apk_paths) def get_baseline(self, device_serial): """ Get the device baseline processes """ process_names = [] list_proc_command = "ls /proc/" output = self.adb.shell(list_proc_command, root=True, needOutput=True, device_serial=device_serial) processes = output.std_output commands = "" for proc in processes: get_proc_name_command = "cat /proc/%s/status" % (proc) commands += get_proc_name_command + " && " proc_name = self.adb.shell(commands, root=True, needOutput=True, device_serial=device_serial).std_output if proc_name: process_names.append(proc_name) return process_names """ DAEMON HANDLER handles the copying daemons into session directory and pushing daemons to android device """ def copy_daemons(self, daemons, session): daemon_dir = session.daemon_dir for module_name, daemons_path in daemons.iteritems(): log.debug("found %s in module %s" % (daemons_path, module_name)) for d_path in daemons_path: shutil.copy(d_path, daemon_dir) return True def push_daemons(self, session, dir, device_serial): daemon_dir = session.daemon_dir for daemon in os.listdir(daemon_dir): log.info("[*] Pushing %s to device" % daemon) log.debug("pushing %s to device %s directory" % (daemon, dir)) source = os.path.join(daemon_dir, daemon) self.adb.push(source=source, dest=dir, device_serial=device_serial) log.info("[*] Changing permission of daemons") device_daemon_path = os.path.join(dir, daemon) chmod_command = "chmod 777 %s" % device_daemon_path chown_command = "chown root:root %s" % device_daemon_path self.adb.shell(chown_command, root=True, device_serial=device_serial) self.adb.shell(chmod_command, root=True, device_serial=device_serial) return True """ PARTITION HANDLER handles the partition extraction and reflashing of android device """ def get_and_extract_boot_partition(self, session, device_serial): self.start_logger.info("Extracting boot partition for modification") EXTRACTED_BOOT_LOC = "/sdcard/boot.img" # retrieve boot partition location retry = True while retry: log.warn("[*] Retrieving boot partition location...") command = "ls -al /dev/block/platform/msm_sdcc.1/by-name | grep ' boot'" result = self.adb.shell(command=command, device_serial=device_serial) boot_image_loc = "" for output in result.std_output: log.debug("result line: %s" % output) try: output_split = output.split("-> ") boot_image_loc = output_split[1] boot_image_loc.replace("\r", "") retry = False except IndexError: log.debug("Cannot get boot partition location. Retrying.") time.sleep(3) pass time.sleep(5) # copy image locally log.info("[*] dd image on device...") command = "dd if=" + boot_image_loc + " of=" + EXTRACTED_BOOT_LOC result = self.adb.shell(root=True, command=command, device_serial=device_serial) if not result.isSuccess: raise OSError time.sleep(5) # pulling boot.img from device log.info("[*] Pulling boot.img from device...") self.adb.pull(source=EXTRACTED_BOOT_LOC, dest=session.partition_dir, device_serial=device_serial) time.sleep(5) # decompress boot.img log.info("[*] Decompressing boot.img with mkboot tool...") params = " ".join([session.bootimg_dir, session.extracted_boot_dir]) log.debug("parameters are %s" % params) cmd = Command() cmd.setCommand(self.tool.mkboot) cmd.setParameters(params) logging.debug(params) cmd.execute() time.sleep(5) if not os.path.exists(session.extracted_boot_dir): self.start_logger.info("Extracting boot partition failed") return False else: return True def push_boot_partition(self, session, device_serial): # create new boot.img logging.debug("creating new boot partition") params = " ".join([session.extracted_boot_dir, session.new_bootimg_dir]) cmd = Command() cmd.setCommand(self.tool.mkboot) cmd.setParameters(params) logging.debug(params) cmd.execute() time.sleep(5) # push new partition to device self.adb.reboot_bootloader(device_serial) time.sleep(5) fastboot_devices = self.fastboot.devices() for i in range(0, 5): if len(fastboot_devices) > 0: log.info("[*] Device found in bootloader mode") break else: log.info("[!] Could not detect device in bootloader mode. Retrying...") time.sleep(10) fastboot_devices = self.fastboot.devices() if i == 4: log.warning("[!] Could not detect device in bootloader mode. TIME OUT") return False # flash boot partition with fastboot # must be in sudo log.info("[*] Flashing partition with new image") self.fastboot.flash(partition="boot", image_path=session.new_bootimg_dir, device_serial=device_serial) time.sleep(5) self.fastboot.reboot(device_serial) def restore_boot_partition(self, session, device_serial): log.info("[*] Restoring boot partition...") self.adb.wait_for_device(device_serial) self.adb.reboot_bootloader(device_serial) while True: devices = self.fastboot.devices() if devices: break self.fastboot.flash("boot", session.bootimg_dir, device_serial=device_serial) self.fastboot.reboot(device_serial)
class Partition(object): __metaclass__ = Singleton def __init__(self): self.adb = Adb() self.fastboot = Fastboot() self.device = Device() #constant variables self.RECOVERY = "recovery" self.TWRP_SWITCH = "BDO" #BSDCO def restore(self, twrp_path, backup_src, backup_dest, device_serial): try: log.info("Restoring android device partitions") RECOVERY = self.RECOVERY ORIGINAL_RECOVERY_PATH = os.path.join(backup_src, "original_recovery") log.info("Waiting for device in adb mode") self.adb.wait_for_device(device_serial) self.adb.reboot_bootloader(device_serial) self.fastboot.flash(partition=RECOVERY, image_path=twrp_path, device_serial=device_serial) self.fastboot.reboot(device_serial) self.adb.wait_for_device(device_serial) self.adb.reboot_recovery(device_serial) #self.adb.shell("mkdir -p %s"%(backup_dest)) backup_file_paths = glob.glob(os.path.join(backup_src, "*.win*")) self.adb.reboot_recovery(device_serial) #needed, if not will have bug in adb push for backup_file_path in backup_file_paths: backup_file_split = backup_file_path.split("/") backup_file_name = backup_file_split[len(backup_file_split) - 1] #self.__copy_backup(source_filepath=backup_file_path, dest_filepath=os.path.join(backup_dest, backup_file_name), direction="push", twrp=True, device_serial=device_serial, check_hash=True) backup_dest_split = backup_dest.split("/") backup_folder_name = backup_dest_split[-2] self.adb.shell("twrp restore %s %s"%(backup_folder_name, self.TWRP_SWITCH),device_serial) self.adb.shell("rm -rf %s"%(backup_dest), device_serial) self.adb.reboot(device_serial) self.adb.wait_for_device(device_serial) self.adb.reboot_bootloader(device_serial) self.fastboot.flash(RECOVERY, ORIGINAL_RECOVERY_PATH, device_serial) self.fastboot.reboot(device_serial) self.adb.wait_for_device(device_serial) log.info("Restore device successfully") return True except Exception as e: log.error("unable to restore device partitions") self.restore(self, twrp_path, backup_src, backup_dest, device_serial) def backup(self, twrp_path, backup_dest, device_serial): try: log.info("Backing up android device partitions") RECOVERY = self.RECOVERY RECOVERY_PATH = self.device.backup_path(device_serial) RECOVERY_TEMP_DEV_LOC = os.path.join(RECOVERY_PATH, RECOVERY) ORIGINAL_RECOVERY_PATH = os.path.join(backup_dest, "original_recovery") mount_point = self.__get_mount_point(device_serial=device_serial) partitions = self.__get_partitions(mount_point, device_serial=device_serial) if partitions.has_key(RECOVERY): recovery_device = partitions[RECOVERY] else: raise BackupError log.info("Waiting for device in adb mode") self.adb.wait_for_device(device_serial) self.__dd_backup_partition(partition_name=RECOVERY, device=recovery_device, dest=RECOVERY_TEMP_DEV_LOC, device_serial=device_serial) self.__copy_backup(source_filepath=RECOVERY_TEMP_DEV_LOC, dest_filepath=ORIGINAL_RECOVERY_PATH, direction="pull", device_serial=device_serial, check_hash=True) self.adb.shell("rm -f %s"%(RECOVERY_TEMP_DEV_LOC), device_serial=device_serial) self.adb.reboot_bootloader(device_serial) self.fastboot.flash(partition=RECOVERY, image_path=twrp_path, device_serial=device_serial) self.fastboot.reboot(device_serial) self.adb.wait_for_device(device_serial) self.adb.reboot_recovery(device_serial) backup_path = self.__twrp_backup_partitions(switches=self.TWRP_SWITCH, device_serial=device_serial) backup_files = self.adb.shell("ls %s"%(backup_path),device_serial=device_serial) self.adb.reboot_recovery(device_serial) #needed, if not there's a bug in adb pull for file in backup_files.std_output: source_filepath = os.path.join(backup_path, file) dest_filepath = os.path.join(backup_dest, file) #self.__copy_backup(source_filepath, dest_filepath, direction="pull", twrp=True, check_hash=False, device_serial=device_serial) time.sleep(2) #self.adb.shell("rm -f %s"%(source_filepath)) self.adb.reboot_bootloader(device_serial) self.fastboot.flash(partition=RECOVERY, image_path=ORIGINAL_RECOVERY_PATH, device_serial=device_serial) self.fastboot.reboot(device_serial) self.adb.wait_for_device(device_serial) #self.adb.shell("rm -rf %s"%(backup_path)) log.info("Backup device successfully") return backup_path except Exception as e: log.error("Unable to perform partition backup") #self.backup(twrp_path,backup_dest, device_serial) def __copy_backup(self, source_filepath, dest_filepath, check_hash, direction,tries=30, twrp=False, device_serial=""): """ Recursive function to backup file from device to host machine with limited retries :param source_filepath: source file path on device :param dest_filepath: destination file path on host machine :param tries: number of retries (default:3) :return: bool """ try: if tries == 0: log.critical("Reach max retries") raise PartitionError if direction =="pull": self.adb.pull(source=source_filepath, dest=dest_filepath, device_serial=device_serial) time.sleep(2) if check_hash: has_file_integrity = self.__compare_md5(source_filepath, dest_filepath, twrp, device_serial) elif direction == "push": self.adb.push(source=source_filepath, dest=dest_filepath, device_serial=device_serial) time.sleep(2) if check_hash: has_file_integrity = self.__compare_md5(dest_filepath, source_filepath, twrp, device_serial) else: raise BackupError if check_hash: if not has_file_integrity : log.critical("Hash of %s of copied file is different from file on device."%(source_filepath)) log.critical("Retrying after 10 seconds...") time.sleep(10) return self.__copy_backup(source_filepath, dest_filepath,check_hash,direction, tries-1, twrp, device_serial) except Exception as e: log.error("Unable to copy backup files from device to host machine") self.__copy_backup(source_filepath, dest_filepath, check_hash, direction,tries-1, twrp, device_serial) def __compare_md5(self, device_path, host_path, twrp, device_serial): """ Compare the md5 of original file on device and copied file to host machine :param device_path: file path on device :param host_path: file path on host machine :return: bool """ try: if not twrp: result = self.adb.shell("md5 " + device_path, device_serial) else: result = self.adb.shell("md5sum " + device_path, device_serial) stdout = result.std_output try: device_md5 = stdout[0].split(" ")[0] except IndexError: device_md5 = "" host_md5 = hashlib.md5(open(host_path).read()).hexdigest() log.debug("device: %s host: %s"%(device_md5, host_md5)) if device_md5 == host_md5: return True else: return False except Exception as e: log.error("Unable to compare md5") raise PartitionError def __twrp_backup_partitions(self, switches, foldername="", device_serial=""): try: command = "twrp backup %s %s"%(switches, foldername) result = self.adb.shell(command, device_serial=device_serial) backup_path = "" log.debug(result.std_output) for line in result.std_output: match = re.search(r'Backup Folder: .*', line) if match: log.debug(match.group()) match_split = match.group().split(":") backup_path = match_split[1].replace(" ", "") return backup_path except Exception as e: log.error("unable to perform twrp partition backup") self.__twrp_backup_partitions(self, switches, foldername, device_serial) def __get_mount_point(self,device_serial): """ Get the mount point of device partition :return: """ try: self.adb.wait_for_device(device_serial) FIRST_LINE = 0 parameter = "mount | grep -E /dev/block/platform/.+/by-name/system" result = self.adb.shell(root=True, command=parameter, device_serial=device_serial) if result.std_error: raise Exception #remove /system from command outline mount_point = result.std_output[FIRST_LINE].split()[FIRST_LINE][:-6] return mount_point except Exception as e: log.error("cannot get device mount points") time.sleep(5) return self.__get_mount_point(device_serial) def __get_partitions(self, device, device_serial): """ Get android device partitions :param device: mount path :return: list of dict of partition name as key and partition location as value """ try: self.adb.wait_for_device(device_serial) parameter = "ls -al " + device result = self.adb.shell(root=True, command=parameter, device_serial=device_serial) if result.std_error: raise Exception partitions = {} for line in result.std_output: match = re.search(r'\w* -> .*', line) if match: match_split = match.group().split(" -> ") partitions[match_split[0]] = match_split[1] return partitions except Exception as e: log.error("Unable to get device partitions") time.sleep(5) return self.__get_partitions(device, device_serial) def __dd_backup_partition(self, partition_name, device, dest, device_serial): """ backup given partition to desired destination :param partition_name: name of partition :param device: dev path of partition :return: """ try: command = "dd if=%s of=%s"%(device, dest) result = self.adb.shell(root=True, command=command, device_serial=device_serial) if result.std_output: log.debug(result.std_output) return True else: log.debug(result.std_error) return False except Exception as e: log.error("Unable to backup partition to destination") raise PartitionError