示例#1
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)
示例#2
0
文件: HMSandbox.py 项目: cxymq/HMLLDB
def sandbox(debugger, command, exe_ctx, result, internal_dict):
    """
    Syntax:
        sandbox

    Examples:
        (lldb) sandbox

    This command is implemented in HMSandbox.py
    """

    HMSandboxViewController.register()

    command_script = f'''
        UIViewController *vc = (UIViewController *)[[NSClassFromString(@"{HMSandboxViewController.gClassName}") alloc] init];
        UINavigationController *nv = [[UINavigationController alloc] initWithRootViewController:vc];
        ((void (*)(id, SEL, long)) objc_msgSend)((id)nv, @selector(setModalPresentationStyle:), 0); // UIModalPresentationFullScreen
        UIViewController *rootVC = [UIApplication sharedApplication].keyWindow.rootViewController;
        if ([rootVC presentedViewController]) {{
            [[rootVC presentedViewController] presentViewController:nv animated:YES completion:nil];
        }} else {{
            [rootVC presentViewController:nv animated:YES completion:nil];
        }}
    '''
    HM.evaluateExpressionValue(command_script)

    HM.processContinue()
示例#3
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)
示例#4
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())
示例#5
0
def inspect(debugger, command, exe_ctx, result, internal_dict):
    """
    Syntax:
        inspect

    Examples:
        (lldb) inspect

    Summary:
        Inspect UIView.
        The "infoView" is based on https://github.com/QMUI/LookinServer

    This command is implemented in HMInspectView.py
    """

    HMInspectViewController.register()

    command_script = f'''
        Class objClass = (Class)objc_lookUpClass("{HMInspectViewController.gClassName}");
        if ((BOOL)[(Class)objClass respondsToSelector:@selector(start)]) {{
            (void)[objClass performSelector:@selector(start)];
        }}
    '''
    HM.evaluateExpressionValue(command_script)

    HM.processContinue()
示例#6
0
def hide() -> None:
    command_script = f'''
        Class progressHUDCls = (Class)objc_lookUpClass("{gClassName}");
        (UIView *)[progressHUDCls performSelector:@selector(hideHUD)];
        (void)[CATransaction flush];
    '''
    HM.evaluateExpressionValue(command_script)
示例#7
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')
示例#8
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"
        )
示例#9
0
def getNavigationVC() -> Optional[str]:
    rootViewController = HM.evaluateExpressionValue("[[[UIApplication sharedApplication] keyWindow] rootViewController]").GetValue()
    if verifyObjIsKindOfClass(rootViewController, "UINavigationController"):
        return rootViewController
    elif verifyObjIsKindOfClass(rootViewController, "UITabBarController"):
        selectedViewController = HM.evaluateExpressionValue(f"[(UITabBarController *){rootViewController} selectedViewController]").GetValue()
        if verifyObjIsKindOfClass(selectedViewController, "UINavigationController"):
            return selectedViewController
        else:
            return None
    else:
        return None
示例#10
0
文件: HMDelay.py 项目: cxymq/HMLLDB
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()
示例#11
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)
示例#12
0
def show(text: Optional[str]) -> None:

    register()

    command_script = f'''
        Class progressHUDCls = (Class)objc_lookUpClass("{gClassName}");
        (UIView *)[progressHUDCls performSelector:@selector(showHUD)];
    '''

    if len(text) > 0:
        command_script += f'(void)[progressHUDCls performSelector:@selector(setText:) withObject:@"{text}"];'

    command_script += "(void)[CATransaction flush];"
    HM.evaluateExpressionValue(command_script)
示例#13
0
def makeShowHUDIMP() -> lldb.SBValue:
    command_script = f'''
        UIView * (^IMPBlock)(id) = ^UIView *(id classSelf) {{
            
            UIView *HUD = (UIView *)[(Class)objc_lookUpClass("{gClassName}") performSelector:@selector(sharedInstance)];
            
            if ([HUD superview] == nil) {{
                [[UIApplication sharedApplication].keyWindow addSubview:HUD];
            }} else {{
                [[HUD superview] bringSubviewToFront:HUD];
            }}
                        
            UIActivityIndicatorView *indicator = (UIActivityIndicatorView *)[HUD valueForKey:@"_indicator"];
            [indicator setHidden:NO];
            [indicator startAnimating];

            [HUD setNeedsLayout];
            [HUD layoutIfNeeded];
            
            return HUD;
        }};

        imp_implementationWithBlock(IMPBlock);    
    '''

    return HM.evaluateExpressionValue(command_script)
