title: Unity⾥实现Hook函数
date: 2019-08-07 23:38:23
tags: Unity3D
categories: 技术积累
⼀.什么是钩⼦函数?
先来看⼀段百科:钩⼦函数是Windows消息处理机制的⼀部分,通过设置“钩⼦”,应⽤程序可以在系统级对所有消息、事件进⾏过滤,访问在正常情况下⽆法访问的消息。钩⼦的本质是⼀段⽤以处理系统消息的程序,通过系统调⽤,把它挂⼊系统。 get关键词,在系统级对所有消息进⾏过滤,就是说钩⼦函数是在⼀个事件触发的时候,在系统级捕获到了他,然后做⼀些操作。⼀段⽤以处理系统消息的程序,⽤以处理系统消息的程序,是说钩⼦函数是⽤于处理系统消息的。
总结⼀下:
钩⼦函数:
1、是个函数,在系统消息触发时被系统调⽤
2、不是⽤户⾃⼰触发的
la-5钩⼦函数的名称是确定的,当系统消息触发,⾃动会调⽤。例如react的componentWillUpdate函数,⽤户只需要编写componentWillUpdate的函数体,当组件状态改变要更新时,系统就会调⽤componentWillUpdate。
常见的钩⼦函数:发光墙
react的⽣命周期函数、vue的⽣命周期函数等
⼆.Unity中可以⽤的Hook函数自制纳米胶带教程
特点:
运⾏时直接修改内存中的 jit 代码,不会修改 UnityEditor.dll 等⽂件,避免让别⼈修改⽂件的尴尬。 不影响调试。
同时⽀持 2.x 与 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环境。发现设备环境确实有点不⼀样的。同样不影响执⾏的效率。