首页
社区
课程
招聘
[求助]内核中怎么去创建一个系统服务
发表于: 2014-2-17 02:39 6743

[求助]内核中怎么去创建一个系统服务

2014-2-17 02:39
6743
ring3下有CreateService
ring0中呢?有办法吗、?多谢

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (9)
雪    币: 78
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
创建服务其实就是写注册表而已
HKLM\SYSTEM\currentControlSet\Services键值下就是服务的注册内容,createservice就是在这里添加键值而已
ring0当然能做到

参看下边的写注册表关键函数
RtlInitUnicodeString( &name,
                L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\myserv"
);
OBJECT_ATTRIBUTES objectAttributes;
//初始化objectAttributes
InitializeObjectAttributes(
                        &objectAttributes,
                        &name ,
                        OBJ_CASE_INSENSITIVE,//对大小写敏感
                        NULL,
                        NULL);

        status = ZwCreateKey(&newKeyHandle ,
            KEY_ALL_ACCESS,                                               
            &objectAttributes,
            0,
            NULL,                                                
            REG_OPTION_VOLATILE,
             &Disposition );//在注册表打开或创建服务项

然后在注册表添加键值,用下边函数写入值就成了
//           status = ZwSetValueKey(
//                                                       valueKeyHandle,
//                                                       &nameKey,
//                                                       0,
//                                                       REG_EXPAND_SZ,
//                                                       dataValue.Buffer,
//                                                       dataValue.Length
  //                                                      );//修改值
2014-2-17 04:34
0
雪    币: 19
活跃值: (1086)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
发现是不行的  光写注册表是不行的 试过了
2014-2-17 15:07
0
雪    币: 78
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
你写的不对吧
要我写个完整版的代码?
2014-2-17 17:12
0
雪    币: 19
活跃值: (1086)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
求代码 icew4y@gmail.com
2014-2-17 17:45
0
雪    币: 155
活跃值: (20)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
如果要服务重启后生效,写注册表就可以了

如果要当时就生效(能启动、查询、停止,通讯,等等),光写注册表是不行的,必须操作services.exe进程内的服务数据库(ServiceDatabase),在ring0可以发送LPC,也可以直接操作services.exe进程内存实现
2014-2-17 21:28
0
雪    币: 19
活跃值: (1086)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7


我试过在 HKLM\SYSTEM\CURRENTSXXXXXXX\SERVICE\[我的服务]
Start 已经改为2
上传的附件:
2014-2-17 22:40
0
雪    币: 78
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SRVTEST]
"Type"=dword:00000010
"Start"=dword:00000002
"ErrorControl"=dword:00000001
"ImagePath"=hex(2):63,3A,5C,77,69,6E,6E,74,5C,6E,75,6B,65,2E,65,78,65
"DisplayName"="SRVTEST"
"ObjectName"="LocalSystem"
"Description"="系统服务测试"

直接保存为.reg文件,导入注册表重启就行
说明是可以直接写注册表的
2014-2-18 14:42
0
雪    币: 78
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
1.ControlSet001:系统真实的配置信息。
CurrentControlSet:运行时配置。

2.windows启动时会从ControlSet001复制一份副本 CurrentControlSet,作为操作系统当前的配置信息。

3.我们对于计算机配置所作的修改都是直接写入到 CurrentControlSet,
重启时会用CurrentControlSet的内容覆盖掉ControlSet001,以 保证这两个控件组一致。

4.ring3
发现合并.reg文件服务项时,系统在CurrentControlSet和ControlSet001都复制了一份,
更改CurrentControlSet services下内容时,ControlSet001内容也马上更改
这个是由services.exe收到注册表改变消息来完成的


5.ring0
改注册表,services.exe没有收到消息,不会自动复制到ControlSet001


6.注意:重启时如CurrentControlSet和ControlSet001的services项内容不一致,会去掉不一致的项
所以ring0单写一个无效,

ring3写一个CurrentControlSet就行【参见4】
ring0下我们就要CurrentControlSet和ControlSet001每个services都写一份建服务的信息

上一个完整代码
void SetKeyStringEx(HANDLE handle,PUNICODE_STRING name,WCHAR *value)
{
	ZwSetValueKey(handle, name, 0, REG_EXPAND_SZ, value, wcslen( value ) * sizeof(WCHAR)+sizeof(WCHAR) );
}