示例#14
0
def makeViewDidLoadIMP() -> lldb.SBValue:
    command_script = f'''
        void (^IMPBlock)(UIViewController *) = ^(UIViewController *vc) {{
            Class cls = objc_lookUpClass("{gClassName}");
            struct objc_super superInfo = {{
                .receiver = vc,
                .super_class = (Class)class_getSuperclass((Class)cls)
            }};
    
            ((void (*)(struct objc_super *, SEL))objc_msgSendSuper)(&superInfo, @selector(viewDidLoad));
            
            // property initialize
            (void)[vc.view setBackgroundColor:[UIColor whiteColor]];
            vc.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:vc action:@selector(dismissSelf)];
            vc.navigationItem.title = @"Tool";
            
            // tableView
            UITableView *tv = [[UITableView alloc] init];
            tv.frame = vc.view.bounds;
            tv.delegate = (id)vc;
            tv.dataSource = (id)vc;
            tv.rowHeight = 50;
            tv.tableFooterView = [[UIView alloc] init];
            if ([tv respondsToSelector:@selector(setContentInsetAdjustmentBehavior:)]) {{
                // UIScrollViewContentInsetAdjustmentAutomatic
                ((void (*)(id, SEL, long)) objc_msgSend)((id)tv, @selector(setContentInsetAdjustmentBehavior:), 0);
            }}
            [vc.view addSubview:tv];
        }};
        
        imp_implementationWithBlock(IMPBlock);

     '''
    return HM.evaluateExpressionValue(command_script)
示例#15
0
def makeViewForHeaderInSectionIMP() -> lldb.SBValue:
    command_script = '''
        UIView * (^IMPBlock)(UIViewController *, UITableView *, long) = ^UIView *(UIViewController *vc, UITableView *tv, long section) {
            UITableViewHeaderFooterView *header = [tv dequeueReusableHeaderFooterViewWithIdentifier:@"Header"];
            if (header == nil) {
                header = [[UITableViewHeaderFooterView alloc] initWithReuseIdentifier:@"Header"];
                UIView *backgroundView = [[UIView alloc] init];
                (void)[backgroundView setBackgroundColor:(UIColor *)[vc.view backgroundColor]];
                [header setBackgroundView:backgroundView];
                
                UILabel *titleLab = [[UILabel alloc] init];
                titleLab.tag = 11111;
                titleLab.font = [UIFont systemFontOfSize:16];
                titleLab.textColor = [UIColor grayColor];
                titleLab.numberOfLines = 0;
                [header.contentView addSubview:titleLab];
                
                titleLab.translatesAutoresizingMaskIntoConstraints = NO;
                [[NSLayoutConstraint constraintWithItem:titleLab attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:header.contentView attribute:NSLayoutAttributeTop multiplier:1.0 constant:8] setActive:YES];
                [[NSLayoutConstraint constraintWithItem:titleLab attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:header.contentView attribute:NSLayoutAttributeLeft multiplier:1.0 constant:16] setActive:YES];
                [[NSLayoutConstraint constraintWithItem:titleLab attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:header.contentView attribute:NSLayoutAttributeBottom multiplier:1.0 constant:-8] setActive:YES];
                [[NSLayoutConstraint constraintWithItem:titleLab attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:header.contentView attribute:NSLayoutAttributeRight multiplier:1.0 constant:-16] setActive:YES];
            }
            
            UILabel *titleLab = (UILabel *)[header.contentView viewWithTag:11111];
            NSString *currentPath = (NSString *)[vc valueForKey:@"_currentPath"];
            titleLab.text = [currentPath stringByAbbreviatingWithTildeInPath];
    
            return header;
        };
        imp_implementationWithBlock(IMPBlock);
     '''
    return HM.evaluateExpressionValue(command_script)
