UE4SS项目中Blueprint库函数Hook问题的分析与解决方案
问题背景
在UE4SS项目3.0.1版本中,开发者报告了一个关于Hook Blueprint库函数的重要问题。当尝试通过Lua或LiveView对任何Blueprint库函数进行Hook时,游戏会冻结并返回错误信息。这个问题在多个使用不同版本Unreal Engine的游戏中普遍存在,包括使用UE 5.1.1的Palworld和使用UE 4.27的Stray等。
问题现象
具体表现为:
- 成功注册Hook后,当Blueprint库函数被执行时
- 游戏冻结并输出错误日志,提示无法找到对应的函数映射条目
- 错误信息表明系统尝试执行UFunction::FuncPtr Hook但失败了
技术分析
经过深入分析,发现问题根源在于UE4SS在处理Blueprint库函数Hook时的机制存在缺陷:
-
CurrentNativeFunction指针缺失:当Hook的本地UFunction通过Blueprint的EX_CallMath kismet表达式调用时,UE源代码中设置Stack.CurrentNativeFunction的代码行被注释掉了,导致Hook无法找到原始函数。
-
参数传递异常:当本地函数通过任何kismet字节码调用时,参数不会放入Stack.Locals中,而UE4SS正是依赖Stack.Locals来获取参数值,导致参数变成随机值。
-
函数指针定位问题:对于Add_IntInt等函数,UFunction指针实际上存储在TheStack.Code - 8的位置,但当前实现没有考虑到这种存储方式。
解决方案
经过技术团队的讨论和测试,提出了以下解决方案:
-
函数指针获取优化:
- 当TheStack.Code可用时,从TheStack.Code - 8位置读取函数指针
- 保留对Stack.CurrentNativeFunction的检查,确保非BP调用场景的正常工作
- 在LuaMod.cpp中停止使用CurrentNativeFunction,转而使用存储的Hook数据
-
参数处理改进:
- 识别BP函数参数的两种存储方式:内联到字节码中或存储在Stack.Locals中
- 对字节码进行回溯分析,直到找到参数类型(如EX_LocalVariable或Ex_IntConst)
- 考虑复用KismetDebugger模块中的部分代码来实现参数解析
实施效果
初步测试表明:
- 原始崩溃问题已解决,Hook的Blueprint库函数不再导致游戏冻结
- 参数获取问题仍然存在,表现为部分参数值异常
- 需要进一步优化参数解析逻辑以完全解决问题
后续计划
技术团队计划:
- 优先解决原始崩溃问题,确保基本功能的稳定性
- 将参数解析问题拆分为单独的任务进行后续优化
- 收集更多测试案例,验证解决方案在不同场景下的兼容性
技术建议
对于开发者在使用UE4SS时的建议:
- 避免在关键业务流程中Hook Blueprint库函数,直到问题完全解决
- 对于必须Hook的场景,建议先进行充分测试
- 关注参数值的有效性检查,防止异常值导致逻辑错误
这个问题展示了Hook系统在复杂引擎环境中的挑战,也为UE4SS项目的持续改进提供了宝贵的技术积累。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



