
简介PcShare源码包是一套经典远程控制软件的完整源码基于VC6.0环境构建可直接编译通过适合C爱好者、逆向分析人员与系统管理员研读。资源共包含403个文件以头文件、源程序文件为主体另含大量图标位图、工程配置、资源脚本与库文件其中bmp位图直观展示客户端各操作界面ico和cur定义了程序图标与光标rc资源脚本则串联起界面与代码逻辑覆盖服务端生成、客户端连接、界面交互等完整模块压缩后仅约1006KB结构紧凑便于逐项分析。已有948人学习浏览是从源码层面理解早期远控实现流程的优秀样本。通过阅读这份代码可以直观看到屏幕监控、键盘记录、鼠标控制、注册表管理、生成被控端等典型功能的后台处理逻辑同时体会VC6.0下多工程管理与MFC资源设计的实践方法对提升网络编程和软件逆向能力都有参考价值。1. 写在前面为什么这套源码值得翻出来再看一次我在整理移动硬盘时翻出了当年收集的PcShare源码顺手在虚拟机里用VC6.0编译了一遍没想到真的一遍通过连警告都少得可怜。作为一个经历过网吧系统维护、机房批量管理年代的老开发这套源码对我来说不只是一堆代码更像是一本活教材——它把远程控制软件的核心细节全都摊开放在你面前网络通信、服务端自启动、钩子注入、界面线程模型每一样都能单独拉出来讲半天。说白了PcShare就是经典的C/S客户端/服务端架构远控软件服务端被植入目标机器后保持静默运行客户端通过配置端生成连接后可以执行文件管理、屏幕查看、键盘记录、命令行操作等任务。源码使用C编写工程文件基于VC6.0整个项目结构清晰到让人舒服。对Windows客户端开发感兴趣的人、安全方向的学习者、或者纯粹想研究老代码的爱好者都可以从这套源码里挖到不少东西。我必须先把话放在前面远程控制技术是一把双刃剑。这篇文章只讨论源码结构、编译原理和技术学习价值所有操作必须在你有权控制的设备、虚拟机或实验环境里进行绝不能用于未授权的监控或入侵。技术本身是中性的怎么用完全取决于人。2. 项目整体设计与技术思路拆解2.1 PcShare到底是个什么样的项目从工程结构上看PcShare由三个相对独立的模块组成服务端、客户端和配置端。服务端运行在被控机器上客户端运行在控制者机器上配置端则是用来定制服务端程序的。三者的关系和实际工作流程大致是这样的模块功能定位关键技术点配置端生成定制化服务端资源写入、加密配置、PE文件操作服务端被控端主程序自启动、端口监听、命令执行、屏幕/文件操作客户端控制端界面连接管理、远程命令下发、实时数据显示配置端生成服务端时会把IP地址、端口、开机启动方式、服务名称等参数写进一个自定义结构体然后通过资源段或文件追加的方式打包进服务端EXE。服务端启动后先读取自身资源解析出配置参数再按照配置执行后续动作。这种“先配置、后编译”的思路在当年的远控软件里非常主流因为不可能让使用者去改源码重新编译必须提供图形化配置入口。源码本身没有用第三方库纯Win32 API MFC实现这也是它能用VC6.0直接编译的原因之一。MFC负责界面部分底层网络、文件、注册表操作全部直接调用系统API。2.2 为什么选VC6.0而不是新版本Visual Studio这个问题我在研究时想了很久。PcShare源码诞生于VC6.0流行的年代工程文件是.dsp/.dsw格式代码风格也完全是那个时代的印记。VC6.0对C标准的支持比较宽松很多写法在今天看来属于“未定义行为”但当时编译器能宽容地处理掉。用新版VS编译老项目的典型痛苦相信不少人经历过_WIN32_WINNT宏定义不匹配导致API声明找不到、char和const char类型转换报错、for循环作用域问题、MFC版本差异引发的链接错误以及最让人头疼的“warning C4996”strcpy、sprintf这类不安全函数警告。VC6.0没有这些条条框框的限制它编译PcShare时几乎不需要额外调整。我实测下来用VC6.0打开.dsw后设置好工作区直接Build Solution就能过连链接库的路径都不用改。这个“直接编译通过”的含金量在于原作者写代码时就是对着VC6.0的编译器习惯来写的这也是老项目研究中使用对应版本编译器的最佳理由。2.3 核心架构命令分发与通信协议设计PcShare的通信模型是典型的TCP长连接。服务端启动后绑定某个端口比如默认8000等待客户端连接。连接建立后双方按照预定义的命令字进行交互。每个功能对应一个命令编号例如文件枚举、文件下载、屏幕截图、键盘记录等。客户端发送一个结构体里面包含命令字和参数缓冲区服务端收到后通过switch-case把任务分发给对应处理函数。这种设计简单直观在当时既不需要序列化框架也避免了复杂的协议解析适合小团队自主研发。不过它的安全防护基本为零。通信数据虽然有一些简单的异或加密处理但密钥是硬编码在源码里的懂行的人逆向服务端就能提取出来。从学习角度看这恰好是理解“协议设计哪些环节容易出安全问题”的反面教材。我在后面会专门讲如何改进通信加密。3. 核心功能原理与实现细节3.1 服务端自启动与驻留技术服务端被植入目标机器后的第一件事就是实现持久化通俗讲就是“下次开机还能活着”。PcShare采用了典型的注册表自启动方式把自身路径写入HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run这行代码非常简单但要注意一个细节如果服务端程序位于临时目录直接写入Run键值就能实现开机自启。但如果程序路径包含空格比如C:\Program Files\xxx.exe必须加上引号否则系统启动时无法正确解析路径。除了注册表PcShare也尝试以服务方式启动。通过OpenSCManager、CreateService等API把自己注册成系统服务这样不仅能在用户登录前运行还能在任务管理器里以“服务”名义隐藏进程降低被普通用户发现的概率。不过注册服务需要管理员权限在Windows XP时代这基本不是问题到了Windows 7以后UAC就会拦一道。从实际学习角度看PcShare的自启动代码非常适合用来理解Windows系统服务的运作机制服务控制管理器SCM如何管理服务状态、SERVICE_MAIN函数如何注册回调、服务如何在Session 0隔离环境下运行。这些知识即使在今天的Windows开发中依然有用。3.2 网络通信的底层实现PcShare的网络层直接使用Winsock 1.1接口。核心代码集中在socket的创建、bind、listen和accept流程中。服务端创建监听Socket的关键代码大致长这样SOCKET sockSrv socket(AF_INET, SOCK_STREAM, 0); SOCKADDR_IN addrSrv; addrSrv.sin_family AF_INET; addrSrv.sin_addr.S_un.S_addr htonl(INADDR_ANY); addrSrv.sin_port htons(8000); bind(sockSrv, (SOCKADDR*)addrSrv, sizeof(SOCKADDR)); listen(sockSrv, 5);客户端使用socket()、connect()建立连接。连接建立后数据交互通过send()和recv()完成。PcShare没有采用IOCP或完成端口这类高并发模型而是为每个客户端连接单独创建一个接收线程配合阻塞式recv等待数据。这种设计在1对1或1对几的控制场景中完全够用代码也容易理解。真正让我觉得值得学习的地方在于它的接收缓冲区处理逻辑。网络数据是流式的一次send不一定对应一次recvPcShare通过自定义包头结构包含数据长度字段解决粘包与半包问题。这个包头设计思路值得展开讲。它定义了一个固定的消息头struct PacketHeader { DWORD dwSize; // 整个数据包大小 DWORD dwCmd; // 命令字 BYTE bData[1]; // 可变长数据起始位置 };收到数据时先读取dwSize如果当前缓冲区长度不够就继续recv直到满足长度要求。这就是最基础的协议分包处理理解了它对后续学习任何网络协议都有帮助。3.3 文件管理、屏幕监控与键盘记录文件管理模块实现了一套完整的远程文件操作枚举目录、上传文件、下载文件、删除文件、创建文件夹。底层直接调用FindFirstFile/FindNextFile枚举文件用WriteFile/ReadFile流式传输文件数据。屏幕监控的思路是隔一段时间抓取一次屏幕快照。核心API是GetDesktopWindow获取桌面窗口句柄GetWindowDC获取窗口设备上下文BitBlt把屏幕内容复制到内存位图最后压缩成JPEG或BMP发送给客户端。由于当年网络带宽有限截屏通常采用低分辨率JPEG压缩来降低数据传输量。键盘记录模块里最有技术含量的是全局钩子SetWindowsHookEx的使用。PcShare通过安装WH_KEYBOARD_LL低级键盘钩子来捕获所有按键消息钩子过程需要放在DLL中才能被系统加载到所有进程的地址空间。DLL注入的思路是系统在分发键盘消息时会自动把包含钩子过程的DLL映射到目标进程钩子函数就能在目标进程上下文中执行。这个机制在学习Windows消息机制时非常典型理解了它后续再看远程线程注入或APC注入都会轻车熟路。4. 编译环境准备与完整编译步骤4.1 环境准备清单想在VC6.0下顺利编译PcShare源码首先要搭好合理的环境。我强烈建议使用Windows XP虚拟机因为PcShare的部分API调用方式在Windows 10/11上运行时会遇到权限和兼容性问题但这与编译无关编译本身不挑系统。环境清单如下VMware或VirtualBox虚拟机安装Windows XP SP3Visual C 6.0最好是包含SP6升级包的完整版本Microsoft Platform SDKWindows Server 2003 SP1 SDK即可用于补充较新的头文件和库文件源码包放在无中文和无空格的目录下比如D:\PcShare为什么强调虚拟机一方面老编译器在老系统里运行最稳定另一方面也是为了隔离风险。研究任何来历不明的源码都应该在虚拟机里进行这是安全底线。4.2 三步完成编译整个编译过程可以分为三步每一步都有需要特别注意的地方。第一步打开工程文件。在VC6.0里通过File-Open Workspace打开源码根目录下的PcShare.dsw。如果目录下有多个.dsp文件通常选择与服务端或客户端同名的那个。第二步检查编译配置。在Build-Set Active Configuration里确认当前活动配置是“Win32 Release”而不是“Win32 Debug”。Debug版运行时依赖调试版MFC库在未安装VC6.0的机器上很容易报“缺少MSVCRTD.dll”的错Release版静态链接MFC和CRT生成的EXE可以直接拷贝运行。第三步执行编译。Build- Build Solution快捷键F7。如果一切正常输出窗口会显示“0 error(s), 0 warning(s)”。整个过程不超过一分钟连“编译生成中”的画面都来不及多看两眼。4.3 编译产物测试编译成功后在Release目录下会生成对应的EXE文件。我建议把配置端和服务端的EXE拷贝到一台单独的Windows XP测试机或另一个虚拟机里做功能验证。先在测试机上运行配置端填入本机IP和端口生成定制服务端。然后在测试机上运行服务端回到开发机上打开客户端输入测试机IP和端口执行连接。如果客户端界面显示已连接并能列出测试机的磁盘目录就说明整套流程是通的。测试时建议关闭测试机的防火墙或者提前在防火墙里放行对应端口。Windows XP SP2开始默认启用防火墙如果忘了放行服务端虽然监听正常但外部连接会被拦掉这个坑我在第一次测试时就踩过。5. 编译过程中的常见错误与排查实录VC6.0编译老代码虽然顺畅但不同来源的源码包可能被修改过或缺少文件依然会遇到一些典型问题。我整理了一份排查表都是实际操作中见过的场景。错误现象可能原因解决思路fatal error C1010: unexpected end of file while looking for precompiled header某个.cpp文件没有包含stdafx.h或强制预编译头设置不一致在Project Settings-C/C-Precompiled Headers里改为“Not using precompiled headers”或统一设置“Use precompiled header”error LNK2001: unresolved external symbol “public: virtual destructor”缺少MFC库或类实现未编译确认工程链接设置里选择了正确的MFC库Use MFC in a Static Library重新Build Allerror C2065: undeclared identifier “...“缺少对应的头文件或Windows API宏定义补#include或检查_WIN32_WINNT版本宏是否太低导致API声明被遮蔽warning C4996: ‘strcpy’ was declared deprecatedVC2005之后编译器对不安全函数告警不影响编译可忽略如要消除用strcpy_s替换或定义_CRT_SECURE_NO_WARNINGS运行时提示找不到DLL使用了动态链接的MFC/CRT换用Release Static Library配置重新编译最值得说的是预编译头文件问题。VC6.0工程默认使用预编译头很多老代码依赖stdafx.h集中包含头文件如果新建文件时忘了添加#include,编译器会在文件末尾报C1010错误。解决办法是逐个检查新加入的.cpp文件确保第一行包含stdafx.h。链接错误多数和库依赖相关。PcShare的客户端用到了MFC的CListCtrl、CStatusBar等控件类必须确保工程的MFC使用方式设置为“Use MFC in a Shared DLL”或“Use MFC in a Static Library”。改成静态库方式可以让程序独立运行但EXE体积会大不少。还有一个常见的运行时崩溃在Windows 7以上系统直接运行PcShare客户端可能一启动就闪退。这是因为老程序默认以管理员权限运行某些操作时没有做错误处理某个API调用失败后直接崩溃。解决办法是以管理员身份运行EXE或设置兼容模式为Windows XP SP3。6. 这份源码的学习价值与合规使用红线6.1 为什么“直接编译通过”最值得感慨现在的开发体验是丰富的IDE、包管理器、自动补全、持续集成只要配置好依赖编译不再是问题。但回到VC6.0年代程序员需要在没有智能提示、没有自动依赖管理的环境里手写所有代码还要保证一份源码换台机器依然能编译通过。PcShare这个“直接编译通过”背后是原作者对工程配置、编码风格、平台差异的精细掌控。从学习角度看这份源码的价值主要体现在四个维度一是理解C/S架构软件的完整链路从界面到网络再到系统操作的全过程二是掌握Windows核心机制包括服务、钩子、注册表、套接字三是学会协议设计的基本思路特别是分包和命令字设计四是通过反面对照理解安全编码的重要性看清弱加密、硬编码密钥这些当年的常见做法存在什么问题。6.2 改进方向参考不动源码只看代码可能会不过瘾。我在研究时总结过几个可自行改进的方向难度递增给通信数据换成AES加密解决密钥硬编码问题把阻塞式recv改成select或IOCP模型提升并发连接能力给服务端加入数字签名校验防止程序被恶意替换将屏幕传输改为H.264硬编码大幅降低带宽占用。这些改进每一个都能独立成一篇研究文章。6.3 红线必须讲清楚写到这里我必须再次强调远程控制软件如果被用于未经授权的设备访问就是非法行为。PcShare源码在网络上流传多年研究它的正确目的应该是了解技术原理、提升编程能力、辅助安全防御。任何涉及未授权控制他人电脑的操作都是绝对不行的。我自己的习惯是所有远控类源码研究都在断网或虚拟网络环境中进行目标设备一定是自己创建的虚拟机或实验室机器测试完成后立即恢复快照不留任何后台程序。这个习惯建议所有阅读这篇文章的人照抄。技术研究最大的魅力不在于“能做到什么”而在于“为什么能做到”以及“如何防止被滥用”。PcShare源码打开了一扇理解Windows网络编程底层原理的窗口透过这扇窗口能看到的是远比代码本身更广阔的知识图景。本文还有配套的精品资源点击获取