You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何Hook DirectX11获取Shader字节码?实现类似DirectX9的随时获取

如何在DirectX11中随时获取Vertex Shader字节码?

你在DirectX9里靠Hook DrawIndexedPrimitive 就能随时拿到Shader字节码,这个思路在DX9里跑通没问题,但到了DX11确实会遇到架构变化带来的局限——你试过Hook DrawIndexed 没达到预期,Hook CreateVertexShader 又必须赶在游戏创建Shader前设置,没法实现像DX9那样“随时获取”的效果对吧?下面给你几个可行的解决方案:

方案1:Hook VSSetShader + 缓存当前绑定的VS

DX11里每次切换Vertex Shader时,都会调用ID3D11DeviceContext::VSSetShader这个方法。你可以在游戏运行后动态Hook这个函数:

  • 当VSSetShader被触发时,把传入的ID3D11VertexShader*对象缓存下来
  • 之后不管你什么时候需要字节码,直接用这个缓存的Shader对象调用ID3D11Device::GetVertexShaderBlob就能提取出对应的字节码

这个方法的好处是完全不需要提前Hook创建Shader的流程,只要游戏还在运行,随时挂Hook都能捕获后续所有绑定的VS,完美满足“随时获取”的需求。

方案2:动态Hook CreateVertexShader + 持久化存储Shader Blob

如果担心某些Shader被绑定后又释放,但你需要长期保留字节码,可以用虚表Hook的方式动态挂CreateVertexShader的钩子(不需要提前注入,只要能拿到ID3D11Device指针就行):

  • 在Hook函数里,除了调用原CreateVertexShader逻辑,还要把传入的pShaderBytecode(或者创建后通过GetVertexShaderBlob获取的Blob)存储到全局容器里,比如用std::unordered_map<ID3D11VertexShader*, ComPtr<ID3DBlob>>关联Shader对象和它的字节码
  • 之后不管什么时候,只要拿到有效的Shader对象,就能从容器里取出对应的字节码

方案3:Hook Draw系列函数 + 实时提取当前VS字节码

如果你想沿用DX9的Draw阶段Hook思路,也可以这么做:

  • HookDrawIndexed或者Draw函数
  • 在Draw调用触发时,先通过ID3D11DeviceContext::VSGetShader获取当前绑定的Vertex Shader对象
  • 再用ID3D11Device::GetVertexShaderBlob从这个对象中提取字节码

这个方法和DX9的逻辑最接近,每次Draw时都能拿到当前生效的VS字节码,同样能实现“随时获取”的效果。

注意细节

  • 所有Hook操作都要处理好COM对象的引用计数,避免内存泄漏或者程序崩溃
  • 调用GetVertexShaderBlob时,要确保Shader对象是有效的(未被释放),否则会调用失败
  • 虚表Hook是DX11中常用的运行时Hook方式,不管游戏什么时候创建设备,只要能拿到设备/上下文的指针,就能动态挂Hook

内容的提问来源于stack exchange,提问作者hksoobe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 09:59:28