Ejemplo n.º 1
0
def removeDebugHUD(debugger, command, exe_ctx, result, internal_dict) -> None:
    """
    Syntax:
        removehud

    Examples:
        (lldb) removehud

    This command is implemented in HMDebugHUD.py
    """

    global gClassName
    if not HM.existClass(gClassName):
        HM.DPrint(f"{gClassName} does not exist.")
        return

    command_script = f'''
        UIView *keyWindow = [UIApplication sharedApplication].keyWindow;
        Class HUDClass = (Class)objc_lookUpClass("{gClassName}");
        UIView *objView = nil;
        for (UIView *subView in keyWindow.subviews) {{
            if ([subView isKindOfClass:HUDClass]) {{
                objView = subView;
                break;
            }}
        }}
        [objView removeFromSuperview];
        objView;
    '''

    val = HM.evaluateExpressionValue(command_script)
    if HM.judgeSBValueHasValue(val):
        HM.DPrint("remove done!")
    else:
        HM.DPrint(f"{gClassName} does not exist.")
Ejemplo n.º 2
0
def registerProtocol():
    global gProtocolName
    if HM.existClass(gProtocolName):
        return

    # Register class
    HM.DPrint(f"Register {gProtocolName}...")

    classValue = HM.allocateClass(gProtocolName, "NSURLProtocol")
    HM.registerClass(classValue.GetValue())

    # Add methods
    HM.DPrint(f"Add methods to {gProtocolName}...")

    canInitWithRequestIMPValue = makeCanInitWithRequestIMP()
    if not HM.judgeSBValueHasValue(canInitWithRequestIMPValue):
        return
    HM.addClassMethod(gProtocolName, "canInitWithRequest:",
                      canInitWithRequestIMPValue.GetValue(), "B@:@")

    HM.DPrint(f"Register {gProtocolName} done!")

    # register NSURLProtocol
    registerClassExp = f"[NSURLProtocol registerClass:(Class){classValue.GetValue()}]"
    HM.evaluateExpressionValue(registerClassExp)
Ejemplo n.º 3
0
def register() -> None:

    if HM.existClass(gClassName):
        return

    # Register class
    HMProgressHUD.show(f"Register {gClassName}...")
    HM.DPrint(f"Register {gClassName}...")

    classValue = HM.allocateClass(gClassName,
                                  HMDebugBaseViewController.gClassName)
    HM.addIvar(classValue.GetValue(), "_leftTextArray", "NSMutableArray *")
    HM.addIvar(classValue.GetValue(), "_rightTextArray", "NSMutableArray *")
    HM.registerClass(classValue.GetValue())

    # Add methods
    HM.DPrint(f"Add methods to {gClassName}...")
    viewDidLoadIMPValue = makeViewDidLoadIMP()
    if not HM.judgeSBValueHasValue(viewDidLoadIMPValue):
        HMProgressHUD.hide()
        return
    HM.addInstanceMethod(gClassName, "viewDidLoad",
                         viewDidLoadIMPValue.GetValue(), "v@:")

    # Methods related to tableView.
    HM.DPrint(f"Add methods to {gClassName}......")

    if not addTableViewMethods():
        HMProgressHUD.hide()
        return

    HM.DPrint(f"Register {gClassName} done!")
    HMProgressHUD.hide()
Ejemplo n.º 4
0
def properties(debugger, command, exe_ctx, result, internal_dict):
    """
    Syntax:
        properties <className/classInstance>

    Examples:
        (lldb) properties UIViewController
        (lldb) properties [NSObject new]

        (lldb) expression -l objc -O -- [NSObject new]
        <NSObject: 0x60000372f760>
        (lldb) properties 0x60000372f760

    This command is implemented in HMClassInfoCommands.py
    """

    if len(command) == 0:
        HM.DPrint(
            "Requires a argument, Please enter \"help properties\" for help.")
        return

    value = HM.evaluateExpressionValue(
        expression=
        f'(NSString *)[{command} performSelector:NSSelectorFromString(@"_propertyDescription")]',
        printErrors=False)
    if HM.successOfSBError(value.GetError()):
        HM.DPrint(value.GetObjectDescription())
        return

    clsPrefixesValue = HM.getClassPrefixes()[1]
    command_script = f'''
        Class inputClass = objc_lookUpClass("{command}");

        if (inputClass == nil) {{   //  Find prefixed class
            for (NSString *prefix in (NSMutableArray *){clsPrefixesValue.GetValue()}) {{
                NSString *clsName = [prefix stringByAppendingString:@".{command}"];
                inputClass = objc_lookUpClass((char *)[clsName UTF8String]);
                if (inputClass) {{
                    break;
                }}
            }}
        }}

        NSMutableString *result = [[NSMutableString alloc] init];
        if (inputClass == nil) {{
            [result appendString:@"Unable to resolve {command} or find {command} class, maybe {command} is not a subclass of NSObject\\n"];
        }} else {{
            if ((BOOL)[(Class)inputClass respondsToSelector:(SEL)NSSelectorFromString(@"_propertyDescription")]) {{
                [result appendString:(NSString *)[inputClass performSelector:NSSelectorFromString(@"_propertyDescription")]];
            }} else {{
                [result appendString:@"{command} is not a subclass of NSObject"];
            }}
        }}

        result;
    '''

    result = HM.evaluateExpressionValue(command_script).GetObjectDescription()
    HM.DPrint(result)
Ejemplo n.º 5
0
def redirect(debugger, command, exe_ctx, result, internal_dict):
    """
    Syntax:
        redirect [--append] <stdout/stderr/both> <path>

    Options:
        --append/-a; Use "a+" mode instead of "w+" mode in freopen function

    Examples:
        (lldb) redirect both /dev/ttys000  (Simulator)
        (lldb) redirect stdout /path/to/file
        (lldb) redirect -a stderr /path/to/file

    This command is implemented in HMRedirectStdout.py
    """

    command_args = shlex.split(command)
    parser = generate_option_parser()
    try:
        # options: optparse.Values
        # args: list
        (options, args) = parser.parse_args(command_args)
    except:
        result.SetError(parser.usage)
        return

    argsLen = len(args)
    if argsLen != 2:
        HM.DPrint(
            "Error input, plase enter 'help redirect' for more infomation")
        return

    stream = args[0]
    path = args[1]

    mode = "w+"
    if options.append:
        mode = "a+"

    if stream == "stdout" or stream == "stderr":
        redirectValue = HM.evaluateExpressionValue(
            f"freopen(\"{path}\", \"{mode}\", {stream})")
        logRedirectResult(redirectValue, stream)

    elif stream == "both":
        stdoutValue = HM.evaluateExpressionValue(
            f"freopen(\"{path}\", \"{mode}\", stdout)")
        logRedirectResult(stdoutValue, "stdout")
        stderrValue = HM.evaluateExpressionValue(
            f"freopen(\"{path}\", \"{mode}\", stderr)")
        logRedirectResult(stderrValue, "stderr")

    else:
        HM.DPrint(
            f"Error input(\"{stream}\"), plase enter \"help redirect\" for more infomation"
        )
