【逆向】Windows服务逆向分析调试

前言

本文主要对Windows服务进行简要介绍,并对服务程序分析方法进行记录。

名词解释

1 服务进程:       //通过服务方式运行的可执行程序
2 服务控制程序:     //所有用于启动服务(StartService())的程序,Windows中可以使用“services.msc”命令启动
3 服务控制管理器:    //SCM(Service Control Manager),Windows中其实就是services.exe或者svchost.exe进程
4 
5 服务Main函数:        //注册服务控制处理函数、设置服务运行状态、执行其它操作。
6 服务控制处理函数:     //SCM通过该回调函数设置服务运行状态。

启动流程

1"服务控制程序" 调用StartService()启动服务,然后由SCM(services.exe)创建对应的 "服务进程"2"服务进程" 在Main函数中调用StartServiceCtrlDispatcher()关联服务主线程,将 "服务Main函数" 地址提交给SCM。
3、SCM调用 "服务Main函数"4"服务Main函数" 调用RegisterServiceCtrlHandler()注册 "服务控制处理函数",然后调用SetServiceStatus()设置服务运行状态。

示例代码

  1 #include <windows.h>
  2 #include <tchar.h>
  3 #include <stdio.h>
  4 
  5 #define SVCNAME L"SvcTest"
  6 
  7 VOID InstallService(LPCTSTR szSvcName, LPCTSTR szPath);
  8 VOID UninstallService(LPCTSTR szSvcName);
  9 VOID WINAPI SvcMain(DWORD argc, LPCTSTR *argv);
 10 VOID WINAPI SvcCtrlHandler( DWORD dwCtrl );
 11 
 12 SERVICE_STATUS_HANDLE g_hServiceStatusHandle = NULL;
 13 SERVICE_STATUS g_ServiceStatus = {SERVICE_WIN32_OWN_PROCESS, 0, 0xFF, 0, 0, 0, 0};
 14 
 15 //Main
 16 void _tmain(int argc, TCHAR *argv[])
 17 { 
 18     TCHAR szPath[MAX_PATH] = {0,};
 19     SERVICE_TABLE_ENTRY DispatchTable[] = 
 20     { 
 21         { SVCNAME, (LPSERVICE_MAIN_FUNCTION)SvcMain }, 
 22         { NULL, NULL } 
 23     }; 
 24 
 25     //作为服务进程启动
 26     if( argc == 1 )
 27     {
 28         //关联服务主线程,将"服务Main函数"地址提交给SCM
 29         if (!StartServiceCtrlDispatcher( DispatchTable )) 
 30         { 
 31             _tprintf(L"StartServiceCtrlDispatcher() failed!!! [%d]\n", 
 32                 GetLastError()); 
 33         }
 34     }
 35     //作为服务安装卸载程序启动
 36     else if( argc == 2 )
 37     {
 38         if( !GetModuleFileName(NULL, szPath, MAX_PATH) )
 39         {
 40             _tprintf(L"GetModuleFileName() failed! [%d]\n", 
 41                 GetLastError());
 42             return;
 43         }
 44 
 45         if( _tcsicmp(argv[1], L"install") == 0 )
 46         {
 47             //安装服务
 48             InstallService(SVCNAME, szPath);
 49             return;
 50         }
 51         else if( _tcsicmp(argv[1], L"uninstall") == 0 )
 52         {
 53             //卸载服务
 54             UninstallService(SVCNAME);
 55             return;
 56         }
 57         else
 58         {
 59             _tprintf(L"Wrong parameters!!!\n");
 60         }
 61     }
 62 
 63     _tprintf(L"\nUSAGE : %s <install | uninstall>\n", argv[0]);
 64 }
 65 
 66 //创建服务
 67 VOID InstallService(LPCTSTR szSvcName, LPCTSTR szPath)
 68 {
 69     SC_HANDLE schSCManager = NULL;
 70     SC_HANDLE schService = NULL;
 71     DWORD dwError = 0;
 72 
 73     schSCManager = OpenSCManager( 
 74         NULL,                    // local computer
 75         NULL,                    // ServicesActive database 
 76         SC_MANAGER_ALL_ACCESS);  // full access rights 
 77     if( NULL == schSCManager ) 
 78     {
 79         _tprintf(L"InstallService() : OpenSCManager failed (%d)\n", GetLastError());
 80         return;
 81     }
 82 
 83     schService = CreateService( 
 84         schSCManager,              // SCM database 
 85         szSvcName,                 // name of service 
 86         szSvcName,                 // service name to display 
 87         SERVICE_ALL_ACCESS,        // desired access 
 88         SERVICE_WIN32_OWN_PROCESS, // service type 
 89         SERVICE_DEMAND_START,      // start type 
 90         SERVICE_ERROR_NORMAL,      // error control type 
 91         szPath,                    // path to service's binary 
 92         NULL,                      // no load ordering group 
 93         NULL,                      // no tag identifier 
 94         NULL,                      // no dependencies 
 95         NULL,                      // LocalSystem account 
 96         NULL);                     // no password 
 97     if( NULL == schService ) 
 98     {
 99         dwError = GetLastError();
100         _tprintf(L"InstallService() : CreateService failed (%d)\n", dwError); 
101         if( ERROR_SERVICE_EXISTS == dwError )
102             _tprintf(L"  -> The specified service already exists.\n");
103         goto _EXIT;
104     }
105 
106     _tprintf(L"InstallService() : Service installed successfully\n"); 
107 
108 _EXIT:
109     if( schService )    CloseServiceHandle(schService); 
110     if( schSCManager)   CloseServiceHandle(schSCManager);
111 }
112 
113 //卸载服务
114 VOID UninstallService(LPCTSTR szSvcName)
115 {
116     SC_HANDLE schSCManager = NULL;
117     SC_HANDLE schService = NULL;
118     SERVICE_STATUS ss = {0,};
119     DWORD dwError = 0;
120 
121     schSCManager = OpenSCManager( 
122         NULL,                    // local computer
123         NULL,                    // ServicesActive database 
124         SC_MANAGER_ALL_ACCESS);  // full access rights 
125     if( NULL == schSCManager ) 
126     {
127         _tprintf(L"UninstallService() : OpenSCManager failed (%d)\n", GetLastError());
128         return;
129     }
130 
131     schService = OpenService( 
132         schSCManager,       // SCM database 
133         szSvcName,          // name of service 
134         SERVICE_INTERROGATE |
135         DELETE);            // need delete access 
136     if( NULL == schService )
137     { 
138         dwError = GetLastError();
139         if( dwError != ERROR_SERVICE_DOES_NOT_EXIST )
140             _tprintf(L"UninstallService() : OpenSCManager failed (%d)\n", dwError);
141 
142         goto _EXIT;
143     }
144         
145     ControlService(schService, SERVICE_CONTROL_INTERROGATE, &ss);
146     if( ss.dwCurrentState != SERVICE_STOPPED )
147     {
148         _tprintf(L"  -> Service is running! Stop the service!!!\n");
149         goto _EXIT;
150     }
151 
152     if( !DeleteService(schService) ) 
153         _tprintf(L"UninstallService() : DeleteService failed (%d)\n", GetLastError()); 
154     else
155         _tprintf(L"Service uninstalled successfully\n"); 
156 
157 _EXIT:
158     if( schService )    CloseServiceHandle(schService); 
159     if( schSCManager )  CloseServiceHandle(schSCManager);
160 }
161 
162 //服务Main(设置服务控制处理函数,修改服务运行状态)
163 VOID WINAPI SvcMain(DWORD argc, LPCTSTR *argv)
164 {
165     // Service Control Handler
166     g_hServiceStatusHandle = RegisterServiceCtrlHandler( 
167         SVCNAME, 
168         SvcCtrlHandler);
169     if( !g_hServiceStatusHandle )
170     { 
171         OutputDebugString(L"RegisterServiceCtrlHandler() failed!!!"); 
172         return; 
173     } 
174 
175     // Service Status -> SERVICE_RUNNING
176     g_ServiceStatus.dwCurrentState = SERVICE_RUNNING;
177     SetServiceStatus(g_hServiceStatusHandle, &g_ServiceStatus);
178 
179     // Print debug string
180     while( TRUE )
181     {
182         OutputDebugString(L"[SvcTest] service is running...");
183         Sleep(3 * 1000);        // 3 sec
184     }
185 }
186 
187 //服务控制处理函数
188 VOID WINAPI SvcCtrlHandler(DWORD dwCtrl)
189 {
190    switch(dwCtrl) 
191    {  
192         //根据SCM传递过来的参数修改服务运行状态
193         case SERVICE_CONTROL_STOP:
194             g_ServiceStatus.dwCurrentState = SERVICE_STOP_PENDING;
195             SetServiceStatus(g_hServiceStatusHandle, &g_ServiceStatus);
196             
197             g_ServiceStatus.dwCurrentState = SERVICE_STOPPED;
198             SetServiceStatus(g_hServiceStatusHandle, &g_ServiceStatus);
199 
200             OutputDebugString(L"[SvcTest] service is stopped...");
201         break;
202  
203       default: 
204          break;
205    }
206 }

服务调试

1、直接设置EIP到服务Main函数

2、修改服务进程入口点代码为死循环,附加后改回原代码,继续往下调试

 

posted @ 2019-12-03 17:01  SunsetR  阅读(514)  评论(0编辑  收藏  举报