开启邀请码注册中,禁止灌水!发现一次永久禁言

墨客安全网

 找回密码
 立即注册

墨客安全网-新手入门指南 常见问题及帮助 | 做任务赚墨币币 新人报道 | 悬赏问答| 墨币充值| 帖子举报

墨客安全网-论坛精华合集 墨客安全网 -精华合集 之 速成之路 原创精品 | 加入墨客Vip | Vip工具| Vip教程

墨客安全网-进阶技术学习区 软件/工具| 社工专区 | 入侵检测| 技术文章 动画教程 | 编程交流| 免杀更新 | 程序源码

[悬赏公告] - 严查灌水,打造一个无水论坛,从即日起.请大家互相监督,发现恶意灌水的,请发贴举报,核实后会给予5-10的墨币奖励。
[官方公告] 从今日起所有会员发布工具必须到审核板块进行审核,如有违反永久禁言处理!
 [招聘招聘]-招聘各方面给力版主,要求每日发帖不少于3贴,每天在线时间6个小时以上,具体福利和待遇联系TG客服或者在线管理员
[官方公告]1.发现网盘下载地址失效!可以发贴举报 审核证实后给予奖励10-20墨币。2.即日起!不管是谁发贴!都不能带QQ群 已及个人QQ。个人网站,发现后严格处理。[官方业务]-加入墨客安全网Vip,圆你日抓千鸡梦,各种精品教程,免杀远控,压力测试等你拿,期待各位会员的加入,即可享受众多福利!
【官方公告】论坛所有广告均为商业行为,需要交易的请尽量走担保程序,所有因广告产生的任何纠纷请私下解决【站外广告】大量收色刷!刷单肉鸡!带飞机肉鸡!寻内网横向技术!懂的来,小白勿扰!长期包养色刷,刷单,带飞机海外盘国内盘灰产肉鸡稳定鸡商
联系飞机:@seeok91
【官方业务】精品广告位招租,需要请联系官方TG客服【官方业务】精品广告位招租,需要请联系官方TG客服【官方业务】精品广告位招租,需要请联系官方TG客服
查看: 144|回复: 0

[编程交流] Windows服务编写原理及探讨

[复制链接]

该用户从未签到

13

主题

44

回帖

661

积分

UID
9323
威望
229 (点)
主题
13 (帖)
精华
0 (帖)
贡献
13  (次)
墨币
133  (枚)
活跃
31  (点)
担保币
0  (枚)
注册时间
2016-12-27
最后登录
2018-1-16
发表于 2017-10-7 13:38:28 | 显示全部楼层 |阅读模式

有那么一类应用程序,是能够为各种用户(包括本地用户和远程用户)所用的,拥有用户授权级进行管理的能力,并且不论用户是否物理的与正在运行该应用程序的计算机相连都能正常执行,这就是所谓的服务了。

(一)服务的基础知识

Question 1. 什么是服务?它的特征是什么?

  在NT/2000中,服务是一类受到操作系统优待的程序。一个服务首先是一个Win32可执行程序,如果要写一个功能完备且强大的服务,需要熟悉动态连接库(Dlls)、结构异常处理、内存映射文件、虚拟内存、设备I/O、线程及其同步、Unicode以及其他的由WinAPI函数提供的应用接口。当然本文讨论的只是建立一个可以安装、运行、启动、停止的没有任何其他功能的服务,所以无需上述知识仍可以继续看下去,我会在过程中将理解本文所需要的知识逐一讲解。

  第二要知道的是一个服务决不需要用户界面。大多数的服务将运行在那些被锁在某些黑暗的,冬暖夏凉的小屋子里的强大的服务器上面,即使有用户界面一般也没有人可以看到。如果服务提供任何用户界面如消息框,那么用户错过这些消息的可能性就极高了,所以服务程序通常以控制台程序的形式被编写,进入点函数是main()而不是WinMain()。

  也许有人有疑问:没有用户界面的话,要怎样设置、管理一个服务?怎样开始、停止它?服务如何发出警告或错误信息、如何报告关于它的执行情况的统计数据?这些问题的答案就是服务能够被远程管理,windows NT/2000提供了大量的管理工具,这些工具允许通过网络上的其它计算机对某台机器上面的服务进行管理。比如Windows 2000里面的“控制台”程序(mmc.exe),用它添加“管理单元”就可以管理本机或其他机器上的服务。



Question 2. 服务的安全性…

  想要写一个服务,就必须熟悉Win NT/2000的安全机制,在上述操作系统之中,所有安全都是基于用户的。换句话说――进程、线程、文件、注册表键、信号、事件等等等等都属于一个用户。当一个进程被产生的时候,它都是执行在一个用户的上下文(context),这个用户帐号可能在本机,也可能在网络中的其他机器上,或者是在一个特殊的账号:System Account――即系统帐号的上下文

  如果一个进程正在一个用户帐号下执行,那么这个进程就同时拥有这个用户所能拥有的一切访问权限,不论是在本机还是网络。系统帐号则是一个特殊的账号,它用来标识系统本身,而且运行在这个帐号下的任何进程都拥有系统上的所有访问权限,但是系统帐号不能在域上使用,无法访问网络资源…

  服务也是Win32可执行程序,它也需要执行在一个context,通常服务都是在系统账号下运行,但是也可以根据情况选择让它运行在一个用户账号下,也就会因此获得相应的访问资源的权限。