示例#16
0
def makeLoadPathIMP() -> lldb.SBValue:
    command_script = '''
        void (^IMPBlock)(UIViewController *, NSString *) = ^(UIViewController *vc, NSString *path) {
            [vc setValue:path forKey:@"_currentPath"];
            if ([path isEqual:(NSString *)NSHomeDirectory()]) {
                vc.navigationItem.title = @"SandBox";
            } else {
                vc.navigationItem.title = [path lastPathComponent];
            }
            
            NSMutableArray *childPaths = [[NSMutableArray alloc] init]; // NSMutableArray<NSString *> *childPaths
            NSArray *subpaths = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:path error:NULL]; // NSArray<NSString *> *subpaths
            for (NSString *subpath in subpaths) {
                [childPaths addObject:[path stringByAppendingPathComponent:subpath]];
            }
            [vc setValue:childPaths forKey:@"_childPaths"];
            
            UITableView *tableView = (UITableView *)[vc valueForKey:@"_tableView"];
            if ([tableView respondsToSelector:@selector(adjustedContentInset)]) {
                [tableView setContentOffset:(CGPoint){0, -tableView.adjustedContentInset.top} animated:NO];
            } else {
                [tableView setContentOffset:(CGPoint){0, -tableView.contentInset.top} animated:NO];
            }
            [tableView reloadData];
        };
        
        imp_implementationWithBlock(IMPBlock);

     '''
    return HM.evaluateExpressionValue(expression=command_script,
                                      prefix=HMExpressionPrefix.gPrefix)
示例#17
0
def makeAddToKeyWindowIMP() -> lldb.SBValue:
    command_script = '''

        UILabel * (^addToKeyWindowBlock)(id) = ^UILabel *(id classSelf) {
            UILabel *fpsLabel = (UILabel *)[[NSClassFromString(@"HMFPSLabel") alloc] init];
            (void)[fpsLabel setFrame:(CGRect){60, [UIApplication sharedApplication].statusBarFrame.size.height, 58, 20}];
            fpsLabel.layer.zPosition = 100;
            fpsLabel.layer.cornerRadius = 5;
            fpsLabel.clipsToBounds = YES;
            fpsLabel.textAlignment = (NSTextAlignment)1;
            fpsLabel.userInteractionEnabled = NO;
            (void)[fpsLabel setBackgroundColor:[[UIColor blackColor] colorWithAlphaComponent:0.6]];
            fpsLabel.font = [UIFont systemFontOfSize:14];
    
            CADisplayLink *link = [CADisplayLink displayLinkWithTarget:fpsLabel selector:NSSelectorFromString(@"tick:")];
            [link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
            [fpsLabel setValue:link forKey:@"_link"];
    
            [[UIApplication sharedApplication].keyWindow addSubview:fpsLabel];
            
            return fpsLabel;
        };
        imp_implementationWithBlock(addToKeyWindowBlock);
        
    '''

    return HM.evaluateExpressionValue(expression=command_script,
                                      prefix=HMExpressionPrefix.gPrefix)
示例#18
0
def makeUpdateFPSIMP() -> lldb.SBValue:
    command_script = '''

        void (^updateFPSBlock)(UIView *, int) = ^(UIView *HUD, int fps) {
            UIColor *valueColor = [UIColor whiteColor];
            if (fps < 45) {
                valueColor = [[UIColor alloc] initWithRed:0.88 green:0.36 blue:0.36 alpha:1];
            } else if (fps < 52) {
                valueColor = [[UIColor alloc] initWithRed:0.91 green:0.73 blue:0.45 alpha:1];
            }
            UIFont *valueFont = [UIFont systemFontOfSize:12];
            UIColor *unitColor = [UIColor whiteColor];
            UIFont *unitFont = [UIFont systemFontOfSize:8];

            NSMutableAttributedString *valueText = [[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:@"%d", fps] attributes:@{(id)NSFontAttributeName: valueFont, (id)NSForegroundColorAttributeName: valueColor}];
            NSAttributedString *unitText = [[NSAttributedString alloc] initWithString:@" FPS" attributes:@{(id)NSFontAttributeName: unitFont, (id)NSForegroundColorAttributeName: unitColor}];
            [valueText appendAttributedString:unitText];

            UILabel *fpsLab = [HUD valueForKey:@"_fpsLab"];
            fpsLab.attributedText = valueText;
        };

        imp_implementationWithBlock(updateFPSBlock);

    '''
    return HM.evaluateExpressionValue(command_script)
