Ejemplo n.º 1
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
                )
            )
Ejemplo n.º 2
0
    def loadChiselIfNecessary(self):
        target = lldb.debugger.GetSelectedTarget()
        symbol_contexts = target.FindSymbols("PrintInstances", lldb.eSymbolTypeCode)
        if any(ctx.symbol.IsValid() for ctx in symbol_contexts):
            return True

        path = self.chiselLibraryPath()
        if not os.path.exists(path):
            print("Chisel library missing: " + path)
            return False

        module = fb.evaluateExpressionValue('(void*)dlopen("{}", 2)'.format(path))
        if module.unsigned != 0 or target.module["Chisel"]:
            return True

        # `errno` is a macro that expands to a call to __error(). In development,
        # lldb was not getting a correct value for `errno`, so `__error()` is used.
        errno = fb.evaluateExpressionValue("*(int*)__error()").value
        error = fb.evaluateExpressionValue("(char*)dlerror()")
        if errno == 50:
            # KERN_CODESIGN_ERROR from <mach/kern_return.h>
            print("Error loading Chisel: Code signing failure; Must re-run codesign")
        elif error.unsigned != 0:
            print("Error loading Chisel: " + error.summary)
        elif errno != 0:
            error = fb.evaluateExpressionValue("(char*)strerror({})".format(errno))
            if error.unsigned != 0:
                print("Error loading Chisel: " + error.summary)
            else:
                print("Error loading Chisel (errno {})".format(errno))
        else:
            print("Unknown error loading Chisel")

        return False
Ejemplo n.º 3
0
def import_uikit():
    """
    Import UIKit framework to the debugger
    """
    global _uikit_imported
    if _uikit_imported:
        return
    _uikit_imported = True
    fb.evaluateExpressionValue("@import UIKit")
Ejemplo n.º 4
0
    def run(self, arguments, options):
        object = fb.evaluateInputExpression(arguments[0])
        ivarName = arguments[1]

        objectClass = fb.evaluateExpressionValue(
            "(id)[(" + object + ") class]").GetObjectDescription()

        ivarTypeCommand = '((char *)ivar_getTypeEncoding((void*)object_getInstanceVariable((id){}, "{}", 0)))[0]'.format(  # noqa B950
            object, ivarName)
        ivarTypeEncodingFirstChar = fb.evaluateExpression(ivarTypeCommand)

        result = fb.evaluateExpressionValue("(({} *)({}))->{}".format(
            objectClass, object, ivarName))
        print(result.GetObjectDescription() if "@" in
              ivarTypeEncodingFirstChar else result)
Ejemplo n.º 5
0
 def depth(self):
     """
     :return: XCUIElement depth
     :rtype: lldb.SBValue
     """
     return fb.evaluateExpressionValue("(int)[{} depth]".format(
         self.element_value))
Ejemplo n.º 6
0
 def suggested_hit_points(self):
     """
     :return: XCUIElement suggested hit points
     :rtype: lldb.SBValue
     """
     return fb.evaluateExpressionValue(
         "(NSArray *)[{} suggestedHitpoints]".format(self.element_value))
Ejemplo n.º 7
0
    def run(self, arguments, options):
        if not self.loadChiselIfNecessary():
            return

        if len(arguments) == 0 or not arguments[0].strip():
            print(
                "Usage: findinstances <classOrProtocol> [<predicate>]; Run `help findinstances`"
            )
            return

        query = arguments[0]
        predicate = arguments[1].strip()
        # Escape double quotes and backslashes.
        predicate = re.sub('([\\"])', r"\\\1", predicate)
        call = '(void)PrintInstances("{}", "{}")'.format(query, predicate)
        fb.evaluateExpressionValue(call)
Ejemplo n.º 8
0
def accessibilityLabel(view):
    # using Apple private API to get real value of accessibility string for element.
    return fb.evaluateExpressionValue(
        "(id)[%s accessibilityAttributeValue:%i]" %
        (view, ACCESSIBILITY_LABEL_KEY),
        False,
    )
