美文网首页
iOS方法名混淆实践

iOS方法名混淆实践

作者: 王方帅 | 来源:发表于2019-09-26 18:14 被阅读0次

    项目缘由:
    由于iOS手机越狱后可以对app进行砸壳,进而进行class-dump操作,从而获取到app中所有类及方法,攻击者对方法进行hook,替换原有代码就可以实现一定程度的攻击。
    混淆实践:
    通过对iOS方法名的混淆,攻击者不能简单的根据方法名得知方法作用,对攻击者展示的是一段无意义的字符串,从而达到加大攻击难度的目的。
    首先用到了ios-class-guard工具,此工具被某文誉为对抗class-dump的神器,然而我看了一下,github已经是5年前的代码,无人维护,按照步骤混淆后,工程无法编译,很多不需要混淆的给混淆了,它提供的是加禁止混淆的列表,加起来太麻烦,所以我写了一个脚本,用来找到工程中所有以某一前缀命名的类的所有方法,此方法获取到后再把ios-class-guard生成的define定义进行筛选,大大减少了混淆带来的编译Error。
    现将代码摘录如下:

    - (void)viewDidLoad {
        [super viewDidLoad];
    
        // Do any additional setup after loading the view.
        NSString *path = @"/Users/wangfangshuai/Downloads/Applications";
        NSFileManager *fileManger = [NSFileManager defaultManager];
        NSArray *allFilePath = [fileManger subpathsOfDirectoryAtPath:path error:nil];
        
        _needConfuseClass = [NSMutableArray array];
        NSMutableArray *needConfuseFilePath = [NSMutableArray array];
    
        for (NSString *subPath in allFilePath) {
            NSString *className = [subPath substringToIndex:subPath.length-2];
            if ([self isNeedConfuse:className]) {
                [_needConfuseClass addObject:className];
                NSString *fullPath = [path stringByAppendingPathComponent:subPath];
                [needConfuseFilePath addObject:fullPath];
            }
        }
        NSLog(@"%@", _needConfuseClass);
        
        _needConfuseMethods = [NSMutableArray array];
        for (NSString *fullPath in needConfuseFilePath) {
            NSArray *allMethods = [self getAllMethodNamesWithFilePath:fullPath];
            NSLog(@"%@",allMethods);
            [_needConfuseMethods addObjectsFromArray:allMethods];
        }
        
        [self symbolHandle];
    }
    
    - (BOOL)isNeedConfuse:(NSString *)fileName {
        if ([fileName hasPrefix:@"CFD"] || [fileName hasPrefix:@"Radar"]) {
            return YES;
        }
        return NO;
    }
    
    - (NSArray *)getAllMethodNamesWithFilePath:(NSString *)path {
        NSMutableArray *methodArray = [NSMutableArray array];
        
        NSFileManager *fileManger = [NSFileManager defaultManager];
        NSData *data = [fileManger contentsAtPath:path];
        NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
        if ([path hasSuffix:@"Info.h"]) {
            
        }
        if ([string rangeOfString:@": PBGeneratedMessage <GeneratedMessageProtocol>"].length > 0) {
            //TODO::从ClassArray里移除
            //            NSString *className = []
            return @[];
        }
        NSArray *lineArray = [string componentsSeparatedByString:@"\n"];
        for (NSString *lineStr in lineArray) {
            if (([lineStr hasPrefix:@"- ("]||[lineStr hasPrefix:@"+ ("]) && [lineStr hasSuffix:@";"]) {
                NSString *methodName = [[[[lineStr componentsSeparatedByString:@":"] firstObject] componentsSeparatedByString:@")"] lastObject];
                if ([self isNotConfuseWithString:methodName]) {
                    
                } else {
                    [methodArray addObject:methodName];
                }
            }
        }
        
        return methodArray;
    }
    
    - (void)symbolHandle {
        NSMutableArray *symbolArray = [NSMutableArray array];
        
        [symbolArray addObject:@"#ifndef iOSSafeSymbols"];
        
        NSString *symbolPath = @"/Users/wangfangshuai/Downloads/symbols.h";
        NSFileManager *fileManger = [NSFileManager defaultManager];
        NSData *data = [fileManger contentsAtPath:symbolPath];
        NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
        NSArray *lineArray = [string componentsSeparatedByString:@"\n"];
        for (NSString *lineStr in lineArray) {
            if ([lineStr hasPrefix:@"#define"]) {
                NSString *defineStr = [lineStr componentsSeparatedByString:@" "][1];
                if (/*[_needConfuseClass containsObject:defineStr] || */[_needConfuseMethods containsObject:defineStr]) {
                    [symbolArray addObject:lineStr];
                }
            }
        }
        [symbolArray addObject:@"#endif"];
        NSString *symbolAllStr = [symbolArray componentsJoinedByString:@"\n"];
        NSData *writeData = [symbolAllStr dataUsingEncoding:NSUTF8StringEncoding];
        [writeData writeToFile:symbolPath atomically:YES];
        
    }
    
    - (BOOL)isNotConfuseWithString:(NSString *)string {
        NSArray *array = @[@"initWithStyle",@"pointInside",@"setNavigationBarHidden",@"addActionWithBlock",@"valueForKey",
                           @"initWithCustomView",@"isValidEmail",@"initWithReuseIdentifier",@"setNavigationBarHidden",@"countChooseView"];
        if ([array containsObject:string]) {
            return YES;
        } else {
            return NO;
        }
    }
    

    筛选后的symbols.h文件如下:


    筛选后的symbols

    混淆后Hopper的方法名如下:


    Hopper后

    相关文章

      网友评论

          本文标题:iOS方法名混淆实践

          本文链接:https://www.haomeiwen.com/subject/zxjnectx.html