示例#19
0
def makeCellForRowAtIndexPathIMP() -> lldb.SBValue:
    command_script = '''
        UITableViewCell * (^IMPBlock)(UIViewController *, UITableView *, NSIndexPath *) = ^UITableViewCell *(UIViewController *vc, UITableView *tv, NSIndexPath *indexPath) {
            NSString * reuseIdentifier = @"Cell";
            UITableViewCell *cell = [tv dequeueReusableCellWithIdentifier:reuseIdentifier];
            if (cell == nil) {
                // UITableViewCellStyleDefault
                cell = [UITableViewCell alloc];
                cell = ((UITableViewCell * (*)(id, SEL, long, id)) objc_msgSend)((id)cell, @selector(initWithStyle:reuseIdentifier:), 0, reuseIdentifier);
                // UITableViewCellSelectionStyleNone
                ((void (*)(id, SEL, long)) objc_msgSend)((id)cell, @selector(setSelectionStyle:), 0);
                // UITableViewCellAccessoryDisclosureIndicator
                ((void (*)(id, SEL, long)) objc_msgSend)((id)cell, @selector(setAccessoryType:), 1);
            }
            
            long row = indexPath.row;
            if (row == 0) {
                cell.textLabel.text = @"App and system information";
            } else if (row == 1) {
                cell.textLabel.text = @"Sandbox";
            } else if (row == 2) {
                cell.textLabel.text = @"Inspect view";
            }
            return cell;
        };
        
        imp_implementationWithBlock(IMPBlock);    
    '''

    return HM.evaluateExpressionValue(command_script)
示例#20
0
def makeDebugHUDtickIMP() -> lldb.SBValue:
    command_script = '''

        void (^debugHUDtickBlock)(UIView *, CADisplayLink *) = ^(UIView *HUD, CADisplayLink *link) {
            NSNumber *countNum = [HUD valueForKey:@"_count"];
            int count = [countNum intValue] + 1;
            [HUD setValue:@(count) forKey:@"_count"];

            NSNumber *lastTimeNum = [HUD valueForKey:@"_lastTime"];
            double delta = link.timestamp - [lastTimeNum doubleValue];
            if (delta < 1) {
                return;
            }

            [HUD setValue:@(link.timestamp) forKey:@"_lastTime"];
            [HUD setValue:@(0) forKey:@"_count"];

            int fps = (int)((count / delta) + 0.5);
            
            (void)[HUD updateMemoryFootprint];
            (void)[HUD updateCPUUtilization];
            (void)[HUD updateFPS:fps];
        };

        imp_implementationWithBlock(debugHUDtickBlock);

    '''
    return HM.evaluateExpressionValue(command_script)
示例#21
0
def makeViewDidLoadIMP() -> lldb.SBValue:
    command_script = f'''
        void (^IMPBlock)(UIViewController *) = ^(UIViewController *vc) {{
            Class cls = objc_lookUpClass("{gClassName}");
            struct objc_super superInfo = {{
                .receiver = vc,
                .super_class = (Class)class_getSuperclass((Class)cls)
            }};

            ((void (*)(struct objc_super *, SEL))objc_msgSendSuper)(&superInfo, @selector(viewDidLoad));

            // property initialize
            (void)[vc.view setBackgroundColor:[UIColor whiteColor]];
            (void)[vc setExtendedLayoutIncludesOpaqueBars:YES];
            (void)[vc setAutomaticallyAdjustsScrollViewInsets:YES];
            
            if ([vc respondsToSelector:@selector(setOverrideUserInterfaceStyle:)]) {{
                [vc setOverrideUserInterfaceStyle:UIUserInterfaceStyleLight];
            }}
        }};

        imp_implementationWithBlock(IMPBlock);

     '''

    return HM.evaluateExpressionValue(command_script)
