Beispiel #1
0
    def _update_dwarf(self):
        path_to_version = os.path.join(self._base_path, os.pardir, os.pardir,
                                       'VERSION')
        if not os.path.exists(path_to_version):
            if utils.is_connected():
                try:
                    # file exists in dwarf >2.0.0 wich means update from 1.x to 2.x
                    request = requests.get(
                        'https://raw.githubusercontent.com/iGio90/Dwarf/master/VERSION'
                    )
                    if request.ok:
                        utils.show_message_box(
                            'This update will break your Dwarf installation!\nSee GitHub for more infos'
                        )
                        from PyQt5.QtCore import QUrl
                        from PyQt5.QtGui import QDesktopServices
                        QDesktopServices.openUrl(
                            QUrl('https://github.com/iGio90/Dwarf'))
                        return
                except:
                    pass

        self._update_thread = DwarfUpdateThread(self)
        self._update_thread.on_finished.connect(self._update_finished)
        if not self._update_thread.isRunning():
            self._update_thread.start()
Beispiel #2
0
    def on_memory_modified(self, pos, length):
        data_pos = self.memory_panel.base + pos
        data = self.memory_panel.data[pos:pos + length]
        data = [data[0]]  # todo: strange js part

        if self.app.dwarf.dwarf_api('writeBytes', [data_pos, data]):
            pass
        else:
            utils.show_message_box('Failed to write Memory')
Beispiel #3
0
def load_script(args, proc, user_script, spawned=False):
    try:
        if not os.path.exists(utils.resource_path('lib/core.js')):
            print('core.js not found!')
            exit(0)

        with open(utils.resource_path('lib/core.js'), 'r') as core_script:
            script_content = core_script.read()

        _script = proc.create_script(script_content, runtime='v8')
        _script.on('message', on_message)
        # _script.on('destroyed', _on_script_destroyed)
        _script.load()

        try:
            is_debug = args.debug_script
        except:
            is_debug = False
        try:
            break_start = args.break_start
        except:
            break_start = False
        # this break_at_start have same behavior from args or from the checkbox i added
        _script.exports.init(break_start, is_debug, spawned)

        plugin_manager.reload_plugins()

        for plugin in plugin_manager.plugins:
            plugin_instance = plugin_manager.plugins[plugin]
            try:
                _script.exports.api(0, 'evaluateFunction', [plugin_instance.__get_agent__()])
                plugin_instance.set_script(_script)
            except Exception as e:
                pass

        if user_script is not None:
            _script.exports.api(0, 'evaluateFunction', [user_script])
        return 0
    except frida.ProcessNotFoundError:
        error_msg = 'Process not found (ProcessNotFoundError)'
        was_error = True
    except frida.ProcessNotRespondingError:
        error_msg = 'Process not responding (ProcessNotRespondingError)'
        was_error = True
    except frida.TimedOutError:
        error_msg = 'Frida timeout (TimedOutError)'
        was_error = True
    except frida.ServerNotRunningError:
        error_msg = 'Frida not running (ServerNotRunningError)'
        was_error = True
    except frida.TransportError:
        error_msg = 'Frida timeout was reached (TransportError)'
        was_error = True

    if was_error:
        utils.show_message_box(error_msg)
    return 1
Beispiel #4
0
 def _start_session(self, session_type, session_data=None):
     if self.welcome_window is not None:
         self.welcome_window.close()
     try:
         self.session_manager.create_session(session_type,
                                             session_data=session_data)
     except Exception as e:
         if self.welcome_window:
             utils.show_message_box(str(e))
Beispiel #5
0
 def _on_proc_selected(self, data):
     device, pid = data
     if device:
         self.dwarf.device = device
     if pid:
         try:
             self.dwarf.attach(pid)
         except Exception as e:
             utils.show_message_box('Failed attaching to {0}'.format(pid), str(e))
             self.stop()
             return
Beispiel #6
0
    def _on_spawn_selected(self, data):
        device, package_name, break_at_start = data
        if device:
            self.dwarf.device = device
        if package_name:
            try:
                self.dwarf.spawn(package_name, break_at_start=break_at_start)
            except Exception as e:
                utils.show_message_box('Failed spawning {0}'.format(package_name), str(e))
                self.stop()
                return

            self._on_objc_modules()
Beispiel #7
0
    def _show_plugin_about(self, plugin):
        plugin = self.plugin_manager.plugins[plugin]
        if plugin:
            info = plugin.__get_plugin_info__()

            version = utils.safe_read_map(info, 'version', '')
            description = utils.safe_read_map(info, 'description', '')
            author = utils.safe_read_map(info, 'author', '')
            homepage = utils.safe_read_map(info, 'homepage', '')
            license_ = utils.safe_read_map(info, 'license', '')

            utils.show_message_box(
                'Name: {0}\nVersion: {1}\nDescription: {2}\nAuthor: {3}\nHomepage: {4}\nLicense: {5}'.
                    format(plugin.name, version, description, author, homepage, license_))
