- 游戏启动后
- 使用Pattern Scanner 找到 TVPCreateStream 函数地址
- Detours 安装 Inline Hook,拦截该函数
- 游戏加载 startup.tjs 文件(这时会触发 Hook 回调)
- HookCallback 判断: · 如果当前加载的文件名 不是 startup.tjs,则正常执行,不做任何处理。 · 如果当前加载的文件名 是 startup.tjs,则进入 PatchAndDump 流程。
PatchAndDump 详细步骤(按顺序执行):
-
调用原始函数的 vtable.GetSize(),得到数据大小 dataSize = 6904 字节。
-
调用 vtable.Read() 读取原始明文块 blockDec,并备份一份为 blockDecOrig。
-
将 writeTarget 临时设为 0,读取加密的 v5enc 数据(也是 6904 字节)。
-
恢复 writeTarget 的值。
-
执行 TjsPatcher::PatchBytecode(blockDec):
用 Tjs2Parser::Parse() 解析字节码。
搜索特定的 VM 指令序列(VM_DOT 寻找 "archiveUniqueKey",
然后找到 VM_CALLD 再定位到 VM_TF)
-
将找到的 VM_TF 和 VM_TT 指令翻转(即条件取反)并记录修改后的明文 patchedPlaintext
-
进行差分 XOR 操作:v5encPatched[i] = v5enc[i] XOR delta[i](其中 delta 是原明文与补丁明文的差异)
-
调用 vtable.Write() 将补丁后的明文写回运行时内存,保证游戏运行时不崩溃。
-
最后执行 PatchAndWrite
-
读取整个原始 EXE 文件(约 4.6 MB)到内存中
使用 KMP 搜索算法定位到 v5enc 数据块(6904 字节)在文件中的位置
用 KMP 差分补丁(异或)将修改后的数据写入该位置
-
再搜索字符串 "steam=yes"",将其首字符 s 改为 a,即修改为 ateam="yes"
这样就可以让引擎以本地非steam版本运行了
-
最后输出新的 EXE保存在与处理exe同个目录即可