示例#22
0
def makeFindSubviewAtPointInViewIMP() -> lldb.SBValue:
    command_script = '''
        UIView * (^IMPBlock)(UIViewController *, CGPoint, UIView *) = ^UIView *(UIViewController *vc, CGPoint point, UIView *view) {
            NSArray *clsArr = @[[UITextField class], [UITextView class], [UIProgressView class], [UIActivityIndicatorView class], [UISlider class], [UISwitch class], [UIPageControl class], [UIStepper class]];
            for (Class cls in clsArr) {
                if ([view isKindOfClass:cls]) {
                    return view;
                }
            }
            
            UIView *targetView = nil;
            for (UIView *sView in view.subviews.reverseObjectEnumerator) {
                if ([sView isHidden] || sView.alpha <= 0.01) {
                    continue;
                }
                
                if (CGRectContainsPoint(sView.frame, point)) {
                    targetView = sView;
                    break;;
                }
            }
            
            if (!targetView) {
                return view;
            }
            
            CGPoint tPoint = [targetView convertPoint:point fromView:view];
            targetView = ((id (*)(id, SEL, CGPoint, id)) objc_msgSend)((id)vc, @selector(findSubviewAtPoint:inView:), tPoint, (id)targetView);
            return targetView;
        };  
        imp_implementationWithBlock(IMPBlock);
     '''
    return HM.evaluateExpressionValue(expression=command_script, prefix=HMExpressionPrefix.gPrefix)
示例#23
0
def makeHandleTapRecognizerIMP() -> lldb.SBValue:
    command_script = '''
        void (^IMPBlock)(UIViewController *, UITapGestureRecognizer *) = ^(UIViewController *vc, UITapGestureRecognizer *tapRecognizer) {
            // find targetView
            CGPoint point = [tapRecognizer locationInView:vc.view];
            UIView *_targetView = nil;
            UIWindow *_previousKeyWindow = (UIWindow *)[vc valueForKey:@"_previousKeyWindow"];
            for (UIWindow *window in [UIApplication sharedApplication].windows.reverseObjectEnumerator) {
                if (_targetView) {
                    break;
                }
                if (window == vc.view.window) {
                    continue;
                }
                if ([window isHidden]) {
                    continue;
                }
    
                CGPoint wPoint = [window convertPoint:point fromWindow:vc.view.window];
                if (window == _previousKeyWindow) {
                    _targetView = ((id (*)(id, SEL, CGPoint, id)) objc_msgSend)((id)vc, @selector(findSubviewAtPoint:inView:), wPoint, (id)window);
                } else {
                    _targetView = [window hitTest:wPoint withEvent:nil];
                }
            }
    
            printf("\\n[HMLLDB]: %s\\n", (char *)[[_targetView description] UTF8String]);
            (void)[vc performSelector:@selector(refreshTargetView:) withObject:(id)_targetView];
        };
        imp_implementationWithBlock(IMPBlock);
     '''
    return HM.evaluateExpressionValue(expression=command_script, prefix=HMExpressionPrefix.gPrefix)
