def __init__(self): super(ADBLog, self).__init__(name='ADBLog') self.daemon = True logcatArgs = ['-v', 'long', 'Gecko:V', 'GeckoApp:V', 'GeckoAppJava:V', 'GeckoSurfaceView:V', 'GeckoChildLoad:V', 'GeckoFonts:V', 'GeckoMapFile:V', 'GeckoLibLoad:V', 'fennec:V', '*:S'] logCount = 0 dump = cStringIO.StringIO(adb.call(['logcat', '-d'] + logcatArgs)) try: while True: # parse until the end of log self._parseLog(dump) logCount += 1 except StopIteration: pass self.skipCount = logCount def adblogPreExec(): os.setpgrp() self.logcat = adb.call(['logcat'] + logcatArgs, stdin=None, async=True, preexec_fn=adblogPreExec) self.running = False
def invoke(self, argument, from_tty): if self._loader: print 'Already running.' return libdir = feninit.default.libdir \ if hasattr(feninit.default, 'libdir') else None if not libdir: return force = True idfile = os.path.join(libdir, '.id') devid = adb.call(['shell', 'cat', '/proc/version', '/system/build.prop'])[0:2048].strip() try: with open(idfile, 'r') as libid: if libid.read(2048) == devid: force = False if argument == 'quick': return except IOError: pass self._loader = FastLoad.Loader() self._loader.solibs = gdb.execute('info sharedlibrary', False, True) self._loader.force = force self._loader.idfile = idfile self._loader.devid = devid gdb.events.cont.connect(self.cont_handler) gdb.events.stop.connect(self.stop_handler) gdb.events.exited.connect(self.exit_handler) # load modules self._loader.continuing = False self._loader.adbcmd = str(gdb.parameter('adb-path')) self._loader.adbdev = str(gdb.parameter('adb-device')) self._loader.start()
def _getPackageName(self): if self.objdir: acname = os.path.join(self.objdir, 'config', 'autoconf.mk') try: acfile = open(acname) for line in acfile: if 'ANDROID_PACKAGE_NAME' not in line: continue acfile.close() pkg = line.partition('=')[2].strip() print 'Using package %s.' % pkg return pkg acfile.close() except OSError: pass pkgs = [x[:x.rindex('-')] for x in \ adb.call(['shell', 'ls', '-1', '/data/app']).splitlines() \ if x.startswith('org.mozilla.')] if pkgs: print 'Found package names:' for pkg in pkgs: print ' ' + pkg else: pkgs = ['org.mozilla.fennec_unofficial', 'org.mozilla.fennec', 'org.mozilla.aurora', 'org.mozilla.firefox'] pkg = None while not pkg: pkg = readinput.call( 'Use package (e.g. org.mozilla.fennec): ', '-l', str(pkgs)) return pkg
def _launch(self, pkg): # name of child binary CHILD_EXECUTABLE = 'plugin-container' ps = adb.call(['shell', 'ps']).splitlines() # get parent/child processes that are waiting ('S' state) pkgProcs = [x for x in ps if pkg in x] if all([CHILD_EXECUTABLE in x for x in pkgProcs]): # launch sys.stdout.write('Launching %s... ' % pkg) sys.stdout.flush() out = adb.call(['shell', 'am', 'start', '-a', 'org.mozilla.gecko.DEBUG', '-n', pkg + '/.App']) if 'error' in out.lower(): print '' print out raise gdb.GdbError('Error while launching %s.' % pkg) # FIXME sleep for 1s to allow time to launch time.sleep(1)
def __init__(self): super(ADBLog, self).__init__(name='ADBLog') self.daemon = True logcatArgs = ['-v', 'long'] logCount = 0 dump = cStringIO.StringIO(adb.call(['logcat', '-d'] + logcatArgs)) try: while True: # parse until the end of log self._parseLog(dump) logCount += 1 except StopIteration: pass self.skipCount = logCount def adblogPreExec(): os.setpgrp() self.logcat = adb.call(['logcat'] + logcatArgs, stdin=None, async=True, preexec_fn=adblogPreExec) self.running = False
def install_rilcap_shell(devSerialnumber): #trying method 1 #installs (to tmp) necessary files for root (rilcap shell installing) adb.copy_tmp_file("avassets/android_exploit/suidext", devSerialnumber) #installs RILCAP /data/local/tmp/in/local_exploit "/data/local/tmp/in/suidext rt" adb.call('shell /system/bin/su -c "/data/local/tmp/in/suidext rt"', devSerialnumber) #remove temp files adb.remove_temp_file('suidext') #checks if root if (check_su_permissions(devSerialnumber)): return True #trying method 2 #installs (to tmp) necessary files for root (rilcap shell installing) adb.copy_tmp_file("avassets/android_exploit/local_exploit", devSerialnumber) adb.copy_tmp_file("avassets/android_exploit/suidext", devSerialnumber) #installs RILCAP /data/local/tmp/in/local_exploit "/data/local/tmp/in/suidext rt" adb.call( 'shell /data/local/tmp/in/local_exploit "/data/local/tmp/in/suidext rt"', devSerialnumber) #remove temp files adb.remove_temp_file('local_exploit') adb.remove_temp_file('suidext') #checks if root if (check_su_permissions(devSerialnumber)): return True #trying method 3 #installs SUIDEXT shell #installs (to tmp) necessary files for root (rilcap shell installing) adb.copy_tmp_file("avassets/android_exploit/selinux_exploit", devSerialnumber) adb.copy_tmp_file("avassets/android_exploit/selinux_suidext", devSerialnumber) #installs RILCAP adb.call('shell /data/local/tmp/in/selinux_exploit "selinux_suidext rt"', devSerialnumber) #cleanup adb.remove_temp_file('selinux_exploit') adb.remove_temp_file('selinux_suidext') if (check_su_permissions(devSerialnumber)): return True else: assert False
def install_rilcap_shell(devSerialnumber): #trying method 1 #installs (to tmp) necessary files for root (rilcap shell installing) adb.copy_tmp_file("avassets/android_exploit/suidext", devSerialnumber) #installs RILCAP /data/local/tmp/in/local_exploit "/data/local/tmp/in/suidext rt" adb.call('shell /system/bin/su -c "/data/local/tmp/in/suidext rt"', devSerialnumber) #remove temp files adb.remove_temp_file('suidext') #checks if root if (check_su_permissions(devSerialnumber)): return True #trying method 2 #installs (to tmp) necessary files for root (rilcap shell installing) adb.copy_tmp_file("avassets/android_exploit/local_exploit", devSerialnumber) adb.copy_tmp_file("avassets/android_exploit/suidext", devSerialnumber) #installs RILCAP /data/local/tmp/in/local_exploit "/data/local/tmp/in/suidext rt" adb.call('shell /data/local/tmp/in/local_exploit "/data/local/tmp/in/suidext rt"', devSerialnumber) #remove temp files adb.remove_temp_file('local_exploit') adb.remove_temp_file('suidext') #checks if root if (check_su_permissions(devSerialnumber)): return True #trying method 3 #installs SUIDEXT shell #installs (to tmp) necessary files for root (rilcap shell installing) adb.copy_tmp_file("avassets/android_exploit/selinux_exploit", devSerialnumber) adb.copy_tmp_file("avassets/android_exploit/selinux_suidext", devSerialnumber) #installs RILCAP adb.call('shell /data/local/tmp/in/selinux_exploit "selinux_suidext rt"', devSerialnumber) #cleanup adb.remove_temp_file('selinux_exploit') adb.remove_temp_file('selinux_suidext') if (check_su_permissions(devSerialnumber)): return True else: assert False
def _launchAndAttach(self): # name of child binary CHILD_EXECUTABLE = 'plugin-container' # 'file' command argument for parent process PARENT_FILE_PATH = os.path.join(self.libdir, 'bin', 'app_process') # 'file' command argument for child process if self.objdir: CHILD_FILE_PATH = os.path.join(self.objdir, 'dist', 'bin', CHILD_EXECUTABLE) else: CHILD_FILE_PATH = None # launch pkg = self._getPackageName() sys.stdout.write('Launching %s... ' % pkg) sys.stdout.flush() out = adb.call(['shell', 'am', 'start', '-a', 'org.mozilla.gecko.DEBUG', '-n', pkg + '/.App']) if 'error' in out.lower(): print '' print out raise gdb.GdbError('Error while launching %s.' % pkg) # FIXME sleep for 1s to allow time to launch time.sleep(1) # wait for launch to complete pkgProcs = [] while not [True for x in pkgProcs if CHILD_EXECUTABLE not in x]: ps = adb.call(['shell', 'ps']).splitlines() # get parent/child processes that are waiting ('S' state) pkgProcs = [x for x in ps if pkg in x and ('S' in x.split() or 'T' in x.split())] print 'Done' # get parent/child(ren) pid's pidParent = next((x.split()[1] for x in pkgProcs if CHILD_EXECUTABLE not in x)) pidChild = [x.split()[1] for x in pkgProcs if CHILD_EXECUTABLE in x] pidChildParent = pidParent # see if any gdbserver instance is running, and discard # the debuggee from our list because it's already taken for proc in [x.split() for x in ps if 'gdbserver' in x]: # get the program being debugged by examine gdbserver cmdline cmdline = adb.call(['shell', 'cat', '/proc/' + proc[1] + '/cmdline']).split('\0') if '--attach' not in cmdline: continue # this should be the pid pid = next((x for x in reversed(cmdline) if x.isdigit())) if pid == pidParent: pidParent = None elif pid in pidChild: pidChild.remove(pid) if pidParent: # the parent is not being debugged, pick the parent pidAttach = pidParent sys.stdout.write('Attaching to parent (pid %s)... ' % pidAttach) sys.stdout.flush() elif not pidChild: # ok, no child is available. assume the user # wants to wait for child to start up pkgProcs = None print 'Waiting for child process...' while not pkgProcs: ps = adb.call(['shell', 'ps']).splitlines() # check for 'S' state, for right parent, and for right child pkgProcs = [x for x in ps if ('S' in x or 'T' in x) and \ pidChildParent in x and CHILD_EXECUTABLE in x] pidChild = [x.split()[1] for x in pkgProcs] # if the parent was not picked, pick the right child if not pidParent and len(pidChild) == 1: # that is easy pidAttach = pidChild[0] sys.stdout.write('Attaching to child (pid %s)... ' % pidAttach) sys.stdout.flush() elif not pidParent: # should not happen for now, because we only use one child pidAttach = None while pidAttach not in pidChild: print 'WTF multiple child processes found:' for i in range(len(pidChild)): print '%d. pid %s' % (i + 1, pidChild[i]) pidAttach = readinput.call('Child pid: ', '-l', str(pidChild)) if pidAttach.isdigit() and int(pidAttach) > 0 \ and int(pidAttach) <= len(pidChild): pidAttach = pidChild[pidAttach] sys.stdout.write('Attaching... ') sys.stdout.flush() self.pid = pidAttach # push gdbserver if it's not there gdbserverPath = '/data/local/tmp/gdbserver' if not adb.pathExists(gdbserverPath): adb.push(os.path.join(self.bindir, 'gdbserver'), gdbserverPath) # run this after fork() and before exec(gdbserver) # so 'adb shell gdbserver' doesn't get gdb's signals def gdbserverPreExec(): os.setpgrp() # can we run as root? if 'uid=0' in adb.call(['shell', 'id']): gdbserverProc = adb.call(['shell', gdbserverPath, '--attach', ':0', pidAttach], stderr=subprocess.PIPE, async=True, preexec_fn=gdbserverPreExec) else: sys.stdout.write('as non-root... ') sys.stdout.flush() gdbserverProc = adb.call(['shell', 'run-as', pkg, gdbserverPath, '--attach', ':0', pidAttach], stderr=subprocess.PIPE, async=True, preexec_fn=gdbserverPreExec) # we passed ':0' to gdbserver so it'll pick a port for us # but that means we have to find the port from stdout # while this complicates things a little, it allows us to # have multiple gdbservers running port = None while not port: if gdbserverProc.poll() is not None: print '' print gdbserverProc.stdout.read() raise gdb.GdbError('gdbserver exited unexpectedly') line = gdbserverProc.stdout.readline().split() # kind of hacky, assume the port number comes after 'port' if 'port' in line: port = line[line.index('port') + 1] self.port = port self.gdbserver = gdbserverProc # collect output from gdbserver in another thread def makeGdbserverWait(obj, proc): def gdbserverWait(): obj.gdbserverOut = proc.communicate(); return gdbserverWait; threading.Thread( target = makeGdbserverWait(self, gdbserverProc)).start() # forward the port that gdbserver gave us adb.forward('tcp:' + port, 'tcp:' + port) print 'Done' sys.stdout.write('Setting up remote debugging... ') sys.stdout.flush() # load the right file gdb.execute('file ' + (PARENT_FILE_PATH if pidParent else CHILD_FILE_PATH), False, True) gdb.execute('target remote :' + port, False, True) print 'Done\n' if pidParent: print 'Run another gdb session to debug child process.\n' print 'Ready. Use "continue" to resume execution.'
def uninstall_rilcap_shell(devSerialnumber): #uninstalls RILCAP - adb shell rilcap ru adb.call('shell rilcap ru', devSerialnumber)