Beispiel #8
0
    def decompile(adb, apk_path):
        if not os.path.exists('.decompile'):
            os.mkdir('.decompile')
        adb.su_cmd('cp ' + apk_path + ' /sdcard/dwarf-decompile.apk')
        adb.pull('/sdcard/dwarf-decompile.apk', '.decompile/base.apk')
        adb.su_cmd('rm /sdcard/dwarf-decompile.apk')
        dex2jar = 'd2j-dex2jar.sh'
        if os.name == 'nt':
            dex2jar = 'd2j-dex2jar.bat'
        try:
            utils.do_shell_command(dex2jar).index('version')
        except:
            utils.show_message_box('failed to find %s' % dex2jar)
            return
        utils.do_shell_command(
            dex2jar + ' .decompile/base.apk -o .decompile/base.jar -f')
        if not external_tools.tool_exist('luyten.jar'):
            if os.name == 'nt':
                external_tools.get_tool(
                    'https://github.com/deathmarine/Luyten/releases/download/v0.5.4_Rebuilt_with_Latest_depenencies/luyten-0.5.4.exe',
                    'luyten.exe')
            else:
                external_tools.get_tool(
                    'https://github.com/deathmarine/Luyten/releases/download/v0.5.4_Rebuilt_with_Latest_depenencies/luyten-0.5.4.jar',
                    'luyten.jar')
        java_version = utils.do_shell_command('java -version')

        try:
            if os.name == 'nt':
                utils.do_shell_command(
                    'tools/luyten.exe .decompile/base.jar &')
            else:
                utils.do_shell_command(
                    'java -jar tools/luyten.jar .decompile/base.jar &')
        except:
            pass
Beispiel #9
0
    def load_script(self, script=None, spawned=False, break_at_start=False):
        try:
            if not os.path.exists(utils.resource_path('lib/core.js')):
                raise self.CoreScriptNotFoundError('core.js not found!')

            with open(utils.resource_path('lib/core.js'), 'r') as core_script:
                script_content = core_script.read()

            self._script = self._process.create_script(script_content, runtime="v8")
            self._script.on('message', self._on_message)
            self._script.on('destroyed', self._on_script_destroyed)
            self._script.load()

            break_at_start = break_at_start or self._app_window.dwarf_args.break_start
            # we invalidate the arg in any case (set this from ui needs a store in args for an eventual restore session)
            self._app_window.dwarf_args.break_start = break_at_start

            is_debug = self._app_window.dwarf_args.debug_script
            # this break_at_start have same behavior from args or from the checkbox i added
            self._script.exports.init(break_at_start, is_debug, spawned, True)

            if not os.path.exists(utils.home_path() + 'keywords.json'):
                self.dump_keywords()

            # resume immediately
            self.resume_proc()

            for plugin in self._app_window.plugin_manager.plugins:
                plugin_instance = self._app_window.plugin_manager.plugins[plugin]
                try:
                    self.dwarf_api('evaluateFunction', plugin_instance.__get_agent__())
                except Exception as e:
                    pass

            if script is not None:
                if os.path.exists(script):
                    with open(script, 'r') as script_file:
                        user_script = script_file.read()

                    self.dwarf_api('evaluateFunction', user_script)

            self.onScriptLoaded.emit()

            return 0
        except frida.ProcessNotFoundError:
            error_msg = 'Process not found (ProcessNotFoundError)'
            was_error = True
        except frida.ProcessNotRespondingError:
            error_msg = 'Process not responding (ProcessNotRespondingError)'
            was_error = True
        except frida.TimedOutError:
            error_msg = 'Frida timeout (TimedOutError)'
            was_error = True
        except frida.ServerNotRunningError:
            error_msg = 'Frida not running (ServerNotRunningError)'
            was_error = True
        except frida.TransportError:
            error_msg = 'Frida timeout was reached (TransportError)'
            was_error = True

        if was_error:
            utils.show_message_box(error_msg)
        return 1
Beispiel #10
0
    def __init__(self, app_window):
        super(AndroidSession, self).__init__(app_window)
        self.adb = Adb()

        if not self.adb.min_required:
            utils.show_message_box(self.adb.get_states_string())
Beispiel #11
0
 def _on_proc_error(self, error_str):
     utils.show_message_box('Failed to refresh Proclist', error_str)
Beispiel #12
0
 def _on_spawn_error(self, error_str):
     utils.show_message_box('Failed to refresh Spawnlist', error_str)
