Пример #1
0
    def accessibilityGrepHierarchy(self, view, needle):
        a11yLabel = accessibilityLabel(view)
        # if we don't have any accessibility string - we should have some children
        if int(a11yLabel.GetValue(), 16) == 0:
            # We call private method that gives back all visible accessibility children
            # for view iOS 10 and higher
            if fb.evaluateBooleanExpression(
                    "[UIView respondsToSelector:@selector(_accessibilityElementsAndContainersDescendingFromViews:options:sorted:)]"  # noqa B950
            ):
                accessibilityElements = fb.evaluateObjectExpression(
                    "[UIView _accessibilityElementsAndContainersDescendingFromViews:@[(id)%s] options:0 sorted:NO]"  # noqa B950
                    % view)
            else:
                accessibilityElements = fb.evaluateObjectExpression(
                    "[[[UIApplication sharedApplication] keyWindow] _accessibilityElementsInContainer:0 topLevel:%s includeKB:0]"  # noqa B950
                    % view)
            accessibilityElementsCount = fb.evaluateIntegerExpression(
                "[%s count]" % accessibilityElements)
            for index in range(0, accessibilityElementsCount):
                subview = fb.evaluateObjectExpression(
                    "[%s objectAtIndex:%i]" % (accessibilityElements, index))
                self.accessibilityGrepHierarchy(subview, needle)
        elif re.match(r".*" + needle + ".*", a11yLabel.GetObjectDescription(),
                      re.IGNORECASE):
            classDesc = objHelpers.className(view)
            print("({} {}) {}".format(classDesc, view,
                                      a11yLabel.GetObjectDescription()))

            # First element that is found is copied to clipboard
            if not self.foundElement:
                self.foundElement = True
                cmd = 'echo %s | tr -d "\n" | pbcopy' % view
                os.system(cmd)
Пример #2
0
    def run(self, arguments, options):
        control = fb.evaluateInputExpression(arguments[0])
        targets = fb.evaluateObjectExpression(
            "[[{control} allTargets] allObjects]".format(control=control)
        )
        targetCount = fb.evaluateIntegerExpression(
            "[{targets} count]".format(targets=targets)
        )

        for index in range(0, targetCount):
            target = fb.evaluateObjectExpression(
                "[{targets} objectAtIndex:{index}]".format(targets=targets, index=index)
            )
            actions = fb.evaluateObjectExpression(
                "[{control} actionsForTarget:{target} forControlEvent:0]".format(
                    control=control, target=target
                )
            )

            targetDescription = fb.evaluateExpressionValue(
                "(id){target}".format(target=target)
            ).GetObjectDescription()
            actionsDescription = fb.evaluateExpressionValue(
                '(id)[{actions} componentsJoinedByString:@", "]'.format(actions=actions)
            ).GetObjectDescription()

            print(
                "{target}: {actions}".format(
                    target=targetDescription, actions=actionsDescription
                )
            )
Пример #3
0
    def run(self, arguments, options):
        commandForObject, ivarName = arguments

        objectAddress = int(fb.evaluateObjectExpression(commandForObject), 0)

        ivarOffsetCommand = '(ptrdiff_t)ivar_getOffset((void*)object_getInstanceVariable((id){}, "{}", 0))'.format(
            objectAddress, ivarName)
        ivarOffset = int(fb.evaluateExpression(ivarOffsetCommand), 0)

        # A multi-statement command allows for variables scoped to the command,
        # not permanent in the session like $variables.
        ivarSizeCommand = (
            "unsigned int size = 0;"
            'char *typeEncoding = (char *)ivar_getTypeEncoding((void*)class_getInstanceVariable((Class)object_getClass((id){}), "{}"));'
            "(char *)NSGetSizeAndAlignment(typeEncoding, &size, 0);"
            "size").format(objectAddress, ivarName)
        ivarSize = int(fb.evaluateExpression(ivarSizeCommand), 0)

        error = lldb.SBError()
        watchpoint = lldb.debugger.GetSelectedTarget().WatchAddress(
            objectAddress + ivarOffset, ivarSize, False, True, error)

        if error.Success():
            print(
                "Remember to delete the watchpoint using: watchpoint delete {}"
                .format(watchpoint.GetID()))
        else:
            print("Could not create the watchpoint: {}".format(
                error.GetCString()))