Ejemplo n.º 9
0
    def run(self, arguments, options):
        element = arguments[0]
        language = fb.currentLanguage()
        if element == "__default__":
            element = ("XCUIApplication()"
                       if language == lldb.eLanguageTypeSwift else
                       "(XCUIApplication *)[[XCUIApplication alloc] init]")

        # Evaluate object
        element_sbvalue = fb.evaluateExpressionValue("{}".format(element),
                                                     language=language)
        """:type: lldb.SBValue"""

        # Get pointer value, so it will be working in Swift and Objective-C
        element_pointer = int(element_sbvalue.GetValue(), 16)

        # Get XCElementSnapshot object
        snapshot = take_snapshot(element_pointer)

        # Print tree for snapshot element
        snapshot_object = XCElementSnapshot(snapshot, language=language)
        elements = snapshot_object.find_missing_identifiers(
            status_bar=options.status_bar)
        if elements is not None:
            print(
                elements.hierarchy_text(pointer=options.pointer,
                                        trait=options.trait,
                                        frame=options.frame))
        else:
            print("Couldn't found elements without identifier")
Ejemplo n.º 10
0
def printInvocationForFrame(frame):
    print(frame)

    symbolName = frame.GetSymbol().GetName()
    if not re.match(r"[-+]\s*\[.*\]", symbolName):
        return

    self = findArgAtIndexFromStackFrame(frame, 0)
    cmd = findArgAtIndexFromStackFrame(frame, 1)

    commandForSignature = (
        "[(id)" + self +
        " methodSignatureForSelector:(char *)sel_getName((SEL)" + cmd + ")]")
    signatureValue = fb.evaluateExpressionValue("(id)" + commandForSignature)

    if (signatureValue.GetError() is not None
            and str(signatureValue.GetError()) != "success"):
        print(
            "My sincerest apologies. I couldn't find a method signature for the selector."  # noqa B950
        )
        return

    signature = signatureValue.GetValue()

    arg0 = stackStartAddressInSelectedFrame(frame)
    commandForInvocation = (
        "[NSInvocation _invocationWithMethodSignature:(id)" + signature +
        " frame:((void *)" + str(arg0) + ")]")
    invocation = fb.evaluateExpression("(id)" + commandForInvocation)

    if invocation:
        prettyPrintInvocation(frame, invocation)
    else:
        print(frame)
Ejemplo n.º 11
0
def _showLayer(layer):
    layer = "(" + layer + ")"
    size = "((CGRect)[(id)" + layer + " bounds]).size"

    width = float(fb.evaluateExpression("(CGFloat)(" + size + ".width)"))
    height = float(fb.evaluateExpression("(CGFloat)(" + size + ".height)"))
    if width == 0.0 or height == 0.0:
        print("Nothing to see here - the size of this element is {} x {}.".
              format(width, height))
        return

    fb.evaluateEffect("UIGraphicsBeginImageContextWithOptions(" + size +
                      ", NO, 0.0)")
    fb.evaluateEffect(
        "[(id)" + layer +
        " renderInContext:(void *)UIGraphicsGetCurrentContext()]")

    result = fb.evaluateExpressionValue(
        "(UIImage *)UIGraphicsGetImageFromCurrentImageContext()")
    if result.GetError() is not None and str(result.GetError()) != "success":
        print(result.GetError())
    else:
        image = result.GetValue()
        _showImage(image)

    fb.evaluateEffect("UIGraphicsEndImageContext()")
Ejemplo n.º 12
0
def _responderChain(startResponder):
    responderAddress = fb.evaluateExpression(startResponder)
    while int(responderAddress, 16):
        yield fb.evaluateExpressionValue(responderAddress).GetObjectDescription()
        responderAddress = fb.evaluateExpression(
            "(id)[(id)" + responderAddress + " nextResponder]"
        )