Ejemplo n.º 6
0
def register() -> None:

    if HM.existClass(gClassName):
        return

    # Register class
    HM.DPrint(f"Register {gClassName}...")
    classValue = HM.allocateClass(gClassName, "UIView")
    HM.addIvar(classValue.GetValue(), "_contentView", "UIView *")
    HM.addIvar(classValue.GetValue(), "_indicator", "UIActivityIndicatorView *")
    HM.addIvar(classValue.GetValue(), "_textLab", "UILabel *")
    HM.addIvar(classValue.GetValue(), "_hideDelayTimer", "NSTimer *")
    HM.registerClass(classValue.GetValue())

    # Add Class methods
    HM.DPrint(f"Add methods to {gClassName}...")
    sharedInstanceIMPValue = makeSharedInstanceIMP()
    if not HM.judgeSBValueHasValue(sharedInstanceIMPValue):
        return
    HM.addClassMethod(gClassName, "sharedInstance", sharedInstanceIMPValue.GetValue(), "@@:")

    showHUDIMPValue = makeShowHUDIMP()
    if not HM.judgeSBValueHasValue(showHUDIMPValue):
        return
    HM.addClassMethod(gClassName, "showHUD", showHUDIMPValue.GetValue(), "@@:")

    showOnlyTextIMPValue = makeShowOnlyTextHiddenAfterDelayIMP()
    if not HM.judgeSBValueHasValue(showOnlyTextIMPValue):
        return
    HM.addClassMethod(gClassName, "showOnlyText:hiddenAfterDelay:", showOnlyTextIMPValue.GetValue(), "@@:@i")

    hideHUDIMPValue = makeHideHUDIMP()
    if not HM.judgeSBValueHasValue(hideHUDIMPValue):
        return
    HM.addClassMethod(gClassName, "hideHUD", hideHUDIMPValue.GetValue(), "@@:")

    setTextIMPValue = makeSetTextIMP()
    if not HM.judgeSBValueHasValue(setTextIMPValue):
        return
    HM.addClassMethod(gClassName, "setText:", setTextIMPValue.GetValue(), "v@:@")

    # Add Instance methods
    HM.DPrint(f"Add methods to {gClassName}......")
    initWithFrameIMPValue = makeInitWithFrameIMP()
    if not HM.judgeSBValueHasValue(initWithFrameIMPValue):
        return
    HM.addInstanceMethod(gClassName, "initWithFrame:", initWithFrameIMPValue.GetValue(), "@@:{CGRect={CGPoint=dd}{CGSize=dd}}")

    layoutSubviewsIMPValue = makeLayoutSubviewsIMP()
    if not HM.judgeSBValueHasValue(layoutSubviewsIMPValue):
        return
    HM.addInstanceMethod(gClassName, "layoutSubviews", layoutSubviewsIMPValue.GetValue(), "v@:")

    HM.DPrint(f"Register {gClassName} done!")
Ejemplo n.º 7
0
def delay(debugger, command, exe_ctx, result, internal_dict):
    """
    Syntax:
        delay [--continue] <second> <lldb command>

    Options:
        --continue/-c; "process continue" after executing specified lldb command

    Notice:
        If <lldb command> has options, you should enclose it in quotes.

    Examples:
        (lldb) delay 3 showhud
        (lldb) delay -c 2 phomedirectory
        (lldb) delay 0.5 push PersonalViewController
        (lldb) delay 2 "deletefile -f path/to/fileOrDirectory"

    This command is implemented in HMDelay.py
    """

    command_args = shlex.split(command)
    parser = generate_option_parser()
    try:
        # options: optparse.Values
        # args: list
        (options, args) = parser.parse_args(command_args)
    except:
        result.SetError(parser.usage)
        return

    if len(args) < 2:
        HM.DPrint("Requires two arguments(second and lldb command), Please enter \"help delay\" for help.")
        return

    secondString = args[0]
    if not isNumber(secondString):
        HM.DPrint(f"\"{secondString}\" cannot be converted to seconds, Please enter \"help delay\" for help.")
        return

    debugger.SetAsync(True)
    debugger.HandleCommand("process continue")
    seconds = float(secondString)
    specifiedCommand: str = ""
    for i, item in enumerate(args):
        if i == 0:
            continue
        specifiedCommand += item + " "
    specifiedCommand = specifiedCommand.rstrip()

    HM.DPrint(f"Execute lldb command after {seconds} seconds: {specifiedCommand}")
    t = Timer(seconds, lambda: runDelayed(specifiedCommand, options.isContinue))
    t.start()
Ejemplo n.º 8
0
def register() -> None:

    if HM.existClass(gClassName):
        return

    # Register class
    HMProgressHUD.show(f"Register {gClassName}...")
    HM.DPrint(f"Register {gClassName}...")

    classValue = HM.allocateClass(gClassName, "UIWindow")
    HM.registerClass(classValue.GetValue())

    HM.DPrint(f"Register {gClassName} done!")
Ejemplo n.º 9
0
def findClass(debugger, command, exe_ctx, result, internal_dict):
    """
    Syntax:
        fclass <className>

    Examples:
        (lldb) fclass
        (lldb) fclass UITabBarController
        (lldb) fclass controller

    Notice:
        Case insensitive.

    This command is implemented in HMClassInfoCommands.py
    """

    HM.DPrint("Waiting...")

    if len(command) == 0:
        addObjectScript = '[classNames appendFormat:@"%@ (%p)\\n", name, classList[i]]; findCount += 1;'
    else:
        command = command.lower()
        addObjectScript = f'''
            if ([[name lowercaseString] containsString:@"{command}"]) {{
                [classNames appendFormat:@"%@ (%p)\\n", name, classList[i]];
                findCount += 1;
            }}
        '''

    command_script = f'''
        unsigned int findCount = 0;
        unsigned int classCount;
        Class *classList = objc_copyClassList(&classCount);
        NSMutableString *classNames = [[NSMutableString alloc] init];
        for (int i = 0; i < classCount; i++) {{
            NSString *name = [[NSString alloc] initWithUTF8String:class_getName(classList[i])];
            {addObjectScript}
        }}
        free(classList);

        if (findCount == 0) {{
            [classNames insertString:@"No class found.\\n" atIndex:0];
        }} else {{
            [classNames insertString:[[NSString alloc] initWithFormat:@"Count: %u \\n", findCount] atIndex:0];
        }}
        classNames;
    '''

    classNames = HM.evaluateExpressionValue(
        command_script).GetObjectDescription()
    HM.DPrint(classNames)
Ejemplo n.º 10
0
def showFPS(debugger, command, exe_ctx, result, internal_dict):
    """
    Syntax:
        showfps

    Examples:
        (lldb) showfps

    Notice:
        showfps is deprecated. Use showhud instead.

    This command is implemented in HMFPSLabel.py
    """

    HM.DPrint("showfps is deprecated. Use showhud instead.")

    FPSClassName = "HMFPSLabel"
    if HM.existClass(FPSClassName):
        HM.DPrint("HMFPSLabel is already on display")
        return

    # Register class
    FPSLabelClassValue = HM.allocateClass(FPSClassName, "UILabel")
    HM.addIvar(FPSLabelClassValue.GetValue(), "_link", "CADisplayLink *")
    HM.addIvar(FPSLabelClassValue.GetValue(), "_count", "int")
    HM.addIvar(FPSLabelClassValue.GetValue(), "_lastTime", "double")
    HM.registerClass(FPSLabelClassValue.GetValue())

    addToKeyWindowIMPValue = makeAddToKeyWindowIMP()
    if not HM.judgeSBValueHasValue(addToKeyWindowIMPValue):
        return
    HM.addClassMethod(FPSClassName, "addToKeyWindow",
                      addToKeyWindowIMPValue.GetValue(), "@@:")

    tickIMPValue = makeTickIMP()
    if not HM.judgeSBValueHasValue(tickIMPValue):
        return
    HM.addInstanceMethod(FPSClassName, "tick:", tickIMPValue.GetValue(),
                         "v@:@")

    # Show fps command
    addToKeyWindowCommand = '''
        Class fps = NSClassFromString(@"HMFPSLabel");
        (UILabel *)[fps performSelector:@selector(addToKeyWindow)];
    '''
    HM.evaluateExpressionValue(addToKeyWindowCommand)

    HM.DPrint("showfps Done!")
    HM.processContinue()
