【iOS安全-(calleng逆向日记)Frida前置知识, ObjC runtime的"反射" KVC实例Demo分析第二部(Demo底部下载)】此文章归类为:iOS安全。
或者可以这样理解, hook函数的4种方式
setter
方法的属性设置,getter
方法的属性调用setter设置
和getter调用
失败后的 _Key,_isKey,Key,isKey
方式设置&获取setValue:forUndefinedKey
设置值方式valueForUndefinedKey
获取值方式通过 打开 KVC的函数文件NSKeyValueCoding.h
Copyright (c) 1994-2019, Apple Inc. All rights reserved.
可以知道
以[author1 setValue:@"author1 的新名字" forKey:@"name"];
为例
setName
_setName
setIsName
accessInstanceVariablesDirectly
返回YES
,则通过成员变量进行设置,顺序是:_name
_isName
name
isName
accessInstanceVariablesDirectly
说明
+ (BOOL)accessInstanceVariablesDirectly
方法让其返回NO
,这样的话,如果KVC
没有找到set<Key>
、_set<Key>
、setIs<Key>
相关方法时,会直接用setValue:forUndefinedKey:
方法
NSString* name = [author1 valueForKey:@"name"];
为例
getter
方法的调用顺序是:getName
name
isName
_name
accessInstanceVariablesDirectly
返回YES
,则直接返回成员变量,获取顺序依然是:_name
_isName
name
isName
oc编程不是太熟悉, 所以一边练习, 一边写代码, 本来想在控制台中输入 1,2,3 的选项来学习的, 迷茫3个小时, 以前的code中, 使用 **showActionSheet
**的方式, 刚好解决iOS中的, switch, input控制台无法处理的问题.学到知识综合利用才是关键
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
@interface Author1 : NSObject
{
@
public
NSString *_isName;
NSString *name;
NSString *isName;
NSString *_name;
}
- (
void
)setName;
- (
void
)_setName;
- (
void
)setIsName;
- (NSString *)getName;
- (NSString *)name;
- (NSString *)isName;
- (NSString *)_name;
@end
@implementation Author1
+(
BOOL
)accessInstanceVariablesDirectly{
return
NO;}
// 设置方法
- (
void
)setName:(NSString*)name{ NSLog(@
"1,设置值的优先函数 %s - %@"
,__func__,name); }
- (
void
)_setName:(NSString *)name{ NSLog(@
"2,设置值的优先函数 %s - %@"
,__func__,name); }
- (
void
)setIsName:(NSString *)name{ NSLog(@
"3,设置值的优先函数 %s - %@"
,__func__,name); }
// 取值方法
- (NSString *)getName{
return
NSStringFromSelector(_cmd);}
- (NSString *)name{
return
NSStringFromSelector(_cmd);}
- (NSString *)isName{
return
NSStringFromSelector(_cmd);}
- (NSString *)_name{
return
NSStringFromSelector(_cmd);}
@end
UIAlertAction *two = [UIAlertAction actionWithTitle:@
"setKey,getKey方式设置&获取"
style:UIAlertActionStyleDestructive handler:^(UIAlertAction * _Nonnull action) {
Author1* author1 = [Author1
new
];
[author1 setValue:@
"author1 的新名字"
forKey:@
"name"
];
NSString* name = [author1 valueForKey:@
"name"
];
NSLog(@
"取值的优先函数 value for key : %@"
,name);
NSLog(@
"取值_name:%@"
,author1->_name);
NSLog(@
"取值_isName:%@"
,author1->_isName);
NSLog(@
"取值name:%@"
,author1->name);
NSLog(@
"取值isName:%@"
,author1->isName);
}];
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
@interface Author2 : NSObject
{
@
public
NSString *_isName;
NSString *name;
NSString *isName;
NSString *_name;
}
@end
@implementation Author2
+(
BOOL
)accessInstanceVariablesDirectly{
return
YES;}
@end
UIAlertAction *three = [UIAlertAction actionWithTitle:@
"_Key,_isKey,Key,isKey方式设置&获取"
style:UIAlertActionStyleDestructive handler:^(UIAlertAction * _Nonnull action) {
Author2* author2 = [Author2
new
];
[author2 setValue:@
"author2 的新名字"
forKey:@
"name"
];
// 设定值
NSString* name = [author2 valueForKey:@
"name"
];
// 取值
NSLog(@
" value for key : %@"
,name);
NSLog(@
"取值_name:%@"
,author2->_name);
NSLog(@
"取值_isName:%@"
,author2->_isName);
NSLog(@
"取值name:%@"
,author2->name);
NSLog(@
"取值isName:%@"
,author2->isName);
}];
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
@interface Author3 : NSObject
{
@
public
NSString *_isName;
NSString *name;
NSString *isName;
NSString *_name;
}
@end
@implementation Author3
+(
BOOL
)accessInstanceVariablesDirectly{
return
YES;}
-(
void
)setValue:(id)value forUndefinedKey:(NSString *)key{ NSLog(@
"forUndefinedKey出现异常,该key不存在%@"
,key);}
@end
UIAlertAction *four = [UIAlertAction actionWithTitle:@
"setValue:forUndefinedKey设置值方式"
style:UIAlertActionStyleDestructive handler:^(UIAlertAction * _Nonnull action) {
Author3* author3 = [Author3
new
];
[author3 setValue:@
"author3 的新名字"
forKey:@
"name"
];
// 设定值
[author3 setValue:@
"设定一个不存在的属性值"
forKey:@
"name3"
];
// 设定一个不存在的属性值
NSString* name = [author3 valueForKey:@
"name"
];
// 取值
NSLog(@
" value for key : %@"
,name);
NSLog(@
"取值_name:%@"
,author3->_name);
NSLog(@
"取值_isName:%@"
,author3->_isName);
NSLog(@
"取值name:%@"
,author3->name);
NSLog(@
"取值isName:%@"
,author3->isName);
}];
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
@interface Author4 : NSObject
{
@
public
NSString *_isName;
NSString *name;
NSString *isName;
NSString *_name;
}
@end
@implementation Author4
+(
BOOL
)accessInstanceVariablesDirectly{
return
YES;}
-(id)valueForUndefinedKey:(NSString *)key{ NSLog(@
"valueForUndefinedKey出现异常,该key不存在%@"
,key);
return
nil;}
@end
UIAlertAction *five = [UIAlertAction actionWithTitle:@
"valueForUndefinedKey获取值方式"
style:UIAlertActionStyleDestructive handler:^(UIAlertAction * _Nonnull action) {
Author4* author4 = [Author4
new
];
[author4 setValue:@
"author4 的新名字"
forKey:@
"name"
];
// 设定值
NSString* name = [author4 valueForKey:@
"name"
];
// 取值
NSString* name4 = [author4 valueForKey:@
"name4"
];
// 取一个不存在的属性值
NSLog(@
" value for key : %@"
,name);
NSLog(@
"取值_name:%@"
,author4->_name);
NSLog(@
"取值_isName:%@"
,author4->_isName);
NSLog(@
"取值name:%@"
,author4->name);
NSLog(@
"取值isName:%@"
,author4->isName);
}];
|
更多【iOS安全-(calleng逆向日记)Frida前置知识, ObjC runtime的"反射" KVC实例Demo分析第二部(Demo底部下载)】相关视频教程:www.yxfzedu.com