Пример #4
0
def _recursiveViewControllerDescriptionWithPrefixAndChildPrefix(
        vc, string, prefix, childPrefix):
    isMac = runtimeHelpers.isMacintoshArch()

    s = "%s%s%s\n" % (
        prefix,
        "" if prefix == "" else " ",
        _viewControllerDescription(vc),
    )

    nextPrefix = childPrefix + "   |"

    numChildViewControllers = fb.evaluateIntegerExpression(
        "(int)[(id)[%s childViewControllers] count]" % (vc))

    for i in range(0, numChildViewControllers):
        viewController = fb.evaluateExpression(
            "(id)[(id)[%s childViewControllers] objectAtIndex:%d]" % (vc, i))
        s += _recursiveViewControllerDescriptionWithPrefixAndChildPrefix(
            viewController, string, nextPrefix, nextPrefix)

    if not isMac:
        isModal = fb.evaluateBooleanExpression(
            "%s != nil && ((id)[(id)[(id)%s presentedViewController] presentingViewController]) == %s"  # noqa B950
            % (vc, vc, vc))

        if isModal:
            modalVC = fb.evaluateObjectExpression(
                "(id)[(id)%s presentedViewController]" % (vc))
            s += _recursiveViewControllerDescriptionWithPrefixAndChildPrefix(
                modalVC, string, childPrefix + "  *M", nextPrefix)
            s += "\n// '*M' means the view controller is presented modally."

    return string + s
Пример #5
0
    def run(self, arguments, options):
        object = fb.evaluateObjectExpression(arguments[0])

        isHidden = fb.evaluateBooleanExpression("[" + object + " isHidden]")
        shouldHide = not isHidden
        for _ in range(0, 2):
            viewHelpers.setViewHidden(object, shouldHide)
            viewHelpers.setViewHidden(object, isHidden)
Пример #6
0
def firstSubviewOfView(view):
    subviews = subviewsOfView(view)
    numViews = fb.evaluateIntegerExpression("[(id)" + subviews + " count]")

    if numViews == 0:
        return None
    else:
        return fb.evaluateObjectExpression("[" + subviews +
                                           " objectAtIndex:0]")
Пример #7
0
 def nextResponder(object):
     command = "[((id){}) nextResponder]".format(object)
     nextResponder = fb.evaluateObjectExpression(command)
     try:
         if int(nextResponder, 0):
             return nextResponder
         else:
             return None
     except Exception:
         return None
Пример #8
0
 def run(self, arguments, options):
     command = arguments[0]
     if len(command.split(".")) == 1:
         lldb.debugger.HandleCommand("po " + command)
     else:
         objectToMessage, keypath = command.split(".", 1)
         object = fb.evaluateObjectExpression(objectToMessage)
         print(
             fb.describeObject('[{} valueForKeyPath:@"{}"]'.format(
                 object, keypath)))
Пример #9
0
    def run(self, arguments, options):
        objectToPrint = fb.evaluateInputExpression(arguments[0])
        pretty = 1 if options.plain is None else 0
        jsonData = fb.evaluateObjectExpression(
            "[NSJSONSerialization dataWithJSONObject:(id){} options:{} error:nil]"
            .format(objectToPrint, pretty))
        jsonString = fb.evaluateExpressionValue(
            "(NSString*)[[NSString alloc] initWithData:(id){} encoding:4]".
            format(jsonData)).GetObjectDescription()

        print(jsonString)
Пример #10
0
    def run(self, arguments, options):
        # Convert to NSObject first to allow for objc runtime to process it
        objectToPrint = fb.evaluateInputExpression(
            "{obj} as NSObject".format(obj=arguments[0]))
        pretty = 1 if options.plain is None else 0
        jsonData = fb.evaluateObjectExpression(
            "[NSJSONSerialization dataWithJSONObject:(NSObject*){} options:{} error:nil]"
            .format(objectToPrint, pretty))
        jsonString = fb.evaluateExpressionValue(
            "(NSString*)[[NSString alloc] initWithData:(NSObject*){} encoding:4]"
            .format(jsonData)).GetObjectDescription()

        print(jsonString)
