
简介PcShare 2005 远程控制软件源码是基于 VC6.0 经典开发环境可直接编译通过的完整经典远控项目面向 C 学习者、系统管理员及安全爱好者可用于深入理解远程控制软件的工作原理与实现方式。资源包共 403 个文件压缩为 rar 格式包后约 1006KB内含 121 个 h 头文件、98 个 cpp 源文件以及大量 ico、bmp 图标界面资源和 rc 资源脚本覆盖屏幕监控、键盘监控、鼠标控制、注册表管理、文件传输等典型功能模块目录结构明确便于按模块检索和二次开发。目前已有 948 人学习下载。通过编译和分析该源码可以掌握 VC6.0 环境下 MFC 应用程序的完整构建思路了解 Socket 通信、消息处理、远程命令执行等关键技术对照源码自行调试还能观察远程控制各功能的运行细节为逆向工程和安全研究提供经典参考样本。 开头要先说点实在的看到标题里“PcShare源码 VC6.0 直接编译通过 经典远控”这几个字我第一反应是——这串字符放在十年前是论坛里某个夜里蹲点等回复的帖子放在今天它更像一个技术考古的入口。PcShare是早期国内流传度极高的远程控制程序在那个Windows 2000/XP遍地走、网速还在用KB计算的年代它几乎成了“远控”二字的代名词。今天我写这篇不是教你怎么部署木马而是想借这个标题把老式Win32网络程序的编译环境、远程控制的底层通信逻辑以及我们做防御时该怎么识别这类工具的痕迹一并拆开讲清楚。无论你是对VC6.0好奇的新手还是做安全分析的老手这篇内容应该都有你能直接拿去用的部分。对了先把边界立住远程控制技术本身是双刃剑授权情况下是运维刚需未授权情况下就是侵入工具。下面所有内容我都站在“分析原理”和“防御排查”的角度来聊。1. “经典远控”这个名头的含金量在哪里1.1 一个时代的远程控制需求现在的人要远程控制一台电脑脑子里大概率会蹦出TeamViewer、向日葵、ToDesk这些现代工具甚至直接用系统自带的RDP。但在2000年代初期这些东西要么没诞生要么对环境要求很高需要公网IP、需要开放端口、需要对方配合操作。那个年代的上网环境很原始ADSL拨号、内网NAT、IP地址动态变化是常态。企业里要做远程运维个人要做远程协助缺乏成熟方案于是远程控制软件成了一个非常垂直且有强需求的市场。PcShare能火起来原因不算复杂它把“生成一个被控端、填上IP和端口、点一下连接”这件事做得足够傻瓜化功能又足够多——屏幕画面、文件操作、远程命令行、系统信息查看几乎覆盖了日常远控的所有高频需求。在一个没有云、没有高速网络、没有大厂统一方案的年代这种“体积小、功能全、开箱即用”的软件自然被大量使用也自然被很多人拿去做了不该做的事。1.2 “VC6.0直接编译通过”这句话的信息量在源码流传的过程中“直接编译通过”其实是一句很有分量的评价。老程序员都知道VC6.0是1998年发布的IDE对C标准的支持停留在远古级别现代C语法根本编译不过。而PcShare这类老工程能在VC6.0下一把过说明它的工程文件、依赖库、头文件路径都被整理得很完整项目本身也是纯Win32 API风格没有奇奇怪怪的第三方依赖。换到今天这句话对普通人的意义更深一个多年前的老项目如果连编译都过不了代码再漂亮也白搭而“直接编译通过”意味着你能马上得到可执行程序拿来分析它的行为、研究它的设计逻辑对学习Windows网络编程和恶意代码分析都有很高的样本价值。我在分析老样本时遇到“能一键编译还自带完整源码”的工程第一反应往往是庆幸——这省了我大量逆向时间直接把代码读完就能理解它的全部行为。2. 没有框架的年代远控程序是怎么搭起来的2.1 通信骨架很纯粹的Socket反向连接现代的远程控制软件底层大多有一整套协议栈甚至直接基于WebSocket/HTTPS封装。但老代码的思路非常直白用Winsock库建立TCP连接自己定一套私有协议两端按约定好的格式收发数据。这里有个关键设计你得先理解——为什么被控端要主动去连控制端而不是让控制端连过来。原因有两个一是那个年代多数电脑在NAT后面没有公网IP控制端根本找不到被控端二是防火墙默认拦截入站流量但对出站连接基本放行。所以“反弹连接”或者说“反向连接”就成了早期远控的标准姿势被控端一开机就去连一个固定的IP和端口控制端只需要在公网监听即可。如果用伪代码还原老式Socket连接的骨架大致是这样// 这是典型的客户端连接初始化流程 WSADATA wsaData; WSAStartup(MAKEWORD(2, 2), wsaData); // 初始化Winsock SOCKET sock socket(AF_INET, SOCK_STREAM, 0); struct sockaddr_in addr; addr.sin_family AF_INET; addr.sin_port htons(8888); // 连接目标端口 addr.sin_addr.s_addr inet_addr(1.2.3.4); // 连接目标IP connect(sock, (struct sockaddr*)addr, sizeof(addr));一旦连接建立起来后面就是数据的“你来我往”控制端发送“截屏”指令被控端执行后把图像数据分块发回去控制端发送“文件列表”指令被控端遍历指定目录后把结果发回去。没有HTTP那样复杂的协议全靠开发者自己约定指令编号和数据结构。这也是为什么老远控非常容易在流量侧被识别——协议往往是明文、固定特征码、没有加密混淆。现在做物联网底层、写即时通信软件你依然会碰到同样的三个基础问题连接保活、心跳机制、粘包拆包。这些问题在老远控代码里全都有最朴素的实现读一遍比看十篇框架文档都管用。2.2 被控端行为面启动项与常驻机制一个远控程序想要长期控制一台机器必须解决“重启后还能继续活着”的问题。老代码里最常见的做法就是写注册表启动项让系统登录时自动拉起被控端稍微高级一点的会注册成Windows服务或者往启动文件夹里丢一个可执行文件。从防御视角来看这里有个特别重要的认知自启动不等于恶意很多合法远程控制软件也做一样的事。判断一个自启动项是否可疑关键看三点程序文件放在哪、启动后连向哪里、签名和创建时间是否对得上。PcShare时代有个典型特征——被控端文件经常伪装成系统文件名放在Temp或Program Files子目录里启动项名称也模仿系统组件。这种“看起来像系统、实际不是”的行为链恰恰是做应急响应时需要重点盯住的。我每次拿到疑似远控样本第一件事不是急着杀进程而是先打开注册表编辑器查看这几个位置HKCU\Software\Microsoft\Windows\CurrentVersion\Run、HKLM\Software\Microsoft\Windows\CurrentVersion\Run再看看服务项和计划任务。先搞清它怎么活的再考虑怎么清。3. 用VC6.0编译老工程最容易卡住的三个地方3.1 环境兼容Win10/11上能不能装VC6先说结论能装但别硬装。VC6.0在Windows 10/11上安装时经常出现兼容性提示装完后IDE界面可能显示异常调试器也可能连不上进程。我用过两种方案解决一是在安装包上右键选择“兼容性疑难解答”用Windows XP SP3模式安装二是干脆装一个Windows XP虚拟机在里面跑VC6这是最省心也最还原当年环境的方式。虚拟机方案额外有个好处让你分析老样本时天然有一个隔离边界不容易污染宿主机。装完之后还有一步容易漏——安装VC6的SP6补丁包。不打这个补丁编译器对部分标准库和ATL的支持会有隐藏问题后面编译到一半蹦出莫名其妙的错误查起来很浪费时间。3.2 Winsock链接错误LNK2001和unresolved external symbol老远控几乎不可能不用Socket所以编译时最典型的问题就是链接阶段报unresolved external symbol __imp__socket12或者LNK2001: unresolved external symbol。我第一次遇到时还以为是代码写错了折腾半天才反应过来链接器没找到Winsock的导入库。解决办法很简单要么在工程设置里把ws2_32.lib加到链接库列表要么在代码头部加一行#pragma comment(lib, ws2_32.lib)这里补充一个排查思路如果报错符号带__imp__前缀基本可以断定是导入库缺失如果报错符号是普通函数名才需要考虑是不是代码里根本没实现这个函数。把这两类问题分开看能少走很多弯路。3.3 字符集、SDK版本和Win32 API宏老工程默认走MBCS字符集很多字符串处理用的都是char*。现在新装的Windows SDK默认推荐Unicode项目的字符集设置如果不匹配轻则界面乱码重则直接编译报错。处理办法是把项目字符集明确改成“未设置”或“使用多字节字符集”然后排查代码里是否混用了MessageBoxA和MessageBox这类API。还有一类报错涉及_WIN32_WINNT宏。有些API是随SDK版本逐步加入的比如SetWindowLongPtr要求目标平台宏至少是_WIN32_WINNT_WIN2K。老工程如果不显式定义这个宏编译器可能直接提示找不到函数声明。在工程预处理器里加一句WINVER0x0501和_WIN32_WINNT0x0501通常能解决大部分这类问题。下面这张表是我踩坑时整理的方便你对照报错现象常见原因处理方式LNK2001 unresolved external symbol __imp__socket12缺少ws2_32.lib工程设置添加库或#pragma comment(lib, ws2_32.lib)字符乱码、无法解析外部符号项目字符集不匹配统一为多字节字符集或Unicode找不到API声明或函数WINVER/_WIN32_WINNT宏太低预处理器定义0x0501及以上IDE兼容性问题VC6与新版系统不兼容兼容模式安装或用XP虚拟机4. 防御视角下怎么识别这类“老牌远程控制”的痕迹4.1 网络层面的行为指纹老远控虽然“年代久远”但它的网络行为特征反而比现代恶意软件更明显对防守方来说简直是教科书级的排查对象。你可以在防火墙日志或路由器连接记录里重点看这两类情况一是某台内网主机长期向某个固定IP地址发起TCP连接连接保持时间长、流量不大不小但从不间断二是连接的目标端口固定不变比如8888、6666这类非标准端口而不是常见的80/443。在Windows本机排查几条命令就够了# 查看当前所有TCP连接及对应进程ID netstat -ano | findstr ESTABLISHED # 根据PID定位进程名 tasklist | findstr PID # 查看自启动项 reg query HKCU\Software\Microsoft\Windows\CurrentVersion\Run reg query HKLM\Software\Microsoft\Windows\CurrentVersion\Run网络层还有一个隐蔽点心跳包。远控为了确认被控端在线会定期发很小的数据包类似“我还活着”的心跳信号。这种流量正常情况下几秒钟到几十秒出现一次规律性极强。排查时如果发现某个连接的数据包收发频率像节拍器一样精准即使流量很小也值得追一下PID对应的进程到底是什么。4.2 主机层面的排查清单主机层检查比网络层更直观关键是养成一套固定排查顺序。我自己的习惯是“进程—文件—自启动—服务/计划任务”四步走排查项需要重点关注的位置或特征进程列表进程名像系统进程但路径在Temp、ProgramData等非系统目录文件签名无数字签名或签名者与发布方不一致自启动项Run键、启动文件夹出现随机命名或伪装系统组件名的条目服务与计划任务服务路径指向非常规文件夹或计划任务频繁执行某个可执行文件这里有个容易被忽略的点老远控为了让自己看起来像系统文件经常起名叫winlog.exe、svch0st.exe这类“高仿”名称。单纯看进程名很难发现问题但只要右键查看属性里的文件路径和数字签名真伪立现。真正的系统进程要么路径在C:\Windows\System32要么有微软签名能做到这两点的恶意样本其实很少。4.3 合规边界远程控制技术的合法使用姿势写到这里必须把话说明白远程控制代码和任何工具一样用在正途是维护系统效率用在歪路就是违法犯罪。合法场景其实非常普遍IT运维人员远程检修授权服务器、员工远程操作自己工位电脑、家庭用户自己控制家中另一台设备这些都是正当需求使用正规的远程控制软件完全够用。未经授权控制他人电脑无论意图是偷窥还是破坏都触碰了法律红线。我见过不少年轻人因为好奇去试老工具觉得自己只是“玩玩”结果给对方造成了实际损失或被用于非法用途最后被依法处理时悔之晚矣。这一点真的不是吓唬人。5. 老代码对今天的安全学习者真正的价值5.1 长连接、心跳和私有协议的基础知识永不过时读老远控源码最直接的收获其实是网络编程基本功。现在很多开发者写网络程序直接用封装好的HTTP库或WebSocket库反向连接、心跳保活、粘包拆包、数据帧格式设计这些底层问题平时根本接触不到。而老式远控程序因为要自己搞定一切这几块知识全都有最朴素、最直白的实现。比如“粘包”问题——连续发送两条指令时接收方怎么区分边界老代码的常见做法是规定每条消息的头部是固定长度的包体长度字段收到头部后按长度读后续数据。这个思路在今天做物联网设备通信、写游戏服务器协议、设计长连接推送系统时依然完全适用。学会了底层原理再去看各种封装好的框架你会发现它们内部无非也是这些套路的工程化。5.2 从“看懂老代码”到“形成防御直觉”分析PcShare这类老样本给我最大的收获不是学会了怎么写远控而是养成了看到任何程序都先想想“它会怎么连、连哪里、怎么活下来”的防御直觉。现在拿到一个疑似可疑的样本我头脑里自动跑完整个排查链路先找网络行为看看有没有外联、连到哪个端点再看进程路径和自启项然后查服务和计划任务。这套思路就是从读远控源码开始建立的——当你理解了攻击者的每一步动作防守时自然知道该看哪里。上个月处理一台内网异常主机我就是沿着“异常外连→定位PID→发现计划任务→溯源到下载文件”这条链路半小时内锁定了问题源头整个过程没有多走一步弯路。不过我也要提醒一句分析这类代码务必放到隔离环境里进行也不要尝试在真实机器上部署和运行——用虚拟机、用静态阅读的方式学习原理就已经足够了。技术没有善恶但使用技术的人有。希望读到这里的你学到的是原理和防御能力而不是去重复那些已经被验证过很多遍的错误。本文还有配套的精品资源点击获取