feature: App 逆向防护

This commit is contained in:
杭城小刘
2024-07-15 20:03:01 +08:00
parent 13f7457be9
commit 83fefff66b
109 changed files with 2549 additions and 672 deletions

View File

@@ -8,7 +8,7 @@
Demo1创建 Person 类,点击事件里触发属性值的改变。
<img src="./../assets/XCodoKVOIsaInspect.png" style="zoom:25%">
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/XCodoKVOIsaInspect.png" style="zoom:25%">
@@ -20,7 +20,7 @@ Demo1创建 Person 类,点击事件里触发属性值的改变。
在内存中的结构如下图
<img src="./../assets/UnusedKVOIsaStructure.png" style="zoom:25%">
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/UnusedKVOIsaStructure.png" style="zoom:25%">
整个流程分析下:
@@ -30,13 +30,13 @@ Demo1创建 Person 类,点击事件里触发属性值的改变。
当我们按照 KVO 后动态生成的类名去创建一个新的类的时候Xcode 会报错:`[general] KVO failed to allocate class pair for name NSKVONotifying_Person, automatic key-value observing will not work for this class`。因为自己创建的类名和系统将要动态创建的类名冲突了,并且 KVO 监听失效
<img src="./../assets/SelfClassNameConflictsWithKVOClass.png" style="zoom:25%">
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/SelfClassNameConflictsWithKVOClass.png" style="zoom:25%">
Demo2:
<img src="./../assets/KVOMethodImplAddressAndIsaInspect.png" style="zoom:25%">
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/KVOMethodImplAddressAndIsaInspect.png" style="zoom:25%">
分析:
@@ -48,7 +48,7 @@ Demo2:
Demo3:
<img src="./../assets/KVOMethodImplAddressWithDouble.png" style="zoom:25%">
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/KVOMethodImplAddressWithDouble.png" style="zoom:25%">
可以看到我们将 KVO 的数据类型改为 double 后,原本的 setHeight 是 `_NSSetLongLongValueAndNotify`,现在是 `_NSSetDoubleValueAndNotify`
@@ -58,11 +58,11 @@ Demo3:
### NSSet**ValueAndNotify 的内部实现
<img src="./../assets/UsedKVOIsaStructure.png" style="zoom:25%">
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/UsedKVOIsaStructure.png" style="zoom:25%">
来对 Person 类增加一些打印方法
<img src="./../assets/KVOKeyMethodPrint.png" style="zoom:25%">
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/KVOKeyMethodPrint.png" style="zoom:25%">
@@ -117,7 +117,7 @@ Demo3:
### 重写 class 方法
<img src="./../assets/KVOOverrrideClassMethod.png" style="zoom:25%">
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/KVOOverrrideClassMethod.png" style="zoom:25%">
可以看到利用 runtime api在添加 KVO 之后,类对象为 `NSKVONotifying_Person`
@@ -129,7 +129,7 @@ Demo3:
### KVO 类的所有方法
<img src="./../assets/PrintKVOClassAllMethodName.png" style="zoom:25%">
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/PrintKVOClassAllMethodName.png" style="zoom:25%">
@@ -148,7 +148,7 @@ QA为什么新创建的类没有 getter
### 修改成员变量的值可以触发 KVO 吗
<img src="./../assets/KVOCannotInvokeWhenChangeIvarDirectly.png" style="zoom:25%">
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/KVOCannotInvokeWhenChangeIvarDirectly.png" style="zoom:25%">
我们将 Person 类的成员变量暴露出来,在点击事件里修改,发现不能触发 KVO。
@@ -158,7 +158,7 @@ QA如何手动触发
手动调用 `willChangeValueForKey`、 `didChangeValueForKey`
<img src="./../assets/KVOInvokeWhenChangeIvarDirectlyMustCallWillChangeAndDidChange.png" style="zoom:25%">
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/KVOInvokeWhenChangeIvarDirectlyMustCallWillChangeAndDidChange.png" style="zoom:25%">
@@ -197,7 +197,7 @@ QA如何手动触发 KVO
KVC 之后会触发 KVO 吗?
<img src="./../assets/KVCWillTriggerKVO.png" style="zoom:25%">
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/KVCWillTriggerKVO.png" style="zoom:25%">
发现 KVC 触发了 KVO。
@@ -205,7 +205,7 @@ KVC 之后会触发 KVO 吗?
整个流程如下
<img src="./../assets/KVC-process.png" style="zoom:45%">
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/KVC-process.png" style="zoom:45%">
`[self.person setValue:@10 forKey:@"age"]` 会先调用 `setKey:` 同名的方法,找不到则调用 `_setKey:` 的方法,如果还是找不到则调用 `+(BOOL)accessInstanceVariableDirectlt`,如果该方法返回 YES则可以直接修改成员变量的值会按照 `_key`、`_isKey`、`key`、`isKey` 的顺序寻找成员变量,如果找到则直接赋值,没找到则抛出异常 `NSUnknownKeyException`
@@ -260,7 +260,7 @@ KVC 之后会触发 KVO 吗?
<img src="./../assets/KVC-get-process.png" style="zoom:45%">
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/KVC-get-process.png" style="zoom:45%">
@@ -425,7 +425,7 @@ Apple 文档告诉我们:被观察对象的 `isa指针` 会指向一个中间
- 键值观察通知依赖于 NSObject 的两个方法:`willChangeValueForKey:、didChangeValueForKey:` 。在一个被观察属性改变之前,调用 `willChangeValueForKey:` 记录旧的值。在属性值改变之后调用 `didChangeValueForKey:`,从而 `observeValueForKey:ofObject:change:context:` 也会被调用。
![KVO原理图](./../assets/2018_11_12_KVO.png)
![KVO原理图](https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/2018_11_12_KVO.png)
为什么要选择是继承的子类而不是分类呢?
子类在继承父类对象,子类对象调用调方法的时候先看看当前子类中是否有方法实现,如果不存在方法则通过 isa 指针顺着继承链向上找到父类中是否有方法实现,如果父类种也不存在方法实现,则继续向上找...直到找到 NSObject 类为止,系统会抛出几次机会给程序员补救,如果未做处理则奔溃