Beispiel #13
0
    def _check_requirements(self):  # pylint: disable=too-many-branches, too-many-statements
        """ Checks root on device
        """
        self._dev_emu = False
        self._is_root = False
        self._is_su = False
        self._alternate_su_binary = False

        if not self._device_serial:
            return

        if self._adb_available:
            # try some command
            date_res = self._do_adb_command('shell date')
            # adb not authorized
            if date_res and 'device unauthorized' in date_res:
                # kill adb daemon
                utils.do_shell_command('adb kill-server')
                utils.show_message_box(
                    'device not authorized! allow access from this computer on the device'
                )

            if date_res and 'no devices/emulators' in date_res:
                self._dev_emu = False
                return
            elif date_res and 'device not found' in date_res:
                self._dev_emu = False
                return
            else:
                self._dev_emu = True

            if self._dev_emu and date_res:
                try:
                    # if date was fine it should end with year
                    # Thu Feb 8 16:47:32 MST 2001
                    date_res = date_res.split(' ')
                    res_year = int(date_res[len(date_res) - 1])
                except ValueError:
                    return  # TODO: raise exceptions

            # try some su command to check for su binary
            res = self._do_adb_command('shell su -c date')
            if res and 'invalid' in res:
                res = self._do_adb_command('shell su 0 date')
                if res:
                    self._alternate_su_binary = True

            if res:
                try:
                    # if su date was fine it should end with year
                    # Thu Feb 8 16:47:32 MST 2001
                    su_res = res.split(' ')
                    res_year = int(su_res[len(su_res) - 1])
                    if res_year:
                        # su cmd is available
                        self._is_su = True

                        # check if both date results matches otherwise its no valid result
                        res_len = len(su_res)
                        date_len = len(date_res)
                        if su_res[res_len - 1] == date_res[date_len -
                                                           1]:  # year
                            if su_res[res_len - 2] == date_res[date_len -
                                                               2]:  # timezone
                                if su_res[res_len - 4] == date_res[date_len -
                                                                   4]:  # day
                                    if su_res[res_len -
                                              5] == date_res[date_len -
                                                             5]:  # month
                                        self._is_root = True

                except ValueError:
                    pass

            res = self._do_adb_command('shell mount | grep system')
            if '/system_root' in res:
                self._syspart_name = '/system_root'

            # check status of selinux
            res = self._do_adb_command('shell getenforce')
            if res:
                res = res.join(res.split())
                if res != 'Permissive' and res != 'Disabled':
                    self._do_adb_command('shell setenforce 0')

            # nox fix
            res = self.su_cmd('mount -o ro,remount ' + self._syspart_name)
            if res and 'invalid' in res:
                self._alternate_su_binary = True

            # no su -> try if the user is already root
            # on some emulators user is root
            if not self._is_su and self._dev_emu:
                res = self._do_adb_command('shell mount -o ro,remount ' +
                                           self._syspart_name)
                if res or res == '':
                    if res and 'not user mountable' in res:
                        # no root user
                        self._is_root = False
                    elif res == '':
                        # cmd executed fine
                        self._is_root = True
                    else:
                        # dont know some other output
                        self._is_root = False
                        # check for uid 0
                        res = self._do_adb_command('shell id')
                        # root should be 0
                        # https://superuser.com/questions/626843/does-the-root-account-always-have-uid-gid-0/626845#626845
                        self._is_root = 'uid=0' in res

            if self._dev_emu:
                # get some infos about the device and keep for later
                self._sdk_version = self._do_adb_command(
                    'shell getprop ro.build.version.sdk')
                if self._sdk_version:
                    self._sdk_version = self._sdk_version.join(
                        self._sdk_version.split())  # cleans '\r\n'
                self._android_version = self._do_adb_command(
                    'shell getprop ro.build.version.release')
                if self._android_version:
                    self._android_version = self._android_version.join(
                        self._android_version.split())

                try:
                    self._oreo_plus = (int(
                        self._android_version.split('.')[0]) >= 8)
                except ValueError:
                    try:
                        self._oreo_plus = (int(self._sdk_version) > 25)
                    except ValueError:
                        pass

                # fix some frida server problems
                # frida default port: 27042
                utils.do_shell_command('adb forward tcp:27042 tcp:27042')

            # check if we have pidof
            res = self._do_adb_command('shell pidof -s pidof')
            self._have_pidof = 'not found' not in res
            res = self._do_adb_command('shell killall')
            self._have_killall = 'not found' not in res

            # check for correct userid
            if self._is_root:
                res = self.su_cmd('id')
                # root should be 0
                # https://superuser.com/questions/626843/does-the-root-account-always-have-uid-gid-0/626845#626845
                self._is_root = 'uid=0' in res
Beispiel #14
0
 def _on_search_error(self, msg):
     utils.show_message_box(msg)