Ejemplo n.º 1
0
    def _waitForDeviceToBeReady(self):
        """Analyzes the device state and returns when it's ready."""
        if self.state != AndroidDevice.STATE_STARTING:
            raise Exception(
                "Cannot wait of a device if its not started, its current state is '{0}'"
                .format(self.state))

        self._logger.debug("Waiting for device {0} to be ready.".format(
            self.serialNumber))

        cmd = [
            self.mainConfiguration.adbPath, "-s", self.serialNumber,
            "wait-for-device"
        ]
        OSCommand.executeCommand(cmd)

        self._logger.debug("Waiting for the device to be ready")
        self._logger.debug(" - (dev.bootcomplete)")
        ready = False
        while not ready:
            cmd = [
                self.mainConfiguration.adbPath, "-s", self.serialNumber,
                "shell", "getprop", "dev.bootcomplete"
            ]
            result = OSCommand.executeCommand(cmd)
            if result is not None and result.strip() == "1":
                ready = True
            else:
                time.sleep(1)

        self._logger.debug("- (sys_bootcomplete)")
        ready = False
        while not ready:
            cmd = [
                self.mainConfiguration.adbPath, "-s", self.serialNumber,
                "shell", "getprop", "sys.boot_completed"
            ]
            result = OSCommand.executeCommand(cmd)
            if result is not None and result.strip() == "1":
                ready = True
            else:
                time.sleep(1)

            self._logger.debug(" - (init.svc.bootanim)")
            ready = False
            while not ready:
                cmd = [
                    self.mainConfiguration.adbPath, "-s", self.serialNumber,
                    "shell", "getprop", "init.svc.bootanim"
                ]
                result = OSCommand.executeCommand(cmd)
                if result is not None and result.strip() == "stopped":
                    ready = True
                else:
                    time.sleep(1)

        time.sleep(5)
        self._logger.debug("Device {0} seems to be ready".format(
            self.serialNumber))
        self.state = AndroidDevice.STATE_STARTED
Ejemplo n.º 2
0
    def createTemplates(mainConfiguration, nb_templates):
        """Duplicates the initial template, one for each emulator.
        This is necessary only during an automatic analysis.
        """

        refAVDName = os.path.split(mainConfiguration.referenceAVD)[1]
        refAvdConfigFile = "{0}.ini".format(mainConfiguration.referenceAVD)
        refAVDDir = os.path.join(mainConfiguration.virtualDevicePath,
                                 "{0}.avd/".format(refAVDName))
        for emulatorId in xrange(nb_templates):
            newAvdConfigFile = "{0}_{1}.ini".format(
                mainConfiguration.referenceAVD, emulatorId)
            newAVDDir = os.path.join(
                mainConfiguration.virtualDevicePath,
                "{0}_{1}.avd/".format(refAVDName, emulatorId))

            # delete old versions
            if os.path.exists(newAvdConfigFile):
                os.remove(newAvdConfigFile)

            if os.path.isdir(newAVDDir):
                shutil.rmtree(newAVDDir)

            shutil.copyfile(refAvdConfigFile, newAvdConfigFile)

            cmd = "cp -R {0} {1}".format(refAVDDir, newAVDDir)
            OSCommand.executeCommand(cmd)
Ejemplo n.º 3
0
 def __pushBackup(self):
     """ Pushes backup folder to sdcard """
     cmd = [
         self.mainConfiguration.adbPath, "-s", self.serialNumber, "push",
         os.path.join(self.__backupDir, "partitions"),
         os.path.join(self._dnadroidDir, "backup")
     ]
     OSCommand.executeCommand(cmd)
Ejemplo n.º 4
0
 def __removeDirectoryHookerFromAVD(self):
     """Removes directory on the emulator where dnadroid has copied files.
     """
     self._logger.debug("Deleting {0} directory on emulator {1}".format(
         self._dnadroidDir, self.serialNumber))
     cmd = [
         self.mainConfiguration.adbPath, "-s", self.serialNumber, "shell",
         "rm", "-rf", self._dnadroidDir
     ]
     OSCommand.executeCommand(cmd)
