def run(self): if self._adb.device is None: return 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, *args, **kwargs): super().__init__(*args, **kwargs) self.process = None if os.name != 'nt': utils.do_shell_command("pkill radare2") else: utils.do_shell_command("tskill radare2")
def _update(): if os.path.exists('frida'): os.remove('frida') r = None arch = self.app.get_adb().get_device_arch().replace('\n', '').replace('\t', '')\ .replace(' ', '').replace('\r', '') if arch == 'arm64' or arch == 'arm64-v8a': r = requests.get(self.updated_frida_assets_url['arm64'], stream=True) elif arch == 'armeabi-v7a': r = requests.get(self.updated_frida_assets_url['arm'], stream=True) else: if arch in self.updated_frida_assets_url: r = requests.get(self.updated_frida_assets_url[arch], stream=True) if r is not None: with open('frida.xz', 'wb') as f: for chunk in r.iter_content(chunk_size=1024): if chunk: f.write(chunk) res = utils.do_shell_command('unxz frida.xz') if len(res) == 0: res = self.app.get_adb().mount_system() if res is None or len(res) == 0: self.app.get_adb().push('frida', '/sdcard/') self.app.get_adb().su('killall -9 frida', stdout=subprocess.DEVNULL) self.app.get_adb().su('mv /sdcard/frida /system/xbin/frida', stdout=subprocess.DEVNULL) self.app.get_adb().su('chmod 755 /system/xbin/frida', stdout=subprocess.DEVNULL) self.update_frida_version() self.app.get_adb().su('frida -D', stdout=subprocess.DEVNULL) os.remove('frida') else: os.remove('frida.xz') self.update_frida_version()
def run(self): self.on_status_text.emit('fetching commit list...') try: utils.do_shell_command('git --version') except IOError as io_error: if io_error.errno == 2: # git command not available self.on_status_text.emit( 'error: git not available on your system') return _git = Git() data = _git.get_dwarf_commits() if data is None: self.on_status_text.emit('Failed to fetch commit list. Try later.') return most_recent_remote_commit = '' most_recent_local_commit = utils.do_shell_command( 'git log -1 master --pretty=format:%H') most_recent_date = '' for commit in data: if most_recent_remote_commit == '': most_recent_remote_commit = commit['sha'] if most_recent_remote_commit != most_recent_local_commit: self.on_update_available.emit() commit = commit['commit'] date = commit['committer']['date'].split('T') if most_recent_date != date[0]: if most_recent_date != '': self.on_add_commit.emit('', True) self.on_add_commit.emit(date[0], True) most_recent_date = date[0] s = ('{0} - {1} ({2})'.format(date[1][:-1], commit['message'], commit['author']['name'])) self.on_add_commit.emit(s, False) if most_recent_remote_commit != most_recent_local_commit: self.on_finished.emit( 'There is an newer Version available... You can use the UpdateButton in Menu' ) else: # keep: it clears status text self.on_finished.emit('')
def __init__(self, app): self.app = app try: adb = utils.do_shell_command('adb --version') self.adb_available = adb.index('Android Debug Bridge') >= 0 except: self.adb_available = False
def _do_adb_command(self, cmd, stdout=subprocess.PIPE): res = utils.do_shell_command(cmd, stdout=stdout) try: if res.index('no device') >= 0: return None return res except: return res
def decompile(adb, apk_path): if not os.path.exists('.decompile'): os.mkdir('.decompile') adb.pull(apk_path, '.decompile/base.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('d2j-dex2jar.sh %s' % '.decompile/base.apk -o .decompile/base.jar -f') if not external_tools.tool_exist('luyten.jar'): external_tools.get_tool( 'https://github.com/deathmarine/Luyten/releases/download/v0.5.3/luyten-0.5.3.jar', 'luyten.jar') java_version = utils.do_shell_command('java -version') try: java_version.index('java version') except: utils.show_message_box('failed to find java') return utils.do_shell_command( 'java -jar tools/luyten.jar .decompile/base.jar &')
def _do_adb_command(self, cmd, timeout=60): if not self._adb_available: return None res = utils.do_shell_command(cmd, timeout=timeout) if res is not None and 'no device' in res: return None return res
def _do_adb_command(self, cmd, timeout=60): """ helper for calling adb """ if not self.is_adb_available(): return None res = utils.do_shell_command(cmd, timeout=timeout) if res is not None and 'no device' in res: return None return res
def pip_install_package(package_name): try: from lib.utils import do_shell_command res = do_shell_command('pip3 install ' + package_name + ' --upgrade --user') if 'Successfully installed' in res: return True elif 'Requirement already up-to-date' in res: return True else: return False except Exception: # pylint: disable=broad-except return False
def _do_adb_command(self, cmd, timeout=60): """ helper for calling adb """ if not self.is_adb_available(): return None # TODO: for android sdk emulator its using -e res = utils.do_shell_command('adb -s ' + self._device_serial + ' ' + cmd, timeout=timeout) if res is not None and 'no device' in res: return None return res
def run(self): self.on_status_text.emit('updating dwarf...') try: utils.do_shell_command('git --version') except IOError as io_error: if io_error.errno == 2: # git command not available self.on_status_text.emit('error while updating: git not available on your system') self.on_finished.emit('error while updating: git not available on your system') return utils.do_shell_command('git fetch -q https://github.com/iGio90/Dwarf.git') utils.do_shell_command('git checkout -f -q master') utils.do_shell_command('git reset --hard FETCH_HEAD') sha = utils.do_shell_command('git log -1 master --pretty=format:%H') s = ('Dwarf updated to commit := {0} - Please restart...'.format(sha)) self.on_status_text.emit(s) self.on_finished.emit(sha)
def list_packages(self): if not self.adb_available: utils.show_message_box('adb not found') return None packages = utils.do_shell_command('adb shell pm list packages -f').split('\n') ret = [] for package in packages: parts = package.split(':') if len(parts) < 2: continue needed = parts[1].split('.apk=') p = AndroidPackage() p.path = needed[0] + '.apk' p.package = needed[1] ret.append(p) return ret
def update_commits(self): r = None try: r = requests.get( 'https://api.github.com/repos/iGio90/dwarf/commits') except: pass if r is None or r.status_code != 200: q = NotEditableListWidgetItem( 'Failed to fetch commit list. Try later.') q.setFlags(Qt.NoItemFlags) self.commit_list.addItem(q) return most_recent_remote_commit = '' most_recent_local_commit = utils.do_shell_command( 'git log -1 master --pretty=format:%H') most_recent_date = '' for commit in r.json(): if most_recent_remote_commit == '': most_recent_remote_commit = commit['sha'] if most_recent_remote_commit != most_recent_local_commit: self.dwarf_update_button.setVisible(True) q = NotEditableListWidgetItem('') q.setFlags(Qt.NoItemFlags) self.commit_list.addItem(q) commit = commit['commit'] date = commit['committer']['date'].split('T') if most_recent_date != date[0]: if most_recent_date != '': q = NotEditableListWidgetItem('') q.setFlags(Qt.NoItemFlags) self.commit_list.addItem(q) q = NotEditableListWidgetItem(date[0]) q.setFlags(Qt.NoItemFlags) self.commit_list.addItem(q) most_recent_date = date[0] q = NotEditableListWidgetItem( '%s - %s (%s)' % (date[1][:-1], commit['message'], commit['author']['name'])) q.setFlags(Qt.NoItemFlags) q.setForeground(Qt.white) self.commit_list.addItem(q)
def _check_min_required(self): """ Checks if adb is available """ self._adb_available = False try: adb_version = utils.do_shell_command('adb --version') if adb_version: if adb_version and 'Android Debug Bridge' in adb_version: self._adb_available = True else: self._adb_available = False # io error is handled here not in do_shell_command # if adb isnt there it gives file not found except IOError as io_error: # file not found if io_error.errno == 2: self._adb_available = False
def update_dwarf(self, item): self.commit_list.clear() q = NotEditableListWidgetItem('Updating dwarf...') q.setFlags(Qt.NoItemFlags) self.commit_list.addItem(q) utils.do_shell_command('git fetch -q https://github.com/iGio90/Dwarf.git', stdout=subprocess.DEVNULL) utils.do_shell_command('git checkout -f -q master', stdout=subprocess.DEVNULL) utils.do_shell_command('git reset --hard FETCH_HEAD', stdout=subprocess.DEVNULL) sha = utils.do_shell_command('git log -1 master --pretty=format:%H') print('') print('') print('Dwarf updated to commit := ' + sha) print('') print('') sys.exit(0)
def update_commits(self): data = self.app.get_dwarf().get_git().get_dwarf_commits() if data is None: q = NotEditableListWidgetItem( 'Failed to fetch commit list. Try later.') q.setFlags(Qt.NoItemFlags) self.commit_list.addItem(q) return most_recent_remote_commit = '' most_recent_local_commit = utils.do_shell_command( 'git log -1 master --pretty=format:%H') most_recent_date = '' for commit in data: if most_recent_remote_commit == '': most_recent_remote_commit = commit['sha'] if most_recent_remote_commit != most_recent_local_commit: self.dwarf_update_button.setVisible(True) q = NotEditableListWidgetItem('') q.setFlags(Qt.NoItemFlags) self.commit_list.addItem(q) commit = commit['commit'] date = commit['committer']['date'].split('T') if most_recent_date != date[0]: if most_recent_date != '': q = NotEditableListWidgetItem('') q.setFlags(Qt.NoItemFlags) self.commit_list.addItem(q) q = NotEditableListWidgetItem(date[0]) q.setFlags(Qt.NoItemFlags) self.commit_list.addItem(q) most_recent_date = date[0] q = NotEditableListWidgetItem( '%s - %s (%s)' % (date[1][:-1], commit['message'], commit['author']['name'])) q.setFlags(Qt.NoItemFlags) q.setForeground(Qt.white) self.commit_list.addItem(q)
def run(self): """Runs the UpdateThread """ self.on_status_text.emit('downloading latest frida server... please wait...') try: request = requests.get(self.frida_url, stream=True) except requests.ConnectionError: self.on_status_text.emit('unable to download latest frida binary') return if request is not None and request.status_code == 200: with open('frida.xz', 'wb') as frida_archive: num = 0 for chunk in request.iter_content(chunk_size=1024): if num == 0: self.on_status_text.emit('downloading latest frida server... please wait.') num += 1 if num == 1: self.on_status_text.emit('downloading latest frida server... please wait..') num += 1 if num == 2: self.on_status_text.emit('downloading latest frida server... please wait...') num += 0 if chunk: frida_archive.write(chunk) self.on_status_text.emit('extracting latest frida server... please wait...') # on windows no unxz command # todo: use lzma on all systems if os.name == 'nt': import lzma with lzma.open('frida.xz') as frida_archive: with open('frida', 'wb') as frida_binary: frida_binary.write(frida_archive.read()) res = '' os.remove('frida.xz') else: res = utils.do_shell_command('unxz frida.xz') if not res: self.on_status_text.emit('mounting devices filesystem... please wait...') # mount system rw res = self.adb.mount_system() if res is None or not res: self.on_status_text.emit('pushing to device... please wait...') # push file to device self.adb.push('frida', '/sdcard/') self.on_status_text.emit('setting up and starting frida server... please wait...') # kill frida self.adb.kill_frida() # copy file note: mv give sometimes a invalid id error self.adb.su_cmd('cp /sdcard/frida /system/xbin/frida') # remove file self.adb.su_cmd('rm /sdcard/frida') # make it executable self.adb.su_cmd('chmod 755 /system/xbin/frida') # start it if not self.adb.start_frida(): self.on_status_text('failed to start frida') os.remove('frida') else: os.remove('frida.xz') else: self.on_status_text.emit('failed to download latest frida server') self.on_finished.emit() self.frida_url = ''
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 # 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') # 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 /system') 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 kill_package(self, package): if not self.adb_available: utils.show_message_box('adb not found') return None utils.do_shell_command("adb shell am force-stop " + package)
def push(self, path, dest): if not self.adb_available: utils.show_message_box('adb not found') return None return utils.do_shell_command('adb push %s %s' % (path, dest))
def get_frida_version(self): if not self.adb_available: utils.show_message_box('adb not found') return None return utils.do_shell_command('adb shell frida --version')
def _check_requirements(self): # pylint: disable=too-many-branches, too-many-statements """ Checks for adb and root on device """ self._adb_available = False self._dev_emu = False self._is_root = False self._is_su = False try: adb_version = utils.do_shell_command('adb --version') if adb_version is not None: if adb_version and 'Android Debug Bridge' in adb_version: self._adb_available = True else: self._adb_available = False # io error is handled here not in do_shell_command # if adb isnt there it gives file not found except IOError as io_error: # file not found if io_error.errno == 2: self._adb_available = False if self._adb_available: # try some su command res = utils.do_shell_command( 'adb shell su -c \'mount -o ro,remount /system\'') if res is not None: # adb not authorized if res and 'device unauthorized' in 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 res and 'no devices/emulators' in res: self._dev_emu = False elif res and 'device not found' in res: self._dev_emu = False else: self._dev_emu = True # user can run su? if res and 'Permission denied' in res: self._is_su = False elif res and 'su: not found' in res: self._is_su = False else: if self._dev_emu: self._is_su = 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 = utils.do_shell_command( 'adb shell mount -o ro,remount /system') if res is not None: 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 print('rootcheck: %s' % res) if self._dev_emu: # get some infos about the device and keep for later self._sdk_version = self._do_adb_command( 'adb shell getprop ro.build.version.sdk') self._sdk_version = self._sdk_version.join( self._sdk_version.split()) # cleans '\r\n' self._android_version = self._do_adb_command( 'adb shell getprop ro.build.version.release') 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 if self._oreo_plus: res = self._do_adb_command('adb shell pidof') self._have_pidof = 'not found' not in res # check for root if self._is_root: res = self.su_cmd('id') self._is_root = 'uid=0' in res
def su(self, cmd, stdout=subprocess.PIPE): if not self.adb_available: utils.show_message_box('adb not found') return None return utils.do_shell_command('adb shell su -c "' + cmd + '"', stdout=stdout)
def run_dwarf(): """ fire it up """ #os.environ["QT_AUTO_SCREEN_SCALE_FACTOR"] = "1" os.environ["QT_SCALE_FACTOR"] = "1" os.environ["QT_AUTO_SCREEN_SCALE_FACTOR"] = "0" os.environ["QT_SCREEN_SCALE_FACTORS"] = "1" args = process_args() #_check_dependencies() # not enabled atm from lib import utils from lib.git import Git from lib.prefs import Prefs from ui.app import AppWindow _prefs = Prefs() local_update_disabled = _prefs.get('disable_local_frida_update', False) if not local_update_disabled: _git = Git() import frida remote_frida = _git.get_frida_version() local_frida = frida.__version__ if remote_frida and local_frida != remote_frida[0]['tag_name']: print('Updating local frida version to ' + remote_frida[0]['tag_name']) try: res = utils.do_shell_command('pip3 install frida --upgrade --user') if 'Successfully installed frida-' + remote_frida[0]['tag_name'] in res: _on_restart() elif 'Requirement already up-to-date' in res: if os.path.exists('.git_cache'): shutil.rmtree('.git_cache', ignore_errors=True) else: print('failed to update local frida') print(res) except Exception as e: # pylint: disable=broad-except, invalid-name print('failed to update local frida') print(str(e)) if os.name == 'nt': # windows stuff import ctypes try: # write ini to show folder with dwarficon folder_stuff = "[.ShellClassInfo]\n" folder_stuff += "IconResource=assets\\dwarf.ico,0\n" folder_stuff += "[ViewState]\n" folder_stuff += "Mode=\n" folder_stuff += "Vid=\n" folder_stuff += "FolderType=Generic\n" try: with open('desktop.ini', 'w') as ini: ini.writelines(folder_stuff) # set fileattributes to hidden + systemfile ctypes.windll.kernel32.SetFileAttributesW( r'desktop.ini', 0x02 | 0x04 ) # FILE_ATTRIBUTE_HIDDEN = 0x02 | FILE_ATTRIBUTE_SYSTEM = 0x04 except PermissionError: # its hidden+system already pass # fix for showing dwarf icon in windows taskbar instead of pythonicon _appid = u'iGio90.dwarf.debugger' ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID( _appid) ctypes.windll.user32.SetProcessDPIAware() except Exception: # pylint: disable=broad-except pass from PyQt5.QtCore import Qt from PyQt5.QtGui import QIcon from PyQt5.QtWidgets import QApplication qapp = QApplication([]) qapp.setDesktopSettingsAware(True) qapp.setAttribute(Qt.AA_EnableHighDpiScaling) qapp.setAttribute(Qt.AA_UseHighDpiPixmaps) qapp.setLayoutDirection(Qt.LeftToRight) qapp.setOrganizationName("https://github.com/iGio90/Dwarf") qapp.setApplicationName("dwarf") # set icon if os.name == "nt" and os.path.exists( utils.resource_path('assets/dwarf.ico')): _icon = QIcon(utils.resource_path('assets/dwarf.ico')) qapp.setWindowIcon(_icon) else: if os.path.exists(utils.resource_path('assets/dwarf.png')): _icon = QIcon(utils.resource_path('assets/dwarf.png')) qapp.setWindowIcon(_icon) app_window = AppWindow(args) app_window.setWindowIcon(_icon) app_window.onRestart.connect(_on_restart) try: sys.exit(qapp.exec_()) except SystemExit as sys_err: if sys_err.code == 0: # thanks for using dwarf print('Thank\'s for using Dwarf\nHave a nice day...') else: # something was wrong print('sysexit with: %d' % sys_err.code)
def _is_frida_running(): # untested utils.do_shell_command( 'ssh -p2222 [email protected] ps -A | grep \'frida\'')
def mount_system(self): if not self.adb_available: utils.show_message_box('adb not found') return None return utils.do_shell_command('adb shell su -c "mount -o rw,remount /system"')
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: date_res = date_res.split(' ') except ValueError: pass # try some su command res = self._do_adb_command('shell su -c date') if res and 'Permission denied' in res: self._is_su = False elif res and 'su: not found' in res: self._is_su = False elif res and 'invalid' in res: res = self._do_adb_command('shell su 0 date') if res: self._alternate_su_binary = True if res is not None: try: res = res.split(' ') except ValueError: pass # check if 'same' results otherwise its no valid result from su -c date if res[len(res) - 1] == date_res[len(date_res) - 1]: # year if res[len(res) - 2] == date_res[len(date_res) - 2]: # timezone if res[len(res) - 4] == date_res[len(date_res) - 4]: # day if res[len(res) - 6] == date_res[len(date_res) - 6]: # month self._is_su = 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 /system') if res is not None: 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 print('rootcheck: %s' % 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 is not None: 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 is not None: 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 root if self._is_root: res = self.su_cmd('id') self._is_root = 'uid=0' in res
def _check_package_version(package_name, min_version): try: if package_name == 'frida': import frida installed_version = frida.__version__ elif package_name == 'capstone': import capstone installed_version = capstone.__version__ elif package_name == 'requests': import requests installed_version = requests.__version__ elif package_name == 'pyqt5': from PyQt5 import QtCore installed_version = QtCore.PYQT_VERSION_STR elif package_name == 'pyperclip': import pyperclip installed_version = pyperclip.__version__ elif package_name == 'unicorn': import unicorn installed_version = unicorn.__version__ if installed_version: installed_version = installed_version.split('.') _min_version = min_version.split('.') needs_update = False if (int(installed_version[0]) < int(_min_version[0])): needs_update = True elif (int(installed_version[0]) <= int(_min_version[0])) and (int(installed_version[1]) < int(_min_version[1])): needs_update = True elif (int(installed_version[1]) <= int(_min_version[1])) and (int(installed_version[2]) < int(_min_version[2])): needs_update = True if needs_update: print('updating ' + package_name + '... to ' + min_version) if pip_install_package(package_name + '>=' + min_version): print('*** success ***') except Exception: # pylint: disable=broad-except # install unicorn on windows if package_name == 'unicorn': if os.name == 'nt': import ctypes is64bit = False if ctypes.sizeof(ctypes.c_void_p) * 8 == 64: is64bit = True # download installer req_url = 'https://github.com/unicorn-engine/unicorn/releases/download/1.0.1/unicorn-1.0.1-python-win32.msi' if is64bit: req_url = 'https://github.com/unicorn-engine/unicorn/releases/download/1.0.1/unicorn-1.0.1-python-win64.msi' import requests request = requests.get(req_url) print('Downloading prebuilt unicorn...') if request is not None and request.status_code == 200: # write installer with open('unicorn-installer.msi', 'wb') as f: for chunk in request.iter_content(chunk_size=1024): if chunk: f.write(chunk) if os.path.exists('unicorn-installer.msi'): from lib.utils import do_shell_command res = do_shell_command('msiexec /i unicorn-installer.msi /l*v unicorn-install.log /qn') if res == '': print('unicorn installed see log ' + os.path.curdir + os.path.sep + 'unicorn-install.log') os.remove('unicorn-installer.msi') print('installing ' + package_name + '...') if pip_install_package(package_name + '>=' + min_version): print('*** success ***')
def get_device_arch(self): if not self.adb_available: utils.show_message_box('adb not found') return None return utils.do_shell_command('adb shell getprop ro.product.cpu.abi')