第 5 课:工程编译顺序与调试方法
# 第 5 课:工程编译顺序与调试方法
免责声明:本专栏仅用于安全工程学习研究,禁止使用本专栏介绍的技术做其他用途,否则后果自负,与本号无关。
本课定位:面向 Visual Studio 新手,讲清楚这套源码的编译顺序、解决方案配置、启动项目、输出窗口、错误排查和安全调试方法。 本课不要求读者实际运行产物,不讲连接真实目标,不讲使用远控功能;所有编译和调试都必须限定在授权、隔离、可回滚的实验环境中。
# 1. 先说清楚:编译顺序不是使用步骤
从第 3 课和第 4 课开始,我们已经知道 Visual Studio 工具链和第三方依赖的基本概念。第 5 课要解决的是另一个新手常见问题:这么多 .sln 和项目,到底先看哪个、先编译哪个、出错了看哪里。
这里要先划清边界:本课讲“编译顺序”,是为了理解工程依赖、产物关系和排错路径,不是鼓励读者生成或运行远控产物。对高风险源码来说,编译动作本身就需要审计,运行动作更要严格控制。
建议先把这一课当成“VS 工程管理课”来学:
- 看懂 README 里的顺序。
- 看懂
.sln里有哪些项目和配置。 - 看懂 VS 输出窗口和错误列表。
- 知道什么时候该停止,而不是继续运行。
# 2. 本课学习目标与适用人群
学完本课后,读者应当能做到:
| 目标 | 说明 |
|---|---|
| 理解编译顺序 | 知道为什么 README 先讲主插件,再讲主控 |
| 看懂解决方案配置 | 能识别 Debug、Release、Release-exe、Win32、x64 |
| 会看 VS 输出 | 知道输出窗口比错误列表更适合定位第一个失败点 |
| 会设置启动项目 | 理解启动项目只是调试入口,不代表应该直接运行 |
| 会做低风险调试 | 从 UI 初始化、配置读取、普通数据结构开始观察 |
| 会记录证据 | 保存输出日志、配置截图、错误信息和产物路径 |
适用人群包括企业安全人员、安全工程学习者、授权红蓝测试人员和安全研发人员。红蓝测试人员可将本课用于授权演练中的构建链复盘、检测验证和日志留存,不得用于未授权环境。
# 3. README 里的原始编译顺序
根目录 README.md 给出了编译顺序。先看源码里的说明。
# 源码位置:README.md:19-25
### 生产使用
1. 打开`主插件\all.sln`以Win32 Release编译;
2. 再以Win32 Release-exe编译`主插件\all.sln`;
3. 再以x64 Release编译`主插件\all.sln`;
4. 再以x64 Release-exe编译`主插件\all.sln`;
5. 打开`主控\Quick.sln`以Win32 Release编译主控...
2
3
4
5
6
7
8
防御分析注释:
- 顺序上先编译
主插件\all.sln,再编译主控\Quick.sln。 - 主插件要覆盖
Win32和x64两个平台。 - 主插件还区分
Release和Release-exe。 - 主控主要按
Win32编译。 - 这条顺序说明主控和插件产物之间存在依赖关系,安全审计不能只看主控。
用图表示就是:

再次强调:这张图用于理解构建依赖和产物关系,不等于建议读者运行产物。新手学习阶段可以先只打开解决方案、查看配置和项目结构。
# 4. 调试使用顺序
README 还给出了调试相关说明。
# 源码位置:README.md:28-37
### 调试使用
1. 打开`主插件\all.sln`以Win32 Release编译;
2. 再以Win32 Release-exe编译`主插件\all.sln`;
3. 再以x64 Release编译`主插件\all.sln`;
4. 再以x64 Release-exe编译`主插件\all.sln`;
5. 如果需要调试Win32 debug被控,将`上线模块`工程设置成启动项,以Win32 debug编译即可调试。
6. 如果需要调试x64 debug被控,将`上线模块`工程设置成启动项,以x64 debug编译即可调试被控。
7. 如果需要调试主控,打开`主控\Quick.sln`以Win32 Debug编译主控即可调试主控。
2
3
4
5
6
7
8
9
10
防御分析注释:
上线模块是被控端调试入口相关工程。- 主控调试入口是
主控\Quick.sln。 - 调试前仍然需要先看主插件的 Release/Release-exe 产物关系。
- 不熟悉项目的新手不应直接按 F5 运行,应先检查启动项目、参数、网络隔离和构建后事件。
# 5. 先看 all.sln:主插件集合
主插件\all.sln 是插件集合解决方案。它把多个插件工程组织在一起。
# 源码位置:主插件\all.sln:2-6
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.14.36717.8
MinimumVisualStudioVersion = 10.0.40219.1
Project(...) = "上线模块", "上线模块\上线模块\上线模块.vcxproj", ...
2
3
4
5
6
这段说明:
| 字段 | 新手解释 |
|---|---|
Visual Studio Version 17 | 对应 VS 2022 这一代 |
Project(...) = "上线模块" | 解决方案里包含一个叫“上线模块”的项目 |
.vcxproj 路径 | 这个项目的 C++ 工程文件位置 |
all.sln 里还能看到大量插件项目。
# 源码位置:主插件\all.sln:6-46
Project(...) = "上线模块", "上线模块\上线模块\上线模块.vcxproj", ...
Project(...) = "播放监听", "播放监听\播放监听\播放监听.vcxproj", ...
Project(...) = "查注册表", "查注册表\查注册表\查注册表.vcxproj", ...
Project(...) = "视频查看", "视频查看\视频查看\视频查看.vcxproj", ...
Project(...) = "文件管理", "文件管理\文件管理\文件管理.vcxproj", ...
Project(...) = "远程终端", "远程终端\远程终端\远程终端.vcxproj", ...
Project(...) = "执行代码", "shellcode\shellcode\shellcode.vcxproj", ...
Project(...) = "驱动插件", "驱动插件\驱动插件\驱动插件.vcxproj", ...
Project(...) = "注入管理", "注入管理\注入管理\注入管理.vcxproj", ...
2
3
4
5
6
7
8
9
10
防御分析注释:
all.sln是高风险能力集合,不能当普通练习项目随便全量运行。执行代码对应shellcode工程,第 18 课已经说明它有构建后执行和动态代码相关风险。驱动插件、注入管理、键盘记录、解密数据等项目应默认按高风险模块处理。
# 6. all.sln 的配置组合
all.sln 明确列出了可选配置。
# 源码位置:主插件\all.sln:48-56
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Release|Win32 = Release|Win32
Release|x64 = Release|x64
Release-exe|Win32 = Release-exe|Win32
Release-exe|x64 = Release-exe|x64
EndGlobalSection
2
3
4
5
6
7
8
9
10
新手要重点理解这个表:
| 配置 | 平台 | 含义 |
|---|---|---|
Debug|Win32 | 32 位调试 | 适合源码级断点,但不代表可以随便运行 |
Debug|x64 | 64 位调试 | 适合观察 64 位结构差异 |
Release|Win32 | 32 位发布配置 | 更接近发布产物,优化更多 |
Release|x64 | 64 位发布配置 | 64 位发布产物 |
Release-exe|Win32 | 32 位 EXE 输出配置 | 要结合具体工程看输出形态 |
Release-exe|x64 | 64 位 EXE 输出配置 | 同样要看具体 .vcxproj |
如果你只在一个配置下修了包含目录或库目录,另一个配置可能仍然失败。VS 属性页顶部也有“配置”和“平台”,改属性前先看清楚。
# 7. 再看 Quick.sln:主控解决方案
主控\Quick.sln 是主控端解决方案。它不只包含 Quick 项目,还包含第三方依赖项目。
# 源码位置:主控\Quick.sln:6-16
Project(...) = "Quick", "Quick\Quick.vcxproj", ...
ProjectSection(ProjectDependencies) = postProject
...
EndProjectSection
EndProject
Project(...) = "thirdParty", "thirdParty", ...
EndProject
Project(...) = "HPSocketLIB", "..\thirdparty\HP-Socket-dev\Windows\Project\HPSocketLIB-2022\HPSocketLIB.vcxproj", ...
EndProject
Project(...) = "Codejock.ToolkitPro.Static", "..\thirdparty\Xtreme ToolkitPro v18.5.0\Workspace\ToolkitPro\ToolkitProStatic.vcxproj", ...
EndProject
2
3
4
5
6
7
8
9
10
11
12
这说明:
Quick是主控项目。HPSocketLIB是网络库依赖。Codejock.ToolkitPro.Static是界面控件相关依赖。- 主控编译不只是编译
Quick.cpp,还涉及第三方项目。
Quick.sln 的配置比 all.sln 更少。
# 源码位置:主控\Quick.sln:18-22
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
2
3
4
5
6
防御分析注释:主控解决方案只列出 Debug|Win32 和 Release|Win32。新手不要强行切 x64 编译主控,除非明确知道项目和依赖都支持。
# 8. 新手在 VS 里怎么操作
只讲安全学习流程,不讲运行远控功能。