Ejemplo n.º 11
0
def register() -> None:

    if HM.existClass(gClassName):
        return

    HMDebugBaseViewController.register()

    # Register class
    HMProgressHUD.show(f"Register {gClassName}...")
    HM.DPrint(f"Register {gClassName}...")

    classValue = HM.allocateClass(gClassName, HMDebugBaseViewController.gClassName)
    HM.registerClass(classValue.GetValue())

    # Add methods
    HM.DPrint(f"Add methods to {gClassName}...")
    presentIMPValue = makePresentIMP()
    if not HM.judgeSBValueHasValue(presentIMPValue):
        HMProgressHUD.hide()
        return
    HM.addClassMethod(gClassName, "present", presentIMPValue.GetValue(), "@@:")

    viewDidLoadIMPValue = makeViewDidLoadIMP()
    if not HM.judgeSBValueHasValue(viewDidLoadIMPValue):
        HMProgressHUD.hide()
        return
    HM.addInstanceMethod(gClassName, "viewDidLoad", viewDidLoadIMPValue.GetValue(), "v@:")

    dismissSelfIMPValue = makeDismissSelfIMP()
    if not HM.judgeSBValueHasValue(dismissSelfIMPValue):
        HMProgressHUD.hide()
        return
    HM.addInstanceMethod(gClassName, "dismissSelf", dismissSelfIMPValue.GetValue(), "v@:")

    # Methods related to tableView.
    HM.DPrint(f"Add methods to {gClassName}......")
    if not addTableViewMethods():
        HMProgressHUD.hide()
        return

    # Methods related to features.
    HM.DPrint(f"Add methods to {gClassName}.........")
    if not addFeatureMethods():
        HMProgressHUD.hide()
        return

    HM.DPrint(f"Register {gClassName} done!")
    HMProgressHUD.hide()
Ejemplo n.º 12
0
def deleteAllFileInDirectory(directoryPath: str) -> None:
    command_script = f'''
        NSString *directoryPath = @"{directoryPath}";
        NSMutableString *result = [[NSMutableString alloc] init];
        NSFileManager *fileMgr = [NSFileManager defaultManager];
        if ([fileMgr fileExistsAtPath:directoryPath]) {{
            NSArray *subFileArray = [fileMgr contentsOfDirectoryAtPath:directoryPath error:nil];
            for (NSString *subFileName in subFileArray) {{
                NSString *subFilePath = [directoryPath stringByAppendingPathComponent:subFileName];
                if ([fileMgr removeItemAtPath:subFilePath error:nil]) {{
                    [result appendFormat:@"removed file: %@\\n", subFilePath];
                }} else {{
                    [result appendFormat:@"failed to remove file: %@\\n", subFilePath];
                }}
            }}
        }} else {{
            [result appendFormat:@"failed to remove non-existing file: %@\\n", directoryPath];
        }}

        if ([result length] == 0) {{
            [result appendString:@"There are no files in this directory.\\n"];
        }}
    
        result;
    '''

    result = HM.evaluateExpressionValue(command_script).GetObjectDescription()
    HM.DPrint(result)
Ejemplo n.º 13
0
def pHomeDirectory(debugger, command, exe_ctx, result, internal_dict):
    """
    Syntax:
        phomedirectory [--open]

    Options:
        --open/-o; open in Finder

    Examples:
        (lldb) phomedirectory
        (lldb) phomedirectory -o

    This command is implemented in HMFileCommands.py
    """

    command_args = shlex.split(command)
    parser = generate_option_parser("phomedirectory")
    try:
        # options: optparse.Values
        # args: list
        (options, args) = parser.parse_args(command_args)
    except:
        result.SetError(parser.usage)
        return

    homeDirectoryValue = HM.evaluateExpressionValue(
        '(NSString *)NSHomeDirectory()')
    path = homeDirectoryValue.GetObjectDescription()
    HM.DPrint(path)
    if options.open:
        os.system('open ' + path)
Ejemplo n.º 14
0
def pBundlePath(debugger, command, exe_ctx, result, internal_dict):
    """
    Syntax:
        pbundlepath [--open]

    Options:
        --open/-o; open in Finder

    Examples:
        (lldb) pbundlepath
        (lldb) pbundlepath -o

    This command is implemented in HMFileCommands.py
    """

    command_args = shlex.split(command)
    parser = generate_option_parser("pbundlepath")
    try:
        # options: optparse.Values
        # args: list
        (options, args) = parser.parse_args(command_args)
    except:
        result.SetError(parser.usage)
        return

    bundlePathValue = HM.evaluateExpressionValue(
        '(NSString*)[[NSBundle mainBundle] bundlePath]')
    path = bundlePathValue.GetObjectDescription()
    HM.DPrint(path)
    if options.open:
        # Cannot open the bundle, so we open the directory where the bundle is located.
        directoryValue = HM.evaluateExpressionValue(
            f'(NSString *)[(NSString *){bundlePathValue.GetValue()} stringByDeletingLastPathComponent]'
        )
        os.system('open ' + directoryValue.GetObjectDescription())
Ejemplo n.º 15
0
def findSuperClass(debugger, command, exe_ctx, result, internal_dict):
    """
    Syntax:
        fsuperclass <className>

    Examples:
        (lldb) fsuperclass UIButton

    This command is implemented in HMClassInfoCommands.py
    """

    if len(command) == 0:
        HM.DPrint(
            "Requires a argument, Please enter \"help fsuperclass\" for help.")
        return

    clsPrefixesValue = HM.getClassPrefixes()[1]
    command_script = f'''
        Class inputClass = objc_lookUpClass("{command}");

        if (inputClass == nil) {{   //  Find prefixed class
            for (NSString *prefix in (NSMutableArray *){clsPrefixesValue.GetValue()}) {{
                NSString *clsName = [prefix stringByAppendingString:@".{command}"];
                inputClass = objc_lookUpClass((char *)[clsName UTF8String]);
                if (inputClass) {{
                    break;
                }}
            }}
        }}

        NSMutableString *result = [[NSMutableString alloc] init];
        if (inputClass == nil) {{
            [result appendString:@"Can't find {command} class\\n"];
        }} else {{
            [result appendString:[[NSString alloc] initWithUTF8String:class_getName(inputClass)]];
            for (Class superClass = class_getSuperclass(inputClass); superClass != nil; superClass = class_getSuperclass(superClass)) {{
                NSString *name = [[NSString alloc] initWithUTF8String:class_getName(superClass)];
                [result appendFormat:@" : %@", name];
            }}
        }}

        result;
    '''

    classNames = HM.evaluateExpressionValue(
        command_script).GetObjectDescription()
    HM.DPrint(classNames)
