Skip to content

Commit ec095a4

Browse files
author
jiang.feng
committed
support reset arguments
1 parent d700550 commit ec095a4

File tree

3 files changed

+46
-6
lines changed

3 files changed

+46
-6
lines changed

Example/Stinger/ASViewController.m

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ - (void)setFrame:(CGRect)rect {
2626

2727
}
2828

29+
- (BOOL)setFrame:(CGRect)rect object:(NSString *)obj num:(NSInteger)num {
30+
NSLog(@"origin fun: %@, %@, %ld", @(rect), obj, num);
31+
return YES;
32+
}
33+
2934
- (void)viewDidLoad {
3035
[super viewDidLoad];
3136
[self.class st_hookInstanceMethod:@selector(methodA) option:STOptionBefore usingIdentifier:@"hook methodA before" withBlock:^(id<StingerParams> params) {
@@ -34,7 +39,18 @@ - (void)viewDidLoad {
3439
[self.class st_hookInstanceMethod:@selector(methodA) option:STOptionAfter usingIdentifier:@"hook methodA after" withBlock:^(id<StingerParams> params) {
3540

3641
}];
37-
42+
43+
[self.class st_hookInstanceMethod:@selector(setFrame:object:num:) option:STOptionAfter usingIdentifier:@"change arg" withBlock:^BOOL(id<StingerParams> params, CGRect rect, NSString *obj, NSInteger num) {
44+
[params setArgument:@(CGRectMake(5, 6, 7, 8)) atIndex:0];
45+
[params setArgument:@"hook success" atIndex:1];
46+
[params setArgument:@(num + 1) atIndex:2];
47+
BOOL returnValue;
48+
[params invokeAndGetOriginalRetValue:&returnValue];
49+
return returnValue;
50+
}];
51+
[self setFrame:CGRectMake(1, 2, 3, 4) object:@"not hook" num:111];
52+
53+
3854
// [self.class aspect_hookSelector:@selector(methodA) withOptions:AspectPositionBefore usingBlock:^(id<AspectInfo> params) {
3955
//
4056
// } error:nil];

Stinger/Classes/STDefines.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ typedef NS_ENUM(NSInteger, STHookResult) {
5353
- (SEL)sel;
5454
- (NSArray *)arguments;
5555
- (NSString *)typeEncoding;
56+
- (void)setArgument:(id)arg atIndex:(NSInteger)idx;
5657
- (void)invokeAndGetOriginalRetValue:(void *)retLoc;
5758
@end
5859

Stinger/Classes/StingerParams.m

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ @interface StingerParams ()
1919
@property (nonatomic) IMP originalIMP;
2020
@property (nonatomic) void **args;
2121
@property (nonatomic) NSArray *argumentTypes;
22-
@property (nonatomic) NSArray *arguments;
22+
@property (nonatomic) NSMutableArray *arguments;
2323
@end
2424

2525
@implementation StingerParams
@@ -46,13 +46,37 @@ - (SEL)sel {
4646
}
4747

4848
- (NSArray *)arguments {
49-
return _arguments;
49+
return [_arguments copy];
5050
}
5151

5252
- (NSString *)typeEncoding {
5353
return _types;
5454
}
5555

56+
/// 修改函数参数
57+
/// - Parameters:
58+
/// - arg: 对应的参数,值类型请转换为NSValue传递
59+
/// - idx: 序号,默认从0开始
60+
- (void)setArgument:(id)arg atIndex:(NSInteger)idx {
61+
_arguments[idx]= arg;
62+
NSString *argTypeStr = _argumentTypes[idx + 2];
63+
const char *argType = argTypeStr.UTF8String;
64+
if (strcmp(argType, @encode(id)) == 0 || strcmp(argType, @encode(Class)) == 0) {
65+
void **objPointer = _args[idx + 2];
66+
*objPointer = (__bridge void *)(arg);
67+
return;
68+
}
69+
if ([arg isKindOfClass:NSValue.class]) {
70+
if (@available(iOS 11.0, *)) {
71+
NSUInteger valueSize = 0;
72+
NSGetSizeAndAlignment(argType, &valueSize, NULL);
73+
[(NSValue *)arg getValue:_args[idx + 2] size:valueSize];
74+
} else {
75+
[(NSValue *)arg getValue:_args[idx + 2]];
76+
}
77+
}
78+
}
79+
5680
- (void)invokeAndGetOriginalRetValue:(void *)retLoc {
5781
NSMethodSignature *signature = [NSMethodSignature signatureWithObjCTypes:_types.UTF8String];
5882
NSInteger count = signature.numberOfArguments;
@@ -69,12 +93,11 @@ - (void)invokeAndGetOriginalRetValue:(void *)retLoc {
6993
#pragma - mark Private
7094

7195
- (void)st_genarateArguments {
72-
NSMutableArray *args = [[NSMutableArray alloc] initWithCapacity:_argumentTypes.count];
96+
_arguments = [NSMutableArray array];
7397
for (NSUInteger i = 2; i < _argumentTypes.count; i++) {
7498
id argument = [self st_argumentWithType:_argumentTypes[i] index:i];
75-
[args addObject:argument ?: NSNull.null];
99+
[_arguments addObject:argument ?: NSNull.null];
76100
}
77-
_arguments = [args copy];
78101
}
79102

80103
- (id)st_argumentWithType:(NSString *)type index:(NSUInteger)index {

0 commit comments

Comments
 (0)