예제 #1
0
    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
예제 #2
0
 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()
예제 #3
0
 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
예제 #4
0
    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)
예제 #5
0
    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
예제 #6
0
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
예제 #7
0
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
예제 #8
0
    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.'
예제 #9
0
def uninstall_rilcap_shell(devSerialnumber):
    #uninstalls RILCAP - adb shell rilcap ru
    adb.call('shell rilcap ru', devSerialnumber)
예제 #10
0
def uninstall_rilcap_shell(devSerialnumber):
    #uninstalls RILCAP - adb shell rilcap ru
    adb.call('shell rilcap ru', devSerialnumber)