建议步骤:
打开
.sln。 主插件打开主插件\all.sln,主控打开主控\Quick.sln。先看解决方案资源管理器。 观察有哪些项目、哪些是依赖、哪些是高风险插件。
选择配置和平台。 顶部下拉框确认
Debug/Release/Release-exe和Win32/x64。检查项目属性。 看包含目录、库目录、运行时库、输出目录、构建前/构建后事件。
生成前创建快照。 这一步不属于 VS,但对高风险源码必须做。
生成时看输出窗口。 输出窗口能看到真实编译命令、链接信息、构建后事件和第一个失败点。
保存结果。 记录错误信息、输出目录、日志、告警和产物哈希。
# 9. Build、Rebuild、Clean 的区别
VS 菜单里常见三个操作,新手要区分:
| 操作 | 中文名 | 含义 | 新手建议 |
|---|---|---|---|
| Build | 生成 | 只编译变化过的文件 | 首次排错时优先用 |
| Rebuild | 重新生成 | 先清理再完整编译 | 配置改动较大时使用 |
| Clean | 清理 | 删除中间产物和输出产物 | 切换配置或排查脏产物时使用 |
对这套源码,任何生成操作前都要先检查构建后事件。尤其是 shellcode 这类工程,构建后可能执行新产物。
# 10. 输出窗口比错误列表更重要
新手常看“错误列表”,但在 C++ 项目里,真正有价值的信息经常在“输出窗口”。
| 位置 | 优点 | 缺点 |
|---|---|---|
| 错误列表 | 能快速跳到文件和行号 | 有时只显示汇总,不完整 |
| 输出窗口 | 能看到完整编译、链接和构建事件输出 | 信息多,需要从第一个失败点开始读 |
建议排错顺序:
- 先看输出窗口最早出现的错误。
- 判断是编译错误还是链接错误。
- 如果是缺头文件,回到包含目录。
- 如果是缺
.lib,回到库目录和附加依赖项。 - 如果是构建后事件失败,先停下来审计命令,不要继续运行。
# 11. 启动项目是什么
启动项目是按 F5 或“开始调试”时,VS 会运行的项目。它只是调试入口,不代表这个项目安全可运行。
README 里提到调试被控时设置 上线模块 为启动项。
# 源码位置:README.md:34-37
5. 如果需要调试Win32 debug被控,将`上线模块`工程设置成启动项,以Win32 debug编译即可调试。
6. 如果需要调试x64 debug被控,将`上线模块`工程设置成启动项,以x64 debug编译即可调试被控。
7. 如果需要调试主控,打开`主控\Quick.sln`以Win32 Debug编译主控即可调试主控。
2
3
4
防御分析注释:
- 设置启动项目之前,要先确认实验环境隔离。
- 被控相关模块属于高风险调试对象,应优先静态阅读。
- 主控调试也要注意网络监听、插件加载和构建器行为。
- 按 F5 前要确认启动参数、工作目录和网络状态。
# 12. 推荐调试策略

