Home

Awesome

ZXBlockLog

基于CTObjectiveCRuntimeAdditions

如何使用

#import "ZXBlockLog.h"
NSLog(ZXBlockLog(block));

使用Demo场景示例&捕获并修改block参数演示

功能&需求

分析

#import "NSObject.h"
@interface HttpRequest : NSObject
{
}
+ (void)sendRequestWithData:(id)arg1 callBack:(CDUnknownBlockType)arg2;
@end

由于class-dump无法解析block,因此显示为CDUnknownBlockType

#import <UIKit/UIKit.h>
#import "ZXBlockLog.h"
//block的本质是结构体,此处CDUnknownBlockType修改id类型即可
%hook HttpRequest
+ (void)sendRequestWithData:(id)arg1 callBack:(id)arg2{
    //打印block
    NSLog(ZXBlockLog(arg2));
    %orig;
}
%end
2019-05-21 21:53:33.281180+0800 ZXBlockLogDemo[62025:5648976] 
----------------------[ZXBlockLogStart]----------------------
[Block声明]void(^)(BOOL,HttpResponse *)
[Block实现]^void(BOOL arg1,HttpResponse *arg2)
-----------------------[ZXBlockLogEnd]-----------------------
#import <UIKit/UIKit.h>
#import "ZXBlockLog.h"
@class HttpResponse;
%hook HttpRequest
+ (void)sendRequestWithData:(id)arg1 callBack:(void(^)(BOOL,HttpResponse *))arg2{
    %orig;
}
%end
#import "NSObject.h"
@class NSString;
@interface HttpResponse : NSObject
{
    int _code;
    NSString *_data;
}
@property(readonly, nonatomic) int code; // @synthesize code=_code;
@property(readonly, copy, nonatomic) NSString *data; // @synthesize data=_data;
- (void).cxx_destruct;
- (id)initWithDic:(id)arg1;
@end

可见HttpResponse中有code和data两个属性,可以直接hook - (id)initWithDic:(id)arg1达到修改返回信息的目的,此例为演示block参数修改,因此不使用此方法

%hook HttpRequest
+ (void)sendRequestWithData:(id)arg1 callBack:(void(^)(BOOL,HttpResponse *))arg2{
    Class cls = NSClassFromString(@"HttpResponse");
    id resp = [cls new];
    [resp setValue:@200 forKey:@"code"];
    [resp setValue:@"hooked" forKey:@"data"];
    arg2(YES,resp);
}
%end
@interface HttpResponse : NSObject

@end
%hook HttpRequest
+ (void)sendRequestWithData:(id)arg1 callBack:(void(^)(BOOL,HttpResponse *))arg2{
    arg2 = ^void(BOOL arg3,HttpResponse *arg4) {
        Class cls = NSClassFromString(@"HttpResponse");
        id resp = [cls new];
        [resp setValue:@200 forKey:@"code"];
        [resp setValue:[NSString stringWithFormat:@"[hooked]%@",[arg4 valueForKey:@"data"]]forKey:@"data"];
        arg2(YES,resp);
    };
    %orig;
}
%end

至此,我们达到了捕获block内部参数并修改的目的