Ejemplo n.º 16
0
def environment(debugger, command, exe_ctx, result, internal_dict):
    """
    Syntax:
        environment

    Examples:
        (lldb) environment

    This command is implemented in HMEnvironment.py
    """

    # Python version
    # LLDB version
    # Target triple
    # Git commit hash
    # Optimized
    # Xcode version
    # Xcode build version
    # Model identifier
    # System version

    HM.DPrint('[Python version] ' + sys.version.replace('\n', '\n\t\t'))

    HM.DPrint('[LLDB version] ' +
              debugger.GetVersionString().replace('\n', '\n\t\t'))

    HM.DPrint('[Target triple] ' + debugger.GetSelectedTarget().GetTriple())

    HM.DPrint('[Git commit hash] ' + getGitCommitHash())

    HM.DPrint('[Optimized] ' + getOptimizedStr())

    XcodeVersionValue = HM.evaluateExpressionValue(
        '(NSString *)([NSBundle mainBundle].infoDictionary[@"DTXcode"] ?: @"-")'
    )
    HM.DPrint('[Xcode version] ' + XcodeVersionValue.GetObjectDescription())

    XcodeBuildVersionValue = HM.evaluateExpressionValue(
        '(NSString *)([NSBundle mainBundle].infoDictionary[@"DTXcodeBuild"] ?: @"-")'
    )
    HM.DPrint('[Xcode build version] ' +
              XcodeBuildVersionValue.GetObjectDescription())

    HM.DPrint('[Model identifier] ' + getModelIdentifier())

    SystemVersionValue = HM.evaluateExpressionValue(
        '(NSString *)[[NSString alloc] initWithFormat:@"%@ %@", [[UIDevice currentDevice] systemName], [[UIDevice currentDevice] systemVersion]]'
    )
    HM.DPrint('[System version] ' + SystemVersionValue.GetObjectDescription())
Ejemplo n.º 17
0
def plifecycle(debugger, command, exe_ctx, result, internal_dict):
    """
    Syntax:
        plifecycle [-i/--ignore_system_classes]

    Options:
        --ignore_system_classes/-i; Ignore the system generated UIViewController classes

    Notice:
        You should use plifecycle in symbolic breakpoint(UIViewController's life cycle) for easier control.
        This command can ignore the system generated UIViewController classes, Otherwise you may use the following command directly.

        Method A: expression -l objc -O -- [[$arg1 description] stringByAppendingString:@"  dealloc/viewDidAppear:/..."]
        Method B: expression -l objc -O -- @import UIKit; [[NSString alloc] initWithFormat:@"%@  %s", (id)$arg1, (char *)$arg2]
        Method C: Add symbolic breakpoint of "UIApplicationMain" with command "expression -l objc -O -- @import UIKit",
                  then add symbolic breakpoint(UIViewController's life cycle) with command "expression -l objc -O -- [[NSString alloc] initWithFormat:@"%@  %s", (id)$arg1, (char *)$arg2]"

    This command is implemented in HMLifeCycle.py
    """

    command_args = shlex.split(command)
    parser = generate_option_parser()
    try:
        # options: optparse.Values
        # args: list
        (options, args) = parser.parse_args(command_args)
    except:
        result.SetError(parser.usage)
        return

    selfDescription = HM.evaluateExpressionValue(
        "(id)$arg1").GetObjectDescription()

    ignore = False
    if options.ignore_system_classes:
        ignoreClasses = [
            "UIAlertController", "_UIAlertControllerTextFieldViewController",
            "UIInputWindowController", "UICompatibilityInputViewController",
            "UIKeyboardCandidateGridCollectionViewController",
            "UISystemKeyboardDockController", "_UIRemoteInputViewController",
            "UIApplicationRotationFollowingController",
            "UISystemInputAssistantViewController",
            "UIPredictionViewController", "UICandidateViewController",
            "_SFAppPasswordSavingViewController",
            "SFPasswordSavingRemoteViewController"
        ]

        for className in ignoreClasses:
            if className in selfDescription:
                ignore = True
                break

    if not ignore:
        selectorDescription = HM.evaluateExpressionValue(
            "(char *)$arg2").GetSummary().strip('"')
        HM.DPrint(selfDescription + '  ' + selectorDescription + '\n')
Ejemplo n.º 18
0
def register() -> None:
    if HM.existClass(gClassName):
        return

    # Register class
    HMProgressHUD.show(f"Register {gClassName}...")
    HM.DPrint(f"Register {gClassName}...")

    classValue = HM.allocateClass(gClassName, "UIViewController")
    HM.registerClass(classValue.GetValue())

    # Add methods
    HM.DPrint(f"Add methods to {gClassName}...")
    viewDidLoadIMPValue = makeViewDidLoadIMP()
    if not HM.judgeSBValueHasValue(viewDidLoadIMPValue):
        return
    HM.addInstanceMethod(gClassName, "viewDidLoad", viewDidLoadIMPValue.GetValue(), "v@:")

    HM.DPrint(f"Register {gClassName} done!")
Ejemplo n.º 19
0
def deleteFileOrDirectory(filePath: str) -> None:
    command_script = f'''
        NSString *filePath = @"{filePath}";
        NSMutableString *result = [[NSMutableString alloc] init];
        NSFileManager *fileMgr = [NSFileManager defaultManager];
        if ([fileMgr fileExistsAtPath:filePath]) {{
            if (![filePath containsString:(NSString *)NSHomeDirectory()]) {{
                [result appendString:@"The file path must be in the sandbox\\n"];
            }} else if ([fileMgr removeItemAtPath:filePath error:nil]) {{
                [result appendFormat:@"removed file: %@\\n", filePath];
            }} else {{
                [result appendFormat:@"failed to remove file: %@\\n", filePath];
            }}
        }} else {{
            [result appendFormat:@"failed to remove non-existing file: %@\\n", filePath];
        }}

        result;
    '''
    result = HM.evaluateExpressionValue(command_script).GetObjectDescription()
    HM.DPrint(result)
Ejemplo n.º 20
0
def addFeatureMethods() -> bool:
    global gClassName

    selectedAPPInfoIMPValue = makeSelectedAPPInfoIMP()
    if not HM.judgeSBValueHasValue(selectedAPPInfoIMPValue):
        return False
    HM.addInstanceMethod(gClassName, "selectedAPPInfo", selectedAPPInfoIMPValue.GetValue(), "v@:")

    selectedSandboxIMPValue = makeSelectedSandboxIMP()
    if not HM.judgeSBValueHasValue(selectedSandboxIMPValue):
        return False
    HM.addInstanceMethod(gClassName, "selectedSandbox", selectedSandboxIMPValue.GetValue(), "v@:")

    selectedInspectViewIMPValue = makeSelectedInspectViewIMP()
    if not HM.judgeSBValueHasValue(selectedInspectViewIMPValue):
        return False
    HM.addInstanceMethod(gClassName, "selectedInspectView", selectedInspectViewIMPValue.GetValue(), "v@:")

    HM.DPrint("Add breakpoints to hook method...")
    HM.addOneShotBreakPointInIMP(selectedAPPInfoIMPValue, "HMDebugMainViewController.selectedAPPInfoBreakPointHandler", "HMDebugMainViewController_selectedAPPInfo_Breakpoint")
    HM.addOneShotBreakPointInIMP(selectedSandboxIMPValue, "HMDebugMainViewController.selectedSandboxBreakPointHandler", "HMDebugMainViewController_selectedSandbox_Breakpoint")
    HM.addOneShotBreakPointInIMP(selectedInspectViewIMPValue, "HMDebugMainViewController.selectedInspectViewBreakPointHandler", "HMDebugMainViewController_selectedInspectView_Breakpoint")

    return True
