当前位置: 首页 > news >正文

保姆级教程:用C++写个进程扫描器,揪出学生机房管理助手7.5的随机马甲

从零构建C进程扫描器精准识别随机化进程名的实战指南在Windows系统管理中进程扫描是排查异常程序的基础技能。想象这样一个场景机房管理员发现学生终端频繁出现伪装成随机名称的进程传统杀毒软件无法识别。这时一个能根据特定特征过滤进程的自定义扫描工具就显得尤为重要。本文将带你用C从头构建一个轻量级进程扫描器不仅能遍历系统所有进程还能实现高级过滤逻辑——这正是识别那些刻意隐藏自己的马甲程序的关键所在。1. 环境准备与基础概念在开始编码前需要确保开发环境配置正确。推荐使用Visual Studio 2019或更高版本社区版即可满足需求。新建一个C控制台项目时务必选择x86或x64平台根据目标系统决定并确保Windows SDK版本为10.0或更新。进程扫描的核心依赖于Windows API中的Toolhelp32系列函数。这套API提供了系统快照功能可以获取包括进程、线程、模块等在内的系统状态信息。与更底层的Psapi相比Toolhelp32更适合大多数应用场景因其不需要特殊权限即可获取基础进程信息提供统一的快照机制保证数据一致性支持递归遍历系统所有进程关键数据结构PROCESSENTRY32包含我们需要的核心信息typedef struct tagPROCESSENTRY32 { DWORD dwSize; // 结构体大小 DWORD cntUsage; // 引用计数 DWORD th32ProcessID; // 进程ID ULONG_PTR th32DefaultHeapID; DWORD th32ModuleID; DWORD cntThreads; DWORD th32ParentProcessID; // 父进程ID LONG pcPriClassBase; DWORD dwFlags; CHAR szExeFile[MAX_PATH]; // 进程映像文件名 } PROCESSENTRY32;2. 实现基础进程遍历功能让我们从最简单的进程枚举开始。创建一个名为ProcessScanner.cpp的新文件首先包含必要的头文件#include windows.h #include tlhelp32.h #include iostream #include string #include vector定义进程扫描类的基本结构class ProcessScanner { public: ProcessScanner(); ~ProcessScanner(); std::vectorDWORD ScanProcesses(); void PrintProcessList(const std::vectorDWORD pids); private: HANDLE CreateProcessSnapshot(); };实现快照创建函数这是所有进程操作的基础HANDLE ProcessScanner::CreateProcessSnapshot() { HANDLE hSnapshot CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, // 获取进程列表 0); // 当前进程 if (hSnapshot INVALID_HANDLE_VALUE) { std::cerr 创建进程快照失败. 错误代码: GetLastError() std::endl; return nullptr; } return hSnapshot; }完整的进程遍历实现如下std::vectorDWORD ProcessScanner::ScanProcesses() { std::vectorDWORD processList; HANDLE hSnapshot CreateProcessSnapshot(); if (!hSnapshot) return processList; PROCESSENTRY32 pe32; pe32.dwSize sizeof(PROCESSENTRY32); if (!Process32First(hSnapshot, pe32)) { CloseHandle(hSnapshot); return processList; } do { processList.push_back(pe32.th32ProcessID); } while (Process32Next(hSnapshot, pe32)); CloseHandle(hSnapshot); return processList; }注意每次调用CreateToolhelp32Snapshot后必须调用CloseHandle释放资源否则会导致内存泄漏。3. 实现高级过滤逻辑针对特定场景如识别随机化进程名我们需要在基础扫描上增加过滤条件。假设目标进程具有以下特征进程名长度为10个字符所有字符都在d-m的ASCII范围内首先添加过滤方法到ProcessScanner类class ProcessScanner { // ... 原有代码 ... std::vectorDWORD FilterProcesses( const std::vectorDWORD pids, size_t nameLength, char rangeStart, char rangeEnd); private: bool CheckProcessName( DWORD pid, size_t nameLength, char rangeStart, char rangeEnd); };实现进程名检查函数bool ProcessScanner::CheckProcessName( DWORD pid, size_t nameLength, char rangeStart, char rangeEnd) { HANDLE hSnapshot CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (!hSnapshot) return false; PROCESSENTRY32 pe32; pe32.dwSize sizeof(PROCESSENTRY32); if (!Process32First(hSnapshot, pe32)) { CloseHandle(hSnapshot); return false; } bool found false; do { if (pe32.th32ProcessID pid) { std::string name(pe32.szExeFile); if (name.length() nameLength) { found true; for (char c : name) { if (tolower(c) rangeStart || tolower(c) rangeEnd) { found false; break; } } } break; } } while (Process32Next(hSnapshot, pe32)); CloseHandle(hSnapshot); return found; }最终过滤方法实现std::vectorDWORD ProcessScanner::FilterProcesses( const std::vectorDWORD pids, size_t nameLength, char rangeStart, char rangeEnd) { std::vectorDWORD filtered; for (DWORD pid : pids) { if (CheckProcessName(pid, nameLength, rangeStart, rangeEnd)) { filtered.push_back(pid); } } return filtered; }4. 优化与错误处理基础功能实现后我们需要考虑性能和健壮性。以下是几个关键优化点错误处理增强版快照创建HANDLE ProcessScanner::CreateProcessSnapshot() { HANDLE hSnapshot CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (hSnapshot INVALID_HANDLE_VALUE) { DWORD err GetLastError(); if (err ERROR_ACCESS_DENIED) { std::cerr 错误: 需要管理员权限 std::endl; } else if (err ERROR_BAD_LENGTH) { std::cerr 错误: 结构体大小设置不正确 std::endl; } else { std::cerr 未知错误: err std::endl; } return nullptr; } return hSnapshot; }性能优化技巧减少重复快照创建在FilterProcesses中我们为每个PID都创建了快照这显然效率低下。更好的做法是一次获取所有进程信息并缓存std::vectorPROCESSENTRY32 GetAllProcessEntries(HANDLE hSnapshot) { std::vectorPROCESSENTRY32 entries; PROCESSENTRY32 pe32; pe32.dwSize sizeof(PROCESSENTRY32); if (!Process32First(hSnapshot, pe32)) { return entries; } do { entries.push_back(pe32); } while (Process32Next(hSnapshot, pe32)); return entries; }使用哈希表加速PID查找std::unordered_mapDWORD, PROCESSENTRY32 CreatePidMap( const std::vectorPROCESSENTRY32 entries) { std::unordered_mapDWORD, PROCESSENTRY32 pidMap; for (const auto entry : entries) { pidMap[entry.th32ProcessID] entry; } return pidMap; }完整优化后的过滤实现std::vectorDWORD ProcessScanner::FilterProcessesOptimized( const std::vectorDWORD pids, size_t nameLength, char rangeStart, char rangeEnd) { std::vectorDWORD filtered; HANDLE hSnapshot CreateProcessSnapshot(); if (!hSnapshot) return filtered; auto entries GetAllProcessEntries(hSnapshot); auto pidMap CreatePidMap(entries); CloseHandle(hSnapshot); for (DWORD pid : pids) { auto it pidMap.find(pid); if (it ! pidMap.end()) { const auto pe32 it-second; std::string name(pe32.szExeFile); if (name.length() nameLength) { bool valid true; for (char c : name) { if (tolower(c) rangeStart || tolower(c) rangeEnd) { valid false; break; } } if (valid) { filtered.push_back(pid); } } } } return filtered; }5. 实战应用与扩展思路现在我们已经有了一个功能完整的进程扫描器如何使用它来识别特定的随机化进程名呢以下是典型的使用示例int main() { ProcessScanner scanner; // 第一步获取所有进程ID auto allPids scanner.ScanProcesses(); std::cout 系统中共有 allPids.size() 个进程 std::endl; // 第二步应用过滤条件 auto filtered scanner.FilterProcessesOptimized( allPids, 10, // 进程名长度 d, // 起始字符 m); // 结束字符 // 输出结果 if (!filtered.empty()) { std::cout 发现可疑进程: std::endl; for (DWORD pid : filtered) { std::cout PID: pid std::endl; } } else { std::cout 未发现匹配进程 std::endl; } return 0; }扩展功能建议进程详细信息获取除了PID还可以获取更多进程信息void PrintProcessDetails(DWORD pid) { HANDLE hProcess OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid); if (hProcess) { CHAR path[MAX_PATH]; if (GetModuleFileNameExA(hProcess, NULL, path, MAX_PATH)) { std::cout 路径: path std::endl; } CloseHandle(hProcess); } }动态过滤条件通过配置文件或命令行参数指定过滤条件struct FilterCriteria { size_t nameLength; char rangeStart; char rangeEnd; std::string parentProcess; // 其他条件... }; std::vectorDWORD FilterByCriteria( const std::vectorDWORD pids, const FilterCriteria criteria);实时监控模式定期扫描并报告新出现的匹配进程void MonitorProcesses(const FilterCriteria criteria, int intervalSec) { std::setDWORD knownPids; while (true) { auto currentPids ScanProcesses(); auto filtered FilterByCriteria(currentPids, criteria); for (DWORD pid : filtered) { if (knownPids.find(pid) knownPids.end()) { std::cout 发现新进程: pid std::endl; knownPids.insert(pid); } } Sleep(intervalSec * 1000); } }性能对比测试结果方法100个进程耗时(ms)500个进程耗时(ms)基础过滤120580优化过滤1565带缓存的优化835在实际项目中我发现当系统进程数量超过1000时优化版本的性能优势会更加明显。特别是在需要频繁扫描的场景下缓存进程信息可以显著降低系统开销。
http://www.gsyq.cn/news/1411162.html

相关文章:

  • 【脑洞】是否可以存在一个“零知识储备”的大模型?一个像实习生的大模型
  • AI技能版本管理实战:像管理代码一样管理你的提示词与配置
  • Reactor反应堆模式
  • 别再给主力机装SQL Server了!用群晖Docker搭个2019版,开发测试两不误
  • VMware Workstation Pro 17免费激活完整指南:终极许可证密钥获取与配置
  • 原来昆明这些味道好的美食店,很多人竟然都不知道?
  • JTAG调试中nSRST信号连接的必要性与实践
  • RTX51 Tiny信号量实现与UART共享应用
  • 英语作文_8B
  • 告别GUI点点点:用Ansys命令流高效搞定点线面体建模(附常用命令清单)
  • 告别第三方录屏软件!用Unity Recorder实现4K多机位动画录制(附Timeline联动技巧)
  • 2026年 欧标镀锌钢板厂家推荐排行榜:EN 10346标准宝钢、山钢集团、烨辉品牌深度解析与选购指南 - 品牌企业推荐师(官方)
  • GTA5 人物模组超详细制作流程Blender+Sollumz建模转模全细节
  • MATLAB回归分析避坑指南:regress函数实战,从数据导入到结果解读(附完整代码)
  • 构建具备主动性的AI Agent系统
  • 详解C++编程中运算符的使用
  • 基于RISC-V架构的商业航天级MCU国产化技术路径与产业生态研究
  • 【408考研·数据结构专题】二叉树、树与森林、线索树及哈夫曼树核心考点与秒杀技巧深度总结
  • LLM应用工程化:将提示词与任务流视为代码管理的实践指南
  • 别再乱调参了!用sklearn的MLPClassifier/Regressor,这3个隐藏层配置技巧让你模型效果立竿见影
  • CGA老年综合评估MMSE量表标准化应用规范
  • 别再死记硬背Sarsa公式了!用Python手搓一个‘贪吃蛇’AI,5分钟搞懂On-Policy策略
  • GEO软件代理服务商推荐:5家主流机构哪个更适合你?
  • 智赋医者,守护健康:AI技术赋能医疗行业革新与升级
  • 2026年彩涂板卷源头厂家推荐榜:宝钢/马钢/鞍钢/首钢/宝武钢铁品牌实力与品质质保书深度解析 - 品牌企业推荐师(官方)
  • 告别查表!用Excel和C语言搞定NTC103和PT100的温度换算(附完整代码)
  • 保姆级教程:在Ubuntu 22.04上通过apt和源码两种方式安装Mosquitto MQTT Broker
  • 多项土壤指标挨个测太麻烦?一台土壤多参数测定仪就能全部检测完成
  • PCIe 5.0显卡/网卡PCB设计避坑:金手指Layout里那些容易忽略的GND孔和禁布区
  • GaussDB(DWS) SQL性能问题案例集