void SetKeyString(HANDLE handle,PUNICODE_STRING name,WCHAR *value)
{
	ZwSetValueKey(handle, name, 0, REG_SZ, value, wcslen( value ) * sizeof(WCHAR)+sizeof(WCHAR) );
}

void SetKeyDWORD(HANDLE handle,PUNICODE_STRING name,DWORD value)
{
	ZwSetValueKey(handle, name, 0, REG_DWORD,&value,sizeof(DWORD));
}

void SetServerKey(HANDLE handle)
{
		UNICODE_STRING SrvImagePath;//服务路径
		UNICODE_STRING SrvType;//类型
		UNICODE_STRING SrvErrorControl;		//1
		UNICODE_STRING SrvStart;		//服务名
		UNICODE_STRING SrvDescription; //描述
		UNICODE_STRING SrvObjectName; //项目
		UNICODE_STRING SrvDisplayName;
		
		RtlInitUnicodeString(&SrvDisplayName,L"DisplayName");
		RtlInitUnicodeString(&SrvDescription,L"Description");
		RtlInitUnicodeString(&SrvImagePath, L"ImagePath");
		RtlInitUnicodeString(&SrvType, L"Type");
		RtlInitUnicodeString(&SrvErrorControl,L"ErrorControl");
		RtlInitUnicodeString(&SrvStart,L"Start");
		RtlInitUnicodeString(&SrvObjectName,L"ObjectName");

//		SetKeyStringEx(RegHandle, &SrvImagePath, L"%SystemRoot%\\System32\\MyServ.exe");
		SetKeyString(handle, &SrvImagePath, L"MyServ.exe");
		SetKeyDWORD(handle, &SrvType, 16);
		SetKeyDWORD(handle, &SrvErrorControl, 1);
		SetKeyDWORD(handle, &SrvStart, 2);
		SetKeyString(handle, &SrvObjectName, L"LocalSystem");
		SetKeyString(handle, &SrvDisplayName, L"MyServ");
		SetKeyString(handle, &SrvDescription,  L"MyServ Description");
}

HANDLE CreateRegKey(PUNICODE_STRING name)
{
	OBJECT_ATTRIBUTES objectAttributes;
	HANDLE newKeyHandle;
	DWORD Disposition;
	NTSTATUS status;

	//初始化objectAttributes 
	InitializeObjectAttributes(
		&objectAttributes,
		name ,
		OBJ_CASE_INSENSITIVE,//对大小写敏感
		NULL,
		NULL);
	
	status = ZwCreateKey(&newKeyHandle ,
		KEY_ALL_ACCESS,                                               
		&objectAttributes,
		0,
		NULL,                                                
		REG_OPTION_VOLATILE,
		&Disposition );//在注册表打开或创建服务项
	
	if(NT_SUCCESS(status))
	{
		if(Disposition == REG_CREATED_NEW_KEY)
		{
			DbgPrint("REG_CREATED_NEW_KEY\n");
		}
		else
		{
			DbgPrint("REG_OPENED_EXISTING_KEY\n");
		}
		ZwClose(newKeyHandle);
		status = ZwOpenKey( &newKeyHandle,   
                            KEY_ALL_ACCESS,   
                            &objectAttributes);  
	}
	else
	{
		return NULL;
	}
	return newKeyHandle;
}

BOOLEAN KeCreateService()
{

	HANDLE RegHandle;
	UNICODE_STRING name; //键值
	UNICODE_STRING name1;
	
	RtlInitUnicodeString( 
		&name,
		L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\MyServ"
//		L"\\Registry\\Machine\\System\\ControlSet002\\Services\\MyServ"
		);
	//打开注册表    
 


	RtlInitUnicodeString( 
		&name1,
		L"\\Registry\\Machine\\System\\ControlSet001\\Services\\MyServ"
		);


	RegHandle=CreateRegKey(&name);

	if(RegHandle!=NULL)
	{
		SetServerKey(RegHandle);
		ZwClose(RegHandle);
	}

	RegHandle=CreateRegKey(&name1);

	if(RegHandle!=NULL)
	{
		SetServerKey(RegHandle);
		ZwClose(RegHandle);
	}

	//RtlStringCbPrintf()
	return TRUE;
}


直接在驱动调用KeCreateService()就行
2014-2-18 17:07
0
雪    币: 19
活跃值: (1086)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
多谢了 哈哈好爽
2014-2-18 17:48
0
游客
登录 | 注册 方可回帖
返回
//