ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Gh0st远控源码VS2019编译迁移全攻略:从工程配置到部署验证

Gh0st远控源码VS2019编译迁移全攻略:从工程配置到部署验证 简介基于Gh0st远控与Visual Studio 2019整合的完整项目源码包适用于安全爱好者、网络管理人员及远程控制开发学习者帮助理解远控软件整体架构、通信机制与界面设计。压缩包共198个文件大小仅9.6MB主要包含60个C/C头文件、48个C源文件、7个DLL动态库以及VS2019工程解决方案、图标与位图资源等代码结构较完整便于直接打开编译、断点调试与二次改造。开发环境明确面向VS2019可借助新版IDE的调试工具快速定位问题适合有一定C基础、希望深入远控原理的读者。目前已有62人学习下载。资源提供了Gh0st-master主分支代码涵盖文件传输、远程协助、屏幕监控等核心模块的实现思路配套图片界面资源和项目配置便于从源码层面拆解功能逻辑也可作为网络安全课程设计或毕业设计的参考资料。1. 先给这份 Gh0st 代码包定个性远控原理学习样本别越界使用拿到这份【Gh0st 远控 VS2019】源码包第一反应不该是“能不能直接用”而是“拿它来做什么”。Gh0st 是安全圈流传十多年的开源远程控制项目整套 C/MFC 代码把客户端、被控端、网络通信、指令分发写得层次分明结构清晰到可以当 Windows 网络编程教材VS2019 则是我试过能把它从 VC6 老工程迁移过来最顺手的环境前提是字符集、MFC 组件这类前置项先配对。适合三类人想搞懂远控原理的安全学习者、做红队工具复现的研究者、被老 MFC 代码迁移折磨的 Windows 开发者。需要反复强调一句它只适合在授权机器、虚拟机上做教学实验别拿它碰任何不属于你的设备。注意本文所有编译、部署、调试步骤均假设你拥有对应设备的完整使用权或在书面授权范围内进行。2. 读懂 Gh0st 代码骨架Client/Server 双工程与四类核心模块老项目的第一个门槛是“看不懂它在干什么”。Gh0st 虽然叫一个名字但源码从来不是单个文件而是两个相对独立的程序加一堆共享头文件。先把工程的物理结构摸清后面编译和排错才有个方向。2.1 工程结构先分清 Client 工程与 Server 工程解压后你会看到两个 Visual Studio 工程目录常见命名是 Client控制端和 Server被控端有的分发版还会多一个 Common 或 Shared 目录放公共头文件。Client 是带界面的 Windows 程序负责发起连接、下发指令、展示结果Server 是不带界面的后台程序运行在目标机器上负责接收指令并执行。两个工程共享协议定义和 socket 封装但编译产物完全不同Client 生成的是操作端 exeServer 生成的是被控端 exe。我拿到手的习惯是先打开 .sln 看解决方案里挂了多少个工程。如果里面只有一个 Client 工程说明分发者把 Server 作为子项目或独立工程放在了别处如果 .sln 打不开就进去找 .vcxproj 文件用 VS2019 单独打开。这一步别跳过因为很多所谓的“2025 首发”源码包只是把老仓库重新打包工程文件路径可能已经被改过。2.2 启动主流程Server 端初始化到什么程度才开始监听搞清楚 Server 的启动顺序就理解了整个远控的工作模式。下面这段是依据 Gh0st 源码流程整理的骨架逻辑不同仓库版本函数封装有差异但主线一致// Server 端启动主流程骨架示例非完整源码 BOOL CServerA:InitInstance() { // 1. 读取配置监听端口、是否开机自启、服务名等 // 常见做法是读一个 server.ini或直接使用编译期常量 CConfig cfg; cfg.Load(_T(server.ini)); // 2. 创建监听线程绑定端口并进入 accept 循环 // 收到控制端连接后把 socket 交给独立会话对象处理 CListener listener(cfg.m_nPort); listener.Start(); // 内部依次调用 socket / bind / listen // 3. 每个连接对应一个 CClientHandler 实例 // 后续指令解析全部在这个会话线程里完成 CClientHandler handler(accept_socket); handler.Run(); return TRUE; }逻辑说明InitInstance 是 MFC 应用的入口Server 在这件事上做得比普通 MFC 程序简单——不创建主窗口直接初始化通信层就进入监听状态。CListener 负责网络监听CClientHandler 负责单连接会话每个控制端连接进来都会新建一个会话对象多个连接之间互不阻塞。这也是老代码里少见的“并发模型写得规整”的部分。参数说明cfg.m_nPort 就是你之后要改的端口号所有部署环节都会跟它打交道。注意配置读取失败时常见做法是回退到默认端口而非退出程序所以你在排查“为什么端口变了但连不上”时第一件事是确认有没有残留的 server.ini 覆盖了编译期默认值。2.3 协议与命令字每个功能模块怎么被远端唤醒远控的核心不是“能传数据”而是“能告诉对方执行什么”。Gh0st 用自定义二进制协议解决这个问题固定长度的包头含命令字和数据长度加可变长度的数据体。命令字就是功能的编号被控端收到包后先解出命令字再 switch 到对应处理函数。不同版本命令字的数值定义不一样但类型基本一致。按下表理解即可命令类型职责典型数据流屏幕类控制端请求截屏被控端返回图像数据请求带分辨率参数响应分块传回位图文件类列目录、上传、下载、删除请求带路径字符串响应带文件列表或数据流终端类远程创建 cmd 进程并回传输出请求带命令字符串响应分块回传管道输出键盘类被控端挂钩子记录按键并定时上报无立即请求按时间窗口主动回传这些命令字的宏定义或枚举集中在公共头文件里我拿到源码后会先搜 Packet 或 Protocol 关键字定位它。联调前务必打开这个文件看一遍别拿网上文章里的数值硬套——我见过有人照着旧帖改命令字改完整个功能串线的。2.4 四个核心模块的类划分与数据流功能模块在 Server 端通常是独立类每个类专职处理一类指令。屏幕模块一般叫 CScreenSpy 或 CScreenManager负责抓屏、分块压缩、传输老版本直接传 BMP改版会加 JPEG 压缩选项减少带宽占用。文件模块通常叫 CFileManager负责枚举目录、文件传输和删除操作。远程终端模块常见命名是 CShellManager 或 CCommandHandler内部用管道创建 cmd.exe 子进程把标准输出和标准错误合并回传。键盘模块则挂 WH_KEYBOARD_LL 钩子做按键捕获这个钩子需要管理员权限所以 Server 必须以管理员身份运行才能完整使用全部功能。理解模块划分对编译很有用如果你只需要研究屏幕和文件两个模块可以把键盘、摄像头等模块的源文件先从工程里摘出去减少编译时间和报错点。老代码的模块耦合度低删模块比改模块省事得多。3. VS2019 编译准备MFC 组件、多字节字符集与三个必改配置Gh0st 是 VC6 时代的老工程直接扔进 VS2019 编译第一轮报错数量能把新手吓退。但绝大多数错误是“环境不对”而非“代码坏”把下面三件事做对编译就能过半。3.1 安装 VS2019 时勾选 MFC一个组件决定后续编译成败Gh0st 的客户端大量使用 MFC 的对话框类和控件封装所以 VS2019 必须装上 MFC 库。安装器里选择“使用 C 的桌面开发”工作负载后右侧“安装详细信息”展开勾选“适用于 v142 生成工具的 MFC (x86 和 x64)”。如果已经装完才发现没勾不用重装打开 Visual Studio Installer点“修改”补勾选后点“修改”按钮等待完成即可。这里顺手解决一个检索高频问题网上铺天盖地的“VS2019产品密钥”“vs2019企业版许可证”不用理会社区版完全免费安装时登录微软账号就能用不需要任何密钥。企业版许可证是公司订阅的事跟编译 Gh0st 没有半毛钱关系。装社区版功能对老代码迁移完全够用。3.2 三个必改配置字符集、SDK 版本与语言标准用 VS2019 打开 Gh0st 工程后别急着点“本地 Windows 调试器”先改三处属性。右键工程 - 属性按表逐项确认配置项推荐值原因字符集使用多字节字符集老代码以 ANSI API 和窄字符为主Unicode 下满屏类型转换报错Windows SDK 版本10.0个别环境切 8.1新版 SDK 对 GetVersion 等老宏不友好报错时换 8.1 验证C 语言标准默认C14C17 的 noexcept 等行为变化会让老代码的析构与异常代码报错预处理器定义追加 _CRT_SECURE_NO_WARNINGS屏蔽 strcpy/strcat 等 deprecated 警告解放输出窗口字符集是最容易翻车的点。VS2019 默认 Unicode老代码里大量 char 数组、CString 隐式转换在 Unicode 下直接变 C2664 类型不匹配。切到多字节字符集后大部分转换错误自动消失这是老 MFC 工程迁移的头号操作。如果你在代码里看到 SetWindowTextA、GetWindowTextA 这类带 A 后缀的硬编码调用建议顺手统一去掉 A/W 后缀让编译器按当前字符集自动选择。多字节下 A 和 W 都能编译但混用容易在后续加功能时出现字符串编码不一致的隐患。3.3 编译顺序与 Build 输出先看 error 再处理 warning两个工程没有严格编译先后因为共享头文件只是声明不单独参与链接。我的习惯是先编译 Client 再编译 Server因为 Client 依赖的 UI 资源更多报错信息更全先啃硬骨头后面顺畅。编译前先确认解决方案配置管理器里两个工程都是 Release Win32 平台。老代码在 x64 下经常有 C4267 等指针截断警告个别版本甚至会直接编译失败没必要在第一步就挑战 x64。Release 也务必选对Debug 版本体积大且依赖调试运行库部署到没装 VS 的机器上会直接报缺 dll。第一次 Build 输出会很长看的时候按类型分流以 error 开头的行优先处理warning 先忽略。其中有大量 C4996 是 deprecated API 提示不影响运行。如果你装了 VS 的代码诊断插件或静态分析扩展warning 量会爆炸式增长我习惯先把“生成时运行代码分析”关掉只保留编译期的 warning 观察否则输出窗口根本没法看。4. 部署与联调把编译产物在局域网跑通的完整链路编译通过只是第一步真正耗时间的往往是“编译产物跑不起来”。Gh0st 的部署链路说长不长但三个环节每个都能卡住人环境、上线、功能验证。4.1 测试环境三件套双虚拟机、同一网段、防火墙放行我强烈建议用两台虚拟机测试而不是一台物理机加一台虚拟机。客户端和 Server 都跑在虚拟机里宿主机的网卡不会接触任何远控流量卸载残留也只需要恢复快照。VMware 里创建两台 Windows 10 虚拟机网络模式都选 NAT 或同一 VMnet 网段保证两台机器能互相 ping 通。被控端机器在部署前装好 VC 运行库不然 Server.exe 双击就报缺 dll这属于 5.1 节要细讲的坑。Server.exe 大概率被杀软报毒测试环境里把整个工作目录加入白名单或者干脆在断网隔离的虚拟机里测试别在宿主机的杀软弹窗里反复点允许那是在给自己添堵。端口放行是局域网测试里最容易忽略的一步。假设源码配置里的端口是 8000以你手上的实际端口为准Client 和 Server 要改一致并重新编译用管理员 PowerShell 执行# 放行 TCP 8000 入站允许被控端监听与响应 New-NetFirewallRule -DisplayName ghost-test-in -Direction Inbound -Protocol TCP -LocalPort 8000 -Action Allow参数说明-LocalPort 对应 Gh0st 配置里设置的端口号务必三处对齐——Server 编译配置、Client 连接配置、防火墙规则。如果测试时换了端口这条规则要删掉重建否则新旧规则叠加容易造成“端口改了却依然能连上旧口”的假象。删除规则用 Remove-NetFirewallRule -DisplayName ghost-test-in。4.2 上线检查进程、端口、客户端列表三层确认Server 启动后很多人的第一反应是看客户端有没有出现主机一旦没出现就陷入“玄学排查”。我的做法是固定三层确认每一层都有明确命令可查被控端先看进程。Server 可能配置了隐藏窗口任务管理器看不到界面但进程一定存在。用命令行查更可靠tasklist | findstr /i Server进程在再确认端口有没有监听netstat -ano | findstr :8000能看到 LISTENING 状态和对应 PID说明网络层已经就绪。此时客户端还不显示主机问题多半在防火墙或网络隔离监听端口都没起来问题一定在 Server 自己的启动流程。最后才看客户端界面里的主机列表——出现条目说明握手已完成条目里通常能看到内网 IP、主机名、系统版本等基础信息。这套顺序能帮你快速定位 80% 的“连不上”。别一上来就怀疑代码先确认进程活没活、端口听没听。4.3 三大功能验证路径屏幕、文件、终端的操作顺序上线成功后的功能验证也有讲究。我先测屏幕监控因为它的数据链路最短、反馈最直观客户端点开屏幕模块如果能看到被控端的桌面画面说明命令字解析、数据传输、图像显示整条链路是通的。画面黑屏先查被控端是否锁屏或断开了物理会话虚拟机黑屏通常是会话未激活远程桌面进去一次再测就好。第二步测文件管理列目录确认通信正常然后传一个小文本文件过去再拉回来本地比对哈希。这一步验证的是双向数据传输比单纯列目录更严格。第三步才测远程终端执行 ipconfig /all 看回显是否完整。终端模块依赖 cmd.exe 的管道输出容易受权限和系统策略影响所以放在最后测——前面两步通了终端出问题就只查管道那一小段逻辑不用整条链路重新排查。功能验证时注意屏幕刷新频率参数在屏幕模块类的成员变量里改常见默认是 500ms 拉一帧。局域网内卡顿先看被控端 CPU虚拟机单核跑图像压缩确实吃力不是你代码的问题。5. 避坑手册VS2019 编译 Gh0st 的五个高频错误现场Gh0st 迁移到 VS2019 的错误大部分是环境与新编译器的摩擦不是源码本身的 bug。下面五条是我反复踩过的现场每条都按“现象 - 原因 - 解决”写清楚能省你半天搜索时间。5.1 报错 msvcp140.dll 缺失动态运行库依赖的坑现象Server.exe 拷到没装 VS 的机器上双击直接弹窗由于找不到 msvcp140.dll无法继续执行代码。原因编译产物动态链接了 VC 运行库目标机器没有对应版本的红istributable。注意这里有个隐蔽分支你编译的是 Win32 程序在 64 位系统上跑加载的是 SysWOW64 里的 32 位运行库很多人只装了 x64 版本的 VC_redist32 位程序依然报缺 dll。解决去微软官网下载 VC 2015-2022 Redistributablex86 和 x64 都装上一劳永逸。如果你是给自己测试机用更省事的做法是 Release 下把工程改成静态链接属性 - C/C - 代码生成 - 运行库 - 多线程 (/MT)。注意 MFC 工程还要在“常规 - MFC 的使用”里选“在静态库中使用 MFC”两个开关配套设置才算数只改 /MT 不配 MFC 静态库照样会缺 mfc140.dll。5.2 C2065 资源ID未声明.rc 与 resource.h 对不上现象编译 Client 工程时报 error C2065“IDD_MAIN_DIALOG”未声明的标识符后面还跟着一串资源相关报错。原因老工程的 .rc 资源文件引用的对话框 ID在 resource.h 里没有对应宏定义。常见诱因是源码包从别处拷贝时 .rc 的包含路径没对上或者 .rc 文件编码在 VS2019 里打开后发生了转换导致部分注释和宏定义丢失。解决打开解决方案资源管理器里的 .rc 文件切到资源视图找到报错的对话框资源看它的实际 ID 数值再去 resource.h 里补一行宏定义。如果 .rc 是文本格式直接以文本方式打开找到 Dialog 定义把 ID 和 resource.h 对齐。这个错误不修的话无论怎么改字符集都没用它是资源编译阶段的硬错误。5.3 LNK2005 重复定义winsock 与 WinInet 符号冲突现象链接阶段报 LNK2005 “_select 已经在 WinInet.lib 中定义”或者类似的“符号已在某库中定义”。原因老代码同时引用了 Winsock 和 WinInet 两个网络库两者存在同名全局符号。另一个常见来源是代码里混用了 winsock.h 和 winsock2.h两个头文件定义了大量同名结构体和函数。解决在链接器 - 输入 - 忽略特定默认库 里添加 WinInet.lib让它不被自动链接。代码层面检查所有源文件确保只 include winsock2.h不要出现 winsock.h。Gh0st 的主要通信走 SocketWinInet 只是个别版本用来做 HTTP 下载附带功能直接不链影响不大。5.4 上线即断防火墙规则与 socket 超时要一起查现象客户端列表里能看到主机但一点屏幕或文件管理连接立刻断开或者主机条目出现后几秒就消失。原因两部分问题叠加。第一防火墙只放行了第一次连接握手数据传输建立的新连接被拦了很多人的入站规则只加了单端口但数据通道可能复用同端口或使用额外端口。第二老代码的 socket 超时时间设得短截屏数据量大、被控端压缩又慢超过超时时间直接被客户端判死。解决防火墙规则做到位——如果抓包发现数据通道走的是其它端口把规则改成端口范围或按程序放行。代码层面找到 socket 封装类的超时设置常见是调用 setsockopt 设置 SO_RCVTIMEO 的地方把默认的 5000 毫秒调到 30000 毫秒再测试。我遇到“上线即断”的案例八成是超时太短两成是防火墙只放了一半。5.5 中文乱码与功能异常字符集设置不当的隐性翻车现象客户端编译通过但界面中文乱码文件管理模块里中文路径的文件打不开。原因工程属性虽然显示多字节字符集但代码里混用了 L 宽字符串和普通字符串或者 .rc 文件在 VS2019 里被转成了 UTF-8而工程编译时按本地代码页解析。这种问题有个迷惑性在同一台机器上换一个字符集设置就能复现换个电脑又恢复正常容易被当成“环境玄学”。解决统一字符串处理涉及界面的文本全部走 _T() 宏按当前字符集自动适配。.rc 文件右键 - 打开方式 - 资源编辑器重新保存一次让 VS2019 按当前工程字符集重写编码。用 UltraEdit 或 VS 的“文件 - 高级保存选项”把 .rc 保存为带 BOM 的 UTF-8 或 GB2312具体选哪个以你系统区域设置一致为准。字符集这类问题修起来不难但排查时容易被一堆 warning 带偏方向认准“乱码 中文路径失效”的组合症状直奔字符集即可。6. 三步验证法抓包与进程监控确认命令链路正常功能能点通只是基本盘想确认代码路径真的在执行而不是瞎猫碰上死耗子我有一套三步验证法全程不用改代码。第一步WireShark 抓包。被控端虚拟机上打开 WireShark选连接控制端那块网卡过滤条件写 tcp.port 8000。在客户端点一次“屏幕监控”观察抓包窗口正常会看到一短一长的两个包——短的请求命令字长的是一大串分块传输的图像数据。老 Gh0st 协议不加密数据负载里能直观看到命令字的数值和文件路径字符串。拿这个数到公共头文件里对比枚举就能确认你点按钮时发出去的确实是屏幕命令。这一步的价值在于它能证明界面操作和网络行为是一一对应的联调时排查“点了没反应”特别有效。第二步Process Monitor 看行为。被控端跑一个 Process Monitor过滤条件设 Server.exe 进程名。客户端下发“文件管理 - 列目录”指令后观察 Procmon 里是否出现一连串 CreateFile 和 FileSystem 目录枚举事件。有说明命令确实触发了文件系统操作没有说明命令可能在模块分派环节就断了问题定位在 Server 端的处理函数而不是网络层。这个验证比客户端界面上的“成功/失败”提示可靠得多因为老代码的界面反馈经常是写死的。第三步快照回滚保环境干净。每次开始测试前给两台虚拟机各建一个干净快照。测试完无论结果如何直接恢复到测试前状态再开始下一轮。不要抱着“反正没中毒”的侥幸心理继续跑Server 在测试中产生的服务、注册表项、开机启动项清理起来比重装还费劲。我最早在物理机上直接跑 Server.exe卸载后注册表和服务残留一堆系统越用越慢从那以后每次测试都强制走一遍“双虚拟机 快照回滚”再也没被远控的残留坑过。这套验证流程看着朴素但真能帮你把“看起来能用”和“确实是按代码路径工作”区分开希望帮到你。本文还有配套的精品资源点击获取
返回列表