Ejemplo n.º 5
0
    def _restartADBServer(self):
        """
        Restarts ADB server. This function is not used because we have to verify we don't have multiple devices.
        """
        self._logger.info("Restarting ADB server...")

        cmd = [self.mainConfiguration.adbPath, "kill-server"]
        OSCommand.executeCommand(cmd)
        self._logger.info("ADB server has been killed.")

        cmd = [self.mainConfiguration.adbPath, "start-server"]
        OSCommand.executeCommand(cmd)
        self._logger.info("ADB server has been restarted.")
Ejemplo n.º 6
0
    def accept(self):
        """accept the apk"""
        self._logger.info("accept {0}".format(self.serialNumber))
        cmd = [
            self.mainConfiguration.adbPath, "-s", self.serialNumber, "shell",
            "input", "tap", "400 730"
        ]
        OSCommand.executeCommand(cmd)
        time.sleep(3)

        self.state = AndroidDevice.STATE_STARTING
        # waits for device to be ready
        self._waitForDeviceToBeReady()
Ejemplo n.º 7
0
    def startActivityFromPackage(self, packageName, activityName):
        """
        Starts the specified activity from the specified package name on the device.
        This method has to be called when package name is different from main activity.
        """
        if self.state != AndroidDevice.STATE_STARTED:
            raise Exception(
                "Cannot start an activity since the device is not started.")

        if activityName is None or len(activityName) == 0:
            raise Exception("Activity name is null.")

        if packageName is None or len(packageName) == 0:
            raise Exception("Package name is null.")

        self._logger.info("Starting activity {0}/{1} on device {2}".format(
            packageName, activityName, self.name))

        # $ adb shell am start -n activityPackage/activity
        cmd = [
            self.mainConfiguration.adbPath, "-s", self.serialNumber, "shell",
            "am", "start", "-n", "{0}/{1}".format(packageName, activityName)
        ]
        p = OSCommand.executeAsyncCommand(cmd)
        stdout, stderr = p.communicate()
        self._logger.debug("{0}".format(stdout))
Ejemplo n.º 8
0
    def installAPK(self, apkFilename):
        """Installs the specified APK on the device"""

        if self.state != AndroidDevice.STATE_STARTED:
            raise Exception(
                "Cannot install the application since the device is not started."
            )

        if apkFilename is None or len(apkFilename) == 0:
            raise Exception("Cannot install an application that has no name.")

        self._logger.info("Installing APK {0} on device {1}".format(
            apkFilename, self.name))

        # $ adb install file.apk
        cmd = [
            self.mainConfiguration.adbPath, "-s", self.serialNumber, "install",
            apkFilename
        ]
        OSCommand.executeCommand(cmd)
Ejemplo n.º 9
0
    def start(self):
        """Starts the emulator"""
        if self.state != AndroidDevice.STATE_PREPARED:
            raise Exception(
                "Cannot start the emulator. (expected state was {0}, current state is {1})"
                .format(AndroidDevice.STATE_PREPARED, self.state))

        # clean the temporary directory
        self.__cleanTemporaryDirectory()
        if self.__partitionSize is None:
            raise Exception("Partition size cannot be None")

        cmd = [
            self.mainConfiguration.emulatorPath, "@{0}".format(self.name),
            "-partition-size",
            str(self.__partitionSize), "-no-snapshot-save", "-netspeed",
            "full", "-netdelay", "none", "-port",
            str(self.adbPort)
        ]

        self.__emulatorProcess = OSCommand.executeAsyncCommand(cmd)
        time.sleep(2)
        if self.__emulatorProcess.poll() is not None:
            raise Exception(self.__emulatorProcess.communicate())

        self.state = AndroidDevice.STATE_STARTING

        # Waits for device to be ready
        self._waitForDeviceToBeReady()

        # Set the same time as host!
        self._logger.info("Setting emulator at the same time as host")
        localTime = datetime.datetime.now().strftime("%Y%m%d.%H%M%S")
        cmd = [
            self.mainConfiguration.adbPath, "-s", self.serialNumber, "shell",
            "date", "-s", localTime
        ]
        self._logger.debug(OSCommand.executeCommand(cmd))

        # Checks that APKInstrumenter is install
        self.checkAPKInstrumenter()