Пример #11
0
def nthSiblingOfView(view, n):
    subviews = subviewsOfView(superviewOfView(view))
    numViews = fb.evaluateIntegerExpression("[(id)" + subviews + " count]")

    idx = fb.evaluateIntegerExpression("[(id)" + subviews + " indexOfObject:" +
                                       view + "]")

    newIdx = idx + n
    while newIdx < 0:
        newIdx += numViews
    newIdx = newIdx % numViews

    return fb.evaluateObjectExpression("[(id)" + subviews + " objectAtIndex:" +
                                       str(newIdx) + "]")
Пример #12
0
def accessibilityElements(view):
    if fb.evaluateBooleanExpression(
            "[UIView instancesRespondToSelector:@selector(accessibilityElements)]"
    ):
        a11yElements = fb.evaluateExpression(
            "(id)[%s accessibilityElements]" % view, False)
        if int(a11yElements, 16) != 0:
            return a11yElements
    if fb.evaluateBooleanExpression(
            "[%s respondsToSelector:@selector(_accessibleSubviews)]" % view):
        return fb.evaluateExpression("(id)[%s _accessibleSubviews]" % (view),
                                     False)
    else:
        return fb.evaluateObjectExpression(
            "[[[UIApplication sharedApplication] keyWindow] _accessibilityElementsInContainer:0 topLevel:%s includeKB:0]"  # noqa B950
            % view)
Пример #13
0
 def run(self, arguments, options):
     object = fb.evaluateObjectExpression(arguments[0])
     if options.appleWay:
         if fb.evaluateBooleanExpression(
             "[{} respondsToSelector:@selector(_ivarDescription)]".format(object)
         ):
             command = "po [{} _ivarDescription]".format(object)
         else:
             print("Sorry, but it seems Apple dumped the _ivarDescription method")
             return
     else:
         objectClass = fb.evaluateExpressionValue(
             "(id)[(id)(" + object + ") class]"
         ).GetObjectDescription()
         command = "p *(({} *)((id){}))".format(objectClass, object)
     lldb.debugger.HandleCommand(command)
Пример #14
0
def printAccessibilityIdentifiersHierarchy(view, indent=0):
    a11yIdentifier = accessibilityIdentifier(view)
    classDesc = objHelpers.className(view)
    indentString = "   | " * indent

    # if we don't have any accessibility identifier - we should have some children
    if int(a11yIdentifier.GetValue(), 16) == 0:
        print(indentString + ("{} {}".format(classDesc, view)))
        # We call private method that gives back all visible accessibility children
        # for view
        a11yElements = accessibilityElements(view)
        accessibilityElementsCount = int(
            fb.evaluateExpression("(int)[%s count]" % a11yElements))
        for index in range(0, accessibilityElementsCount):
            subview = fb.evaluateObjectExpression("[%s objectAtIndex:%i]" %
                                                  (a11yElements, index))
            printAccessibilityIdentifiersHierarchy(subview, indent + 1)
    else:
        print(indentString + ("({} {}) {}".format(
            classDesc, view, a11yIdentifier.GetObjectDescription())))
Пример #15
0
def subviewAtIndex(views, index):
    return fb.evaluateObjectExpression("[%s objectAtIndex:%i]" %
                                       (views, index))
Пример #16
0
def subviewsOfView(view):
    return fb.evaluateObjectExpression("[%s subviews]" % view)
Пример #17
0
def rootView():
    return fb.evaluateObjectExpression(
        "[[UIApplication sharedApplication] keyWindow]")
Пример #18
0
def setTextInView(view, text):
    fb.evaluateObjectExpression('[%s setText:@"%s"]' % (view, text))
    viewHelpers.flushCoreAnimationTransaction()
Пример #19
0
def accessibilityIdentifier(view):
    return fb.evaluateObjectExpression("[%s accessibilityIdentifier]" % view)
