C/C++ 操作注冊表與服務


由於這些代碼百年不變,也沒有啥野路子寫法,所以我直接把《C++黑客編程揭秘與防范(第3版)》《WINDOWS黑客編程技術詳解》兩本書中的內容稍作修改后搞到這里,用的時候方便直接看了。注冊表,與服務常用來注冊自啟動程序,開機自動運行,多用於后門。

枚舉注冊表啟動項: 遍歷注冊表 HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run

#include <stdio.h>
#include <Windows.h>

void Enum_Regedit(const char *Reg_Path)
{
	HKEY hKey = NULL;
	DWORD dwType = 0;
	char szValueName[MAXBYTE], szValueKey[MAXBYTE] = { 0 };
	DWORD dwBufferSize = MAXBYTE, dwKeySize = MAXBYTE;

	// 打開注冊表項
	LONG lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, Reg_Path, 0, KEY_ALL_ACCESS, &hKey);

	int index = 0;
	while (1)
	{
		// 枚舉注冊表鍵項
		lRet = RegEnumValue(hKey, index, szValueName, &dwBufferSize, NULL,
			&dwType, (unsigned char *)szValueKey, &dwKeySize);

		if (lRet == ERROR_NO_MORE_ITEMS)
			break;

		printf("ID: %3d --> 名稱: %30s --> 鍵: %-50s --> 值: %d \n", index, szValueName, szValueKey, dwKeySize);

		ZeroMemory(szValueKey, MAXBYTE);
		ZeroMemory(szValueKey, MAXBYTE);
		dwBufferSize = MAXBYTE;
		dwKeySize = MAXBYTE;
		index++;
	}
	RegCloseKey(hKey);
}

int main(int argc,char *argv[])
{
	Enum_Regedit("Software\\Microsoft\\Windows\\CurrentVersion\\Run\\");

	system("pause");
	return 0;
}

添加注冊表啟動項:

#include <stdio.h>
#include <Windows.h>

#define Reg_Path "Software\\Microsoft\\Windows\\CurrentVersion\\Run"

BOOL Reg_CurrentUser(char *lpszFileName, char *lpszValueName)
{
	HKEY hKey;
	if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_CURRENT_USER, Reg_Path, 0, KEY_WRITE, &hKey))
	{
		return FALSE;
	}

	if (ERROR_SUCCESS != RegSetValueEx(hKey, lpszValueName, 0, REG_SZ, (BYTE *)lpszFileName, (1 + ::lstrlen(lpszFileName))))
	{
		RegCloseKey(hKey);
		return FALSE;
	}
	RegCloseKey(hKey);
	return TRUE;
}

BOOL Reg_LocalMachine(char *lpszFileName, char *lpszValueName)
{
	HKEY hKey;
	if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_LOCAL_MACHINE, Reg_Path, 0, KEY_WRITE, &hKey))
	{
		return FALSE;
	}

	if (ERROR_SUCCESS != RegSetValueEx(hKey, lpszValueName, 0, REG_SZ, (BYTE *)lpszFileName, (1 + lstrlen(lpszFileName))))
	{
		RegCloseKey(hKey);
		return FALSE;
	}
	RegCloseKey(hKey);
	return TRUE;
}

int main(int argc, char *argv[])
{
	Reg_CurrentUser("C:\\main.exe", "main1");
	Reg_LocalMachine("C:\\main.exe", "main2");

	system("pause");
	return 0;
}

刪除注冊表啟動項:

#include <stdio.h>
#include <Windows.h>

void Delete_Regedit(const char *Reg_Path,const char *Key_Name)
{
	char szKeyName[MAXBYTE] = { 0 };
	HKEY hKey = NULL;
	LONG lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, Reg_Path, 0, KEY_ALL_ACCESS, &hKey);
	RegDeleteValue(hKey, Key_Name);
	RegCloseKey(hKey);
}

int main(int argc, char *argv[])
{
	Delete_Regedit("Software\\Microsoft\\Windows\\CurrentVersion\\Run", "main1");
	Delete_Regedit("Software\\Microsoft\\Windows\\CurrentVersion\\Run", "main2");

	system("pause");
	return 0;
}

枚舉系統服務操作:

#include <stdio.h>
#include <Windows.h>