Ejemplo n.º 10
0
 def checkAPKInstrumenter(self):
     """Checks that APKInstrumenter application is installed on the device"""
     cmd = [
         self.mainConfiguration.adbPath, "-s", self.serialNumber, "shell",
         "pm", "list", "packages", "com.amossys.dnadroid"
     ]
     ret = OSCommand.executeCommand(cmd)
     if ret is None or len(ret) == 0 or 'dnadroid' not in ret:
         raise Exception(
             "APKInstrumenter application is not installed on your device. Please set up your device properly (see README file)"
         )
     self._logger.info("ApkInstrumenter application is installed on device")
Ejemplo n.º 11
0
    def __pushRecoveryScript(self):
        """
        Pushes recovery script to TWRP recovery directory.
        This is done is 2 parts: first create the file on /sdcard/, then copy it to /cache/recovery/, using busybox.
        """
        cmd = [
            self.mainConfiguration.adbPath, "-s", self.serialNumber, "shell",
            "touch",
            os.path.join(self._dnadroidDir, "openrecoveryscript")
        ]
        OSCommand.executeCommand(cmd)

        cmd = '{0} -s {1} shell echo "restore /sdcard/dnadroid/backup/" > {2}'.format(
            self.mainConfiguration.adbPath, self.serialNumber,
            os.path.join(self._dnadroidDir, "openrecoveryscript"))
        OSCommand.executeCommand(cmd)

        cmd = '{0} -s {1} shell su -c \'busybox cp {2} /cache/recovery/openrecoveryscript\''.format(
            self.mainConfiguration.adbPath, self.serialNumber,
            os.path.join(self._dnadroidDir, "openrecoveryscript"))
        ret = OSCommand.executeCommand(cmd)
        if len(ret) != 0:
            raise Exception(ret)
Ejemplo n.º 12
0
    def reboot(self):
        """Reboot the device"""
        self._logger.info("Rebooting device listening on port {0}".format(
            self.serialNumber))
        cmd = [
            self.mainConfiguration.adbPath, "-s", self.serialNumber, "reboot"
        ]
        self._logger.debug(OSCommand.executeCommand(cmd))

        # Real device can take time to reboot
        time.sleep(15)
        # waits for device to be ready
        self._waitForDeviceToBeReady()
        self.state = AndroidDevice.STATE_STARTING
Ejemplo n.º 13
0
    def _pullResults(self):
        """Pull results of analysis"""
        self._logger.info("Pulling results of analysis")
        cmd = [
            self.mainConfiguration.adbPath, "-s", self.serialNumber, "pull",
            "/sdcard/dnadroid/events.logs", "{0}{1}-events.logs".format(
                self.mainConfiguration.androidTemporaryPath,
                datetime.datetime.now().strftime("%Y-%m-%d-%H:%M"))
        ]
        p = OSCommand.executeAsyncCommand(cmd)
        stdout, stderr = p.communicate()
        self._logger.debug("{0}".format(stdout))

        self._logger.info("Event logs has been pulled in {0}".format(
            self.mainConfiguration.androidTemporaryPath))
Ejemplo n.º 14
0
    def reboot(self):
        """Reboot the emulator"""
        self._logger.info("Rebooting AVD listening on port {0}".format(
            self.serialNumber))
        cmd = [
            self.mainConfiguration.adbPath, "-s", self.serialNumber, "shell",
            "setprop", "ctl.restart", "zygote"
        ]
        self._logger.debug(OSCommand.executeCommand(cmd))

        time.sleep(5)

        self.state = AndroidDevice.STATE_STARTING
        # waits for device to be ready
        self._waitForDeviceToBeReady()
Ejemplo n.º 15
0
    def __checkADBRecognizeDevice(self):
        """
        Checks that ADB recognizes the device. Returns True if device is recognized by ADB, False otherwise.
        """
        self._logger.info("Checking if ADB recognizes device...")

        cmd = [self.mainConfiguration.adbPath, "devices"]

        output = OSCommand.executeCommand(cmd)

        if self.serialNumber in output:
            self._logger.debug("Device has been find!")
            return True

        self._logger.error("Device has not been found.")
        return False
