C/C++ 操作注册表与服务

注册表,与服务常用来注册自启动程序,开机自动运行,多用于后门。

枚举注册表启动项: 遍历注册表 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;
}

参考文献

《C++黑客编程揭秘与防范(第3版)》
《WINDOWS黑客编程技术详解》

原文链接: https://www.cnblogs.com/LyShark/p/12919475.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍;

也有高质量的技术群,里面有嵌入式、搜广推等BAT大佬

    C/C++ 操作注册表与服务

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/349465

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年3月2日 上午5:42
下一篇 2023年3月2日 上午5:42

相关推荐