示例#24
0
def makeViewDidLayoutSubviewsIMP() -> lldb.SBValue:
    command_script = f'''
        void (^IMPBlock)(UIViewController *) = ^(UIViewController *vc) {{
            Class cls = objc_lookUpClass("{gClassName}");
            struct objc_super superInfo = {{
                .receiver = vc,
                .super_class = (Class)class_getSuperclass((Class)cls)
            }};
            ((void (*)(struct objc_super *, SEL))objc_msgSendSuper)(&superInfo, @selector(viewDidLayoutSubviews));
            
            UIEdgeInsets safeAreaInsets = UIEdgeInsetsZero;
            if ([UIApplication.sharedApplication.keyWindow respondsToSelector:@selector(safeAreaInsets)]) {{
                safeAreaInsets = [UIApplication.sharedApplication.keyWindow safeAreaInsets];
            }}

            UIButton *_exitBtn = (UIButton *)[vc valueForKey:@"_exitBtn"];
            CGSize exitBtnSize = (CGSize){{_exitBtn.intrinsicContentSize.width + 20, _exitBtn.intrinsicContentSize.height}}; 
            CGFloat exitBtnY = vc.view.frame.size.height - safeAreaInsets.bottom - 10 - exitBtnSize.height;
            (void)[_exitBtn setFrame:(CGRect){{(vc.view.frame.size.width - exitBtnSize.width) / 2, exitBtnY, exitBtnSize.width, exitBtnSize.height}}];
            _exitBtn.layer.cornerRadius = exitBtnSize.height / 2;
        }};

        imp_implementationWithBlock(IMPBlock);
     '''
    return HM.evaluateExpressionValue(expression=command_script, prefix=HMExpressionPrefix.gPrefix)
示例#25
0
def makeStartIMP() -> lldb.SBValue:
    command_script = f'''
        UIViewController * (^IMPBlock)(id) = ^UIViewController *(id classSelf) {{
            UIViewController *vc = (UIViewController *)[[(Class)objc_lookUpClass("{gClassName}") alloc] init];
            [vc setValue:[UIApplication sharedApplication].keyWindow forKey:@"_previousKeyWindow"];

            UIWindow *window = (UIWindow *)[[(Class)objc_lookUpClass("{HMDebugWindow.gClassName}") alloc] init];
            if ((BOOL)[[UIApplication sharedApplication] respondsToSelector:@selector(connectedScenes)]) {{
                NSSet *scenes = [[UIApplication sharedApplication] connectedScenes]; // NSSet<UIScene *> *scenes
                for (id scene in scenes) {{
                    if ((long)[scene activationState] == 0 && (BOOL)[scene isKindOfClass:NSClassFromString(@"UIWindowScene")]) {{
                        // UISceneActivationStateForegroundActive
                        (void)[window setWindowScene:scene];
                        break;
                    }}
                }}
            }}
            (void)[window setFrame:(CGRect)UIScreen.mainScreen.bounds];
            (void)[window setBackgroundColor:[UIColor clearColor]];
            window.windowLevel = UIWindowLevelAlert - 1;
            window.tag = {gWindowTag};
            window.rootViewController = vc;
            [window makeKeyAndVisible];
            return vc;
        }};

        imp_implementationWithBlock(IMPBlock);
     '''
    return HM.evaluateExpressionValue(command_script, prefix=HMExpressionPrefix.gPrefix)
示例#26
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)
示例#27
0
def makeCanEditRowAtIndexPathIMP() -> lldb.SBValue:
    command_script = '''
        BOOL (^IMPBlock)(UIViewController *, UITableView *, NSIndexPath *) = ^BOOL(UIViewController *vc, UITableView *tv, NSIndexPath * indexPath) {
            return YES;
        };
        imp_implementationWithBlock(IMPBlock);
     '''
    return HM.evaluateExpressionValue(command_script)
示例#28
0
def makeEditingStyleForRowAtIndexPathIMP() -> lldb.SBValue:
    command_script = '''
        UITableViewCellEditingStyle (^IMPBlock)(UIViewController *, UITableView *, NSIndexPath *) = ^UITableViewCellEditingStyle(UIViewController *vc, UITableView *tv, NSIndexPath *indexPath) {
            return UITableViewCellEditingStyleDelete;
        };
        imp_implementationWithBlock(IMPBlock);
     '''
    return HM.evaluateExpressionValue(command_script)