Ejemplo n.º 16
0
    def stimulateWithMonkey(self, packageName):
        """Stimulates application with monkey"""

        if packageName is None or len(packageName) == 0:
            raise Exception("Cannot stimulate package that has no name.")

        self._logger.info(
            "Stimulating package {0} with monkey.".format(packageName))
        cmd = [
            self.mainConfiguration.adbPath, "-s", self.serialNumber, "shell",
            "monkey", "-p", packageName, "-v", "500", "--throttle", "6000",
            "--ignore-timeouts"
        ]
        p = OSCommand.executeAsyncCommand(cmd)
        stdout, stderr = p.communicate()
        self._logger.debug("{0}".format(stdout))
Ejemplo n.º 17
0
    def stop(self, askUser=False):
        """ Stop the device"""
        self._logger.info("Stopping device listening on port {0}".format(
            self.serialNumber))
        clean = True

        # Pull our analysis events
        self._pullResults()

        # Ask user if they want to clean the device
        if askUser:
            answer = raw_input(
                "Do you want to clean your device? [Yes or No] ").lower()
            while answer != 'yes' and answer != 'no':
                answer = raw_input(
                    "Do you want to clean your device? [Yes or No] ").lower()
            if answer == 'no':
                clean = False

        if clean:
            # If we have a real device we have to push backup to sdcard and push TWRP script to /cache/recovery/
            # at each experiment
            self.__pushBackup()
            self.__pushRecoveryScript()

            # reboot into recovery
            cmd = [
                self.mainConfiguration.adbPath, "-s", self.serialNumber,
                "reboot", "recovery"
            ]
            self._logger.debug(OSCommand.executeCommand(cmd))

            time.sleep(30)
            self._waitForDeviceToBeReady()

            time.sleep(5)  # Wait 5 seconds to be sure SDcard will be mounted

            # When device is ready, don't forget to restore sdcard
            self.__restoreSDCard()
Ejemplo n.º 18
0
    def startActivity(self, activity):
        """Starts the specified activity on the device"""
        if self.state != AndroidDevice.STATE_STARTED:
            raise Exception(
                "Cannot start an activity since the device is not started.")

        if activity is None or len(activity) == 0:
            raise Exception("Cannot start an activity that has no name.")

        self._logger.info("Starting activity {0} on device {1}".format(
            activity, self.name))

        activityPackage = '.'.join(activity.split('.')[:-1])
        activityName = ''.join(activity.split('.')[-1:])

        # $ adb shell am start -n activityPackage/activity
        cmd = [
            self.mainConfiguration.adbPath, "-s", self.serialNumber, "shell",
            "am", "start", "-n", "{0}/.{1}".format(activityPackage,
                                                   activityName)
        ]
        res = OSCommand.executeCommand(cmd)
        self._logger.debug("{}".format(res))
Ejemplo n.º 19
0
    def writeContentOnSdCard(self, filename, fileContent):
        """Create (or replace) the filename related to the dnadroid path
        on the sdcard of the device with the specified fileContent."""
        cmd = [
            self.mainConfiguration.adbPath, "-s", self.serialNumber, "shell",
            "mkdir", self._dnadroidDir
        ]
        OSCommand.executeCommand(cmd)

        filePath = os.path.join(self._dnadroidDir, filename)
        self._logger.debug("Writing content on '{0}'".format(filePath))

        cmd = [
            self.mainConfiguration.adbPath, "-s", self.serialNumber, "shell",
            "touch", filePath
        ]
        OSCommand.executeCommand(cmd)

        cmd = [
            self.mainConfiguration.adbPath, "-s", self.serialNumber, "shell",
            "echo", "\"{}\"".format(fileContent), ">", filePath
        ]
        OSCommand.executeCommand(cmd)
