To install and run a service DLL compiled with MinGW on Kali, I execute following commands from a BAT file with an elevated command prompt:copy SvcHostDemo.dll %SystemRoot%\System32\SvcHostDemo.dll sc create SvcHostDemo binPath= ^%%SystemRoot^%%"\system32\svchost.exe -k mygroup" type= share start= demand reg add HKLM\SYSTEM\CurrentControlSet\services\SvcHostDemo\Parameters /v ServiceDll /t REG_EXPAND_SZ /d ^%%SystemRoot^%%\System32\SvcHostDemo.dll /f reg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Svchost" /v mygroup /t REG_MULTI_SZ /d SvcHostDemo /f
Line 1 copies the DLL to system32.
Line 2 creates a service with name SvcHostDemo, that will start svchost.exe with service host group “mygroup”. The service can run in a shared svchost process, and it needs to be started manually.
Line 3 creates the registry entry ServiceDll referring to SvcHostDemo.dll.
Line 4 creates the service host group “mygroup” under the key for svchost. This service host group contains the service SvcHostDemo.
These commands create the following registry entries:
On a 64-bit Windows system, system32\svchost.exe is a 64-bit application and thus the service DLL needs to be a 64-bit DLL.
On a 32-bit Windows system, system32\svchost.exe is a 32-bit application and thus the service DLL needs to be a 32-bit DLL.
To start the service from the command line, the following command can be issued from an elevated command prompt: sc start SvcHostDemo.
Since service SvcHostDemo is the only service of service host group mygroup, starting the service causes a svchost.exe process to be created and the DLL is loaded inside this new process.
To pause the service: sc pause SvcHostDemo.
To resume the service: sc continue SvcHostDemo.
To stop the service: sc stop SvcHostDemo.
And since service SvcHostDemo is the only service of service host group mygroup, stopping the service causes the svchost.exe process to be terminated.
The many debug messages generated by this demo service can be viewed with DebugView. Run dbgview.exe elevated and enable “Capture Global Win32”, otherwise debug messages from a service (running under the local system account) will no be captured and displayed.
This service can also run inside an existing service host group, like netsvcs. To achieve this, line 2 of the commands above needs to use service host group netsvcs in stead of mygroup. And line 4 is not needed, but the existing multistring netsvcs under key Svchost needs to be updated to include SvcHostDemo. This change requires a reboot of the Windows machine to become effective.
With these changes, starting the service results in loading of the DLL in the existing svchost.exe process for the netsvcs service host group.
Stopping the service does not result in termination of the svchost.exe process, as it is hosting many other Microsoft Windows services.
To unload the DLL from the svchost.exe process when the service is stopped, set registry value ServiceDllUnloadOnStop under Parameters to 1.reg add HKLM\SYSTEM\CurrentControlSet\services\SvcHostDemo\Parameters /v ServiceDllUnloadOnStop /t REG_DWORD /d 1 /f
If the name of the service function is not ServiceMain, but another name like RunThisService for example, then registry value ServiceMain under Parameters can be set to RunThisService.reg add HKLM\SYSTEM\CurrentControlSet\services\SvcHostDemo\Parameters /v ServiceMain /t REG_SZ /d RunThisService /f
I used Windows 7 to demo this, as shared services on Windows 10 behave differently. Starting with Windows 10 version 1703, a service host refactoring took place and on machines with more than 3.5 GB of RAM each service DLL has its own svchost process, regardless of service host groups. This resulted in a change in the ImagePath registry entries. On Windows 10 machines version 1703 and later, almost all ImagePath entries for “svchost.exe -k servicegroup” have an extra option “-p”, like this: “svchost.exe -k servicegroup -p”. One of the very few svchost services not having this -p option, is the BTAGService service.
I still need to figure out what this option -p means exactly.