type
status
date
slug
summary
tags
category
icon
password
我是怎么发现的
逆向的时候取了一些RenderDoc的截帧(别问我怎么弄来的),在VS Input中的预览看到了这个神奇的传入模型

很显然,正常模型不长这样。但是它的VS Out是一个明显有形状的东西

这说明这个模型在传入的时候position数据是encode的,且在Vertex Shader中做了Decoding。那接下来就是要分析Vertex Shader
源码解析
参考来源
最开始拿到的是RenderDoc的截帧,至少在rdc中,我能拿到的格式是dxbc,大概长下图这样。

打码的部分是直接能看到的CBuffer中Variable的名字,就这点来说这个引擎还挺好的,比较好通过这些命名推断功能。
定位算法
这里我不得不说AI真好用。之前有见过有群友把整个dxbc喂给AI让AI转成hlsl的,我就尝试让AI帮我做了一下语义分析,直接让AI用shaderlab的语法实现了一遍,然后AI给了我这个。(我用的Cursor Auto模式,不知道实际用的是哪个模型)

我专门让AI在对应算法上标记注释来源于源码的哪些行。经过验证可以发现AI的分析实际上非常准确,只是在最关键最复杂的“位操作解压缩逻辑”被它省略了。
根据注释和上下文算法的对应,最终能定位到解压缩算法为下图红框区域,也就是源码第14行到第33行

(后续经过一些验证证明所有shader的decode走的都是这套算法)
弯路
由于DXBC的可读性没那么好,中间尝试过使用其他截帧工具进行另外的截帧,但是最终都没有办法直接使用,情况如下,帮大家踩了一下坑。另外新版本的该游戏已经无法直接通过RenderDoc截帧了,Global hook后Capture按键亮不起来。
- PIX:无法注入
- GPA:可以截帧,解析shader为DXIL格式,由于没有现成DXIL转其他高级语言格式的插件,且Shader和CBuffer可读性都很差,遂放弃
- NSight:可以截帧,解析shader可以上DXIL格式,也可以自动使用Spirv-Cross翻译为HLSL,但是无法正常查看模型数据(Geometry界面无法正常显示,Vertex Input数据无法加载),翻译后的HLSL可读性也较差
算法难点
这是一套需要确认精度进行位运算的算法。在DXBC码中的ubfe、bfi函数,都没有在hlsl中有直接的调用。在NSight的截帧版本中也可以看到其转译后的实现函数相当复杂。(实际上这个转译的算法结果存在问题,后续通过一样路径并没有能够正确还原)

- 关于ubfe - ubfe (sm5 - asm) - Win32 apps | Microsoft Learn
- 指令格式 ubfe dest src0 src1 src2
- 将 src2 从第 src1 位开始的 src0 长度移到最低位
- 关于bfi - bfi (sm5 - asm) - Win32 apps | Microsoft Learn
- 指令格式 bfi dest src0 src1 src2 src3
- 从第 src1 位开始的 src0 长度位设置为掩码,将src2掩码内的部分替换src3掩码内的部分
还原结果
- 作者:Reguluz
- 链接:https://reguluz.cn/article/25d65fbc-2b71-806a-b69a-ffe02ea9e6eb
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。

