load方法能否被hook钩挂交换?(中)

3 篇文章 1 订阅
1 篇文章 0 订阅

修改代码:
提交过程(由编辑时极其不稳定的临时性Cache缓存状态送入本地端待同步的硬盘区域)。
推送过程:通过推送动作实现将本地端待同步的硬盘区域最新内容状态同步上传至远程端。


了解元类(Meta Class)。Objc中实例方法的调用是通过给实例对象发消息实现的,对于实例方法是可行的,但类方法呢?类方法的调用没有“实例对象”可以发送消息。所以Objc的设计者引入了元类概念:元类对象是描述类对象的类,每个类都有自己的元类,也就是类的isa指针指向的类,调用类方法实际上是给类的元类对象(isa指针指向的类)发送消息。上文中class_getClassMethod 实现是调用class_getInstanceMethod并且入参 cls->getMeta()获取元类(给类的元类对象(isa指针指向的类)发送消息)正是这个原因。
在这里插入图片描述
了解元类概念后,既然名称为load声明方法是类风格定义方法(囊括类风格方法的容器方法列表存在于ClassA类的元类中),通过获取ClassA类的元类下的方法列表:

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Class metaClass = objc_getMetaClass("ClassA");
        runTests(metaClass);
    }
    return 0;
}

void runTests (Class c ) {
    unsigned int count;
    Method *methods = class_copyMethodList(c, &count);
    for (int i = 0; i < count; i++) {
        Method method = methods[i];
        SEL selector = method_getName(method);
        NSString *name = NSStringFromSelector(selector);
        NSLog(@"方法名:%@",name);
    }
}

 HookDemo[10929:9866637] 方法名:swizzle_load
 HookDemo[10929:9866637] 方法名:load

现在成功的获取到了ClassA类相关的容器方法列表。容器方法列表中既然有名称load的方法名称元素 ,说明名称load方法元素是可以hook钩挂交换。新建ClassB类并在ClassB类中定义声明某个名称为load的成员方法并保证编译运行后先调用ClassB类的load声明方法(CompileSources顺序:ClassB类资源文件放在ClassA类的资源文件前面),然后在ClassB类中的load方法名称下钩挂hook ClassA类下的定义load方法的IMP实际执行区(注意:这里钩挂交换的是ClassA类的元类下的方法IMP):

+ (void) load {
   NSString *className = @"ClassA";
    Class class = NSClassFromString(className);
    //钩挂交换的是ClassA类的元类下的方法
    Class mateClass = objc_getMetaClass("ClassA");
    //字段名部分+实际执行区Method的IMP部分
    //原方法名称字段名的选择器盒和替换方法名称字段名的选择器盒//selector本身仅仅字段名部分
    SEL originalSelector = @selector(load);
    SEL swizzledSelector = @selector(swizzle_load);
    
    // 原方法Method和替换方法Method(IMP部分所属Method实例)
    Method originalMethod = class_getClassMethod(class, originalSelector);
    Method swizzledMethod = class_getClassMethod(class, swizzledSelector);

    //如果当前类没有原方法的实现IMP,先调用class_addMethod来给原方法添加实现
    BOOL didAddMethod = class_addMethod(mateClass,
                                        originalSelector,
                                      method_getImplementation(swizzledMethod),
                                        method_getTypeEncoding(swizzledMethod));
    if (didAddMethod) {// 添加方法实现IMP成功后,替换方法实现
        class_replaceMethod(mateClass,
                            swizzledSelector,
                            method_getImplementation(originalMethod),
                            method_getTypeEncoding(originalMethod));
    } else { // 有原方法,交换两个方法的实现
        method_exchangeImplementations(originalMethod, swizzledMethod);
    }
}
@end

运行后发现:ClassA类涉及的swizzle_load方法实例的执行IMP部分并未被调用,名称load方法的执行部分hook钩挂失败。
名称load方法钩挂Hook的特殊分析*

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

HaiJunYa

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值