Ejemplo n.º 20
0
    def __restoreSDCard(self):
        """
        Restores the SDCard contents from backup folder.
        Iterates through sdcard folders and deletes files and folders that are not empty.
        Backup folder which contains sdcard initial folders and files will do the restore.
        """
        self._logger.info("Restoring sdcard...")

        ls = [
            self.mainConfiguration.adbPath, "-s", self.serialNumber, "shell",
            "ls"
        ]
        rm = [
            self.mainConfiguration.adbPath, "-s", self.serialNumber, "shell",
            "rm", "-r"
        ]

        result = OSCommand.executeCommand(ls + ['/sdcard/'])
        folders = result.split('\r\n')

        for folder in folders:
            if len(folder) != 0:
                # If folder (or file) is not empty, deletes it
                res = OSCommand.executeCommand(ls + ['/sdcard/' + folder])
                if len(res) != 0:
                    self._logger.info("Deleting {0}".format('/sdcard/' +
                                                            folder))
                    OSCommand.executeCommand(rm + ['/sdcard/' + folder])

        # Push sdcard backup folder
        push = [
            self.mainConfiguration.adbPath, "-s", self.serialNumber, "push",
            os.path.join(self.__backupDir, 'sdcard/'), '/sdcard/'
        ]
        OSCommand.executeCommand(push)
        self._logger.info("SDcard has been restored.")
Ejemplo n.º 21
0
    def __duplicateAVD(self):
        """Creates a new emulator based on a reference one."""
        self._logger.debug("Duplicate AVD '{0}'.".format(
            self.mainConfiguration.referenceAVD))

        refAVDName = os.path.split(self.mainConfiguration.referenceAVD)[1]

        if self.analysisType == "manual":
            avdConfigFile = "{0}.ini".format(
                self.mainConfiguration.referenceAVD)
            referenceAVDDir = os.path.join(
                self.mainConfiguration.virtualDevicePath,
                "{0}.avd/".format(refAVDName))
        else:
            #avdConfigFile = "{0}_{1}.ini".format(self.mainConfiguration.referenceAVD, self.emulatorId)
            #referenceAVDDir = os.path.join(self.mainConfiguration.virtualDevicePath, "{0}_{1}.avd/".format(refAVDName, self.emulatorId))
            avdConfigFile = "{0}.ini".format(
                self.mainConfiguration.referenceAVD)
            referenceAVDDir = os.path.join(
                self.mainConfiguration.virtualDevicePath,
                "{0}.avd/".format(refAVDName))

        if not os.path.exists(avdConfigFile):
            raise Exception("AVD configuration file does not exist: {}".format(
                avdConfigFile))
        if not os.path.isdir(referenceAVDDir):
            raise Exception(
                "AVD directory does not exist: {}".format(referenceAVDDir))

        newConfigFile = os.path.join(self.mainConfiguration.virtualDevicePath,
                                     "{0}.ini".format(self.name))
        newAVDDir = os.path.join(self.mainConfiguration.virtualDevicePath,
                                 "{0}.avd/".format(self.name))

        # If dir exists, remove it
        if os.path.exists(newAVDDir):
            self._logger.debug(
                "Old AVD detected, removing: {}".format(newAVDDir))
            shutil.rmtree(newAVDDir)
        if os.path.exists(newConfigFile):
            self._logger.debug(
                "Old AVD configuration detected, removing: {}".format(
                    newConfigFile))
            os.remove(newConfigFile)

        hwQemuConfigFile = os.path.join(newAVDDir, "hardware-qemu.ini")
        defaultSnapshotConfigFile = os.path.join(
            newAVDDir, "snapshots.img.default-boot.ini")

        # First we copy the template
        self._logger.debug(
            "Copying AVD reference config file '{0}' in '{1}'...".format(
                avdConfigFile, newConfigFile))
        shutil.copyfile(avdConfigFile, newConfigFile)

        # Copy the internal files of the reference avd
        self._logger.debug(
            "Duplicating the AVD internal content from '{0}' in '{1}'...".
            format(referenceAVDDir, newAVDDir))
        # we use the internal linux 'cp' command for performance issues (shutil is too long)
        # shutil.copytree(referenceAVDDir, newAVDDir)
        cmd = "cp -R {0} {1}".format(referenceAVDDir, newAVDDir)
        OSCommand.executeCommand(cmd)

        # Than adapt the content of the copied files
        self.__replaceContentInFile(newConfigFile, refAVDName, self.name)
        self.__replaceContentInFile(hwQemuConfigFile, refAVDName, self.name)
        self.__replaceContentInFile(defaultSnapshotConfigFile, refAVDName,
                                    self.name)

        self.state = AndroidDevice.STATE_PREPARED