首页
社区
课程
招聘
[原创]Deadlock 游戏辅助源码分析与二次开发全记录
发表于: 2026-6-7 09:24 5123

[原创]Deadlock 游戏辅助源码分析与二次开发全记录

2026-6-7 09:24
5123

项目通过 MinHook 挂载了 12 个关键函数:

这是项目最精巧的设计。Source 2 引擎提供了 schemasystem.dll,其中包含所有实体类的字段名→偏移映射。CSchemaOffset.cpp 在运行时遍历所有 TypeScope,动态读取 CSchemaClassBinding 结构的成员偏移,存入 unordered_map<string, unordered_map<string, uint32_t>>

这意味着游戏更新导致实体字段偏移变化时,无需重新逆向,运行时自动解析。

对于非 Schema 暴露的函数(如 CalcWorldSpaceBonesScreenTransform),项目通过 CBasePattern 在 DLL 加载时执行 AOB(Array of Bytes)扫描定位:

支持三种扫描类型:直接匹配、CALL指令追踪(SEARCH_TYPE_CALL)、LEA RIP相对寻址(SEARCH_TYPE_PTR2)。

拿到源码之后我想着能不能自己扫描进行适配,发现还真可以,使用AI进行批量文件扫描进行版本适配几乎可以无脑适配,但是适配之后骨骼和aimbot失效后续我也解决了!嘿嘿

编写了 Python 脚本 pattern_scan.py,通过 Boyer-Moore 风格的通配符匹配算法,一次性扫描所有目标 DLL:

对 8 个 DLL 的 35 个模式进行批量扫描,输出命中/缺失/歧义三类结果。

针对新版 Deadlock(ClientVersion 6536),扫描结果 30/32 OK,0 MISS,仅 CameraManager 和 CreateMaterial 存在歧义(2 处命中指向同一地址),确认无需修改即可运行。

本人英文不好所以手动给他添加了所有的翻译工程,然后重新编译即可
图片描述

新增 LangHelper.hpp 翻译宏:

遍历 17 个菜单文件的数百处 XorStr("English") 替换为 L("English", "中文")

同时为 ImGui 字体系统添加 CJK Merge Font(msyh.ttc),解决中文字符显示为方框的问题。

添加 /utf-8 MSVC 编译标志,确保 UTF-8 字符串在 GBK 环境下正确编译。

原始代码通过 GetDllDir() 获取 DLL 所在目录作为配置路径。由于 DLL 被注入器提取到 %TEMP%\随机目录,注入完成后被全零覆盖删除,导致配置不保存。

修改 CSettingsJson.cpp,新增 GetConfigDir()

配置保存到 %APPDATA%\LiveLock\,永久保留。
图片描述

原始项目依赖 HeroSkeletonPairs.hpp 中的预先提取的骨骼映射表。由于 BoneExtractor 源码缺失,初版使用空存根导致自瞄无法锁定目标。

CAimbot.hppbool Active = false; 改为 true;,避免用户找不到开关。

从 UC 获取 Deadlock-BoneExtractor 源码,其对游戏 VPK 文件(Valve Pak)执行解析:

Andromeda 的自瞄和骨骼 ESP 都依赖 HeroSkeletonPairs.hpp 中预先提取的骨骼数据:

VPK读取 → 遍历 4966 个 .vmdl_c 条目
→ 过滤英雄模型路径
→ 解析 ValveResourceFormat 提取骨骼名称/ID
→ 构建 slotBones 部位分类 (Head/Neck/Torso/Arms/Legs)
→ 生成 C++ 头文件

源码仓库中的 HeroSkeletonPairs.hpp 仅包含一个空存根 g_HeroModelData = {},因为完整的骨骼数据由 PreBuildEvent 调用 BoneExtractor 运行生成后填入。此步骤需要 .NET SDK 且 BoneExtractor 源码在主仓库中缺失的。直接编译后所有 GetHitboxBones() 调用返回 nullptr,导致自瞄无法锁定目标和骨骼 ESP 无法绘制。

最初尝试了三种途径:

Deadlock 的资源存储在 game\citadel\pak01_dir.vpk(索引文件,6.5MB)和 pak01_000.vpk ~ pak01_270.vpk(数据分片)中。VPK v2 的文件头结构:

依赖 .NET 10.0 + ValveResourceFormat NuGet 包。生成 63 个英雄模型、总计 235KB 的 HeroSkeletonPairs.hpp
目录树定位TreeOffset = FileSize - TreeSize

目录树中每个文件条目为 18 字节:

在等待 .NET 10 SDK 期间,手动解析了 VPK v2 二进制格式:

条目按 Extension → Path → Filename 的三层树结构组织。遍历时以空字符串标记层级结束。

手动编写 Python VPK 解析器成功定位到扩展名 vmdl_c 下的 152 个英雄模型路径,但 latin-1 编码的目录名在 UTF-8 转换时触发 UnicodeDecodeError

工具的核心逻辑:

Header: Magic(4B) + Version(4B) + TreeSize(4B) + FileDataSize(4B) + ...
Tree offset = FileSize - TreeSize
Entry: CRC(4B) + Preload(2B) + ArchiveIdx(2B) + Offset(4B) + Length(4B) + Term(2B)

关键 NuGet 依赖:

.vmdl_c 中提取的骨骼名(如 neck_0, spine_1, arm_upper_l, leg_lower_r)通过启发式规则映射到五个部位槽位:

成功定位 4966 个 vmdl_c 条目,但字符编码问题导致解析中止。最终 BoneExtractor 工具完美解决。
骨骼父子连接 (BonePair) 通过 .vmdl_c 中的层级关系构建,用于骨架 ESP 绘制连线。

