一.什么是钩子函数?
先来看一段百科:钩子函数是Windows消息处理机制的一部分,通过设置“钩子”,应用程序可以在系统级对所有消息、事件进行过滤,访问在正常情况下无法访问的消息。钩子的本质是一段用以处理系统消息的程序,通过系统调用,把它挂入系统。
get关键词,在系统级对所有消息进行过滤,就是说钩子函数是在一个事件触发的时候,在系统级捕获到了他,然后做一些操作。一段用以处理系统消息的程序,用以处理系统消息的程序,是说钩子函数是用于处理系统消息的。
总结一下:
钩子函数: 1、是个函数,在系统消息触发时被系统调用 2、不是用户自己触发的
钩子函数的名称是确定的,当系统消息触发,自动会调用。例如react的componentWillUpdate函数,用户只需要编写componentWillUpdate的函数体,当组件状态改变要更新时,系统就会调用componentWillUpdate。 常见的钩子函数: react的生命周期函数、vue的生命周期函数等
二.Unity中可以用的Hook函数
分享公司大佬的Misaka Mikoto的https://github.com/easy66/MonoHooker,
特点:
运行时直接修改内存中的 jit 代码,不会修改 UnityEditor.dll 等文件,避免让别人修改文件的尴尬。
不影响调试。
同时支持 .net 2.x 与 .net 4.x。
目前测试支持 unity4.7.2, unity5.x, unity 2017 与 unity 2018。
使用很方便,在C#内定义签名与原始方法相同的两个方法然后注册一下就能用了。
目前已支持 Android Mono, Windows Mono/IL2CPP
三.在项目中遇到的问题中的使用
定位一个FxClear的cs,被添加两次,看着逻辑本身没有什么问题,还是不清楚哪里让Fxclear被添加两次。通过hook函数定位到问题在哪里了.
FxClear有[RequireComponent(typeof(ParticleLOD))],而ParticleLOD在Awake()里有gameObject.GetOrAddComponent(); 修改到Start();
particleSystem的Render 的enable被设置为false。之前在所有render被改为false的地方加断点,没断到。通过hook函数成功定位到了问题。
GetComponentsInChildren(); 当某个节点setactive(false)的时候,在子节点的render并不会被Get到。解决方案是GetComponentsInChildren(true);
四.怎么做到呢
底层是汇编,在x8,x64上不同的处理,因为我也缺少汇编相关的知识,请大佬讲解了下,push作为一个函数的开始,ret是函数的结束。
在push函数地址替换成自己用的函数地址,执行完毕再继续执行原来的函数,通过这样达到hook,在不同的环境可以使用。当然也要函数长度满足8个字节长度。
因为也支持arm环境。发现设备环境确实有点不一样的。
同样不影响执行的效率。
本文标题:Unity里实现Hook函数
文章作者:zhutaorun
发布时间:2019-08-07, 23:38:23
最后更新:2019-08-08, 00:03:44
原始链接:http://zhutao.github.io/2019/08/07/Unity里实现Hook函数/
许可协议: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。