Question 3. 服务的三个组成部分

  一个服务由三部分组成,第一部分是Service Control Manager(SCM)。每个Windows NT/2000系统都有一个SCM,SCM存在于Service.exe中,在Windows启动的时候会自动运行,伴随着操作系统的启动和关闭而产生和终止。这个进程以系统特权运行,并且提供一个统一的、安全的手段去控制服务。它其实是一个RPC Server,因此我们可以远程安装和管理服务,不过这不在本文讨论的范围之内。SCM包含一个储存着已安装的服务和驱动程序的信息的数据库,通过SCM可以统一的、安全的管理这些信息,因此一个服务程序的安装过程就是将自身的信息写入这个数据库。

  第二部分就是服务本身。一个服务拥有能从SCM收到信号和命令所必需的的特殊代码,并且能够在处理后将它的状态回传给SCM。

  第三部分也就是最后一部分,是一个Service Control Dispatcher(SCP)。它是一个拥有用户界面,允许用户开始、停止、暂停、继续,并且控制一个或多个安装在计算机上服务的Win32应用程序。SCP的作用是与SCM通讯,Windows 2000管理工具中的“服务”就是一个典型的SCP。



  在这三个组成部分中,用户最可能去写服务本身,同时也可能不得不写一个与其伴随的客户端程序作为一个SCP去和SCM通讯,本文只讨论去设计和实现一个服务,关于如何去实现一个SCP则在以后的其它文章中介绍。

Question 4. 怎样开始设计服务

  还记得前面我提到服务程序的入口点函数一般都是main()吗?一个服务拥有很重要的三个函数,第一个就是入口点函数,其实用WinMain()作为入口点函数也不是不可以,虽然说服务不应该有用户界面,但是其实存在很少的几个例外,这就是下面图中的选项存在的原因。



  由于要和用户桌面进行信息交互,服务程序有时会以WinMain()作为入口点函数。

  入口函数负责初始化整个进程,由这个进程中的主线程来执行。这意味着它应用于这个可执行文件中的所有服务。要知道,一个可执行文件中能够包含多个服务以使得执行更加有效。主进程通知SCM在可执行文件中含有几个服务,并且给出每一个服务的ServiceMain回调(Call Back)函数的地址。一旦在可执行文件内的所有服务都已经停止运行,主线程就在进程终止前对整个进程进行清除。

  第二个很重要的函数就是ServiceMain,我看过一些例子程序里面对自己的服务的进入点函数都固定命名为ServiceMain,其实并没有规定过一定要那样命名,任何的函数只要符合下列的形式都可以作为服务的进入点函数。

VOID WINAPI ServiceMain(
  DWORD dwArgc, // 参数个数
  LPTSTR *lpszArgv // 参数串
);

  这个函数由操作系统调用,并执行能完成服务的代码。一个专用的线程执行每一个服务的ServiceMain函数,注意是服务而不是服务程序,这是因为每个服务也都拥有与自己唯一对应的ServiceMain函数,关于这一点可以用“管理工具”里的“服务”去察看Win2000里面自带的服务,就会发现其实很多服务都是由service.exe单独提供的。当主线程调用Win32函数StartServiceCtrlDispatcher的时候,SCM为这个进程中的每一个服务产生一个线程。这些线程中的每一个都和它的相应的服务的ServiceMain函数一起执行,这就是服务总是多线程的原因――一个仅有一个服务的可执行文件将有一个主线程,其它的线程执行服务本身。

  第三个也就是最后的一个重要函数是CtrlHandler,它必须拥有下面的原型:

VOID WINAPI CtrlHandler(
DWORD fdwControl //控制命令
)

  像ServiceMain一样,CtrlHandler也是一个回调函数,用户必须为它的服务程序中每一个服务写一个单独的CtrlHandler函数,因此如果有一个程序含有两个服务,那么它至少要拥有5个不同的函数:作为入口点的main()或WinMain(),用于第一个服务的ServiceMain函数和CtrlHandler函数,以及用于第二个服务的ServiceMain函数和CtrlHandler函数。

  SCM调用一个服务的CtrlHandler函数去改变这个服务的状态。例如,当某个管理员用管理工具里的“服务”尝试停止你的服务的时候,你的服务的CtrlHandler函数将收到一个SERVICE_CONTROL_STOP通知。CtrlHandler函数负责执行停止服务所需的一切代码。由于是进程的主线程执行所有的CtrlHandler函数,因而必须尽量优化你的CtrlHandler函数的代码,使它运行起来足够快,以便相同进程中的其它服务的CtrlHandler函数能在适当的时间内收到属于它们的通知。而且基于上述原因,你的CtrlHandler函数必须要能够将想要传达的状态送到服务线程,这个传递过程没有固定的方法,完全取决于你的服务的用途。

本文测试环境为Win2000 Server + SP2
Athlon XP 1700 + 256MB DDR
全部资料参考自MSDN OCT 2001
新人必看帖,如何快速赚取墨币,了解墨客安全网论坛版规,等等...( 点我查看

如果你在论坛悬赏问答求助问题,并且已经从坛友或者管理的回复中解决了问题,请在帖子内点击(已解决)

发帖求助前要善用 论坛搜索 功能,如果搜不到可以试试,论坛顶上的 百度站内搜索 - 纵横站内搜索 那里可能会有你要找的答案;

如果发现论坛有灌水帖、下载地址失效帖、后门帖、广告帖、工具不能正常使用、都可以去 举报版块 发帖举报,核实给予退回墨币+额外的墨币奖励哦;
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

1、请认真发帖,禁止回复纯表情,纯数字等无意义的内容!帖子内容不要太简单!
2、提倡文明上网,净化网络环境!抵制低俗不良违法有害信息。
3、每个贴内连续回复请勿多余3贴,每个版面回复请勿多余10贴!
4、如果你对主帖作者的帖子不屑一顾的话,请勿回帖。谢谢合作!

关闭

站长推荐上一条 /1 下一条