background servicesaz12722.vo.msecnd.net/windows7trainingcourse1-0/labs... · web viewin this lab...
TRANSCRIPT
![Page 1: Background Servicesaz12722.vo.msecnd.net/windows7trainingcourse1-0/Labs... · Web viewIn this lab you have improved the performance and security of a Windows service to become a better](https://reader036.vdocuments.us/reader036/viewer/2022090114/5e65ab4a83f11c525672090f/html5/thumbnails/1.jpg)
Hands-On LabBackground Services - .NET
Lab version: 1.0.0
Last updated: 10/8/2009
![Page 2: Background Servicesaz12722.vo.msecnd.net/windows7trainingcourse1-0/Labs... · Web viewIn this lab you have improved the performance and security of a Windows service to become a better](https://reader036.vdocuments.us/reader036/viewer/2022090114/5e65ab4a83f11c525672090f/html5/thumbnails/2.jpg)
Background Services
CONTENTS
OVERVIEW................................................................................................................................................. 3
EXERCISE 1: TRIGGER-START SERVICE...............................................................................................7Task 1 – Implement Service Configuration Changes............................................................................7
Task 2 – Add Code to Register the Service as Trigger-Start...............................................................10
Task 3 – Enable the UsbCopyService to Trigger-Start........................................................................12
SUMMARY................................................................................................................................................ 18
2
![Page 3: Background Servicesaz12722.vo.msecnd.net/windows7trainingcourse1-0/Labs... · Web viewIn this lab you have improved the performance and security of a Windows service to become a better](https://reader036.vdocuments.us/reader036/viewer/2022090114/5e65ab4a83f11c525672090f/html5/thumbnails/3.jpg)
Background Services
Overview
Windows 7 and Windows Vista have introduced many improvements in background processing. The modern challenges of implementing efficient background processes are:
Performance – boot latency, logon latency, shutdown latency; background work interfering with foreground processing
Power consumption
Security – increased attack surface
Windows 7 background services and scheduled tasks offer a variety of mechanisms for minimizing power consumption, reducing the system’s attack surface and improving application and system performance. Among these mechanisms are:
Service requested security privileges
Service SIDs
Delayed auto-start services
Trigger-start services
Scheduled tasks conditions and settings
With the abundance of services in any modern installation of Windows, background processing must be designed to meet security, performance and power consumption requirements.
Objectives
In this Hands-On Lab, you will learn how to:
Design and implement a trigger-start service
Minimize the amount of privileges requested by a service
System Requirements
You must have the following items to complete this lab:
Microsoft Visual Studio 2008
Windows 7
Windows 7 SDK
3
![Page 4: Background Servicesaz12722.vo.msecnd.net/windows7trainingcourse1-0/Labs... · Web viewIn this lab you have improved the performance and security of a Windows service to become a better](https://reader036.vdocuments.us/reader036/viewer/2022090114/5e65ab4a83f11c525672090f/html5/thumbnails/4.jpg)
Background Services
Windows Sysinternals Process Explorer
Setup
This lab requires that the Windows 7 SDK is correctly integrated with Visual Studio 2008. To do this you can follow these steps:
1. From the Start Menu, go to All Programs | Microsoft Windows SDK v7.0 | Visual Studio Registration and click Windows SDK Configuration Tool. On the Windows SDK Configuration Tool dialog, verify that the v7.0 version is selected and then click Make Current.
Figure 1Windows SDK Configuration tool
2. You also need update Visual C++ directories to point to the Windows 7 SDK headers, libraries and tools. These paths should match your local Windows 7 SDK installation. To do this, from the Microsoft Visual Studio 2008 menu, select Tools | Options to open the Options dialog. Expand the Projects and Solutions node from the left panel, select VC++ Directories and follow these steps:
a. From the right panel, select Executable files from the combo located at the upper-right
corner. Then select the button, browse to the %Windows7SDKInstallDir%\v7.0\Bin folder and click Select Folder.
4
![Page 5: Background Servicesaz12722.vo.msecnd.net/windows7trainingcourse1-0/Labs... · Web viewIn this lab you have improved the performance and security of a Windows service to become a better](https://reader036.vdocuments.us/reader036/viewer/2022090114/5e65ab4a83f11c525672090f/html5/thumbnails/5.jpg)
Background Services
Figure 2Configuring the VC++ directories
Note: Windows 7 SDK is installed by default under the C:\Program Files\Microsoft SDKs\Windows folder.
b. Repeat the previous step adding the %Windows7SDKInstallDir%\v7.0\Include folder for the Include files option, and the %Windows7SDKInstallDir%\v7.0\Lib folder for the Library Files option.
c. Finally, click OK to save the settings.
Additionally, this lab requires specific “hard coded” folders to work with that you need to create:
1. On the local C drive you need to create a C:\FromUSB folder to which all the images from the USB key will be copied.
2. On the generic USB key you need to create a ToCopy folder from which all the images will be copied from.
Note: The service demonstrated in this exercise is not well-designed with regard to the design goals for background processes on Windows. It is a just sample application showing how to use the Trigger Start Services in Windows 7. For more information on designing efficient background processes, consult the Microsoft whitepaper “Designing Efficient Background Processes”.
5
![Page 6: Background Servicesaz12722.vo.msecnd.net/windows7trainingcourse1-0/Labs... · Web viewIn this lab you have improved the performance and security of a Windows service to become a better](https://reader036.vdocuments.us/reader036/viewer/2022090114/5e65ab4a83f11c525672090f/html5/thumbnails/6.jpg)
Background Services
6
![Page 7: Background Servicesaz12722.vo.msecnd.net/windows7trainingcourse1-0/Labs... · Web viewIn this lab you have improved the performance and security of a Windows service to become a better](https://reader036.vdocuments.us/reader036/viewer/2022090114/5e65ab4a83f11c525672090f/html5/thumbnails/7.jpg)
Background Services
Exercise 1: Trigger-Start Service
In this exercise, you will modify an existing service to be a better citizen of the operating system. You will change the service’s requested security privileges to run with least privileges; and you will change the service configuration so that it automatically starts when necessary instead of running and polling the system in the background.
The sample service used for this purpose is a USB file copy service, which copies files from a specific directory on any USB storage device inserted to the system. The techniques used in this exercise are applicable to any service that can trigger-start when certain criteria are met.
Task 1 – Implement Service Configuration Changes
To modify service configuration programmatically, the Win32 API function ChangeServiceConfig2 must be called with the appropriate parameters.
1. Open the starting solution Begin.sln located under the %TrainingKitInstallDir%\BackgroundServices\Ex1-TriggerStartService\Begin folder, choosing the language of your preference (C# or VB).
Note: Visual Studio 2008 must be run in elevated mode. To do this, right-click the Visual Studio 2008 icon and select Run as Administrator.
2. In the ServiceControlInterop project, locate the ServiceControlInterop.cpp file, under the Source Files folder, and add code in the RemoveAllPrivilegesFromService method to specify that the service requires no privileges:
a. Allocate a SERVICE_REQUIRED_PRIVILEGES_INFO structure and set its pmszRequiredPrivileges member to SE_CHANGE_NOTIFY_NAME L"\0".
b. Call the ChangeServiceConfig2 method with the SERVICE_CONFIG_REQUIRED_PRIVILEGES_INFO information level and pass the address of the structure allocated in the previous step.
Use the following code as a complete example (shown in bold):
C++
void ServiceControl::RemoveAllPrivilegesFromService(System::String^ serviceName){ .... if (hService == NULL)
7
![Page 8: Background Servicesaz12722.vo.msecnd.net/windows7trainingcourse1-0/Labs... · Web viewIn this lab you have improved the performance and security of a Windows service to become a better](https://reader036.vdocuments.us/reader036/viewer/2022090114/5e65ab4a83f11c525672090f/html5/thumbnails/8.jpg)
Background Services
{ DWORD dwLastError = GetLastError(); CloseServiceHandle(hSCManager); throw Marshal::GetExceptionForHR(dwLastError); }
//This effectively strips out all other privileges. SERVICE_REQUIRED_PRIVILEGES_INFO requiredPrivileges = {0}; requiredPrivileges.pmszRequiredPrivileges = SE_CHANGE_NOTIFY_NAME L"\0";
if (ChangeServiceConfig2(hService, SERVICE_CONFIG_REQUIRED_PRIVILEGES_INFO, &requiredPrivileges) == FALSE) { DWORD dwLastError = GetLastError(); CloseServiceHandle(hService); CloseServiceHandle(hSCManager); throw Marshal::GetExceptionForHR(dwLastError); }
CloseServiceHandle(hService); CloseServiceHandle(hSCManager);}
3. In the SetServiceTriggerStartOnUSBArrival method, add code to set the service to trigger-start when a generic USB disk becomes available:
a. Allocate a SERVICE_TRIGGER_SPECIFIC_DATA_ITEM structure. To do this:
i. Set its dwDataType member to SERVICE_TRIGGER_DATA_TYPE_STRING.
ii. Set its cbData member to the length of the string L"USBSTOR\\GenDisk" in bytes.
iii. Set its pData member to that string.
b. Allocate a SERVICE_TRIGGER structure. To do this:
i. Set its dwTriggerType member to SERVICE_TRIGGER_TYPE_DEVICE_INTERFACE_ARRIVAL.
ii. Set its dwAction member to SERVICE_TRIGGER_ACTION_SERVICE_START.
iii. Set its pTriggerSubtype member to the address of the GUID_USBDevice GUID.
iv. Set its cDataItems member to 1 and its pDataItems member to the address of the structure allocated in the previous step.
c. Allocate a SERVICE_TRIGGER_INFO structure. To do this:
8
![Page 9: Background Servicesaz12722.vo.msecnd.net/windows7trainingcourse1-0/Labs... · Web viewIn this lab you have improved the performance and security of a Windows service to become a better](https://reader036.vdocuments.us/reader036/viewer/2022090114/5e65ab4a83f11c525672090f/html5/thumbnails/9.jpg)
Background Services
i. Set set its cTriggers member to 1 and its pTriggers member to the address of the structure allocated in the previous step.
d. Call the ChangeServiceConfig2 function with the SERVICE_CONFIG_TRIGGER_INFO information level and pass to it the address of the structure allocated in the previous step.
Use the following code as a complete example (shown in bold):
C++
void ServiceControl::SetServiceTriggerStartOnUSBArrival(System::String^ serviceName){ ... if (hService == NULL) { DWORD dwLastError = GetLastError(); CloseServiceHandle(hSCManager); throw Marshal::GetExceptionForHR(dwLastError); }
LPCWSTR lpszDeviceString = L"USBSTOR\\GenDisk";
SERVICE_TRIGGER_SPECIFIC_DATA_ITEM deviceData = {0}; deviceData.dwDataType = SERVICE_TRIGGER_DATA_TYPE_STRING; deviceData.cbData = (wcslen(lpszDeviceString)+1) * sizeof(WCHAR); deviceData.pData = (PBYTE)lpszDeviceString;
SERVICE_TRIGGER serviceTrigger = {0}; serviceTrigger.dwTriggerType = SERVICE_TRIGGER_TYPE_DEVICE_INTERFACE_ARRIVAL; serviceTrigger.dwAction = SERVICE_TRIGGER_ACTION_SERVICE_START; serviceTrigger.pTriggerSubtype = (GUID*)&GUID_USBDevice; serviceTrigger.cDataItems = 1; serviceTrigger.pDataItems = &deviceData;
SERVICE_TRIGGER_INFO serviceTriggerInfo = {0}; serviceTriggerInfo.cTriggers = 1; serviceTriggerInfo.pTriggers = &serviceTrigger;
if (ChangeServiceConfig2(hService, SERVICE_CONFIG_TRIGGER_INFO, &serviceTriggerInfo) == FALSE) { DWORD dwLastError = GetLastError(); CloseServiceHandle(hService); CloseServiceHandle(hSCManager); throw Marshal::GetExceptionForHR(dwLastError);
9
![Page 10: Background Servicesaz12722.vo.msecnd.net/windows7trainingcourse1-0/Labs... · Web viewIn this lab you have improved the performance and security of a Windows service to become a better](https://reader036.vdocuments.us/reader036/viewer/2022090114/5e65ab4a83f11c525672090f/html5/thumbnails/10.jpg)
Background Services
}
CloseServiceHandle(hService); CloseServiceHandle(hSCManager);}
This completes the C++/CLI wrapper necessary for .NET interaction with the service trigger-start APIs.
Task 2 – Add Code to Register the Service as Trigger-Start
Services can be registered as trigger-start from the sc.exe command line utility (using the sc triggerinfo command from an elevated Command Shell), or using the ChangeServiceConfig2 API programmatically, which we wrapped as part of the previous task.
1. In the RegisterService project, locate the RegisterServiceForm.cs (C#) or RegisterServiceForm.vb (Visual Basic) code file and within it add code to the btnRegisterTriggerStart_Click method to change the service configuration to trigger-start using the C++/CLI wrapper, as follows (shown in bold):
C#
private void btnRegisterTriggerStart_Click(object sender, EventArgs e){ AddService();
ServiceControl.SetServiceTriggerStartOnUSBArrival(ServiceName);
StopLogReaderTimer(); StartLogReaderTimer();}
Visual Basic
Private Sub btnRegisterTriggerStart_Click() Handles btnRegisterTriggerStart.Click AddService()
ServiceControl.SetServiceTriggerStartOnUSBArrival(ServiceName)
StopLogReaderTimer() StartLogReaderTimer()End Sub
2. In the btnRemovePrivileges_Click method, add code to change the service configuration to request the minimum possible privileges using the C++/CLI wrapper, as follows:
10
![Page 11: Background Servicesaz12722.vo.msecnd.net/windows7trainingcourse1-0/Labs... · Web viewIn this lab you have improved the performance and security of a Windows service to become a better](https://reader036.vdocuments.us/reader036/viewer/2022090114/5e65ab4a83f11c525672090f/html5/thumbnails/11.jpg)
Background Services
C#
private void btnRemovePrivileges_Click(object sender, EventArgs e){ ServiceControl.RemoveAllPrivilegesFromService(ServiceName);}
Visual Basic
Private Sub btnRemovePrivileges_Click() Handles btnRemovePrivileges.Click ServiceControl.RemoveAllPrivilegesFromService(ServiceName)End Sub
You have now completed the changes to the service registration UI application so that the service can be registered as a trigger-start service with the minimum amount of necessary privileges.
11
![Page 12: Background Servicesaz12722.vo.msecnd.net/windows7trainingcourse1-0/Labs... · Web viewIn this lab you have improved the performance and security of a Windows service to become a better](https://reader036.vdocuments.us/reader036/viewer/2022090114/5e65ab4a83f11c525672090f/html5/thumbnails/12.jpg)
Background Services
Task 3 – Enable the UsbCopyService to Trigger-Start
Unlike auto-start services which typically poll for interesting events using periodic timers, trigger-start services act when a trigger starts them and then deactivate (stop) themselves when there is no more work to perform.
1. In the UsbCopyService project, locate and open the USBService.cs (C#) or USBService.vb (Visual Basic) code file.
2. (For Visual Basic users only) Add the ProcessTriggerStart method, which will be called when the service is configured to trigger-start.
Visual Basic
Private Sub ProcessTriggerStart() DoWork()End Sub
3. Modify the OnStart method to check whether the service is configured to trigger-start using the ServiceControl.IsServiceTriggerStart method (pass the ServiceName property inherited from the ServiceBase class as the parameter). To do this, replace the method implementation with the following code:
C#
protected override void OnStart(string[] args){ if (ServiceControl.IsServiceTriggerStart(ServiceName)) { } else { _timer = new Timer(delegate { DoWork(); }); _timer.Change(0, 5000); }}
Visual Basic
Protected Overrides Sub OnStart(ByVal args() As String) If ServiceControl.IsServiceTriggerStart(ServiceName) Then
Else _timer = New Timer(AddressOf ProcessTimerEvent) _timer.Change(0, 5000) End If
12
![Page 13: Background Servicesaz12722.vo.msecnd.net/windows7trainingcourse1-0/Labs... · Web viewIn this lab you have improved the performance and security of a Windows service to become a better](https://reader036.vdocuments.us/reader036/viewer/2022090114/5e65ab4a83f11c525672090f/html5/thumbnails/13.jpg)
Background Services
End Sub
4. Now if the service is configured to trigger-start, instead of creating the periodic timer the method will enqueue the work to be performed only once. To do this, add the following code (shown in bold):
C#
protected override void OnStart(string[] args){ if (ServiceControl.IsServiceTriggerStart(ServiceName)) { ThreadPool.QueueUserWorkItem(delegate { DoWork(); }); } else { _timer = new Timer(delegate { DoWork(); }); _timer.Change(0, 5000); }}
Visual Basic
Protected Overrides Sub OnStart(ByVal args() As String) If ServiceControl.IsServiceTriggerStart(ServiceName) Then ThreadPool.QueueUserWorkItem(AddressOf ProcessTriggerStart) Else _timer = New Timer(AddressOf ProcessTimerEvent) _timer.Change(0, 5000) End IfEnd Sub
5. After completing the work, the service should stop using the Stop method inherited from the ServiceBase class. To do this, add the following code (shown in bold) to the OnStart method (C#) or to the ProcessTriggerStart method (Visual Basic):
C#
protected override void OnStart(string[] args){ if (ServiceControl.IsServiceTriggerStart(ServiceName))
13
![Page 14: Background Servicesaz12722.vo.msecnd.net/windows7trainingcourse1-0/Labs... · Web viewIn this lab you have improved the performance and security of a Windows service to become a better](https://reader036.vdocuments.us/reader036/viewer/2022090114/5e65ab4a83f11c525672090f/html5/thumbnails/14.jpg)
Background Services
{ ThreadPool.QueueUserWorkItem(delegate { DoWork(); Stop(); }); } else { ... }}
Visual Basic
Private Sub ProcessTriggerStart() DoWork() Me.Stop()End Sub
6. You are now ready to test the service. Run the RegisterService project.
Note: The project should be run as administrator. You can do this either from the elevated Visual Studio instance or by running the executable elevated from the shell or command prompt.
7. Register the service as demand-start by clicking the Register Demand-Start button and start it by clicking the Start button. It will continuously poll for a USB device every 5 seconds. When a USB device with the ToCopy directory is detected, it will copy that directory’s contents to the C:\FromUSB directory.
Figure 3
14
![Page 15: Background Servicesaz12722.vo.msecnd.net/windows7trainingcourse1-0/Labs... · Web viewIn this lab you have improved the performance and security of a Windows service to become a better](https://reader036.vdocuments.us/reader036/viewer/2022090114/5e65ab4a83f11c525672090f/html5/thumbnails/15.jpg)
Background Services
Registering the service as demand-start
8. Inspect the service’s access token by launching Sysinternals Process Explorer. Right-click on the UsbCopyService.exe process in the process tree, select Properties and switch to the Security tab. Under the service’s privilege list, many privileges are either enabled or just present (disabled).
Figure 4Inspecting service privileges
Note: Find the download link for Sysinternals Process Explorer (procexp.exe) in the Prerequisites section of this hands-on lab.
15
![Page 16: Background Servicesaz12722.vo.msecnd.net/windows7trainingcourse1-0/Labs... · Web viewIn this lab you have improved the performance and security of a Windows service to become a better](https://reader036.vdocuments.us/reader036/viewer/2022090114/5e65ab4a83f11c525672090f/html5/thumbnails/16.jpg)
Background Services
9. Stop the service using the Stop button.
10. Remove privileges from the service by clicking the Remove Privileges button.
11. Start the service by clicking the Start button and inspect its access token again using Sysinternals Process Explorer. The service’s privilege list should now contain only the SeChangeNotifyPrivilege (which is always retained for application compatibility purposes).
Figure 5Service privileges (after removing privileges)
12. Stop the service using the Stop button and delete it using the Delete button.
13. Remove the USB Device from the computer.
14. Register the service as trigger-start by clicking the Register Trigger-Start button. Do not start the service manually.
16
![Page 17: Background Servicesaz12722.vo.msecnd.net/windows7trainingcourse1-0/Labs... · Web viewIn this lab you have improved the performance and security of a Windows service to become a better](https://reader036.vdocuments.us/reader036/viewer/2022090114/5e65ab4a83f11c525672090f/html5/thumbnails/17.jpg)
Background Services
15. Inspect the service’s trigger-start configuration by running the following command from an elevated command prompt.
Command
sc qtriggerinfo UsbCopyService
Figure 6Inspecting service's trigger-start configuration
16. Insert a USB device with a ToCopy directory. The service should automatically start, copy the files and then shut itself down.
17. You can verify that the service is down by running the following command from an elevated command prompt.
Command
sc queryex UsbCopyService
Figure 7Verifying service is down
17
![Page 18: Background Servicesaz12722.vo.msecnd.net/windows7trainingcourse1-0/Labs... · Web viewIn this lab you have improved the performance and security of a Windows service to become a better](https://reader036.vdocuments.us/reader036/viewer/2022090114/5e65ab4a83f11c525672090f/html5/thumbnails/18.jpg)
Background Services
18. When done, delete the service by clicking the Delete button.
19. You can ensure that the service has been deleted by running the same previous command from an elevated command prompt.
Command
sc queryex UsbCopyService
Figure 8Verifying service has been deleted
In this exercise, you have modified an existing service to trigger-start when a USB device is detected in the system. You have also modified the service’s requested privilege list to the minimum necessary amount of privileges, thus reducing the system’s attack surface. The full exercise solution can be found in the %TrainingKitInstallDir%\BackgroundServices\Ex1-TriggerStartService\End directory, depending on the language of your preference.
Summary
In this lab you have improved the performance and security of a Windows service to become a better citizen of the operating system. You used the trigger-start service mechanism to launch the service only when there is actual work for it to perform, and you have minimized the service’s attack surface by removing unnecessary privileges from its process’ token.
You can find a full demo of the USB copy service and the Weather Updater service as part of this Windows 7 course’s code samples.
18