void Enum_Services(DWORD dwServiceType)
{
	SC_HANDLE hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);

	if (NULL == hSCM)
		return;

	DWORD ServiceCount = 0, dwSize = 0;
	LPENUM_SERVICE_STATUS lpInfo;

	BOOL bRet = EnumServicesStatus(hSCM, dwServiceType, SERVICE_STATE_ALL, NULL, 0, &dwSize, &ServiceCount, NULL);
	if (!bRet && GetLastError() == ERROR_MORE_DATA)
	{
		// 分配緩沖區,保存服務列表
		lpInfo = (LPENUM_SERVICE_STATUS)(new BYTE[dwSize]);
		bRet = EnumServicesStatus(hSCM, dwServiceType, SERVICE_STATE_ALL, (LPENUM_SERVICE_STATUS)lpInfo,
			dwSize, &dwSize, &ServiceCount, NULL);
		if (NULL == hSCM)
			return;
		// 逐個遍歷獲取服務信息
		for (int x = 0; x < ServiceCount; x++)
		{
			printf("服務名稱: %-30s --> 顯示名稱: %50s --> 狀態: ", lpInfo[x].lpServiceName,lpInfo[x].lpDisplayName);
			switch (lpInfo[x].ServiceStatus.dwCurrentState)
			{
			case SERVICE_PAUSED:  printf("暫停 \n"); break;
			case SERVICE_STOPPED: printf("停止 \n"); break;
			case SERVICE_RUNNING: printf("運行 \n"); break;
			default: printf("其他 \n");
			}
		}
		delete lpInfo;
	}
	CloseServiceHandle(hSCM);
}

int main(int argc, char *argv[])
{
	// 0x0 => 設備驅動程序 0x2=>內核模式文件系統驅動程序
	// 0x8 =>  文件系統識別器驅動程序 0x10 =>  獨占一個進程的服務
	// 0x20 => 與其他服務共享一個進程的服務

	Enum_Services(0x10);

	system("pause");
	return 0;
}

設置服務自啟動: 我們需要將服務放到 C://windows/system32/目錄下,然后注冊服務才能運行.

#include <Windows.h>

void AutoRunService()
{
	char szFileName[MAX_PATH] = { 0 };
	GetModuleFileName(NULL, szFileName, MAX_PATH);
	SC_HANDLE scHandle = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
	SC_HANDLE scHandleOpen = OpenService(scHandle, "lyshark", SERVICE_ALL_ACCESS);
	if (scHandleOpen == NULL)
	{
		char szSelfFile[MAX_PATH] = { 0 };
		char szSystemPath[MAX_PATH] = { 0 };

		GetSystemDirectory(szSystemPath, MAX_PATH);
		strcat(szSystemPath, "\\main.exe");

		GetModuleFileName(NULL, szSelfFile, MAX_PATH);

		CopyFile(szSelfFile, szSystemPath, FALSE);
		SC_HANDLE scNewHandle = CreateService(scHandle,"lyshark","lyshark",
			SERVICE_ALL_ACCESS,SERVICE_WIN32_OWN_PROCESS,SERVICE_AUTO_START,
			SERVICE_ERROR_IGNORE,szSystemPath,NULL,NULL,NULL,NULL,NULL);

		StartService(scNewHandle, 0, NULL);
		CloseServiceHandle(scNewHandle);
		MessageBox(NULL, "服務已注冊", "lyshark", MB_OK);
	}
	CloseServiceHandle(scHandleOpen);
	CloseServiceHandle(scHandle);
}

int main(int argc,char * argv[])
{
	// 注冊為自啟動
	AutoRunService();

	return 0;
}

創建標准服務程序:

#include <Windows.h>

// 服務入口函數以及處理回調函數
void __stdcall ServiceMain(DWORD dwArgc, char *lpszArgv);
void __stdcall ServiceCtrlHandle(DWORD dwOperateCode);
BOOL TellSCM(DWORD dwState, DWORD dwExitCode, DWORD dwProgress);
void DoTask();

// 全局變量
char g_szServiceName[MAX_PATH] = "ServiceTest.exe";    // 服務名稱 
SERVICE_STATUS_HANDLE g_ServiceStatusHandle = { 0 };

int main(int argc, char * argv[])
{
	// 注冊服務入口函數
	SERVICE_TABLE_ENTRY stDispatchTable[] = { { g_szServiceName, (LPSERVICE_MAIN_FUNCTION)ServiceMain }, { NULL, NULL } };
	::StartServiceCtrlDispatcher(stDispatchTable);

	return 0;
}

