zoukankan      html  css  js  c++  java
  • SVCHOST启动服务实战

    本文转载自:https://blog.csdn.net/huanglong8/article/details/70666987

    转载出处:
    https://sanwen8.cn/p/2cenbHs.html

    最近在做小项目,用到了一些此类技术,觉得文章很细,手把手教的,粘在这里备忘下。。。望原作者海涵。

    这里写图片描述

    svchost.exe是一个属于微软Windows操作系统的系统程序,微软官方对它的解释是:Svchost.exe 是从动态链接库 (DLL) 中运行的服务的通用主机进程名称。这个程序对系统的正常运行是非常重要。又因为svchost进程用来启动各种服务,所以病毒、木马也想尽办法来利用它,企图利用它的特性来迷惑用户,达到感染、入侵、破坏的目的(如冲击波变种病毒“w32.welchia.worm”)。下面我们来用手动修改注册表并编写我们自己的测试dll来实例解析运用svchost.exe的过程。
    测试所用的操作系统环境: Windows XP
    测试所用的编程环境: VS2010和VC++6.0都可以

    一、首先我们来手动在注册表注册一个服务

    开始->运行 输入regedit 找到如下子健
    HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServices
    1. 在Services子健下新建一个子健TestSvchost。
    2. 在子健TestSvchost新建所需子健项,子健项说明如下:
    (1) Description 服务描述
    (2) DisplayName 服务显示名
    (3) ErrorControl 当该启动服务失败时产生错误的严重程度以及采取的保护措施 这里我们填 1 表示服务启动程序将把该错误记录到事件日志中并返回继续执行
    (4) ImagePath 程序的路径 我们要启动的是svchost.exe所以填入
    %systemRoot%system32svchost.exe -k netsvcs-k netsvcs表示这个服务是属于netsvcs服务组
    (5) ObjectName 指定服务帐号 LocalSystem表示本地登录
    (6)Start 服务启动选项
    填入2表示系统启动时由服务控制管理器自动启动该服务程序
    (7)Type 服务类型
    填入0x10表示运行于独立进程的服务程序
    这里写图片描述
    3. 在子健TestSvchost下再建一个子健Parameters。
    4. 在子健Parameters新建子健项ServiceDll
    这里写图片描述
    ServiceDll表示服务所对应dll所在的全路径

    二、将我们在注册表写入服务加入Svchost的服务组netsvcs中

    1.找到注册表子健HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindows NTCurrentVersionSvchost 并打开子健项netsvcs。netsvcs里面的值就是svchost的服务组netsvcs所启动的所有服务
    这里写图片描述
    2.打开netsvcs键值项 添加数值数据TestSvchost(服务名)
    这里写图片描述
    我们打开PCHunter可以看到该服务的相关情况:
    这里写图片描述
    可看到这个时候该服务已经注册,但由于缺少Dll文件,服务是无法启动的

    三 编写正确的Dll文件

    Svchost每次启动一个服务时,SCM都会调用Dll导出的ServiceMain函数来启动服务,这就需要在ServiceMain函数里调用RegisterServiceCtrlHandler来注册相应的控制请求的函数。我们打开vs新建一个动态dll工程写入下面代码并编译成Dll文件:

    #include "stdafx.h"
    #include <stdlib.h>
    
    DWORD g_dwServiceType;
    SERVICE_STATUS_HANDLE g_hServiceStatus;
    DWORD g_dwCurrState;
    
    BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
    {
        return TRUE;
    }
    
    int TellSCM(DWORD dwState, DWORD dwExitCode, DWORD dwProgress)
    {
        SERVICE_STATUS srvStatus;
        srvStatus.dwServiceType = SERVICE_WIN32_SHARE_PROCESS;
        srvStatus.dwCurrentState = g_dwCurrState = dwState;
        srvStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
        srvStatus.dwWin32ExitCode = dwExitCode;
        srvStatus.dwServiceSpecificExitCode = 0;
        srvStatus.dwCheckPoint = dwProgress;
        srvStatus.dwWaitHint = 1000;
        return SetServiceStatus(g_hServiceStatus, &srvStatus);
    }
    
    void __stdcall ServiceHandler(DWORD dwControl)
    {
        switch (dwControl)
        {
        case SERVICE_CONTROL_STOP:
            TellSCM(SERVICE_STOP_PENDING, 0, 1);
            Sleep(10);
            TellSCM(SERVICE_STOPPED, 0, 0);
            break;
        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_INTERROGATE:
            TellSCM(g_dwCurrState, 0, 0);
            break;
        }
    }
    
    extern "C" __declspec(dllexport) void ServiceMain(int argc, wchar_t* argv[])
    {
    char szSvcName[MAX_PATH];
        wcstombs(szSvcName, argv[0], sizeof szSvcName);
    
    // 注册一个服务控制程序
        g_hServiceStatus = RegisterServiceCtrlHandler(szSvcName, (LPHANDLER_FUNCTION)ServiceHandler);
        if (g_hServiceStatus == NULL)
        {
            return;
        } else FreeConsole();
    
        TellSCM(SERVICE_START_PENDING, 0, 1); // 通知服务控制管理器该服务开始
        TellSCM(SERVICE_RUNNING, 0, 0);  // 通知服务控制管理器该服务运行
    
    // 在D盘创建一个txt创建并写入服务名作为测试
    HANDLE hFile = CreateFile("D:\TestSvchost.txt", GENERIC_WRITE,FILE_SHARE_WRITE | FILE_SHARE_READ,NULL,CREATE_ALWAYS,
    FILE_ATTRIBUTE_NORMAL, NULL);
    if (hFile != INVALID_HANDLE_VALUE)
    {
    DWORD nTemp = 0;
    WriteFile(hFile, szSvcName, strlen(szSvcName), &nTemp, NULL);
    CloseHandle(hFile);
    }
    
    do {
    Sleep(100);
    } while (g_dwCurrState != SERVICE_STOP_PENDING && g_dwCurrState != SERVICE_STOPPED);
        return;
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78

    四 将Dll放入合适的位置并重启

    将TestSvchostDll.dll放入C:WINDOWSsystem32目录下并重启电脑。重启后,点击开始->运行 输入services.msc 可以查看到该服务处于已启动状态。
    这里写图片描述
    打开D盘,可以看到我们在dll中创建的文件和写入的服务名
    这里写图片描述

    至此,文章就结尾了,可以查看原文地址 有百度云盘,我是没去下啦。你们可以看看,贵在理解与实践。

    再次感谢作者分享这么优质的文章。

  • 相关阅读:
    spring bean的作用域
    Web前端开发CSS规范总结
    前端技术都包含哪些?
    Web安全常见问题及解决方法
    如何让手游更省带宽,耗电量更少?TBR渲染架构解析!
    新手学Java,有哪些入门知识点?
    如何让手游内存占用更小?从内存消耗iOS实时统计开始
    动作游戏老是卡?试试从这些方面提升流畅度
    开发者必知!2020年大前端发展趋势解读
    游戏编程入门! 想成为专业的游戏开发程序员需要掌握哪些?
  • 原文地址:https://www.cnblogs.com/csnd/p/12897010.html
Copyright © 2011-2022 走看看