示例#29
0
def makeCellForRowAtIndexPathIMP() -> lldb.SBValue:
    command_script = '''
        UITableViewCell * (^IMPBlock)(UIViewController *, UITableView *, NSIndexPath *) = ^UITableViewCell *(UIViewController *vc, UITableView *tv, NSIndexPath *indexPath) {
            NSString * reuseIdentifier = @"Cell";
            UITableViewCell *cell = [tv dequeueReusableCellWithIdentifier:reuseIdentifier];
            if (cell == nil) {
                // UITableViewCellStyleDefault
                cell = [UITableViewCell alloc];
                cell = ((UITableViewCell * (*)(id, SEL, long, id)) objc_msgSend)((id)cell, @selector(initWithStyle:reuseIdentifier:), 0, reuseIdentifier);
                
                // UITableViewCellSelectionStyleNone
                ((void (*)(id, SEL, long)) objc_msgSend)((id)cell, @selector(setSelectionStyle:), 0);
                
                CGFloat marginX = 16;
                CGFloat marginY = 12;
                
                UILabel *leftLab = [[UILabel alloc] init];
                leftLab.tag = 1111;
                leftLab.font = [UIFont systemFontOfSize:16];
                leftLab.textColor = [UIColor blackColor];
                [cell.contentView addSubview:leftLab];
                
                leftLab.translatesAutoresizingMaskIntoConstraints = NO;
                [leftLab setContentCompressionResistancePriority:1000 forAxis:(UILayoutConstraintAxis)0];
                [[NSLayoutConstraint constraintWithItem:leftLab attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:cell.contentView attribute:NSLayoutAttributeTop multiplier:1.0 constant:marginY] setActive:YES];
                [[NSLayoutConstraint constraintWithItem:leftLab attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:cell.contentView attribute:NSLayoutAttributeLeft multiplier:1.0 constant:marginX] setActive:YES];
                [[NSLayoutConstraint constraintWithItem:leftLab attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationLessThanOrEqual toItem:cell.contentView attribute:NSLayoutAttributeBottom multiplier:1.0 constant:-marginY] setActive:YES];
    
                UILabel *rightLab = [[UILabel alloc] init];
                rightLab.tag = 2222;
                rightLab.font = [UIFont systemFontOfSize:16];
                rightLab.textColor = [UIColor grayColor];
                rightLab.textAlignment = (NSTextAlignment)2;
                rightLab.numberOfLines = 0;
                [cell.contentView addSubview:rightLab];
                
                rightLab.translatesAutoresizingMaskIntoConstraints = NO;
                [[NSLayoutConstraint constraintWithItem:rightLab attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:cell.contentView attribute:NSLayoutAttributeTop multiplier:1.0 constant:marginY] setActive:YES];
                [[NSLayoutConstraint constraintWithItem:rightLab attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:leftLab attribute:NSLayoutAttributeRight multiplier:1.0 constant:20] setActive:YES];
                [[NSLayoutConstraint constraintWithItem:rightLab attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:cell.contentView attribute:NSLayoutAttributeBottom multiplier:1.0 constant:-marginY] setActive:YES];
                [[NSLayoutConstraint constraintWithItem:rightLab attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:cell.contentView attribute:NSLayoutAttributeRight multiplier:1.0 constant:-marginX] setActive:YES];
            }
            
            NSArray *leftTextArray = [vc valueForKey:@"_leftTextArray"];
            NSArray *rightTextArray = [vc valueForKey:@"_rightTextArray"];
            
            UILabel *leftLab = (UILabel *)[cell.contentView viewWithTag:1111];
            UILabel *rightLab = (UILabel *)[cell.contentView viewWithTag:2222];
            leftLab.text = leftTextArray[indexPath.row];
            rightLab.text = rightTextArray[indexPath.row];
            
            return cell;
        };

        imp_implementationWithBlock(IMPBlock);    
    '''

    return HM.evaluateExpressionValue(command_script)
示例#30
0
def makeNumberOfRowsInSectionIMP() -> lldb.SBValue:
    command_script = '''
        long (^IMPBlock)(UIViewController *, UITableView *, long) = ^long(UIViewController *vc, UITableView *tv, long section) {
            NSMutableArray *childPaths = (NSMutableArray *)[vc valueForKey:@"childPaths"];
            return [childPaths count];
        };
        imp_implementationWithBlock(IMPBlock);
     '''
    return HM.evaluateExpressionValue(command_script)