Пример #20
0
 def run(self, args, options):
     viewOrLayer = fb.evaluateObjectExpression(args[0])
     viewHelpers.unmaskView(viewOrLayer)
Пример #21
0
 def run(self, args, options):
     viewOrLayer = fb.evaluateObjectExpression(args[0])
     viewHelpers.maskView(viewOrLayer, options.color, options.alpha)
Пример #22
0
    def run(self, arguments, options):
        request = fb.evaluateInputExpression(arguments[0])
        HTTPHeaderSring = ""
        HTTPMethod = fb.evaluateExpressionValue(
            "(id)[{} HTTPMethod]".format(request)).GetObjectDescription()
        URL = fb.evaluateExpressionValue(
            "(id)[{} URL]".format(request)).GetObjectDescription()
        timeout = fb.evaluateExpression(
            "(NSTimeInterval)[{} timeoutInterval]".format(request))
        HTTPHeaders = fb.evaluateObjectExpression(
            "(id)[{} allHTTPHeaderFields]".format(request))
        HTTPHeadersCount = fb.evaluateIntegerExpression(
            "[{} count]".format(HTTPHeaders))
        allHTTPKeys = fb.evaluateObjectExpression(
            "[{} allKeys]".format(HTTPHeaders))
        for index in range(0, HTTPHeadersCount):
            key = fb.evaluateObjectExpression("[{} objectAtIndex:{}]".format(
                allHTTPKeys, index))
            keyDescription = fb.evaluateExpressionValue(
                "(id){}".format(key)).GetObjectDescription()
            value = fb.evaluateExpressionValue(
                "(id)[(id){} objectForKey:{}]".format(
                    HTTPHeaders, key)).GetObjectDescription()
            if len(HTTPHeaderSring) > 0:
                HTTPHeaderSring += " "
            HTTPHeaderSring += '-H "{}: {}"'.format(keyDescription, value)
        HTTPData = fb.evaluateObjectExpression("[{} HTTPBody]".format(request))
        dataFile = None
        dataAsString = None
        if fb.evaluateIntegerExpression("[{} length]".format(HTTPData)) > 0:
            if options.embed:
                if fb.evaluateIntegerExpression(
                        "[{} respondsToSelector:@selector(base64EncodedStringWithOptions:)]"
                        .format(  # noqa B950
                            HTTPData)):
                    dataAsString = fb.evaluateExpressionValue(
                        "(id)[(id){} base64EncodedStringWithOptions:0]".format(
                            HTTPData)).GetObjectDescription()
                else:
                    print(
                        "This version of OS doesn't supports base64 data encoding"
                    )
                    return False
            elif not runtimeHelpers.isIOSDevice():
                dataFile = self.generateTmpFilePath()
                if not fb.evaluateBooleanExpression(
                        '(BOOL)[{} writeToFile:@"{}" atomically:NO]'.format(
                            HTTPData, dataFile)):
                    print("Can't write data to file {}".format(dataFile))
                    return False
            else:
                print(
                    'HTTPBody data for iOS Device is supported only with "--embed-data" flag'  # noqa B950
                )
                return False

        commandString = ""
        if dataAsString is not None and len(dataAsString) > 0:
            dataFile = self.generateTmpFilePath()
            commandString += 'echo "{}" | base64 -D -o "{}" && '.format(
                dataAsString, dataFile)
        commandString += "curl -X {} --connect-timeout {}".format(
            HTTPMethod, timeout)
        if len(HTTPHeaderSring) > 0:
            commandString += " " + HTTPHeaderSring
        if dataFile is not None:
            commandString += ' --data-binary @"{}"'.format(dataFile)

        commandString += ' "{}"'.format(URL)
        print(commandString)
Пример #23
0
 def run(self, arguments, options):
     forceStartAccessibilityServer()
     rootView = fb.evaluateObjectExpression(
         "[[UIApplication sharedApplication] keyWindow]")
     self.foundElement = False
     self.accessibilityGrepHierarchy(rootView, arguments[0])
Пример #24
0
def subviewsOfView(view):
    return fb.evaluateObjectExpression("[" + view + " subviews]")