Ejemplo n.º 13
0
 def is_top_level_touch_bar_element(self):
     """
     :return: XCUIElement is top level touch bar element
     :rtype: lldb.SBValue
     """
     return fb.evaluateExpressionValue(
         "(BOOL)[{} isTopLevelTouchBarElement]".format(self.element_value))
Ejemplo n.º 14
0
def _viewControllerDescription(viewController):
    vc = "(%s)" % (viewController)

    if fb.evaluateBooleanExpression("[(id)%s isViewLoaded]" % (vc)):
        result = fb.evaluateExpressionValue(
            '(id)[[NSString alloc] initWithFormat:@"<%%@: %%p; view = <%%@; %%p>; frame = (%%g, %%g; %%g, %%g)>", (id)NSStringFromClass((id)[(id)%s class]), %s, (id)[(id)[(id)%s view] class], (id)[(id)%s view], ((CGRect)[(id)[(id)%s view] frame]).origin.x, ((CGRect)[(id)[(id)%s view] frame]).origin.y, ((CGRect)[(id)[(id)%s view] frame]).size.width, ((CGRect)[(id)[(id)%s view] frame]).size.height]'  # noqa B950
            % (vc, vc, vc, vc, vc, vc, vc, vc))
    else:
        result = fb.evaluateExpressionValue(
            '(id)[[NSString alloc] initWithFormat:@"<%%@: %%p; view not loaded>", (id)NSStringFromClass((id)[(id)%s class]), %s]'  # noqa B950
            % (vc, vc))

    if result.GetError() is not None and str(result.GetError()) != "success":
        return "[Error getting description.]"
    else:
        return result.GetObjectDescription()
Ejemplo n.º 15
0
 def run(self, arguments, options):
     tableView = tableViewInHierarchy()
     print(
         fb.evaluateExpressionValue(
             "(id)[(id)" + tableView + " visibleCells]"
         ).GetObjectDescription()
     )
Ejemplo n.º 16
0
def tableViewInHierarchy():
    viewDescription = fb.evaluateExpressionValue(
        "(id)[(id)[[UIApplication sharedApplication] keyWindow] recursiveDescription]"
    ).GetObjectDescription()

    searchView = None

    # Try to find an instance of
    classPattern = re.compile(r"UITableView: (0x[0-9a-fA-F]+);")
    for match in re.finditer(classPattern, viewDescription):
        searchView = match.group(1)
        break

    # Try to find a direct subclass
    if not searchView:
        subclassPattern = re.compile(
            r"(0x[0-9a-fA-F]+); baseClass = UITableView;")
        for match in re.finditer(subclassPattern, viewDescription):
            searchView = match.group(1)
            break

    # SLOW: check every pointer in town
    if not searchView:
        pattern = re.compile(r"(0x[0-9a-fA-F]+)[;>]")
        for view in re.findall(pattern, viewDescription):
            if fb.evaluateBooleanExpression(
                    "[" + view + " isKindOfClass:(id)[UITableView class]]"):
                searchView = view
                break

    return searchView
Ejemplo n.º 17
0
def prettyPrintInvocation(frame, invocation):
    object = fb.evaluateExpression("(id)[(id)" + invocation + " target]")
    description = fb.evaluateExpressionValue(
        "(id)" + invocation).GetObjectDescription()
    argDescriptions = description.splitlines(True)[4:]

    print("NSInvocation: " + invocation)
    print("self: " + fb.evaluateExpression("(id)" + object))

    if len(argDescriptions) > 0:
        print("\n" + str(len(argDescriptions)) +
              " Arguments:" if len(argDescriptions) > 1 else "\nArgument:")

        index = 2
        for argDescription in argDescriptions:
            s = re.sub(r"argument [0-9]+: ", "", argDescription)

            address = findArgAdressAtIndexFromStackFrame(frame, index)

            encoding = s.split(" ")[0]
            description = " ".join(s.split(" ")[1:])

            readableString = argumentAsString(frame, address, encoding)

            if readableString:
                print(readableString)
            else:
                if encoding[0] == "{":
                    encoding = encoding[1:]
                print((hex(address) + ", address of " + encoding + " " +
                       description).strip())

            index += 1
