木马编程DIY之系统服务

作者在 2008-11-29 15:29:24 发布以下内容

来源:黑白网络  作者:  日期:2008-04-28  

对系统服务的管理几乎是目前的木马必不可少的功能,比如神气儿、上兴远程控制等,都提供了此项服务。要是我们能给自己编写的木马也加上这个功能,看着也不赖哦。好啦,废话不多说,下面开始干活!
 
  取得配置权限

  在对服务进行管理设置前,我们需要以相应的权限打开服务,本文通过下面的两个API来实现操作。

SC_HANDLE OpenSCManager(

LPCTSTR lpMachineName,

// pointer to machine name string

LPCTSTR lpDatabaseName,

// pointer to database name string

DWORD dwDesiredAccess  // type of access

);

SC_HANDLE OpenService(

SC_HANDLE hSCManager,

// handle to service control manager database

LPCTSTR lpServiceName,

// pointer to name of service to start

DWORD dwDesiredAccess

// type of access to service

);
 


  对于系统服务的管理,通常情况下我们是以完全权限打开的,要实现这个功能,我们可以使用下面的代码来操作。

SC_HANDLE scm;
    SC_HANDLE service;

       if((scm=OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS))==NULL)

       {     Printf("OpenSCManager Error/n");

       }

    service=OpenService(scm,ServerName,SERVICE_ALL_ACCESS);

       if(!service)

       {    Printf("OpenService error!/n");

       }
 


  这样,就可以通过Service句柄对服务进行各种操作了。

  枚举基本服务信息

  想要对服务进行设置,就需要知道服务的当前信息。其中对我们有用的通常是以下几项:服务名称、显示名称、启动状态、启动方式和程序路径等。这些信息我们可以通过API函数EnumServicesStatus来实现,它的原形如下:

BOOL EnumServicesStatus(
  SC_HANDLE hSCManager,

 // handle to service control manager database

  DWORD dwServiceType,

 // type of services to enumerate

  DWORD dwServiceState,

 // state of services to enumerate

  LPENUM_SERVICE_STATUS lpServices,

  // pointer to service status buffer

  DWORD cbBufSize,

 // size of service status buffer

  LPDWORD pcbBytesNeeded,

 // pointer to variable for bytes needed

  LPDWORD lpServicesReturned,

  // pointer to variable for number returned

  LPDWORD lpResumeHandle

 // pointer to variable for next entry

 );
 


  在上面的代码中,LPENUM_SERVICE_STATUS lpServices是一个结构,其原形如下:

typedef struct _ENUM_SERVICE_STATUS { // ess

LPTSTR lpServiceName;

LPTSTR lpDisplayName;

SERVICE_STATUS ServiceStatus;

} ENUM_SERVICE_STATUS, *LPENUM_SERVICE_STATUS;
 


  这个结构中包含服务名称、显示名称、启动状态。虽然它所返回的信息是极为有限的,但它是一次枚举所有的服务信息的。在要求不高的情况下,用它还是相当方便的。下面的示例代码可以枚举系统中所有服务的基本信息,实现代码如下所示。

LPENUM_SERVICE_STATUS lpServices    = NULL;

       DWORD    nSize = 0;

       DWORD    n;

       DWORD    nResumeHandle = 0;

       lpServices=(LPENUM_SERVICE_STATUS) LocalAlloc(LPTR, 64 * 1024);   //注意分配足够的空间

       EnumServicesStatus(scm,SERVICE_WIN32,SERVICE_STATE_ALL,(LPENUM_SERVICE_STATUS)lpServices,64 * 1024,&nSize,&n,&nResumeHandle);

       for ( i = 0; i < n; i++)

       {

       Printf("服务名称: %s",lpServices[i].lpServiceName);

       Printf("显示名称: %s",lpServices[i].lpDisplayName);

       if ( lpServices[i].ServiceStatus.dwCurrentState!=SERVICE_STOPPED)

       {     Printf("启动状态:  已启动/n");

       }

       }
 


  枚举详细服务信息

  如果想要得到更详细的服务信息,我们可以使用另一个API函数QueryServiceConfig来获得,它的原形如下所示。

BOOL QueryServiceConfig(
  SC_HANDLE hService, // handle of service

  LPQUERY_SERVICE_CONFIG lpServiceConfig,

  // address of service config. structure

  DWORD cbBufSize,

  // size of service configuration buffer

  LPDWORD pcbBytesNeeded

 // address of variable for bytes needed

 );
 
其中LPQUERY_SERVICE_CONFIG lpServiceConfig也是一个结构,它包含指定服务的详细资料,其原形如下所示。
typedef struct _QUERY_SERVICE_CONFIG { // qsc

DWORD dwServiceType;

DWORD dwStartType;

DWORD dwErrorControl;

LPTSTR lpBinaryPathName;

LPTSTR lpLoadOrderGroup;

DWORD dwTagId;

LPTSTR lpDependencies;

LPTSTR lpServiceStartName;

LPTSTR lpDisplayName;

}QUERY_SERVICE_CONFIG, LPQUERY_SERVICE_

CONFIG;
 


  很清楚了吧?服务类型、启动类型、程序路径、服务名称、显示名称尽在其中。而下面的示例代码则可以得到程序路径和启动方式,其代码如下所示。

LPQUERY_SERVICE_CONFIG ServicesInfo = NULL;

   for ( i = 0; i < n; i++)

   {

       SC_HANDLE service = NULL;

       DWORD     nResumeHandle = 0;

       service=OpenService(scm,lpServices[i].lpServiceName,SERVICE_ALL_ACCESS);

       ServicesInfo = (LPQUERY_SERVICE_CONFIG) LocalAlloc(LPTR, 64 * 1024);

       //注意分配足够的空间

       QueryServiceConfig(service,ServicesInfo,64 * 1024,&nResumeHandle);

       //枚举各个服务信息

       Printf("程序路径: %s",ServicesInfo->lpBinaryPathName);

       if(2==ServicesInfo->dwStartType)      //启动方式

       {

       Printf("自动/n");

       }

       if(3==ServicesInfo->dwStartType)

       {

       Printf("手动/n");

       }

       if(4==ServicesInfo->dwStartType)

       {     Printf("禁止/n");

       }

   }
 
  上面的代码,只要大家根据需要稍加修改,就可以用到自己的程序中了。现在,对于服务信息的显示就算完成了。

默认分类 | 阅读 4872 次
文章评论,共0条
游客请输入验证码