def load_script(args, proc, 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() is_debug = args.debug_script # this break_at_start have same behavior from args or from the checkbox i added _script.exports.init(args.break_start, is_debug, spawned) if args.script is not None: if os.path.exists(args.script): with open(args.script, 'r') as script_file: user_script = script_file.read() _script.exports.api(0, 'evaluateFunction', [user_script]) plugin_manager = PluginManager(None) 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__()) except Exception as e: pass 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, dwarf_args, flags=None): super(AppWindow, self).__init__(flags) self.dwarf_args = dwarf_args self.session_manager = SessionManager(self) self.session_manager.sessionCreated.connect(self.session_created) self.session_manager.sessionStopped.connect(self.session_stopped) self.session_manager.sessionClosed.connect(self.session_closed) self._tab_order = [ 'debug', 'modules', 'ranges', 'jvm-inspector', 'jvm-debugger' ] self._is_newer_dwarf = False self.q_settings = QSettings(utils.home_path() + "dwarf_window_pos.ini", QSettings.IniFormat) self.menu = self.menuBar() self.view_menu = None self._initialize_ui_elements() self.setWindowTitle( 'Dwarf - A debugger for reverse engineers, crackers and security analyst' ) # load external assets _app = QApplication.instance() # themes self.prefs = Prefs() utils.set_theme(self.prefs.get('dwarf_ui_theme', 'black'), self.prefs) # load font if os.path.exists(utils.resource_path('assets/Anton.ttf')): QFontDatabase.addApplicationFont( utils.resource_path('assets/Anton.ttf')) else: QFontDatabase.addApplicationFont(':/assets/Anton.ttf') if os.path.exists(utils.resource_path('assets/OpenSans-Regular.ttf')): QFontDatabase.addApplicationFont( utils.resource_path('assets/OpenSans-Regular.ttf')) else: QFontDatabase.addApplicationFont(':/assets/OpenSans-Regular.ttf') if os.path.exists(utils.resource_path('assets/OpenSans-Bold.ttf')): QFontDatabase.addApplicationFont( utils.resource_path('assets/OpenSans-Bold.ttf')) else: QFontDatabase.addApplicationFont(':/assets/OpenSans-Bold.ttf') font = QFont("OpenSans", 9, QFont.Normal) # TODO: add settingsdlg font_size = self.prefs.get('dwarf_ui_font_size', 12) font.setPixelSize(font_size) _app.setFont(font) # mainwindow statusbar self.progressbar = QProgressBar() self.progressbar.setRange(0, 0) self.progressbar.setVisible(False) self.progressbar.setFixedHeight(15) self.progressbar.setFixedWidth(100) self.progressbar.setTextVisible(False) self.progressbar.setValue(30) self.statusbar = QStatusBar(self) self.statusbar.setAutoFillBackground(False) self.statusbar.addPermanentWidget(self.progressbar) self.statusbar.setObjectName("statusbar") self.setStatusBar(self.statusbar) self.main_tabs = QTabWidget(self) self.main_tabs.setMovable(False) self.main_tabs.setTabsClosable(True) self.main_tabs.setAutoFillBackground(True) self.main_tabs.tabCloseRequested.connect(self._on_close_tab) self.setCentralWidget(self.main_tabs) # pluginmanager self.plugin_manager = PluginManager(self) self.plugin_manager.reload_plugins() if dwarf_args.any == '': self.welcome_window = WelcomeDialog(self) self.welcome_window.setModal(True) self.welcome_window.onIsNewerVersion.connect( self._enable_update_menu) self.welcome_window.onUpdateComplete.connect( self._on_dwarf_updated) self.welcome_window.setWindowTitle( 'Welcome to Dwarf - A debugger for reverse engineers, crackers and security analyst' ) self.welcome_window.onSessionSelected.connect(self._start_session) # wait for welcome screen self.hide() self.welcome_window.show() else: print('* Starting new Session') self._start_session(dwarf_args.target)
def main(): import argparse import frida import os import sys from dwarf.lib import utils plugin_manager = PluginManager(None) def process_args(): """ process commandline params """ parser = argparse.ArgumentParser() parser.add_argument( "-t", "--target", default='local', type=str, help="SessionType - android, ios, local, remote - default: local") parser.add_argument( "-s", "--script", type=str, help= "Path to an additional script to load with dwarf and frida js api") parser.add_argument("-dev", "--device", help="DeviceSerial adb devices") parser.add_argument("-bs", "--break-start", action='store_true', help="break at start") parser.add_argument("-ds", "--debug-script", action='store_true', help="debug outputs from frida script") parser.add_argument('any', nargs='?', default='', help='path/pid/package') parser.add_argument('args', nargs='*', default=[''], help='arguments') args = parser.parse_args() return args def attach(args, device): """ Attach to pid """ _process = None was_error = False error_msg = '' pid = args.pid # for commandline arg if isinstance(pid, str): try: process = device.get_process(pid) pid = [process.pid, process.name] except frida.ProcessNotFoundError as error: raise Exception('Frida Error: ' + str(error)) if isinstance(pid, list): pid = pid[0] if not isinstance(pid, int): raise Exception('Error pid!=int') try: _process = device.attach(pid) _pid = pid 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 # keep for debug except Exception as error: # pylint: disable=broad-except error_msg = error was_error = True if was_error: raise Exception(error_msg) load_script(args, _process) def spawn(args, device): _process = None _pid = 0 package = args.any package_args = args.args if args is None: args = [] try: if package == '-': args.pid = os.getpid() attach(args, device) else: if device.type == 'local': _pid = device.spawn([package] + package_args) else: # args not supported in remote targets _pid = device.spawn(package) _package = package _process = device.attach(_pid) #_process.on('detached', self._on_detached) _spawned = True except Exception as e: raise Exception('Frida Error: ' + str(e)) load_script(args, _process, spawned=True) device.resume(_pid) def on_message(message, payload): for plugin in plugin_manager.plugins: plugin_instance = plugin_manager.plugins[plugin] try: plugin_instance.on_frida_message(message, payload) except: pass def load_script(args, proc, 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() is_debug = args.debug_script # this break_at_start have same behavior from args or from the checkbox i added _script.exports.init(args.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 args.script is not None: if os.path.exists(args.script): with open(args.script, 'r') as script_file: user_script = script_file.read() _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 ######## # INIT # ######## args = process_args() if not args.target and not args.device: print( 'missing session type. use -t local|android|ios|remote to define the session type' ' or specify a device id with --device') exit(0) if args.any == '': print('missing file or package name to attach') exit(0) device = None try: if args.device: device = frida.get_device(id=args.device) else: session_type = args.target.lower() if session_type == 'local': device = frida.get_local_device() elif session_type == 'android' or session_type == 'ios': device = frida.get_usb_device(5) elif session_type == 'remote': device = frida.get_remote_device() except Exception as e: print('failed to get frida device') print(e) if device is not None: try: # parse target as pid args.pid = int(args.any) except ValueError: args.pid = 0 if args.pid > 0: print('* Trying to attach to {0}'.format(args.pid)) try: attach(args, device) except Exception as e: # pylint: disable=broad-except print('-failed-') print('Reason: ' + str(e)) print('Help: you can use -sp to force spawn') exit(0) else: print('* Trying to spawn {0}'.format(args.any)) try: spawn(args, device) except Exception as e: # pylint: disable=broad-except print('-failed-') print('Reason: ' + str(e)) exit(0) sys.stdin.read()