Ejemplo n.º 21
0
def methods(debugger, command, exe_ctx, result, internal_dict):
    """
    Syntax:
        methods [--short] <className/classInstance>

    Examples:
        (lldb) methods UIViewController
        (lldb) methods -s UIViewController
        (lldb) methods [UIView new]

        (lldb) expression -l objc -O -- [NSObject new]
        <NSObject: 0x60000375f9a0>
        (lldb) methods 0x60000375f9a0

    Options:
        --short/-s; Use [inputClass _shortMethodDescription] instead of [inputClass _methodDescription]

    This command is implemented in HMClassInfoCommands.py
    """

    command_args = shlex.split(command)
    parser = generate_methods_option_parser()
    try:
        # options: optparse.Values
        # args: list
        (options, args) = parser.parse_args(command_args)
    except:
        result.SetError(parser.usage)
        return

    inputStr: str = ""
    for string in args:
        inputStr += string + " "
    inputStr = inputStr.rstrip()

    if len(inputStr) == 0:
        HM.DPrint(
            "Requires a argument, Please enter \"help methods\" for help.")
        return

    if options.short:
        selName = "_shortMethodDescription"
    else:
        selName = "_methodDescription"

    value = HM.evaluateExpressionValue(
        expression=
        f'(NSString *)[{inputStr} performSelector:NSSelectorFromString(@"{selName}")]',
        printErrors=False)
    if HM.successOfSBError(value.GetError()):
        HM.DPrint(value.GetObjectDescription())
        return

    clsPrefixesValue = HM.getClassPrefixes()[1]
    command_script = f'''
        Class inputClass = objc_lookUpClass("{inputStr}");

        if (inputClass == nil) {{   //  Find prefixed class
            for (NSString *prefix in (NSMutableArray *){clsPrefixesValue.GetValue()}) {{
                NSString *clsName = [prefix stringByAppendingString:@".{inputStr}"];
                inputClass = objc_lookUpClass((char *)[clsName UTF8String]);
                if (inputClass) {{
                    break;
                }}
            }}
        }}

        NSMutableString *result = [[NSMutableString alloc] init];
        if (inputClass == nil) {{
            [result appendString:@"Unable to resolve {inputStr} or find {inputStr} class, maybe {inputStr} is not a subclass of NSObject\\n"];
        }} else {{
            if ((BOOL)[(Class)inputClass respondsToSelector:(SEL)NSSelectorFromString(@"{selName}")]) {{
                [result appendString:(NSString *)[inputClass performSelector:NSSelectorFromString(@"{selName}")]];
            }} else {{
                [result appendString:@"{inputStr} is not a subclass of NSObject"];
            }}
        }}

        result;
    '''

    result = HM.evaluateExpressionValue(command_script).GetObjectDescription()
    HM.DPrint(result)
Ejemplo n.º 22
0
def register() -> None:

    if HM.existClass(gClassName):
        return

    HMProgressHUD.register()
    HMDebugBaseViewController.register()

    # Register class
    HMProgressHUD.show(f"Register {gClassName}...")
    HM.DPrint(f"Register {gClassName}...")

    classValue = HM.allocateClass(gClassName,
                                  HMDebugBaseViewController.gClassName)
    HM.addIvar(classValue.GetValue(), "_tableView", "UITableView *")
    HM.addIvar(classValue.GetValue(), "_currentPath", "NSString *")
    HM.addIvar(classValue.GetValue(), "_childPaths", "NSMutableArray *")
    HM.registerClass(classValue.GetValue())

    # Add methods
    HM.DPrint(f"Add methods to {gClassName}...")
    viewDidLoadIMPValue = makeViewDidLoadIMP()
    if not HM.judgeSBValueHasValue(viewDidLoadIMPValue):
        HMProgressHUD.hide()
        return
    HM.addInstanceMethod(gClassName, "viewDidLoad",
                         viewDidLoadIMPValue.GetValue(), "v@:")

    loadPathIMPValue = makeLoadPathIMP()
    if not HM.judgeSBValueHasValue(loadPathIMPValue):
        HMProgressHUD.hide()
        return
    HM.addInstanceMethod(gClassName, "loadPath:", loadPathIMPValue.GetValue(),
                         "v@:@")

    clickBackItemIMPValue = makeClickBackItemIMP()
    if not HM.judgeSBValueHasValue(clickBackItemIMPValue):
        HMProgressHUD.hide()
        return
    HM.addInstanceMethod(gClassName, "clickBackItem",
                         clickBackItemIMPValue.GetValue(), "v@:")

    clickPopItemIMPValue = makeClickPopItemIMP()
    if not HM.judgeSBValueHasValue(clickPopItemIMPValue):
        HMProgressHUD.hide()
        return
    HM.addInstanceMethod(gClassName, "clickPopItem",
                         clickPopItemIMPValue.GetValue(), "v@:")

    deleteFileOrDirIMPValue = makeDeleteFileOrDirIMP()
    if not HM.judgeSBValueHasValue(deleteFileOrDirIMPValue):
        HMProgressHUD.hide()
        return
    HM.addInstanceMethod(gClassName, "deleteFileOrDir:",
                         deleteFileOrDirIMPValue.GetValue(), "v@:@")

    # Methods related to tableView.
    HM.DPrint(f"Add methods to {gClassName}......")
    if not addTableViewMethods():
        HMProgressHUD.hide()
        return

    HM.DPrint(f"Register {gClassName} done!")
    HMProgressHUD.hide()
