Hi~ 我是李小咖,主要从事网络安全技术开发和研究。
本文取自《李小咖·网安技术库》,欢迎一起交流学习🫡:https://imbyter.com
Windows系统中的sc命令用于管理系统服务(service),可以创建、删除、启动、停止、查询和修改系统服务。
一、服务管理器
通过在“运行”中输入services.msc,可以打开服务管理器界面查看服务列表:
注意:在服务管理器界面中“名称”列,表示的并不是“服务名”,而是服务的“显示名”。可以在指定服务列表中双击或者右键“属性”,即可查看到其“服务名”:
“显示名”是仅显示给用户看的,“服务名”才是我们后面使用sc命令需要用到的参数。
二、查看服务
格式:sc query <服务名>
-
TYPE:表示服务的类型,
WIN32_SHARE_PROCESS表示当前服务是共享类型,WIN32_OWN_PROCESS表示独占服务。共享服务表示多个服务使用同一个进程,独占服务表示当前进程单独使用一个服务。
-
STATE:服务状态,STOPPED 表示已经停止的服务。
通过使用sc queryex+服务名能查看更详细的服务信息:
使用sc qdescription <服务名>用于查看服务的描述信息,sc GetDisplayName <服务名>用于查看服务的显示名:
sc qdescription W32Time
sc GetDisplayName W32Time
三、创建服务
格式:sc create <服务名>
创建服务需要至少两个输入参数:服务名,执行程序。
-
服务名:可以按需要自定义,但不能和已有服务名重名; -
执行程序:即服务运行后执行的程序。
要将一个程序设置为服务,还需要具备两个条件:
-
需要具备高权(管理员权限);
-
程序内部有服务处理功能。
比如我们要将demo.exe注册为系统服务,首先需要以管理员权限打开cmd,然后执行:
D:\>sc create aaa binpath= E:\demo.exe
-
sc create用于创建新服务,后跟新服务名; -
binpath表示被创建为服务的程序,需要写上绝对路径。
执行成功后,E:\demo.exe便被注册为一个名为aaa的系统服务:
-
因为我们注册服务的时候并未指明“描述”信息,所以“描述”是空的;
-
在没有指明服务的启动方式的情况下,启动类型默认为“手动”。
我们也可以使用下面这种方式,创建参数更加明确的服务:
D:\>sc create aaa binpath= E:\demo.exe DisplayName="demo" start= auto obj="NT Authority\LocalService"
-
DisplayName:服务的显示名; -
start:服务的启动方式:-
auto:自动启动(即每次开机随系统自启动);
-
demand:表示手动启动;
-
disabled:表示禁用。
-
-
obj:服务的登陆类型,可选类型有:-
NT Authority\LocalService:表示本地服务;
-
LocalSystem:表示本地系统;
-
NT Authority\NetworkService:表示网络服务;
-
同时也可以创建用户下的服务:
sc create aaa binpath= E:\demo.exe obj= ".\user1" password= 123456,“.\user1”表示本系统中存在的用户,password是该用户的系统登陆密码。这样创建的服务仅属于该用户,其他用户登陆时此服务不会被启动。
-
被注册为服务的程序demo.exe的源码实例:
#include <stdio.h>
#include <Windows.h>
#define SLEEP_TIME 3000 //间隔时间
#define FILE_PATH "E:\\log.txt" //信息输出文件
bool brun = false;
SERVICE_STATUS servicestatus;
SERVICE_STATUS_HANDLE hstatus;
int WriteToLog(const char* str);
void WINAPI ServiceMain(int argc, char** argv);
void WINAPI CtrlHandler(DWORD request);
int WriteToLog(const char* str)
{
FILE* pfile;
fopen_s(&pfile, FILE_PATH, "a+");
if (pfile == NULL)
{
return -1;
}
fprintf_s(pfile, "%s\n", str);
fclose(pfile);
return 0;
}
void WINAPI ServiceMain(int argc, char** argv)
{
OutputDebugStringA("进入ServiceMain函数,正在挂起3秒...");
//Sleep(3000);
servicestatus.dwServiceType = SERVICE_WIN32;
servicestatus.dwCurrentState = SERVICE_START_PENDING;
servicestatus.dwControlsAccepted = SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_STOP;//在本例中只接受系统关机和停止服务两种控制命令
servicestatus.dwWin32ExitCode = 0;
servicestatus.dwServiceSpecificExitCode = 0;
servicestatus.dwCheckPoint = 0;
servicestatus.dwWaitHint = 0;
hstatus = ::RegisterServiceCtrlHandler(L"testservice", CtrlHandler);
if (hstatus == 0)
{
WriteToLog("RegisterServiceCtrlHandler failed");
return;
}
WriteToLog("RegisterServiceCtrlHandler success");
//向SCM 报告运行状态
servicestatus.dwCurrentState = SERVICE_RUNNING;
SetServiceStatus(hstatus, &servicestatus);
//在此处添加你自己希望服务做的工作,在这里我做的工作是获得当前可用的物理和虚拟内存信息
brun = true;
while (brun)
{
WriteToLog("demo");
Sleep(SLEEP_TIME);
}
}
void WINAPI CtrlHandler(DWORD request)
{
OutputDebugStringA("进入CtrlHandler函数");
switch (request)
{
case SERVICE_CONTROL_STOP:
brun = false;
servicestatus.dwCurrentState = SERVICE_STOPPED;
break;
case SERVICE_CONTROL_SHUTDOWN:
brun = false;
servicestatus.dwCurrentState = SERVICE_STOPPED;
break;
default:
break;
}
SetServiceStatus(hstatus, &servicestatus);
}
void main()
{
system("whoami > E:\\1.txt");
OutputDebugStringA("进入Main函数,正在挂起5秒...");
//Sleep(50000);
SERVICE_TABLE_ENTRY entrytable[2];
entrytable[0].lpServiceName = (LPWSTR)L"testservice";
entrytable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain;
entrytable[1].lpServiceName = NULL;
entrytable[1].lpServiceProc = NULL;
OutputDebugStringA("进入Main函数,执行了StartServiceCtrlDispatcher");
StartServiceCtrlDispatcher(entrytable);
}
如上代码对应的demo执行后,首先会生成E:\1.txt文件,同时把cmd中执行whoami的结果输出到这个文件中。在服务执行的过程中,创建E:\log.txt文件,并每隔3秒,向里面添加demo这个字符串。
程序直接“打开”运行和以服务的形式运行,两种方式执行的代码分支是不同的,功能是不一样的。直接双击或者右键“打开”的方式执行,程序进入的仅仅是main入口函数,执行完成就结束了。以服务的形式启动,程序先会进入main函数,然后会进入我们在程序中注册的ServiceMain函数执行。
四、启动服务
启动服务命令为sc start,需要使用管理员权限的cmd去执行。
# 开启服务
D:\>sc start WSearch
五、停止服务
停止服务命令为sc stop,需要使用管理员权限的cmd去执行。
# 停止服务
D:\>sc stop WSearch
六、修改服务
使用sc config <服务名>用于修改服务的配置信息,包括服务类型、启动方式、执行程序、显示名、组、密码等。
sc config aaa start= auto type= own binPath= c:\windows\system32\calc.exe displayname= aa1
使用sc description <服务名> <新描述信息>用于修改服务的描述信息:
sc description aaa 这是服务描述信息
七、删除服务
删除服务命令为sc delete,需要使用管理员权限的cmd去执行。
# 删除服务
D:\>sc delete aaa
1428



被折叠的 条评论
为什么被折叠?