输出:

跳过 89 个文件的原因是:turret、projectile、LOD 模型、spectre_hand 等非玩家骨骼。63 个有效模型覆盖了游戏中全部可玩英雄及其变体形态。

替换前后 DLL 大小对比:

注入游戏后验证:

成功定位 4966 个 vmdl_c 条目,但字符编码问题导致解析中止。最终 BoneExtractor 工具完美解决。

编译命令:

16 字节 Payload → AES-256-CBC(随机 IV)→ Base32 → "VITT-XXXXX-..."

GUI 卡密生成器,通过 libmysql C API 直连 MySQL,每张卡密记录到 deadlock.cards 表,支持查询状态。

本次开发涉及以下技术栈:

完整源代码和工具已整理归档,可作为 Source 2 引擎游戏学习的参考框架。

Hook 点 所在 DLL 用途
CreateMove client.dll 自瞄角度写入
FireEventClientSide client.dll 游戏事件拦截
OnAddEntity / OnRemoveEntity client.dll 实体缓存更新
ParseMessage engine2.dll 网络消息解析(伤害事件)
OnClientOutput engine2.dll 客户端渲染回调
GetMatricesForView client.dll 视图矩阵获取
DrawModel scenesystem.dll Chams 模型上色
Present / ResizeBuffers GameOverlayRenderer64.dll D3D11 渲染层注入
方案 方法 结果
IDA 提取 VITTLOCK.dll 从 .rdata 段解析 STL 容器结构 数据嵌入在 133KB 静态初始化函数 sub_180008530 中,手动提取不现实
手写 VPK Python 解析器 按 VPK v2 二进制格式逐字节读取 成功定位目录树,但模型路径字符编码异常中止
BoneExtractor 原版工具 从 GitHub 获取源码,配置 .NET 环境运行 成功生成 63 个英雄的完整数据
版本 DLL 大小 HeroSkeletonPairs.hpp
空存根 6,353,920 bytes 0 字节
BoneExtractor 生成 6,578,176 bytes (+224KB) 235KB, 63 模型
组件 版本 作用
VS2026 Community 18.6.2 主编译器 (v143 toolset)
VS2019 Community 16.11.53 Wrapper 编译器
.NET 8.0 SDK 8.0.421 基础运行时
.NET 10.0 SDK 10.0.300 BoneExtractor
MySQL 9.3 - KeyGen 数据库
Andromeda-DeadLock-Base/ (VS DLL项目)
├── DllMain.cpp                    # DLL入口
├── DeadLock/
│   ├── Hook/                      # 12个MinHook引擎钩子
│   ├── SDK/                       # 逆向的Source2 SDK封装
│   │   ├── CFunctionList.hpp      # 19个字节模式函数查找
│   │   ├── CSchemaOffset.cpp      # 运行时Schema字段偏移解析
│   │   └── Interface/             # 引擎接口封装
│   └── Protobuf/                  # 94个预编译protobuf文件
├── AndromedaClient/
│   ├── Features/
│   │   ├── CAimbot/               # 自瞄 (轨迹预测/惯性/AntiFrog)
│   │   ├── CVisual/               # ESP (方框/骨骼/Chams/观战)
│   │   ├── CMisc/                 # 自动格挡/换弹
│   │   └── CHeroes/               # 英雄专属功能
│   └── GUI/                       # ImGui渲染菜单
└── GameClient/                     # 实体缓存/控制器封装
// 示例:通过函数头字节码定位
CBasePattern ScreenTransform = {
    "ScreenTransform",
    "33 C0 48 39 05 ? ? ? ? 0F 84", // 字节模式,?? 为通配符
    CLIENT_DLL,
    0,
    SEARCH_TYPE_NONE
};
# 核心扫描逻辑
def scan(data, pat_bytes, mask):
    n = len(pat_bytes)
    first_byte = pat_bytes[first_lit]  # 首个固定字节
    pos = data.find(first_byte)        # 快速定位候选
    ...

[内核课程]《Windows内核攻防实战》!从零到实战,融合AI与Windows内核攻防全技术栈,打造具备自动化能力的内核开发高手。

最后于 2026-6-7 09:37 被刘宝编辑 ,原因:
收藏
免费 9
打赏
分享
最新回复 (7)
雪    币: 883
活跃值: (753)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
2
前两天死锁又更新了,V社更新真的频繁,不过源码只需要更新下搜索函数的特征和dll加载的返回依然可以正常使用,不过这游戏外挂真的多,可能是内侧游戏的问题吧
2026-6-13 20:25
0
雪    币: 883
活跃值: (753)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
3
我把源码下载链接放在评论区了,有想研究的可以自己搞一下,链接:fc4K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6%4N6$3q4D9L8q4)9J5k6h3I4S2L8Y4A6G2N6i4g2Q4x3X3g2U0L8$3#2Q4x3V1k6A6K9V1c8r3d9K6y4J5N6o6k6$3j5X3V1`.
2026-6-13 20:29
0
雪    币: 6280
活跃值: (8061)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
这游戏外挂赚钱吗?
2026-6-15 15:15
0
雪    币: 883
活跃值: (753)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
5
木志本柯 这游戏外挂赚钱吗?
不知道,这游戏在国内好像热度不是很高
2026-6-15 15:25
0
雪    币: 50
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
6
666
2026-6-15 16:11
0
雪    币: 3900
活跃值: (4061)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
逆向学得好,老饭吃得饱
2026-6-18 11:02
0
雪    币: 883
活跃值: (753)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
8
MsScotch 逆向学得好,老饭吃得饱
孩子都快饿死了
2026-6-18 11:18
0
游客
登录 | 注册 方可回帖
返回