Ejemplo n.º 23
0
def showDebugHUD(debugger, command, exe_ctx, result, internal_dict):
    """
    Syntax:
        showhud

    Examples:
        (lldb) showhud

    Summary:
        Show debug HUD.
        1.Memory footprint.
        2.CPU utilization.
        3.FPS in main thread.
        The UI style is based on https://github.com/meitu/MTHawkeye

    This command is implemented in HMDebugHUD.py
    """

    global gClassName
    if isDisplayingHUD():
        HM.DPrint(f"{gClassName} is already on display")
        HM.processContinue()
        return
    elif HM.existClass(gClassName):
        showHUDFunc()
        HM.processContinue()
        return

    # Register class
    HMProgressHUD.show(f"Register {gClassName}...")
    HM.DPrint(f"Register {gClassName}...")

    classValue = HM.allocateClass(gClassName, "UIView")
    HM.addIvar(classValue.GetValue(), "_link", "CADisplayLink *")
    HM.addIvar(classValue.GetValue(), "_count", "int")  # count in 1 second
    HM.addIvar(classValue.GetValue(), "_lastTime", "double")

    HM.addIvar(classValue.GetValue(), "_memoryLab", "UILabel *")
    HM.addIvar(classValue.GetValue(), "_cpuUtilizationLab", "UILabel *")
    HM.addIvar(classValue.GetValue(), "_fpsLab", "UILabel *")

    HM.registerClass(classValue.GetValue())

    # Add methods
    HM.DPrint(f"Add methods to {gClassName}...")

    addToKeyWindowIMPValue = makeAddToKeyWindowIMP()
    if not HM.judgeSBValueHasValue(addToKeyWindowIMPValue):
        HMProgressHUD.hide()
        return
    HM.addClassMethod(gClassName, "addToKeyWindow",
                      addToKeyWindowIMPValue.GetValue(), "@@:")

    tapSelfIMPValue = makeTapSelfIMP()
    if not HM.judgeSBValueHasValue(tapSelfIMPValue):
        HMProgressHUD.hide()
        return
    HM.addInstanceMethod(gClassName, "tapSelf", tapSelfIMPValue.GetValue(),
                         "v@:")

    # Add methods(update)
    if not addUpdateMethods():
        HMProgressHUD.hide()
        return

    # Add methods(move)
    HM.DPrint(f"Add methods to {gClassName}......")
    if not addMoveMethods():
        HMProgressHUD.hide()
        return

    # Add breakpoint in tapSelf
    HM.DPrint("Add breakpoint to hook method...")
    HM.addOneShotBreakPointInIMP(tapSelfIMPValue,
                                 "HMDebugHUD.tapSelfBreakPointHandler",
                                 "HMDebugHUD_TapSelf_Breakpoint")

    HM.DPrint(f"Register {gClassName} done!")

    # Show HUD command
    showHUDFunc()

    HMProgressHUD.hide()

    HM.processContinue()
Ejemplo n.º 24
0
def findSubclass(debugger, command, exe_ctx, result, internal_dict):
    """
    Syntax:
        fsubclass [--nonrecursively] <className>

    Options:
        --nonrecursively/-n; Find subclass non-recursively

    Examples:
        (lldb) fsubclass UIViewController
        (lldb) fsubclass -n UIViewController


    This command is implemented in HMClassInfoCommands.py
    """

    command_args = shlex.split(command)
    parser = generate_findSubclass_option_parser()
    try:
        # options: optparse.Values
        # args: list
        (options, args) = parser.parse_args(command_args)
    except:
        result.SetError(parser.usage)
        return

    if len(args) != 1:
        HM.DPrint(
            "Requires a argument, Please enter \"help fsubclass\" for help.")
        return

    HM.DPrint("Waiting...")

    if options.nonrecursively:
        compareScript = '''
            if (class_getSuperclass(cls) == inputClass){
                NSString *name = [[NSString alloc] initWithUTF8String:class_getName(cls)];
                [result appendFormat:@"%@\\n", name];
                findCount += 1;
            }
        '''

    else:
        compareScript = '''
            for (Class superClass = class_getSuperclass(cls); superClass != nil; superClass = class_getSuperclass(superClass)) {
                if (superClass == inputClass) {
                    NSString *name = [[NSString alloc] initWithUTF8String:class_getName(cls)];
                    [result appendFormat:@"%@\\n", name];
                    findCount += 1;

                    break;
                }
            }
        '''

    clsPrefixesValue = HM.getClassPrefixes()[1]
    command_script = f'''
        Class inputClass = objc_lookUpClass("{args[0]}");

        if (inputClass == nil) {{   //  Find prefixed class
            for (NSString *prefix in (NSMutableArray *){clsPrefixesValue.GetValue()}) {{
                NSString *clsName = [prefix stringByAppendingString:@".{args[0]}"];
                inputClass = objc_lookUpClass((char *)[clsName UTF8String]);
                if (inputClass) {{
                    break;
                }}
            }}
        }}

        NSMutableString *result = [[NSMutableString alloc] init];
        if (inputClass == nil) {{
            [result appendString:@"Can't find {args[0]} class\\n"];
        }} else {{
            unsigned int classCount;
            unsigned int findCount = 0;
            Class *classList = objc_copyClassList(&classCount);

            for (int i = 0; i < classCount; i++) {{
                Class cls = classList[i];
                {compareScript}
            }}

            if (findCount == 0) {{
                [result insertString:@"No subclass found.\\n" atIndex:0];
            }} else {{
                [result insertString:[[NSString alloc] initWithFormat:@"Subclass count: %u \\n", findCount] atIndex:0];
            }}
            
            free(classList);
        }}

        result;
    '''

    classNames = HM.evaluateExpressionValue(
        command_script).GetObjectDescription()
    HM.DPrint(classNames)
Ejemplo n.º 25
0
def logRedirectResult(val: lldb.SBValue, stream: str) -> None:
    if val.GetValueAsSigned() == 0:
        HM.DPrint(f"redirect {stream} failed")
    else:
        HM.DPrint(f"redirect {stream} successful")
Ejemplo n.º 26
0
def push(debugger, command, exe_ctx, result, internal_dict):
    """
    Syntax:
        push <className>
        push [--instance] <instance>

    Options:
        --instance/-i; Push the UIViewController instance.

    Examples:
        (lldb) push PersonalViewController
        (lldb) push -i [[PersonalViewController alloc] init]

        (lldb) expression -l objc -O -- [PersonalViewController new]
        <PersonalViewController: 0x7fed30c5a070>
        (lldb) push -i 0x7fed30c5a070

    Notice:
        "push MyViewController" needs to execute "[[MyViewController alloc] init]" first.
        If the initializer of the class requires parameters, or the class needs to pass parameters after initialization, this command may cause errors.

    This command is implemented in HMPushViewController.py
    """

    # HM.DPrint(type(command))  # <class 'str'>
    # HM.DPrint(type(exe_ctx))  # <class 'lldb.SBExecutionContext'>
    # HM.DPrint(type(result))  # <class 'lldb.SBCommandReturnObject'>
    # HM.DPrint(type(internal_dict))  # <class 'dict'>


    command_args = shlex.split(command)
    parser = generate_option_parser()
    try:
        # options: optparse.Values
        # args: list
        (options, args) = parser.parse_args(command_args)
    except:
        result.SetError(parser.usage)
        return

    if len(args) == 0:
        HM.DPrint("Error input, plase enter 'help push' for more infomation")
        return

    HM.DPrint("Waiting...")

    navigationVC = getNavigationVC()
    if navigationVC is None:
        HM.DPrint("Cannot find a UINavigationController")
        return

    state = False
    if options.instance:
        instanceExpr: str = ""
        for string in args:
            instanceExpr += string + " "
        instanceExpr = instanceExpr.rstrip()
        VCObject = HM.evaluateExpressionValue(instanceExpr).GetValue()
    else:
        makeVCExpression = f"(UIViewController *)[[NSClassFromString(@\"{args[0]}\") alloc] init]"
        VCObject = HM.evaluateExpressionValue(makeVCExpression).GetValue()     # address

    if verifyObjIsKindOfClass(VCObject, "UIViewController"):
        pushExpression = f"(void)[{navigationVC} pushViewController:(id){VCObject} animated:YES]"
        debugger.HandleCommand('expression -l objc -O -- ' + pushExpression)
        state = True
    elif not options.instance:
        classPrefixes = HM.getClassPrefixes()[0]
        for prefix in classPrefixes:  # for Swift file
            className = f"{prefix}.{args[0]}"
            if not HM.existClass(className):
                continue

            makeVCExpression = f"(UIViewController *)[[NSClassFromString(@\"{className}\") alloc] init]"
            VCObject = HM.evaluateExpressionValue(makeVCExpression).GetValue()  # address
            if verifyObjIsKindOfClass(VCObject, "UIViewController"):
                pushExpression = f"(void)[{navigationVC} pushViewController:(id){VCObject} animated:YES]"
                debugger.HandleCommand('expression -l objc -O -- ' + pushExpression)
                state = True
                break

    HM.DPrint("push succeed" if state else "push failed")
    if state:
        HM.processContinue()
