美文网首页
减少crash的方法hook

减少crash的方法hook

作者: 哥只是个菜鸟 | 来源:发表于2021-06-18 11:38 被阅读0次
    • 这种方法可能不够严谨,会出现找不到originalSelector方法的情况
    - (void)hookInstanceMethod:(SEL)originalSelector AndSelector:(SEL)swizzledSelector {
        Method originMethod = class_getInstanceMethod(self.class, originalSelector);
        Method newMethod = class_getInstanceMethod(self.class, swizzledSelector);
        method_exchangeImplementations(originMethod, newMethod);
    }
    
    + (void)SwizzledMethod:(Class)class OriginalSelector:(SEL)originalSelector newSelector:(SEL)newSelector {
        Method originalMethod = class_getInstanceMethod(class, originalSelector);
        Method newMethod = class_getInstanceMethod(class, newSelector);
    //    if (originMethod && newMethod) {
    //        method_exchangeImplementations(originMethod, newMethod);
    //    }
        
        //class_addMethod 添加的SEL是 originalSelector ,IMP 是 method_getImplementation(originalMethod),我称他们为原配,
           //如果本类中,已经有 originalSelector,再添加 originalSelector, 肯定返回NO,添加失败,那就直接交换了,跟第一版hook流程一模一样了,
           //如果本类中,没有此SEL,那就会去父类里找,返回的就是父类里的信息,然后将父类的信息,添加到本类中,就相当于,本类完全的继承了父类的方法,
           BOOL didAddMethod = class_addMethod(class, originalSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));
           if (didAddMethod) {
               //添加成功后,本类中,已经有一个originalSelector方法了
               //我们第一次获得originalMethod是返回父类的originalMethod
               //我们需要再重新获得一下originalMethod,这次返回的不是父类的originalMethod
               //而是我们刚刚class_addMethod添加的到本类的originalMethod
               
               originalMethod = class_getInstanceMethod(class, originalSelector);
           }
           
           //走到这,就证明了,本类中肯定已经有这两个方法了,那就这样直接交换吧。
           method_exchangeImplementations(newMethod, originalMethod);
    }
    
    • 这里只贴避免数组越界的例子,(其他字典,字符串类似),这里注意替换方法的class不能是[NSArray class],之前一直方法替换不成功,问题出在这里
     swizzling_exchangeMethod([NSArray class], @selector(objectAtIndex:), 
    swizzling_exchangeMethod(objc_getClass("__NSArray0"), @selector(objectAtIndex:), 
    
    image.png
    
    + (void)load {
        //__NSArrayI:不可变,2个或2以上元素  __NSArray0:空数组  __NSArrayM:可变  __NSSingleObjectArrayI:只有单个元素
    //    [array objectAtIndex:8]
        [SwizzledHelper SwizzledMethod:objc_getClass("__NSArrayI") OriginalSelector:@selector(objectAtIndex:) newSelector:@selector(array_objectAtIndex:)];
        [SwizzledHelper SwizzledMethod:objc_getClass("__NSArray0") OriginalSelector:@selector(objectAtIndex:) newSelector:@selector(empty_objectAtIndex:)];
        [SwizzledHelper SwizzledMethod:objc_getClass("__NSArrayM") OriginalSelector:@selector(objectAtIndex:) newSelector:@selector(arrayM_objectAtIndex:)];
        [SwizzledHelper SwizzledMethod:objc_getClass("__NSSingleObjectArrayI") OriginalSelector:@selector(objectAtIndex:) newSelector:@selector(singleArray_objectAtIndex:)];
    
        //array[8]
        [SwizzledHelper SwizzledMethod:objc_getClass("__NSArrayI") OriginalSelector:@selector(objectAtIndexedSubscript:) newSelector:@selector(array_objectAtIndexedSubscript:)];
        [SwizzledHelper SwizzledMethod:objc_getClass("__NSArray0") OriginalSelector:@selector(objectAtIndexedSubscript:) newSelector:@selector(empty_objectAtIndexedSubscript:)];
        [SwizzledHelper SwizzledMethod:objc_getClass("__NSArrayM") OriginalSelector:@selector(objectAtIndexedSubscript:) newSelector:@selector(arrayM_objectAtIndexedSubscript:)];
        [SwizzledHelper SwizzledMethod:objc_getClass("__NSSingleObjectArrayI") OriginalSelector:@selector(objectAtIndexedSubscript:) newSelector:@selector(singleArray_objectAtIndexedSubscript:)];
    
        [SwizzledHelper SwizzledMethod:objc_getClass("__NSArrayM") OriginalSelector:@selector(removeObjectAtIndex:) newSelector:@selector(arrayM_removeObjectAtIndex:)];
        [SwizzledHelper SwizzledMethod:objc_getClass("__NSArrayM") OriginalSelector:@selector(replaceObjectAtIndex:withObject:) newSelector:@selector(arrayM_replaceObjectAtIndex:withObject:)];
        [SwizzledHelper SwizzledMethod:objc_getClass("__NSArrayM") OriginalSelector:@selector(insertObject:atIndex:) newSelector:@selector(arrayM_insertObject:atIndex:)];
    }
    
    - (id)array_objectAtIndex:(NSUInteger)index {
        if (index < self.count) {
            return [self array_objectAtIndex:index];
        } else {
            return nil;
        }
    }
    
    - (id)empty_objectAtIndex:(NSUInteger)index {
        if (index < self.count) {
            return [self empty_objectAtIndex:index];
        } else {
            return nil;
        }
    }
    
    - (id)arrayM_objectAtIndex:(NSUInteger)index {
        if (index < self.count) {
            return [self arrayM_objectAtIndex:index];
        } else {
            return nil;
        }
    }
    
    - (id)singleArray_objectAtIndex:(NSUInteger)index {
        if (index < self.count) {
            return [self singleArray_objectAtIndex:index];
        } else {
            return nil;
        }
    }
    
    - (id)array_objectAtIndexedSubscript:(NSUInteger)index {
        if (index < self.count) {
            return [self array_objectAtIndexedSubscript:index];
        } else {
            return nil;
        }
    }
    
    - (id)empty_objectAtIndexedSubscript:(NSUInteger)index {
        if (index < self.count) {
            return [self empty_objectAtIndexedSubscript:index];
        } else {
            return nil;
        }
    }
    
    - (id)arrayM_objectAtIndexedSubscript:(NSUInteger)index {
        if (index < self.count) {
            return [self arrayM_objectAtIndexedSubscript:index];
        } else {
            return nil;
        }
    }
    
    - (id)singleArray_objectAtIndexedSubscript:(NSUInteger)index {
        if (index < self.count) {
            return [self singleArray_objectAtIndexedSubscript:index];
        } else {
            return nil;
        }
    }
    
    - (void)arrayM_insertObject:(id)object atIndex:(NSUInteger)index {
        if (object && index <= self.count) {
            [self arrayM_insertObject:object atIndex:index];
        }
    }
    
    - (void)arrayM_removeObjectAtIndex:(NSUInteger)index {
        if (index < self.count) {
             [self arrayM_removeObjectAtIndex:index];
        }
    }
    
    - (void)arrayM_replaceObjectAtIndex:(NSUInteger)index withObject:(id)object {
        if (object && index < self.count) {
             [self arrayM_replaceObjectAtIndex:index withObject:object];
        }
    }
    
    
    @end
    

    相关文章

      网友评论

          本文标题:减少crash的方法hook

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