Ejemplo n.º 18
0
def _showColor(color):
    color = "(" + color + ")"

    colorToUse = color
    isCF = _colorIsCGColorRef(color)
    if isCF:
        colorToUse = "[[UIColor alloc] initWithCGColor:(CGColorRef){}]".format(
            color)
    else:
        isCI = objectHelpers.isKindOfClass(color, "CIColor")
        if isCI:
            colorToUse = "[UIColor colorWithCIColor:(CIColor *){}]".format(
                color)

    imageSize = 58
    fb.evaluateEffect(
        "UIGraphicsBeginImageContextWithOptions((CGSize)CGSizeMake({imageSize}, {imageSize}), NO, 0.0)"
        .format(imageSize=imageSize))
    fb.evaluateEffect("[(id){} setFill]".format(colorToUse))
    fb.evaluateEffect(
        "UIRectFill((CGRect)CGRectMake(0.0, 0.0, {imageSize}, {imageSize}))".
        format(imageSize=imageSize))

    result = fb.evaluateExpressionValue(
        "(UIImage *)UIGraphicsGetImageFromCurrentImageContext()")
    if result.GetError() is not None and str(result.GetError()) != "success":
        print("got error {}".format(result))
        print(result.GetError())
    else:
        image = result.GetValue()
        _showImage(image)

    fb.evaluateEffect("UIGraphicsEndImageContext()")
Ejemplo n.º 19
0
 def uniquely_identifying_objective_c_code(self):
     """
     :return: XCUIElement uniquely identifying Objective-C code
     :rtype: lldb.SBValue
     """
     return fb.evaluateExpressionValue(
         "(id)[{} _uniquelyIdentifyingObjectiveCCode]".format(
             self.element_value))
def isIOSSimulator():
    return (
        fb.evaluateExpressionValue("(id)[[UIDevice currentDevice] model]")
        .GetObjectDescription()
        .lower()
        .find("simulator")
        >= 0
    )
Ejemplo n.º 21
0
 def hit_point_for_scrolling(self):
     """
     :return: XCUIElement hit point for scrolling
     :rtype: lldb.SBValue
     """
     import_uikit()
     return fb.evaluateExpressionValue(
         "(CGPoint)[{} hitPointForScrolling]".format(self.element_value))
Ejemplo n.º 22
0
def _inheritanceHierarchy(instanceOfAClass):
    instanceAddress = fb.evaluateExpression(instanceOfAClass)
    instanceClass = fb.evaluateExpression("(id)[(id)" + instanceAddress +
                                          " class]")
    while int(instanceClass, 16):
        yield fb.evaluateExpressionValue(instanceClass).GetObjectDescription()
        instanceClass = fb.evaluateExpression("(id)[(id)" + instanceClass +
                                              " superclass]")
Ejemplo n.º 23
0
 def uniquely_identifying_swift_code(self):
     """
     :return: XCUIElement uniquely identifying Swift code
     :rtype: lldb.SBValue
     """
     return fb.evaluateExpressionValue(
         "(id)[{} _uniquelyIdentifyingSwiftCode]".format(
             self.element_value))
Ejemplo n.º 24
0
 def visible_frame(self):
     """
     :return: XCUIElement visible frame
     :rtype: lldb.SBValue
     """
     import_uikit()
     return fb.evaluateExpressionValue("(CGRect)[{} visibleFrame]".format(
         self.element_value))