Ejemplo n.º 27
0
def findMethod(debugger, command, exe_ctx, result, internal_dict):
    """
    Syntax:
        fmethod <methodName>  (Case insensitive.)
        fmethod [--class] <className>

    Options:
        --class/-c; Find all method in the class

    Examples:
        (lldb) fmethod viewdid
        (lldb) fmethod viewDidLayoutSubviews
        (lldb) fmethod -c UITableViewController

    This command is implemented in HMClassInfoCommands.py
    """

    command_args = shlex.split(command)
    parser = generate_findMethod_option_parser()
    try:
        # options: optparse.Values
        # args: list
        (options, args) = parser.parse_args(command_args)
    except:
        result.SetError(parser.usage)
        return

    if not options.cls:
        if len(args) != 1:
            HM.DPrint("Error input, Please enter \"help fmethod\" for help.")
            return
        elif len(args[0]) <= 5:
            HM.DPrint("Argument length must be greater than 5.")
            return

    HM.DPrint("Waiting...")

    if options.cls:
        clsPrefixesValue = HM.getClassPrefixes()[1]
        command_script = f'''
            NSMutableString *result = [[NSMutableString alloc] init];
            Class inputClass = objc_lookUpClass("{options.cls}");
            if (inputClass == nil) {{   //  Find prefixed class
                for (NSString *prefix in (NSMutableArray *){clsPrefixesValue.GetValue()}) {{
                    NSString *clsName = [prefix stringByAppendingString:@".{options.cls}"];
                    inputClass = objc_lookUpClass((char *)[clsName UTF8String]);
                    if (inputClass) {{
                        break;
                    }}
                }}
            }}

            if (inputClass == nil) {{
                [result appendString:@"Can't find {options.cls} class\\n"];
            }} else {{
                unsigned int instanceMethodCount;
                Method *instanceMethodList = class_copyMethodList(inputClass, &instanceMethodCount);
                for (int j = 0; j < instanceMethodCount; ++j) {{
                    Method method = instanceMethodList[j];
                    SEL sel = method_getName(method);
                    NSString *selName = [[NSString alloc] initWithUTF8String:sel_getName(sel)];
                    [result appendFormat:@"(-) %@\\n\\tType encoding:%s\\n", selName, method_getTypeEncoding(method)];
                }}
                free(instanceMethodList);
                
                unsigned int classMethodCount = 0;
                Class metaCls = object_getClass(inputClass);
                if (class_isMetaClass(metaCls)) {{
                    Method *classMethodList = class_copyMethodList(metaCls, &classMethodCount);
                    for (int j = 0; j < classMethodCount; ++j) {{
                        Method method = classMethodList[j];
                        SEL sel = method_getName(method);
                        NSString *selName = [[NSString alloc] initWithUTF8String:sel_getName(sel)];
                        [result appendFormat:@"(+) %@\\n\\tType encoding:%s\\n", selName, method_getTypeEncoding(method)];
                    }}
                    free(classMethodList);
                }}
                
                if (instanceMethodCount + classMethodCount == 0) {{
                    [result insertString:@"No method found.\\n" atIndex:0];
                }} else {{
                    [result insertString:[[NSString alloc] initWithFormat:@"Instance methods count: %u. Class method count: %u.\\n", instanceMethodCount, classMethodCount] atIndex:0];
                    NSString *clsName = [[NSString alloc] initWithUTF8String:class_getName(inputClass)];
                    [result insertString:[[NSString alloc] initWithFormat:@"Class: %@ (%p)\\n", clsName, inputClass] atIndex:0];
                }}
            }}
            
            result;
        '''

    else:
        inputMethodName = args[0].lower()
        command_script = f'''
            NSString *inputMethodName = [[NSString alloc] initWithUTF8String:"{inputMethodName}"];
            
            NSMutableString *result = [[NSMutableString alloc] init];
        
            unsigned int classCount;
            unsigned int findCount = 0;
            Class *classList = objc_copyClassList(&classCount);
        
            for (int i = 0; i < classCount; ++i) {{
                Class cls = classList[i];
                // Instance Methods
                unsigned int instanceMethodCount;
                Method *instanceMethodList = class_copyMethodList(cls, &instanceMethodCount);
        
                for (int j = 0; j < instanceMethodCount; ++j) {{
                    Method method = instanceMethodList[j];
                    SEL sel = method_getName(method);
                    NSString *selName = [[NSString alloc] initWithUTF8String:sel_getName(sel)];
                    if ([[selName lowercaseString] containsString:inputMethodName]) {{
                        NSString *clsName = [[NSString alloc] initWithUTF8String:class_getName(cls)];
                        [result appendFormat:@"(-) %@\\n\\tType encoding:%s\\n\\tClass:%@\\n", selName, method_getTypeEncoding(method), clsName];
                        findCount += 1;
                    }}
                }}
                free(instanceMethodList);
                
                // Class Methods
                Class metaCls = object_getClass(cls);
                if (!class_isMetaClass(metaCls)) {{
                    continue;
                }}
                unsigned int classMethodCount;
                Method *classMethodList = class_copyMethodList(metaCls, &classMethodCount);
        
                for (int j = 0; j < classMethodCount; ++j) {{
                    Method method = classMethodList[j];
                    SEL sel = method_getName(method);
                    NSString *selName = [[NSString alloc] initWithUTF8String:sel_getName(sel)];
                    if ([[selName lowercaseString] containsString:inputMethodName]) {{
                        NSString *clsName = [[NSString alloc] initWithUTF8String:class_getName(cls)];
                        [result appendFormat:@"(+) %@\\n\\tType encoding:%s\\n\\tClass:%@\\n", selName, method_getTypeEncoding(method), clsName];
                        findCount += 1;
                    }}
                }}
                free(classMethodList);
            }}
            if (findCount == 0) {{
                [result insertString:@"No method found.\\n" atIndex:0];
            }} else {{
                [result insertString:[[NSString alloc] initWithFormat:@"Methods count: %u \\n", findCount] atIndex:0];
            }}

            free(classList);
            result;
        '''

    result = HM.evaluateExpressionValue(command_script).GetObjectDescription()
    HM.DPrint(result)
