美文网首页
runtime 在逆向中的使用

runtime 在逆向中的使用

作者: CDLOG | 来源:发表于2020-03-05 15:08 被阅读0次

在逆向工程中,利用runtime可以动态获取类和属性,绑定属性,替换方法的实现。

KVC

可以通过直接获取类的私有属性。

    MyClass *myClass = [[MyClass alloc] init];
    
    //KVC
    NSString* property = [myClass valueForKey:@"_property"];
    NSLog(@"property: %@", property);
    
    Ivar ivar = class_getInstanceVariable(objc_getClass("MyClass"), "_property");
    if(ivar){
        NSString* ivarProperty = (__bridge NSString *)(*(void**)((__bridge void*)myClass + ivar_getOffset(ivar)));
        NSLog(@"ivarProperty: %@", ivarProperty);
    }

关联对象AssociatedObject

在对象实例化后是不能动态添加属性的,除非是动态创建一个类。要为已存在的对象添加一个属性,可以通过关联对象(AssociatedObject)添加。关联对象相当于把一个对象关联到另一个对象上,关联后可以随时获取该关联对象,在对象被销毁时会移除所有关联对象。

objc_setAssociatedObject给myClass对象关联一个字符串
objc_getAssociatedObject获取myClass对象的字符串
第二个参数作为关联对象的唯一标识,有3种标识方法

//1,第一种标识方法
//static const void *kAssociatedKey = &kAssociatedKey;
objc_setAssociatedObject(myClass, kAssociatedKey, @"AssociatedObject1", OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    
    NSString* associatedString = objc_getAssociatedObject(myClass, kAssociatedKey);
    
    NSLog(@"associatedString: %@", associatedString);
 //第二种标识方法
//static void *kExampleDoubleKey;
    objc_setAssociatedObject(myClass, &kExampleDoubleKey, @"AssociatedObject2", OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    
    associatedString = objc_getAssociatedObject(myClass, &kExampleDoubleKey);
    
    NSLog(@"associatedString: %@", associatedString);
   //第三种标识方法
    objc_setAssociatedObject(myClass, @selector(myProperty), @"AssociatedObject3", OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    
    associatedString = objc_getAssociatedObject(myClass, @selector(myProperty));
    
    NSLog(@"associatedString: %@", associatedString);

交换方法 method Swizzling

对某方法进行拦截和修改来修改程序的逻辑和数据。

+ (void)load {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        Class class = [self class];
        //源方法IMP
        SEL originalSelector = @selector(viewWillAppear:);
       //目标方法IMP
        SEL swizzledSelector = @selector(ms_viewWillAppear:);
        //源方法名
        Method originalMethod = class_getInstanceMethod(class, originalSelector);
        //目标方法名
        Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
        //给类添加方法以及IMP
        BOOL didAddMethod =
        class_addMethod(class,
                        originalSelector,
                        method_getImplementation(swizzledMethod),
                        method_getTypeEncoding(swizzledMethod));
        
        if (didAddMethod) {
          //给类的方法替换IMp
            class_replaceMethod(class,
                                swizzledSelector,
                                method_getImplementation(originalMethod),
                                method_getTypeEncoding(originalMethod));
        } else {
            method_exchangeImplementations(originalMethod, swizzledMethod);
        }
    });
}

#pragma mark - Method Swizzling

- (void)ms_viewWillAppear:(BOOL)animated {
    [self ms_viewWillAppear:animated];
    NSLog(@"viewWillAppear: %@", self);
}

相关文章

网友评论

      本文标题:runtime 在逆向中的使用

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