Ejemplo n.º 25
0
    def run(self, arguments, options):
        maxDepth = int(options.depth)
        window = int(options.window)
        isMac = runtimeHelpers.isMacintoshArch()

        if window > 0:
            if isMac:
                arguments[0] = (
                    "(id)[[[[NSApplication sharedApplication] windows] objectAtIndex:"
                    + str(window)
                    + "] contentView]"
                )
            else:
                arguments[0] = (
                    "(id)[[[UIApplication sharedApplication] windows] objectAtIndex:"
                    + str(window)
                    + "]"
                )
        elif arguments[0] == "__keyWindow_dynamic__":
            if isMac:
                arguments[
                    0
                ] = "(id)[[[[NSApplication sharedApplication] windows] objectAtIndex:0] contentView]"
            else:
                arguments[0] = "(id)[[UIApplication sharedApplication] keyWindow]"

        if options.upwards:
            view = arguments[0]
            description = viewHelpers.upwardsRecursiveDescription(view, maxDepth)
            if description:
                print(description)
            else:
                print(
                    "Failed to walk view hierarchy. Make sure you pass a view, not any other kind of object or expression."
                )
        else:
            printingMethod = "recursiveDescription"
            if isMac:
                printingMethod = "_subtreeDescription"

            description = fb.evaluateExpressionValue(
                "(id)[" + arguments[0] + " " + printingMethod + "]"
            ).GetObjectDescription()
            if maxDepth > 0:
                separator = re.escape("   | ")
                prefixToRemove = separator * maxDepth + " "
                description += "\n"
                description = re.sub(r"%s.*\n" % (prefixToRemove), r"", description)

            if options.short:
                toRemove = ":.*(?:\n|$)"
                description = re.sub(toRemove, r">\n", description)
            elif options.medium:
                toRemove = ";.*(?:\n|$)"
                description = re.sub(toRemove, r">\n", description)

            print(description)
Ejemplo n.º 26
0
 def run(self, arguments, options):
     lldbOutput = fb.evaluateExpressionValue(
         "[{changeset} description]".format(
             changeset=arguments[0])).GetObjectDescription()
     process = subprocess.Popen("pbcopy",
                                env={"LANG": "en_US.UTF-8"},
                                stdin=subprocess.PIPE)
     process.communicate(lldbOutput.encode("utf-8"))
     print("Object copied to clipboard")
Ejemplo n.º 27
0
 def run(self, arguments, options):
     path = fb.evaluateExpressionValue(
         "(NSString*)[[NSBundle mainBundle] bundlePath]")
     pathString = "{}".format(path).split('"')[1]
     cmd = 'echo {} | tr -d "\n" | pbcopy'.format(pathString)
     os.system(cmd)
     print(pathString)
     if options.open:
         os.system("open " + pathString)
Ejemplo n.º 28
0
 def run(self, arguments, options):
     tableView = tableViewInHierarchy()
     if tableView:
         viewValue = fb.evaluateExpressionValue(tableView)
         print(viewValue.GetObjectDescription())
         cmd = 'echo %s | tr -d "\n" | pbcopy' % tableView
         os.system(cmd)
     else:
         print("Sorry, chump. I couldn't find a table-view. :'(")
Ejemplo n.º 29
0
    def run(self, arguments, options):
        element = arguments[0]
        language = fb.currentLanguage()

        if element == "__default__":
            element = ("XCUIApplication()"
                       if language == lldb.eLanguageTypeSwift else
                       "(XCUIApplication *)[[XCUIApplication alloc] init]")

        if language == lldb.eLanguageTypeSwift:
            print(
                fb.evaluateExpressionValue(
                    "{}.debugDescription".format(element),
                    language=language).GetObjectDescription().replace(
                        "\\n", "\n").replace("\\'", "'").strip(' "\n\t'))
        else:
            print(
                fb.evaluateExpressionValue("[{} debugDescription]".format(
                    element)).GetObjectDescription())
Ejemplo n.º 30
0
def _dataIsImage(data):
    data = "(" + data + ")"

    result = fb.evaluateExpressionValue("(id)[UIImage imageWithData:" + data + "]")

    if result.GetError() is not None and str(result.GetError()) != "success":
        return False
    else:
        isImage = result.GetValueAsUnsigned() != 0
        return isImage