Ejemplo n.º 28
0
def deleteFile(debugger, command, exe_ctx, result, internal_dict):
    """
    Syntax:
        deletefile [--option]
        deletefile [--file] <path>

    Options:
        --all/-a; Delete all file in the sandbox
        --documents/-d; Delete the "~/Documents" directory
        --library/-l; Delete the "~/Library" directory
        --tmp/-t; Delete the "~/tmp" directory
        --caches/-c; Delete the "~/Library/Caches" directory
        --preferences/-p; Delete the "~Library/Preferences" directory
        --file/-f; Delete the specified file or directory

    Examples:
        (lldb) deletefile -a
        (lldb) deletefile -c -p
        (lldb) deletefile -f path/to/fileOrDirectory

    This command is implemented in HMFileCommands.py
    """

    command_args = shlex.split(command)
    parser = generate_DeleteFile_optionParser()
    try:
        # options: optparse.Values
        # args: list
        (options, args) = parser.parse_args(command_args)
    except:
        result.SetError(parser.usage)
        return

    hasOption = False

    if options.all:
        # Reserve the directory under the Home directory
        hasOption = True
        subFileArrayValue = HM.evaluateExpressionValue(
            "[[NSFileManager defaultManager] contentsOfDirectoryAtPath:(NSString *)NSHomeDirectory() error:nil]"
        )
        for i in range(subFileArrayValue.GetNumChildren()):
            subFileValue = subFileArrayValue.GetChildAtIndex(i)
            HM.DPrint("=============" + subFileValue.GetObjectDescription() +
                      "=============")
            subFilePathValue = HM.evaluateExpressionValue(
                f"[(NSString *)NSHomeDirectory() stringByAppendingPathComponent:(NSString *){subFileValue.GetValue()}]"
            )
            deleteAllFileInDirectory(subFilePathValue.GetObjectDescription())

    if options.documents:
        hasOption = True
        documentsDirectoryValue = HM.evaluateExpressionValue(
            "(NSString *)[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject]"
        )
        deleteAllFileInDirectory(
            documentsDirectoryValue.GetObjectDescription())

    if options.library:
        hasOption = True
        libraryDirectoryValue = HM.evaluateExpressionValue(
            "(NSString *)[NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) firstObject]"
        )
        deleteAllFileInDirectory(libraryDirectoryValue.GetObjectDescription())

    if options.tmp:
        hasOption = True
        tmpDirectoryValue = HM.evaluateExpressionValue(
            "(NSString *)NSTemporaryDirectory()")
        deleteAllFileInDirectory(tmpDirectoryValue.GetObjectDescription())

    if options.caches:
        hasOption = True
        cachesDirectoryValue = HM.evaluateExpressionValue(
            "(NSString *)[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject]"
        )
        deleteAllFileInDirectory(cachesDirectoryValue.GetObjectDescription())

    if options.preferences:
        hasOption = True
        libraryDirectoryValue = HM.evaluateExpressionValue(
            "(NSString *)[NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) firstObject]"
        )
        preferencesDirectoryValue = HM.evaluateExpressionValue(
            f"(NSString *)[(NSString *){libraryDirectoryValue.GetValue()} stringByAppendingPathComponent:@\"Preferences\"]"
        )
        deleteAllFileInDirectory(
            preferencesDirectoryValue.GetObjectDescription())

    if options.file:
        hasOption = True
        deleteFileOrDirectory(options.file)

    if not hasOption:
        HM.DPrint(
            "Requires at least one target file/directory, Please enter \"help deletefile\" for help."
        )
Ejemplo n.º 29
0
def register() -> None:

    if HM.existClass(gClassName):
        return

    HMProgressHUD.register()
    HMDebugWindow.register()
    HMDebugBaseViewController.register()

    # Register class
    HMProgressHUD.show(f"Register {gClassName}...")
    HM.DPrint(f"Register {gClassName}...")

    classValue = HM.allocateClass(gClassName, HMDebugBaseViewController.gClassName)
    HM.addIvar(classValue.GetValue(), "_previousKeyWindow", "UIWindow *")
    HM.addIvar(classValue.GetValue(), "_highlightView", "UIView *")
    HM.addIvar(classValue.GetValue(), "_targetView", "UIView *")
    HM.addIvar(classValue.GetValue(), "_exitBtn", "UIButton *")

    HM.addIvar(classValue.GetValue(), "_infoView", "UIView *")
    HM.addIvar(classValue.GetValue(), "_actionView", "UIButton *")
    HM.registerClass(classValue.GetValue())

    HM.DPrint(f"Add methods to {gClassName}...")
    startIMPValue = makeStartIMP()
    if not HM.judgeSBValueHasValue(startIMPValue):
        HMProgressHUD.hide()
        return
    HM.addClassMethod(gClassName, "start", startIMPValue.GetValue(), "@@:")

    viewDidLoadIMPValue = makeViewDidLoadIMP()
    if not HM.judgeSBValueHasValue(viewDidLoadIMPValue):
        HMProgressHUD.hide()
        return
    HM.addInstanceMethod(gClassName, "viewDidLoad", viewDidLoadIMPValue.GetValue(), "v@:")

    viewDidLayoutSubviewsIMPValue = makeViewDidLayoutSubviewsIMP()
    if not HM.judgeSBValueHasValue(viewDidLayoutSubviewsIMPValue):
        HMProgressHUD.hide()
        return
    HM.addInstanceMethod(gClassName, "viewDidLayoutSubviews", viewDidLayoutSubviewsIMPValue.GetValue(), "v@:")

    # event
    HM.DPrint(f"Add methods to {gClassName}......")
    clickExitBtnIMPValue = makeClickExitBtnIMP()
    if not HM.judgeSBValueHasValue(clickExitBtnIMPValue):
        HMProgressHUD.hide()
        return
    HM.addInstanceMethod(gClassName, "clickExitBtn", clickExitBtnIMPValue.GetValue(), "v@:")

    clickCloseBtnIMPValue = makeClickCloseBtnIMP()
    if not HM.judgeSBValueHasValue(clickCloseBtnIMPValue):
        HMProgressHUD.hide()
        return
    HM.addInstanceMethod(gClassName, "clickCloseBtn", clickCloseBtnIMPValue.GetValue(), "v@:")

    handleTapRecognizerIMPValue = makeHandleTapRecognizerIMP()
    if not HM.judgeSBValueHasValue(handleTapRecognizerIMPValue):
        HMProgressHUD.hide()
        return
    HM.addInstanceMethod(gClassName, "handleTapRecognizer:", handleTapRecognizerIMPValue.GetValue(), "v@:@")

    findSubviewAtPointInViewIMPValue = makeFindSubviewAtPointInViewIMP()
    if not HM.judgeSBValueHasValue(findSubviewAtPointInViewIMPValue):
        HMProgressHUD.hide()
        return
    HM.addInstanceMethod(gClassName, "findSubviewAtPoint:inView:", findSubviewAtPointInViewIMPValue.GetValue(), "@@:{CGPoint=dd}@")

    refreshTargetViewIMPValue = makeRefreshTargetViewIMP()
    if not HM.judgeSBValueHasValue(refreshTargetViewIMPValue):
        HMProgressHUD.hide()
        return
    HM.addInstanceMethod(gClassName, "refreshTargetView:", refreshTargetViewIMPValue.GetValue(), "v@:@")

    getInfoArrayFromTargetViewIMPValue = makeGetInfoArrayFromTargetViewIMP()
    if not HM.judgeSBValueHasValue(getInfoArrayFromTargetViewIMPValue):
        HMProgressHUD.hide()
        return
    HM.addInstanceMethod(gClassName, "getInfoArrayFromTargetView:", getInfoArrayFromTargetViewIMPValue.GetValue(), "@@:@")

    # function action
    HM.DPrint(f"Add methods to {gClassName}.........")
    if not addFunctionMethods():
        HMProgressHUD.hide()
        return

    HM.DPrint(f"Register {gClassName} done!")
    HMProgressHUD.hide()