Пример #25
0
def viewControllerRecursiveDescription(vc):
    return _recursiveViewControllerDescriptionWithPrefixAndChildPrefix(
        fb.evaluateObjectExpression(vc), "", "", "")
Пример #26
0
def _copyFromURL(url, preferredFilename, noOpen):
    data = fb.evaluateObjectExpression(
        '(id)[NSData dataWithContentsOfURL:(id){}]'.format(url))
    defaultFilename = fb.describeObject(
        '(id)[[{} pathComponents] lastObject]'.format(url))
    _copyFromData(data, defaultFilename, preferredFilename, noOpen)
Пример #27
0
    def run(self, arguments, options):
        expression = arguments[0]

        methodPattern = re.compile(
            r"""
      (?P<scope>[-+])?
      \[
        (?P<target>.*?)
        (?P<category>\(.+\))?
        \s+
        (?P<selector>.*)
      \]
""",
            re.VERBOSE,
        )

        match = methodPattern.match(expression)

        if not match:
            print("Failed to parse expression. Do you even Objective-C?!")
            return

        expressionForSelf = objc.functionPreambleExpressionForSelf()
        if not expressionForSelf:
            arch = objc.currentArch()
            print(
                "Your architecture, {}, is truly fantastic. However, I don't currently support it."
                .format(arch))
            return

        methodTypeCharacter = match.group("scope")
        classNameOrExpression = match.group("target")
        category = match.group("category")
        selector = match.group("selector")

        methodIsClassMethod = methodTypeCharacter == "+"

        if not methodIsClassMethod:
            # The default is instance method, and methodTypeCharacter
            # may not actually be '-'.
            methodTypeCharacter = "-"

        targetIsClass = False
        targetObject = fb.evaluateObjectExpression(
            "({})".format(classNameOrExpression), False)

        if not targetObject:
            # If the expression didn't yield anything then it's likely a class.
            # Assume it is. We will check again that the class does actually
            # exist anyway.
            targetIsClass = True
            targetObject = fb.evaluateObjectExpression(
                "[{} class]".format(classNameOrExpression), False)

        targetClass = fb.evaluateObjectExpression(
            "[{} class]".format(targetObject), False)

        if not targetClass or int(targetClass, 0) == 0:
            print(
                'Couldn\'t find a class from the expression "{}". Did you typo?'
                .format(classNameOrExpression))
            return

        if methodIsClassMethod:
            targetClass = objc.object_getClass(targetClass)

        found = False
        nextClass = targetClass

        while not found and int(nextClass, 0) > 0:
            if classItselfImplementsSelector(nextClass, selector):
                found = True
            else:
                nextClass = objc.class_getSuperclass(nextClass)

        if not found:
            print(
                "There doesn't seem to be an implementation of {} in the class hierarchy. Made a boo boo with the selector name?"
                .format(selector))
            return

        breakpointClassName = objc.class_getName(nextClass)
        formattedCategory = category if category else ""
        breakpointFullName = "{}[{}{} {}]".format(methodTypeCharacter,
                                                  breakpointClassName,
                                                  formattedCategory, selector)

        if targetIsClass:
            breakpointCondition = "(void*)object_getClass({}) == {}".format(
                expressionForSelf, targetClass)
        else:
            breakpointCondition = "(void*){} == {}".format(
                expressionForSelf, targetObject)

        print("Setting a breakpoint at {} with condition {}".format(
            breakpointFullName, breakpointCondition))

        if category:
            lldb.debugger.HandleCommand(
                'breakpoint set --skip-prologue false --fullname "{}" --condition "{}"'
                .format(breakpointFullName, breakpointCondition))
        else:
            breakpointPattern = r"{}\[{}(\(.+\))? {}\]".format(
                methodTypeCharacter, breakpointClassName, selector)
            lldb.debugger.HandleCommand(
                'breakpoint set --skip-prologue false --func-regex "{}" --condition "{}"'
                .format(breakpointPattern, breakpointCondition))
Пример #28
0
def superviewOfView(view):
    superview = fb.evaluateObjectExpression("[" + view + " superview]")
    if int(superview, 16) == 0:
        return None

    return superview