建议按风险分层:
| 风险层 | 可以做什么 | 暂时不要做什么 |
|---|---|---|
| 低风险 | 静态阅读 .sln、.vcxproj、UI 初始化、配置读取 | 不运行高风险插件 |
| 中风险 | 在虚拟机里编译必要项目、观察输出、断点调试普通逻辑 | 不连接真实目标 |
| 高风险 | shellcode、注入、驱动、键盘记录、解密数据默认静态审计 | 不复现攻击路径,不做绕过实验 |
调试目标不是“把功能跑通”,而是:
- 理解调用链。
- 记录证据。
- 验证检测点。
- 发现安全缺陷。
- 形成加固建议。
# 13. 断点应该先下在哪里
新手不要一开始就在高风险函数上下断点。可以先从低风险入口开始。
| 场景 | 推荐断点位置 | 学习目标 |
|---|---|---|
| 主控启动 | Quick.cpp、MainFrm.cpp 的初始化逻辑 | 看主窗口如何启动 |
| 界面事件 | 菜单或按钮对应的消息处理函数 | 看界面操作如何进入业务逻辑 |
| 网络类 | HpTcpServer.cpp、HpUdpServer.cpp 的回调包装 | 看收发回调结构,不连接真实目标 |
| 插件视图 | PlugView.cpp 等主控侧展示逻辑 | 看插件状态如何显示 |
| 构建器界面 | BuildDlg.cpp 的配置读取和界面逻辑 | 只看配置处理,不生成真实目标 |
高风险模块如 shellcode、注入管理、驱动插件、键盘记录、解密数据,应先读源码和项目配置,后续专栏会按防御视角拆解。
# 14. 常见编译失败怎么定位
| 现象 | 先看哪里 | 可能原因 |
|---|---|---|
| 很多项目一起失败 | 输出窗口第一个失败项目 | 依赖库、SDK、MFC 或配置问题 |
| 只有 x64 失败 | 平台下拉框、libx64 | 64 位库缺失或路径错误 |
| 只有 Release-exe 失败 | 对应 .vcxproj 配置 | 输出类型、构建事件或库配置不同 |
| 主控失败 | Quick.sln 里的 thirdParty 项目 | HPSocketLIB、Codejock 依赖问题 |
| 插件失败 | 对应插件 .vcxproj | HPSocket 头文件、运行时库、输出目录 |
| 构建后失败 | PostBuildEvent | 编译完成后执行命令失败或风险命令被拦截 |
| 报路径不存在 | .vcxproj 里硬编码路径 | 原作者本机路径在本机不存在 |
排错时不要一次改很多地方。每次只改一个问题,重新生成,保存输出日志。
# 15. 编译前安全确认事项
| 检查项 | 说明 |
|---|---|
| 授权范围 | 是否有明确研究授权 |
| 虚拟机 | 是否在独立 Windows 实验机中 |
| 快照 | 是否已创建可回滚快照 |
| 网络 | 是否断网或隔离到实验网络 |
| 配置 | 是否确认 Debug/Release/Release-exe 和 Win32/x64 |
| 依赖 | 是否确认 thirdparty、lib、libx64 存在 |
| 构建后事件 | 是否检查 PostBuildEvent |
| 输出目录 | 是否知道产物写到哪里 |
| 日志 | 是否保存 VS 输出窗口和系统日志 |
| 停止条件 | 是否明确出现高风险行为时立即停止 |
# 16. 企业检测点
编译和调试过程本身也可以纳入企业安全监控。
| 检测对象 | 关注点 | 数据源 |
|---|---|---|
| VS/MSBuild 进程 | 是否生成高风险 EXE/DLL | EDR、进程日志、CI 日志 |
| 构建后事件 | 编译后是否自动执行产物 | .vcxproj、输出窗口、进程树 |
| 输出目录 | 是否写入新二进制和插件产物 | 文件监控、产物哈希 |
| 依赖项目 | HPSocket、Codejock 等是否被重新编译 | CI 日志、依赖台账 |
| 调试器行为 | devenv.exe 是否启动高风险产物 | 进程树、命令行、用户操作日志 |
| 网络行为 | 调试期间是否出现外联或监听 | 防火墙、NDR、TCPView、Wireshark |
| 安全软件告警 | 产物是否被隔离或拦截 | EDR 控制台、隔离区记录 |
这些检测点不是为了阻止授权研究,而是为了让研究行为有边界、有记录、可复盘。
# 17. 常见误区
把 README 编译步骤当成使用教程。 本教程只用它理解工程关系,不指导实际使用远控能力。
一上来全量 Rebuild。 全量重新生成会触发大量项目和构建事件。新手应先看结构,再编译必要项目。
只看错误列表。 C++ 项目排错要优先看输出窗口,尤其是第一个失败点。
不知道启动项目是谁。 按 F5 前必须确认启动项目、参数、工作目录和网络状态。
忽略 Release-exe。 这套源码里 Release 和 Release-exe 可能输出不同形态,审计时要分开看。
把调试目标设成“跑通功能”。 安全学习的调试目标是理解调用链、记录证据和验证检测点。
# 18. 本课小结
第 5 课的核心是工程顺序和调试方法。README.md 告诉我们先看主插件 all.sln,再看主控 Quick.sln;all.sln 覆盖多个插件和多种配置,Quick.sln 则包含主控和第三方依赖项目。新手在 VS 里应先看解决方案资源管理器、配置下拉框、项目属性、输出窗口和错误列表。
对安全工程来说,编译和调试不是为了运行远控功能,而是为了理解构建链、识别高风险产物、记录检测线索和形成审计证据。
# 19. 合法练习题
- 阅读
README.md,把生产和调试两套编译顺序整理成表格。 - 打开
主插件\all.sln,列出其中所有项目名,并标出你认为的高风险项目。 - 打开
主控\Quick.sln,说明Quick、HPSocketLIB、Codejock.ToolkitPro.Static三个项目的关系。 - 不运行程序,只检查
.vcxproj中的PostBuildEvent,记录哪些项目存在构建后事件。 - 写一份 VS 输出窗口排错记录模板,至少包含配置、平台、第一个错误、失败项目、输出目录和处理建议。
安全工程知识交流加wx:easy_coder,黑灰产勿扰,企业单位合作请出示有效证件。
本留言区仅对应当前文章,欢迎补充观点、提出问题或帮助修正文中疏漏。 留言由 GitHub/Gitalk 提供,需要使用 GitHub 登录。
社区交流
讨论与留言