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()
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')
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
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))
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
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()
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_))
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
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
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())
def _on_proc_error(self, error_str): utils.show_message_box('Failed to refresh Proclist', error_str)
def _on_spawn_error(self, error_str): utils.show_message_box('Failed to refresh Spawnlist', error_str)
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
def _on_search_error(self, msg): utils.show_message_box(msg)