class SmaliThread(QThread): onFinished = pyqtSignal(name='onFinished') onError = pyqtSignal(name='onError') def __init__(self, parent=None, package_name=None): super(SmaliThread, self).__init__(parent) self._adb = Adb() self._package_name = package_name def run(self): if not self._package_name: self.onError.emit() return _path = self._adb.package_path(self._package_name) if not os.path.exists('.tmp'): os.mkdir('.tmp') if _path: self._adb.pull(_path, '.tmp/base.apk') if os.path.exists('.tmp/base.apk'): _baksmali_cmd = 'd2j-baksmali.sh' if os.name == 'nt': _baksmali_cmd = _baksmali_cmd.replace('.sh', '.bat') try: utils.do_shell_command(_baksmali_cmd + ' .tmp/base.apk -o .tmp/smali') self.onFinished.emit() except: # no d2j self.onError.emit() else: self.onError.emit()
def __init__(self, parent=None, show_path=True): super(ApkList, self).__init__(parent=parent) self.adb = Adb() if not self.adb.available(): return self.retrieve_thread = PackageRetrieveThread(self.adb) if self.retrieve_thread is not None: self.retrieve_thread.onAddPackage.connect(self._on_addpackage) if show_path: self.apk_model = QStandardItemModel(0, 2) else: self.apk_model = QStandardItemModel(0, 1) self.apk_model.setHeaderData(0, Qt.Horizontal, 'Name') if show_path: self.apk_model.setHeaderData(1, Qt.Horizontal, 'Path') self.setModel(self.apk_model) self.header().setSectionResizeMode(0, QHeaderView.ResizeToContents) self.doubleClicked.connect(self._on_apk_selected) if self.retrieve_thread is not None: if not self.retrieve_thread.isRunning(): self.retrieve_thread.start()
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()) self._smali_thread = None
def __init__(self, parent=None, device_type='usb'): super().__init__(parent=parent) # dont show for local if device_type != 'usb': return self.parent = parent self.wait_for_devtype = device_type self.is_waiting = True self._adb = Adb() if not self._adb.min_required: return self._git = Git() self.setAutoFillBackground(True) self.setStyleSheet( 'background-color: crimson; color: white; font-weight: bold; margin: 0; padding: 10px;' ) self.setup() self._timer = QTimer() self._timer.setInterval(500) self._timer.timeout.connect(self._on_timer) self._timer.start() self._timer_step = 0 frida.get_device_manager().on('added', self._on_device) frida.get_device_manager().on('removed', self._on_device) self.devices_thread = DevicesUpdateThread(self) self.devices_thread.onAddDevice.connect(self.on_add_deviceitem) self.devices_thread.onDevicesUpdated.connect(self._on_devices_finished) self._update_thread = FridaUpdateThread(self) self._update_thread._adb = self._adb self._update_thread.onStatusUpdate.connect(self._update_statuslbl) self._update_thread.onFinished.connect(self._frida_updated) self._update_thread.onError.connect(self._on_download_error) self.updated_frida_version = '' self.updated_frida_assets_url = {} self._device_id = None self._devices = [] remote_frida = self._git.get_frida_version() if remote_frida is None: self.updated_frida_version = '' self.updated_frida_assets_url.clear() else: remote_frida = remote_frida[0] self.updated_frida_version = remote_frida['tag_name'] for asset in remote_frida['assets']: try: name = asset['name'] tag_start = name.index('android-') if name.index('server') >= 0: tag = name[tag_start + 8:-3] self.updated_frida_assets_url[tag] = asset[ 'browser_download_url'] except ValueError: pass
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()) if app_window.dwarf_args.package is None: self._device_window = DeviceWindow(self._app_window, 'usb') self._smali_thread = None
def __init__(self, app_window): super(AndroidSession, self).__init__(app_window) self._app_window = app_window self.adb = Adb() if not self.adb.min_required: utils.show_message_box(self.adb.get_states_string()) self._device_window = DeviceWindow(self._app_window, 'usb') # main menu every session needs self._menu = [] self._smali_thread = None
def __init__(self, app_window): super(AndroidSession, self).__init__(app_window) self._app_window = app_window self.adb = Adb() if not self.adb.is_adb_available(): utils.show_message_box(self.adb.get_states_string()) self._device_window = DeviceWindow(self._app_window, 'usb') # main menu every session needs self._menu = [QMenu(self.session_type + ' Session')] #self._menu[0].addAction('Save Session', self._save_session) self._menu[0].addAction('Close Session', self.stop_session)
def __init__(self, app_window): super(AndroidSession, self).__init__(app_window) self._app_window = app_window self.adb = Adb() if not self.adb.min_required: utils.show_message_box(self.adb.get_states_string()) self._device_window = DeviceWindow(self._app_window, 'usb') # main menu every session needs self._menu = [QMenu(self.session_type + ' Session')] self._menu[0].addAction('Save Session', self.dwarf.save_session) self._menu[0].addAction('Close Session', self.stop_session) self._smali_thread = None
def __init__(self, dwarf_args, flags=None, *args, **kwargs): super().__init__(flags, *args, **kwargs) self.app = App(self) self.adb = Adb(self.app) self.dwarf = Dwarf(self) self.update_title() self.setCentralWidget(self.app) self.app.setup_ui() self.menu = MenuBar(self) if dwarf_args.package is not None: self.dwarf.spawn(dwarf_args.package, dwarf_args.script)
def __init__(self, dwarf_args, flags=None, *args, **kwargs): super().__init__(flags, *args, **kwargs) self.app = App(self) self.adb = Adb() self.dwarf = Dwarf(self) self.update_title() self.setCentralWidget(self.app) self.app.setup_ui() self.menu = MenuBar(self) if dwarf_args.package is not None: # we skip welcome ui here if not self.get_adb().available(): # additional check if we have a local server to starts with if frida.get_local_device() is None: utils.show_message_box( 'adb/device/emu not found or not rooted! see details or output', self.app.get_adb().get_states_string()) return if dwarf_args.spawn is not None: err = self.dwarf.spawn(dwarf_args.package, dwarf_args.script) else: err = self.dwarf.attach(dwarf_args.package, dwarf_args.script, print_debug_error=False) if err > 0: if err == 1: # no device? kidding? pass elif err == 2: # no proc to attach - fallback to spawn err = self.dwarf.spawn(dwarf_args.package, dwarf_args.script)
class DeviceBar(QWidget): """ DeviceBar Signals: onDeviceUpdated() onDeviceSelected(str) # str = id onDeviceChanged(str) # str = id """ onDeviceUpdated = pyqtSignal(str, name="onDeviceUpdated") onDeviceSelected = pyqtSignal(str, name="onDeviceSelected") onDeviceChanged = pyqtSignal(str, name="onDeviceChanged") def __init__(self, parent=None, device_type='usb'): super().__init__(parent=parent) # dont show for local if device_type != 'usb': return self.parent = parent self.wait_for_devtype = device_type self.is_waiting = True self._adb = Adb() if not self._adb.min_required: return self._git = Git() self.setAutoFillBackground(True) self.setStyleSheet( 'background-color: crimson; color: white; font-weight: bold; margin: 0; padding: 10px;' ) self.setup() self._timer = QTimer() self._timer.setInterval(500) self._timer.timeout.connect(self._on_timer) self._timer.start() self._timer_step = 0 frida.get_device_manager().on('added', self._on_device) frida.get_device_manager().on('removed', self._on_device) self.devices_thread = DevicesUpdateThread(self) self.devices_thread.onAddDevice.connect(self.on_add_deviceitem) self.devices_thread.onDevicesUpdated.connect(self._on_devices_finished) self._update_thread = FridaUpdateThread(self) self._update_thread._adb = self._adb self._update_thread.onStatusUpdate.connect(self._update_statuslbl) self._update_thread.onFinished.connect(self._frida_updated) self._update_thread.onError.connect(self._on_download_error) self.updated_frida_version = '' self.updated_frida_assets_url = {} self._device_id = None self._devices = [] remote_frida = self._git.get_frida_version() if remote_frida is None: self.updated_frida_version = '' self.updated_frida_assets_url.clear() else: remote_frida = remote_frida[0] self.updated_frida_version = remote_frida['tag_name'] for asset in remote_frida['assets']: try: name = asset['name'] tag_start = name.index('android-') if name.index('server') >= 0: tag = name[tag_start + 8:-3] self.updated_frida_assets_url[tag] = asset[ 'browser_download_url'] except ValueError: pass def setup(self): """ Setup ui """ h_box = QHBoxLayout() h_box.setContentsMargins(0, 0, 0, 0) self.update_label = QLabel('Waiting for Device') self.update_label.setFixedWidth(self.parent.width()) self.update_label.setOpenExternalLinks(True) self.update_label.setTextFormat(Qt.RichText) self.update_label.setFixedHeight(35) self.update_label.setTextInteractionFlags(Qt.TextBrowserInteraction) self._install_btn = QPushButton('Install Frida', self.update_label) self._install_btn.setStyleSheet('padding: 0; border-color: white;') self._install_btn.setGeometry(self.update_label.width() - 110, 5, 100, 25) self._install_btn.clicked.connect(self._on_install_btn) self._install_btn.setVisible(False) self._start_btn = QPushButton('Start Frida', self.update_label) self._start_btn.setStyleSheet('padding: 0; border-color: white;') self._start_btn.setGeometry(self.update_label.width() - 110, 5, 100, 25) self._start_btn.clicked.connect(self._on_start_btn) self._start_btn.setVisible(False) self._update_btn = QPushButton('Update Frida', self.update_label) self._update_btn.setStyleSheet('padding: 0; border-color: white;') self._update_btn.setGeometry(self.update_label.width() - 110, 5, 100, 25) self._update_btn.clicked.connect(self._on_install_btn) self._update_btn.setVisible(False) self._restart_btn = QPushButton('Restart Frida', self.update_label) self._restart_btn.setStyleSheet('padding: 0; border-color: white;') self._restart_btn.setGeometry(self.update_label.width() - 110, 5, 100, 25) self._restart_btn.clicked.connect(self._on_restart_btn) self._restart_btn.setVisible(False) self._devices_combobox = QComboBox(self.update_label) self._devices_combobox.setStyleSheet( 'padding: 2px 5px; border-color: white;') self._devices_combobox.setGeometry(self.update_label.width() - 320, 5, 200, 25) self._devices_combobox.currentIndexChanged.connect( self._on_device_changed) self._devices_combobox.setVisible(False) h_box.addWidget(self.update_label) self.setLayout(h_box) def on_add_deviceitem(self, device_ident): """ Adds an Item to the DeviceComboBox """ if device_ident['type'] == self.wait_for_devtype: if device_ident['name'] not in self._devices: self._devices.append(device_ident) self._timer_step = -1 self.is_waiting = False def _on_device_changed(self, index): device = None device_id = self._devices_combobox.itemData(index) if device_id: try: device = frida.get_device(device_id) except: return if device: self._device_id = device.id self._check_device(device) self.onDeviceChanged.emit(self._device_id) def _check_device(self, frida_device): self.update_label.setStyleSheet('background-color: crimson;') self._install_btn.setVisible(False) self._update_btn.setVisible(False) self._start_btn.setVisible(False) self._restart_btn.setVisible(False) self._adb.device = frida_device.id self._device_id = frida_device.id if self._adb.available(): self.update_label.setText('Device: ' + frida_device.name) # try getting frida version device_frida = self._adb.get_frida_version() # frida not found show install button if device_frida is None: self._install_btn.setVisible(True) else: # frida is old show update button if self.updated_frida_version != device_frida: self._start_btn.setVisible(True) self._update_btn.setVisible(False) # old frida is running allow use of this version if self._adb.is_frida_running(): self._start_btn.setVisible(False) if self.updated_frida_assets_url: self._update_btn.setVisible(True) self.update_label.setStyleSheet( 'background-color: yellowgreen;') self.onDeviceUpdated.emit(frida_device.id) # frida not running show start button elif device_frida and not self._adb.is_frida_running(): self._start_btn.setVisible(True) # frida is running with last version show restart button elif device_frida and self._adb.is_frida_running(): self.update_label.setStyleSheet( 'background-color: yellowgreen;') self._restart_btn.setVisible(True) self.onDeviceUpdated.emit(frida_device.id) def _on_devices_finished(self): if len(self._devices) > 1: self._devices_combobox.clear() self._devices_combobox.setVisible(True) self.update_label.setText('Please select the Device: ') for device in self._devices: self._devices_combobox.addItem(device['name'], device['id']) else: self._devices_combobox.setVisible(False) try: device = frida.get_device(self._devices[0]['id']) self._check_device(device) except: pass def _on_timer(self): if self._timer_step == -1: self._timer.stop() return if self._timer_step == 0: self.update_label.setText(self.update_label.text() + ' .') self._timer_step = 1 elif self._timer_step == 1: self.update_label.setText(self.update_label.text() + '.') self._timer_step = 2 elif self._timer_step == 2: self.update_label.setText(self.update_label.text() + '.') self._timer_step = 3 else: self.update_label.setText( self.update_label.text()[:-self._timer_step]) self._timer_step = 0 if self.is_waiting and self.devices_thread is not None: if not self.devices_thread.isRunning(): self.devices_thread.start() def _on_download_error(self, text): self._timer_step = -1 self.update_label.setStyleSheet('background-color: crimson;') self.update_label.setText(text) self._install_btn.setVisible(True) self._update_btn.setVisible(False) def _on_device(self): self._timer_step = 4 self.is_waiting = True self._on_timer() def _on_install_btn(self): # urls are empty if not self.updated_frida_assets_url: return arch = self._adb.get_device_arch() request_url = '' if arch is not None and len(arch) > 1: arch = arch.join(arch.split()) if arch == 'arm64' or arch == 'arm64-v8a': request_url = self.updated_frida_assets_url['arm64'] elif arch == 'armeabi-v7a': request_url = self.updated_frida_assets_url['arm'] else: if arch in self.updated_frida_assets_url: request_url = self.updated_frida_assets_url[arch] try: if self._adb.available() and request_url.index( 'https://') == 0: self._install_btn.setVisible(False) self._update_btn.setVisible(False) if self._update_thread is not None: if not self._update_thread.isRunning(): self._update_thread.frida_update_url = request_url self._update_thread.adb = self._adb self._update_thread.start() except ValueError: # something wrong in .git_cache folder print("request_url not set") def _update_statuslbl(self, text): self._timer.stop() self._timer_step = 0 self._timer.start() self.update_label.setText(text) def _frida_updated(self): #self._timer_step = 3 #self.is_waiting = True self._on_devices_finished() def _on_start_btn(self): if self._adb.available(): self._start_btn.setVisible(False) if self._adb.start_frida(): #self.onDeviceUpdated.emit(self._device_id) self._on_devices_finished() else: self._start_btn.setVisible(True) def _on_restart_btn(self): if self._adb.available(): self._restart_btn.setVisible(False) if self._adb.start_frida(restart=True): self._restart_btn.setVisible(True) #self.onDeviceUpdated.emit(self._device_id) self._on_devices_finished()
class AndroidSession(Session): """ All Android Stuff goes here if u look for something android related its here then """ def __init__(self, app_window): super(AndroidSession, self).__init__(app_window) self._app_window = app_window self.adb = Adb() if not self.adb.min_required: utils.show_message_box(self.adb.get_states_string()) if app_window.dwarf_args.package is None: self._device_window = DeviceWindow(self._app_window, 'usb') # main menu every session needs self._menu = [] self._smali_thread = None @property def session_ui_sections(self): # what sections we want in session_ui return [ 'hooks', 'bookmarks', 'threads', 'registers', 'memory', 'console', 'watchers', 'modules', 'jvm-inspector', 'jvm-debugger', 'ranges', 'backtrace' ] @property def non_closable(self): return ['memory', 'ranges', 'modules', 'jvm-inspector', 'jvm-debugger'] @property def session_type(self): """ return session name to show in menus etc """ return 'Android' @property def main_menu(self): """ return our created menu """ return self._menu def initialize(self, config): # session supports load/save then use config # setup ui etc for android self._setup_menu() # all fine were done wait for ui_ready self.onCreated.emit() def _setup_menu(self): """ Build Menus """ # additional menus file_menu = QMenu('&Device') save_apk = QAction("&Save APK", self) save_apk.triggered.connect(self.save_apk) decompile_apk = QAction("&Decompile APK", self) decompile_apk.triggered.connect(self.decompile_apk) file_menu.addAction(save_apk) file_menu.addAction(decompile_apk) self._menu.append(file_menu) process_menu = QMenu('&Process') process_menu.addAction('Resume', self._on_proc_resume, Qt.Key_F5) process_menu.addAction('Restart', self._on_proc_restart, Qt.Key_F9) process_menu.addAction('Detach', self._on_detach, Qt.Key_F10) self._menu.append(process_menu) java_menu = QMenu('&Java') java_menu.addAction('Trace', self._on_java_trace) java_menu.addSeparator() java_menu.addAction('Classes', self._on_java_classes) self._menu.append(java_menu) def stop_session(self): # cleanup ur stuff # end session super().stop() def start(self, args): self.dwarf.onScriptDestroyed.connect(self.stop) if args.package is None: self._device_window.setModal(True) self._device_window.onSelectedProcess.connect( self.on_proc_selected) self._device_window.onSpwanSelected.connect(self.on_spawn_selected) self._device_window.onClosed.connect(self._on_devdlg_closed) self._device_window.show() else: if not args.device: self.dwarf.device = frida.get_usb_device() else: self.adb.device = args.device self.dwarf.device = frida.get_device(id=args.device) if not args.spawn: print('* Trying to attach to {0}'.format(args.package)) try: self.dwarf.attach(args.package, args.script, False) except Exception as e: # pylint: disable=broad-except print('-failed-') print('Reason: ' + str(e)) print('Help: you can use -sp to force spawn') self.stop() exit(0) else: print('* Trying to spawn {0}'.format(args.package)) try: self.dwarf.spawn(args.package, args.script) except Exception as e: # pylint: disable=broad-except print('-failed-') print('Reason: ' + str(e)) self.stop() exit(0) def decompile_apk(self): apk_dlg = ApkListDialog(self._app_window) apk_dlg.onApkSelected.connect(self._decompile_package) apk_dlg.show() def _decompile_package(self, data): package, path = data if path is not None: # todo: make qthread AndroidDecompileUtil.decompile(self.adb, path) def save_apk(self): apk_dlg = ApkListDialog(self._app_window) apk_dlg.onApkSelected.connect(self._save_package) apk_dlg.show() def _save_package(self, data): package, path = data if path is not None: result = QFileDialog.getSaveFileName( caption='Location to save ' + package, directory='./' + package + '.apk', filter='*.apk') if result and result[0]: self.adb.pull(path, result[0]) def on_proc_selected(self, data): device, pid = data if device: self.adb.device = device.id 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.adb.device = device.id self.dwarf.device = device if package_name: # smalistuff if self._smali_thread is None: self._app_window.show_progress('Baksmali ' + package_name + ' ...') self._smali_thread = SmaliThread(self, device.id, package_name) self._smali_thread.onError.connect( self._app_window.hide_progress) self._smali_thread.onFinished.connect( self._app_window.hide_progress) self._smali_thread.start() try: self.dwarf.spawn(package=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_java_classes() def _on_proc_resume(self, tid=0): self.dwarf.dwarf_api('release', tid) def _on_proc_restart(self): self.dwarf.restart_proc() def _on_detach(self): self.dwarf.detach() self._smali_thread = None def _on_java_trace(self): should_request_classes = self._app_window.java_trace_panel is None self._app_window.show_main_tab('java-trace') if should_request_classes: self.dwarf.dwarf_api('enumerateJavaClasses') def _on_java_classes(self): self._app_window.show_main_tab('jvm-inspector') self.dwarf.dwarf_api('enumerateJavaClasses') def _on_devdlg_closed(self): if self.dwarf.device is None: self.stop_session()
class ApkList(DwarfListView): """ Displays installed APKs """ onApkSelected = pyqtSignal(list, name='onApkSelected') def __init__(self, parent=None, show_path=True): super(ApkList, self).__init__(parent=parent) self.adb = Adb() if not self.adb.available(): return self.retrieve_thread = PackageRetrieveThread(self.adb) if self.retrieve_thread is not None: self.retrieve_thread.onAddPackage.connect(self._on_addpackage) if show_path: self.apk_model = QStandardItemModel(0, 2) else: self.apk_model = QStandardItemModel(0, 1) self.apk_model.setHeaderData(0, Qt.Horizontal, 'Name') if show_path: self.apk_model.setHeaderData(1, Qt.Horizontal, 'Path') self.setModel(self.apk_model) self.header().setSectionResizeMode(0, QHeaderView.ResizeToContents) self.doubleClicked.connect(self._on_apk_selected) if self.retrieve_thread is not None: if not self.retrieve_thread.isRunning(): self.retrieve_thread.start() # ************************************************************************ # **************************** Functions ********************************* # ************************************************************************ def refresh(self): """ Refresh Packages """ if self.retrieve_thread is not None: if not self.retrieve_thread.isRunning(): self.clear() self.retrieve_thread.start() # ************************************************************************ # **************************** Handlers ********************************** # ************************************************************************ def _on_addpackage(self, package): if package: name = QStandardItem() name.setText(package[0]) if self.apk_model.columnCount() == 2: path = QStandardItem() path.setText(package[1]) self.apk_model.appendRow([name, path]) else: self.apk_model.appendRow([name]) def _on_apk_selected(self, model_index): item = self.apk_model.itemFromIndex(model_index).row() if item != -1: package = self.apk_model.item(item, 0).text() if self.apk_model.columnCount() == 2: path = self.apk_model.item(item, 1).text() self.onApkSelected.emit([package, path]) else: self.onApkSelected.emit([package, None])
class AndroidSession(Session): """ All Android Stuff goes here if u look for something android related its here then """ 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()) self._smali_thread = None @property def session_ui_sections(self): # what sections we want in session_ui return [ 'hooks', 'bookmarks', 'threads', 'registers', 'debug', 'console', 'watchers', 'modules', 'jvm-inspector', 'jvm-debugger', 'ranges', 'backtrace' ] @property def non_closable(self): return ['debug', 'ranges', 'modules', 'jvm-inspector', 'jvm-debugger'] @property def session_type(self): """ return session name to show in menus etc """ return 'android' @property def device_manager_type(self): return 'usb' @property def frida_device(self): return frida.get_usb_device() def _setup_menu(self): """ Build Menus """ # additional menus file_menu = QMenu('&Device') save_apk = QAction("&Save APK", self) save_apk.triggered.connect(self.save_apk) decompile_apk = QAction("&Decompile APK", self) decompile_apk.triggered.connect(self.decompile_apk) file_menu.addAction(save_apk) file_menu.addAction(decompile_apk) self._menu.append(file_menu) super()._setup_menu() java_menu = QMenu('&Java') java_menu.addAction('Trace', self._on_java_trace) java_menu.addSeparator() java_menu.addAction('Classes', self._on_java_classes) self._menu.append(java_menu) def start(self, args): super().start(args) self.adb.device = self.dwarf.device def decompile_apk(self): apk_dlg = ApkListDialog(self._app_window) apk_dlg.onApkSelected.connect(self._decompile_package) apk_dlg.show() def _decompile_package(self, data): package, path = data if path is not None: # todo: make qthread AndroidDecompileUtil.decompile(self.adb, path) def save_apk(self): apk_dlg = ApkListDialog(self._app_window) apk_dlg.onApkSelected.connect(self._save_package) apk_dlg.show() def _save_package(self, data): package, path = data if path is not None: result = QFileDialog.getSaveFileName( caption='Location to save ' + package, directory='./' + package + '.apk', filter='*.apk') if result and result[0]: self.adb.pull(path, result[0]) def _on_proc_selected(self, data): super()._on_proc_selected(data) device, pid = data if device: self.adb.device = device.id def _on_spawn_selected(self, data): device, package_name, break_at_start = data if device: self.adb.device = device.id self.dwarf.device = device if package_name: # smalistuff if self._smali_thread is None: self._app_window.show_progress('Baksmali ' + package_name + ' ...') self._smali_thread = SmaliThread(self, device.id, package_name) self._smali_thread.onError.connect( self._app_window.hide_progress) self._smali_thread.onFinished.connect( self._app_window.hide_progress) self._smali_thread.start() 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_java_classes() def _on_java_trace(self): tag = 'jvm-tracer' should_request_classes = \ self._app_window.java_trace_panel is None or tag not in self._app_window.ui_elements self._app_window.show_main_tab(tag) if should_request_classes: self.dwarf.dwarf_api('enumerateJavaClasses') def _on_java_classes(self): self._app_window.show_main_tab('jvm-inspector') self.dwarf.dwarf_api('enumerateJavaClasses')
def __init__(self, parent=None, device_id=None, package_name=None): super(SmaliThread, self).__init__(parent) self._adb = Adb() self._adb.device = device_id self._package_name = package_name
class AndroidSession(Session): """ All Android Stuff goes here if u look for something android related its here then """ def __init__(self, app_window): super(AndroidSession, self).__init__(app_window) self._app_window = app_window self.adb = Adb() if not self.adb.is_adb_available(): utils.show_message_box(self.adb.get_states_string()) self._device_window = DeviceWindow(self._app_window, 'usb') # main menu every session needs self._menu = [QMenu(self.session_type + ' Session')] #self._menu[0].addAction('Save Session', self._save_session) self._menu[0].addAction('Close Session', self.stop_session) @property def session_ui_sections(self): # what sections we want in session_ui return [ 'hooks', 'threads', 'registers', 'memory', 'console', 'watchers' ] @property def session_type(self): """ return session name to show in menus etc """ return 'Android' @property def main_menu(self): """ return our created menu """ return self._menu def initialize(self, config): # session supports load/save then use config # setup ui etc for android self._setup_menu() # all fine were done wait for ui_ready self.onCreated.emit() def _setup_menu(self): """ Build Menus """ # additional menus file_menu = QMenu('&Device') save_apk = QAction("&Save APK", self) save_apk.triggered.connect(self.save_apk) decompile_apk = QAction("&Decompile APK", self) decompile_apk.triggered.connect(self.decompile_apk) file_menu.addAction(save_apk) file_menu.addAction(decompile_apk) self._menu.append(file_menu) process_menu = QMenu('&Process') process_menu.addAction('Resume', self._on_proc_resume, Qt.Key_F5) process_menu.addAction('Restart', self._on_proc_restart, Qt.Key_F9) process_menu.addAction('Detach', self._on_detach, Qt.Key_F10) self._menu.append(process_menu) java_menu = QMenu('&Java') java_menu.addAction('Trace', self._on_java_trace) java_menu.addSeparator() java_menu.addAction('Classes', self._on_java_classes) self._menu.append(java_menu) def stop_session(self): # cleanup ur stuff # end session super().stop() def start(self, args): self.dwarf.onScriptDestroyed.connect(self.stop) if args.package is None: self._device_window.setModal(True) self._device_window.onSelectedProcess.connect( self.on_proc_selected) self._device_window.onSpwanSelected.connect(self.on_spawn_selected) self._device_window.onClosed.connect(self._on_devdlg_closed) self._device_window.show() else: self.dwarf.device = frida.get_usb_device() if not args.spawn: print('* Trying to attach to {0}'.format(args.package)) ret_val = self.dwarf.attach(args.package, args.script, False) if ret_val == 2: print('Failed to attach: use -sp to force spawn') self.stop() exit() else: print('* Trying to spawn {0}'.format(args.package)) ret_val = self.dwarf.spawn(args.package, args.script) if ret_val != 0: print('-failed-') exit(ret_val) def decompile_apk(self): apk_dlg = ApkListDialog(self._app_window) apk_dlg.onApkSelected.connect(self._decompile_package) apk_dlg.show() """ packages = self.adb.list_packages() if packages: accept, items = ListDialog.build_and_show( self.build_packages_list, packages, double_click_to_accept=True) if accept: if len(items) > 0: path = items[0].get_apk_path() AndroidDecompileUtil.decompile(self.adb, path)""" def _decompile_package(self, data): package, path = data if path is not None: # todo: make qthread AndroidDecompileUtil.decompile(self.adb, path) def save_apk(self): apk_dlg = ApkListDialog(self._app_window) apk_dlg.onApkSelected.connect(self._save_package) apk_dlg.show() def _save_package(self, data): package, path = data if path is not None: result = QFileDialog.getSaveFileName( caption='Location to save ' + package, directory='./' + package + '.apk', filter='*.apk') if result and result[0]: self.adb.pull(path, result[0]) def on_proc_selected(self, data): device, pid = data if device: self.dwarf.device = device if pid: self.dwarf.attach(pid) def on_spawn_selected(self, data): device, package_name = data if device: self.dwarf.device = device if package_name: if self.dwarf.spawn(package=package_name): self.stop() # smalistuff self._app_window.show_progress('Baksmali ' + package_name + ' ...') _smali_thread = SmaliThread(self, package_name) _smali_thread.onError.connect(self._app_window.hide_progress) _smali_thread.onFinished.connect(self._app_window.hide_progress) _smali_thread.start() self._on_java_classes() def _on_proc_resume(self, tid=0): if tid == 0: self._app_window.contexts_list_panel.clear() self._app_window.context_panel.clear() # self._app_window.backtrace_panel.setRowCount(0) self._app_window.memory_panel.clear_panel() self.dwarf.contexts.clear() self.dwarf.dwarf_api('release', tid) def _on_proc_restart(self): self.dwarf.dwarf_api('restart') self._on_proc_resume() def _on_detach(self): self.dwarf.detach() def _on_java_trace(self): should_request_classes = self._app_window.java_trace_panel is None if self._app_window.java_trace_panel is None: self._app_window._create_ui_elem('java-trace') self._app_window.show_main_tab('java-trace') if should_request_classes: self.dwarf.dwarf_api('enumerateJavaClasses') def _on_java_classes(self): #should_request_classes = self._app_window.java is None if self._app_window.java_inspector_panel is None: self._app_window._create_ui_elem('java-inspector') self._app_window.show_main_tab('java-inspector') self.dwarf.dwarf_api('enumerateJavaClasses') def _on_devdlg_closed(self): if self.dwarf.device is None: self.stop_session()
def __init__(self, parent=None, package_name=None): super(SmaliThread, self).__init__(parent) self._adb = Adb() self._package_name = package_name if not self._adb.available(): return
class DeviceBar(QWidget): onDeviceUpdated = pyqtSignal() def __init__(self, parent=None, device_type='usb'): super().__init__(parent=parent) if device_type == 'local': return self.parent = parent self.wait_for_devtype = device_type self.is_waiting = True self._adb = Adb() self._git = Git() self.setAutoFillBackground(True) self.setStyleSheet( 'background-color: crimson; color: white; font-weight: bold; margin: 0; padding: 10px;' ) self.setup() self._timer = QTimer() self._timer.setInterval(500) self._timer.timeout.connect(self._on_timer) self._timer.start() self._timer_step = 0 frida.get_device_manager().on('added', self._on_device) frida.get_device_manager().on('removed', self._on_device) self.devices_thread = DevicesUpdateThread(self) self.devices_thread.onAddDevice.connect(self.on_add_deviceitem) self._update_thread = FridaUpdateThread(self) self._update_thread.on_status_text.connect(self._update_statuslbl) self._update_thread.on_finished.connect(self._frida_updated) self._update_thread.onError.connect(self._on_download_error) self.updated_frida_version = '' self.updated_frida_assets_url = {} remote_frida = self._git.get_frida_version() if remote_frida is None: self.updated_frida_version = '' self.updated_frida_assets_url.clear() else: remote_frida = remote_frida[0] self.updated_frida_version = remote_frida['tag_name'] for asset in remote_frida['assets']: try: name = asset['name'] tag_start = name.index('android-') if name.index('server') >= 0: tag = name[tag_start + 8:-3] self.updated_frida_assets_url[tag] = asset[ 'browser_download_url'] except ValueError: pass def setup(self): """ Setup ui """ h_box = QHBoxLayout() h_box.setContentsMargins(0, 0, 0, 0) self.update_label = QLabel('Waiting for Device') self.update_label.setFixedWidth(self.parent.width()) self.update_label.setOpenExternalLinks(True) self.update_label.setTextFormat(Qt.RichText) self.update_label.setFixedHeight(35) self.update_label.setTextInteractionFlags(Qt.TextBrowserInteraction) self._install_btn = QPushButton('Install Frida', self.update_label) self._install_btn.setStyleSheet('padding: 0; border-color: white;') self._install_btn.setGeometry(self.update_label.width() - 110, 5, 100, 25) self._install_btn.clicked.connect(self._on_install_btn) self._install_btn.setVisible(False) self._start_btn = QPushButton('Start Frida', self.update_label) self._start_btn.setStyleSheet('padding: 0; border-color: white;') self._start_btn.setGeometry(self.update_label.width() - 110, 5, 100, 25) self._start_btn.clicked.connect(self._on_start_btn) self._start_btn.setVisible(False) self._update_btn = QPushButton('Update Frida', self.update_label) self._update_btn.setStyleSheet('padding: 0; border-color: white;') self._update_btn.setGeometry(self.update_label.width() - 110, 5, 100, 25) self._update_btn.clicked.connect(self._on_install_btn) self._update_btn.setVisible(False) self._restart_btn = QPushButton('Restart Frida', self.update_label) self._restart_btn.setStyleSheet('padding: 0; border-color: white;') self._restart_btn.setGeometry(self.update_label.width() - 110, 5, 100, 25) self._restart_btn.clicked.connect(self._on_restart_btn) self._restart_btn.setVisible(False) h_box.addWidget(self.update_label) self.setLayout(h_box) def on_add_deviceitem(self, device_name, device_type): """ Adds an Item to the DeviceComboBox """ if device_type == self.wait_for_devtype: self._timer_step = -1 self.is_waiting = False self.update_label.setStyleSheet('background-color: yellowgreen;') self.update_label.setText('Device found: ' + device_name) self._adb._check_requirements() if self._adb.available(): device_frida = self._adb.get_frida_version() if device_frida is None: self._install_btn.setVisible(True) else: if self.updated_frida_version != device_frida: self._update_btn.setVisible(True) if self._adb.is_frida_running(): self.onDeviceUpdated.emit() elif device_frida and not self._adb.is_frida_running(): self._start_btn.setVisible(True) elif device_frida and self._adb.is_frida_running(): self._restart_btn.setVisible(True) self.onDeviceUpdated.emit() def _on_timer(self): if self._timer_step == -1: self._timer.stop() return if self._timer_step == 0: self.update_label.setText(self.update_label.text() + ' .') self._timer_step = 1 elif self._timer_step == 1: self.update_label.setText(self.update_label.text() + '.') self._timer_step = 2 elif self._timer_step == 2: self.update_label.setText(self.update_label.text() + '.') self._timer_step = 3 else: self.update_label.setText( self.update_label.text()[:-self._timer_step]) self._timer_step = 0 if self.is_waiting and self.devices_thread is not None: if not self.devices_thread.isRunning(): self.devices_thread.start() def _on_download_error(self, text): self._timer_step = -1 self.update_label.setStyleSheet('background-color: crimson;') self.update_label.setText(text) self._install_btn.setVisible(True) self._update_btn.setVisible(False) def _on_device(self): self._timer_step = 4 self.is_waiting = True self._on_timer() def _on_install_btn(self): # urls are empty if not self.updated_frida_assets_url: return arch = self._adb.get_device_arch() request_url = '' if arch is not None and len(arch) > 1: arch = arch.join(arch.split()) if arch == 'arm64' or arch == 'arm64-v8a': request_url = self.updated_frida_assets_url['arm64'] elif arch == 'armeabi-v7a': request_url = self.updated_frida_assets_url['arm'] else: if arch in self.updated_frida_assets_url: request_url = self.updated_frida_assets_url[arch] try: if self._adb.available() and request_url.index( 'https://') == 0: self._install_btn.setVisible(False) self._update_btn.setVisible(False) if self._update_thread is not None: if not self._update_thread.isRunning(): self._update_thread.frida_url = request_url self._update_thread.adb = self._adb self._update_thread.start() except ValueError: # something wrong in .git_cache folder print("request_url not set") def _update_statuslbl(self, text): self._timer.stop() self._timer_step = 0 self._timer.start() self.update_label.setText(text) def _frida_updated(self): self._timer_step = 3 self.is_waiting = True self._on_timer() def _on_start_btn(self): if self._adb.available(): self._start_btn.setVisible(False) if self._adb.start_frida(): self.onDeviceUpdated.emit() else: self._start_btn.setVisible(True) def _on_restart_btn(self): if self._adb.available(): self._restart_btn.setVisible(False) if self._adb.start_frida(restart=True): self._restart_btn.setVisible(True) self.onDeviceUpdated.emit()
methodString = enable while (True): result = QcUsbSwitch.SendCommandAndGetResponse(methodString) if not result.Status.HasError(): break return result @staticmethod def SendCommandAndGetResponse(methodStrings, timeout=30): executionString = CommonApplicationUtilities._ToolsPath + "QcUSBSwitchTool\\QcUSBSwitchTool.exe " + methodStrings logger.debug("Executing Command :" + executionString) result = CommandLine.RunCommand(executionString, timeout) if (result.Status.HasError() or (not 'Success' in result.CmdResult.Output)): logger.error(result.CmdResult.Output) result.Status.AddError(result.CmdResult.Output) return result if __name__ == '__main__': for i in range(10): QcUsbSwitch.SetUsbConnection('usb_on') result = Adb.IsDeviceDetected() logger.info("first time: " + str(result.IsSuccess())) if result.HasError(): logger.info("set usb on again") QcUsbSwitch.SetUsbConnection('usb_on') result = Adb.IsDeviceDetected() logger.info("second time: " + str(result.IsSuccess()))
def InitEnvironmnet(self): if 'KratosLite' in TestSuiteConfig.HardwareType: try: #self.PowerHandler = KratosLite() self.PowerHandler = PTTKratoslite() result = self.PowerHandler.SetConfigurationFile( TestSuiteConfig.ChannelConfiguration) # if result.HasError(): # return result result = self.PowerHandler.PowerOn() result = self.PowerHandler.UsbOn() result = Adb.IsDeviceDetected() if result.HasError(): logger.info("set usb on again") QcUsbSwitch.SetUsbConnection('usb_on') result = Adb.IsDeviceDetected() logger.info("second time: " + str(result.IsSuccess())) else: logger.info("first time: " + str(result.IsSuccess())) result = Adb.SetAdbRoot() if result.HasError(): return result result = Adb.SetAdbRemount() if result.HasError(): return result except Exception as e: return StatusResult.Error('Failed to initialize KRATOSLITE: ', str(e)) elif 'Kratos' in TestSuiteConfig.HardwareType: logger.info("----------supply with Kratos--------------") try: #self.PowerHandler = Kratos() self.PowerHandler = PTTKratos() result = self.PowerHandler.SetConfigurationFile( TestSuiteConfig.ChannelConfiguration) # if result.HasError(): # return result result = self.PowerHandler.PowerOn() result = self.PowerHandler.UsbOn() except Exception as e: logger.info(str(e)) return StatusResult.Error('Failed to initialize KRATOS: ', str(e)) elif 'Monitor' in TestSuiteConfig.HardwareType: try: self.PowerHandler = PTTPowerMonitor() except Exception as e: logger.info(str(e)) return StatusResult.Error( 'Failed to initialize PowerMonitor: ', str(e)) else: logger.error( "Can't support hardware type, please check TestSuiteConfig.HardwareType" ) return logger.info(TestSuiteConfig.HardwareType + " : initialization successful.") logger.info("Waiting for device ...") result = Adb.WaitForDevice(30) logger.info("wait for device ready...") result = AdbSettings.ReMountDevice() if result.HasError(): logger.error("Unable to set root & remount privileges") self.Wakelock() self.Discharging() logger.info("Disable charging & Enable wakelock")