iOS方法名混淆实践

2019-09-26  本文已影响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后
上一篇下一篇

猜你喜欢

热点阅读