void __stdcall ServiceMain(DWORD dwArgc, char *lpszArgv)
{
	g_ServiceStatusHandle = ::RegisterServiceCtrlHandler(g_szServiceName, ServiceCtrlHandle);

	TellSCM(SERVICE_START_PENDING, 0, 1);
	TellSCM(SERVICE_RUNNING, 0, 0);

	// 自己程序實現部分代碼放在這里
	// !!注意!! 此處一定要為死循環, 否則在關機再開機的情況(不是點擊重啟), 不能創建用戶進程
	while (TRUE)
	{
		Sleep(5000);
		DoTask();
	}
}

void __stdcall ServiceCtrlHandle(DWORD dwOperateCode)
{
	switch (dwOperateCode)
	{
	case SERVICE_CONTROL_PAUSE:
	{
		// 暫停
		TellSCM(SERVICE_PAUSE_PENDING, 0, 1);
		TellSCM(SERVICE_PAUSED, 0, 0);
		break;
	}
	case SERVICE_CONTROL_CONTINUE:
	{
		// 繼續
		TellSCM(SERVICE_CONTINUE_PENDING, 0, 1);
		TellSCM(SERVICE_RUNNING, 0, 0);
		break;
	}
	case SERVICE_CONTROL_STOP:
	{
		// 停止
		TellSCM(SERVICE_STOP_PENDING, 0, 1);
		TellSCM(SERVICE_STOPPED, 0, 0);
		break;
	}
	case SERVICE_CONTROL_INTERROGATE:
	{
		// 詢問
		break;
	}
	default:
		break;
	}
}

BOOL TellSCM(DWORD dwState, DWORD dwExitCode, DWORD dwProgress)
{
	SERVICE_STATUS serviceStatus = { 0 };
	BOOL bRet = FALSE;

	::RtlZeroMemory(&serviceStatus, sizeof(serviceStatus));
	serviceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
	serviceStatus.dwCurrentState = dwState;
	serviceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PAUSE_CONTINUE | SERVICE_ACCEPT_SHUTDOWN;
	serviceStatus.dwWin32ExitCode = dwExitCode;
	serviceStatus.dwWaitHint = 3000;

	bRet = ::SetServiceStatus(g_ServiceStatusHandle, &serviceStatus);
	return bRet;
}

void DoTask()
{
	// 自己程序實現部分代碼放在這里
}

實現服務管理器:

#include <stdio.h>
#include <Windows.h>
#include <Shlwapi.h>

#pragma comment(lib, "Shlwapi.lib")

BOOL SystemServiceOperate(char *lpszDriverPath, int iOperateType)
{
	BOOL bRet = TRUE;
	char szName[MAX_PATH] = { 0 };
	lstrcpy(szName, lpszDriverPath);
	PathStripPath(szName);           // 只保留文件名稱,去掉文件路徑

	SC_HANDLE shOSCM = NULL, shCS = NULL;
	SERVICE_STATUS ss;
	DWORD dwErrorCode = 0;
	BOOL bSuccess = FALSE;

	// 打開服務控制管理器數據庫
	shOSCM = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
	if (iOperateType != 0)
	{
		// 打開一個已經存在的服務
		shCS = OpenService(shOSCM, szName, SERVICE_ALL_ACCESS);
		if (!shCS)
		{
			CloseServiceHandle(shOSCM);
			shOSCM = NULL;
			return FALSE;
		}
	}

	switch (iOperateType)
	{
	case 0:
	{
			  // 創建服務
			  // SERVICE_AUTO_START   隨系統自動啟動
			  // SERVICE_DEMAND_START 手動啟動
			  shCS = ::CreateService(shOSCM, szName, szName, SERVICE_ALL_ACCESS,
				  SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS, SERVICE_AUTO_START,
				  SERVICE_ERROR_NORMAL, lpszDriverPath, NULL, NULL, NULL, NULL, NULL);
			  break;
	}
	case 1:
	{
			  // 啟動服務
			  if (!::StartService(shCS, 0, NULL)) { bRet = FALSE; }
			  break;
	}
	case 2:
	{
			  // 停止服務
			  if (!::ControlService(shCS, SERVICE_CONTROL_STOP, &ss)) { bRet = FALSE; }
			  break;
	}
	case 3:
	{
			  // 刪除服務
			  if (!::DeleteService(shCS)) { bRet = FALSE; }
			  break;
	}
	default: break;
	}
	return bRet;
}


int main(int argc, char *argv[])
{
	char *path = "c://1.exe";

	// 0 加載服務    1 啟動服務    2 停止服務    3 刪除服務
	SystemServiceOperate(path, 3);

	system("pause");
	return 0;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM