Jump to content
Tuts 4 You

[WINAPI] Enumerate all services


mrexodia

Recommended Posts

Hi everyone,

Some time ago I put this small utility together for a friend that needed it. Turns out to be a useful piece of code. Code was found on the internet, only slightly modified and cleaned up a little. Credits to the original author of the code (sorry, couldn't find the website I found it on).

This is the code:

#include <stdio.h>#include <windows.h>void ErrorDescription(DWORD p_dwError){    HLOCAL hLocal=0;    FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_ALLOCATE_BUFFER,                  0,                  p_dwError,                  MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),                  (LPTSTR)&hLocal,                  0,                  0);    MessageBox(0, (LPCTSTR)LocalLock(hLocal), "Error", MB_ICONERROR|MB_SYSTEMMODAL);    LocalFree(hLocal);}int main(){    SC_HANDLE hManager=OpenSCManager(0, 0, SC_MANAGER_ALL_ACCESS);    if(!hManager)    {        ErrorDescription(GetLastError());        return -1;    }    ENUM_SERVICE_STATUS service;    DWORD dwBytesNeeded=0;    DWORD dwServicesReturned=0;    DWORD dwResumedHandle=0;    if(!EnumServicesStatus(hManager,                           SERVICE_WIN32|SERVICE_DRIVER,                           SERVICE_STATE_ALL,                           &service,                           sizeof(ENUM_SERVICE_STATUS),                           &dwBytesNeeded,                           &dwServicesReturned,                           &dwResumedHandle))    {        if(GetLastError()==ERROR_MORE_DATA)        {            DWORD dwBytes=sizeof(ENUM_SERVICE_STATUS)+dwBytesNeeded;            ENUM_SERVICE_STATUS* pServices=0;            pServices=(ENUM_SERVICE_STATUS*)new BYTE[dwBytes];            EnumServicesStatus(hManager,                               SERVICE_WIN32|SERVICE_DRIVER,                               SERVICE_STATE_ALL, pServices,                               dwBytes,                               &dwBytesNeeded,                               &dwServicesReturned,                               &dwResumedHandle);            FILE* file=fopen("services.txt", "w+");            for(unsigned int i=0; i<dwServicesReturned; i++)            {                fprintf(file,                        "     DisplayName: %s\n"                        "     ServiceName: %s\n"                        "     ServiceType: 0x%.8X\n"                        "    CurrentState: 0x%.8X\n"                        "ControlsAccepted: 0x%.8X\n"                        "   Win32ExitCode: 0x%.8X\n"                        "SpecificExitCode: 0x%.8X\n"                        "      CheckPoint: 0x%.8X\n"                        "        WaitHint: 0x%.8X\n\n",                        (unsigned int)(pServices+i)->lpDisplayName,                        (unsigned int)(pServices+i)->lpServiceName,                        (unsigned int)(pServices+i)->ServiceStatus.dwServiceType,                        (unsigned int)(pServices+i)->ServiceStatus.dwCurrentState,                        (unsigned int)(pServices+i)->ServiceStatus.dwControlsAccepted,                        (unsigned int)(pServices+i)->ServiceStatus.dwWin32ExitCode,                        (unsigned int)(pServices+i)->ServiceStatus.dwServiceSpecificExitCode,                        (unsigned int)(pServices+i)->ServiceStatus.dwCheckPoint,                        (unsigned int)(pServices+i)->ServiceStatus.dwWaitHint);            }            fclose(file);            delete[] pServices;            pServices=0;        }        else            ErrorDescription(GetLastError());    }    if(!CloseServiceHandle(hManager))        ErrorDescription(GetLastError());    else        system("start services.txt");    return 0;}
Attached the binary.

Greetings,

Mr. eXoDia

enumservices.rar

Edited by Mr. eXoDia
Link to comment

hey,


 


i think you are allocating too much memory. Better use:


 


new BYTE[dwBytes]


 


Also you should call OpenSCManager only with SC_MANAGER_ENUMERATE_SERVICE access right.  SC_MANAGER_ALL_ACCESS will probably trigger UAC.


  • Like 2
Link to comment

hey,

 

i think you are allocating too much memory. Better use:

 

new BYTE[dwBytes]

 

Also you should call OpenSCManager only with SC_MANAGER_ENUMERATE_SERVICE access right.  SC_MANAGER_ALL_ACCESS will probably trigger UAC.

Yup, you're probably right. As said, just copy&pasted this :) Will update it.

 

 

Yep, looks like an interesting tut :)

Greetings

Link to comment

for dev-c++ i had to change the code to:


 


 pServices=new ENUM_SERVICE_STATUS[dwBytes];


 


the printout was nice indeed... good stuff...


 


 

Tell ya what though, this Service Enumerator and a good System Module Driver Enumerator and thats kickin!

Edited by JMC31337
Link to comment

for dev-c++ i had to change the code to:

 

 pServices=new ENUM_SERVICE_STATUS[dwBytes];

 

the printout was nice indeed... good stuff...

 

 

Tell ya what though, this Service Enumerator and a good System Module Driver Enumerator and thats kickin!

Now it should also be fixed in the initial post.

Link to comment

for(unsigned int i=0; i<dwServicesReturned; i++) {

fwprintf(

file,

L"Display Name\t\t: %s\n"

L" Service Name\t\t: %s\n"

L" ServiceType\t\t: 0x%p\n"

L" CurrentState\t\t: 0x%p\n"

L" ControlsAccepted\t: 0x%p\n"

L" Win32ExitCode\t\t: 0x%p\n"

L" ServiceExitCode\t: 0x%p\n"

L" CheckPoint\t\t: 0x%p\n"

L" WaitHint\t\t\t: 0x%p\n---------------------\n",

(pServices + i)->lpDisplayName,

(pServices + i)->lpServiceName,

(pServices + i)->ServiceStatus.dwServiceType,

(pServices + i)->ServiceStatus.dwCurrentState,

(pServices + i)->ServiceStatus.dwControlsAccepted,

(pServices + i)->ServiceStatus.dwWin32ExitCode,

(pServices + i)->ServiceStatus.dwServiceSpecificExitCode,

(pServices + i)->ServiceStatus.dwCheckPoint,

(pServices + i)->ServiceStatus.dwWaitHint);

}

Some useful additional information from SERVICE_STATUS structure...

http://msdn.microsoft.com/en-us/library/windows/desktop/ms685996%28v=vs.85%29.aspx

Link to comment

Sorry to post again here. This snippet is really not that important, but due to my post you made a bad fix.


 


pServices=new ENUM_SERVICE_STATUS[dwBytes/sizeof(ENUM_SERVICE_STATUS)];


 


Please read this:


A pointer to a buffer that contains an array of ENUM_SERVICE_STATUS structures that receive the name and service status information for each service in the database. The buffer must be large enough to hold the structures, plus the strings to which their members point.


 


The only valid fix is:


new BYTE[dwBytes]


 


with a type cast obviously.


Link to comment

@Insid3Code: thanks for your contribution, code + binary has been updated!

@Aguila: you're right, the code has been updated :)

Greetings

Link to comment

Duke, Nuke Em'  (may require admin privs for some)


 




:LISTSERVICES START STOP
SC query state= all type= all | FOR /F "tokens=2" %%i IN ('FIND /I "SERVICE_NAME"') DO @ECHO %%i
SC query | FOR /F "tokens=2" %%i IN ('FIND /I "SERVICE_NAME"') DO @ECHO %%i
SC query | FOR /F "tokens=2" %%i IN ('FIND /I "SERVICE_NAME"') DO sc stop %%i
SC query | FOR /F "tokens=2" %%i IN ('FIND /I "SERVICE_NAME"') DO net stop %%i

http://www.askapache.com/windows/advanced-batch-scripting.html


Edited by JMC31337
Link to comment

DisplayName       : Abiosdsk

ServiceName       : Abiosdsk

ServiceType       : 0x00000001

CurrentState       : 0x00000001

ControlsAccepted  : 0x00000000

Win32ExitCode       : 0x00000435

-->> ServiceExitCode      : 0x00000000

-->> ServiceExitCode      : 0x00000000

-->> ServiceExitCode      : 0x00000000

CheckPoint       : 0x77C31AE8

WaitHint       : 0x0022FF2C

Typo: Duplicated (ServiceExitCode) string in binary...

Edited by Insid3Code
Link to comment
DisplayName          : AbiosdskServiceName          : AbiosdskServiceType          : 0x00000001CurrentState         : 0x00000001ControlsAccepted     : 0x00000000Win32ExitCode        : 0x00000435   -->>    ServiceExitCode      : 0x00000000   -->>    ServiceExitCode      : 0x00000000   -->>    ServiceExitCode      : 0x00000000CheckPoint           : 0x77C31AE8WaitHint             : 0x0022FF2C
Typo: Duplicated (ServiceExitCode) string in binary...
 

What's the problem? I don't see this on my side...

 

DisplayName		: 1394 OHCI Compliant Host ControllerServiceName		: 1394ohciServiceType		: 0x00000001CurrentState		: 0x00000001ControlsAccepted	: 0x00000000Win32ExitCode		: 0x00000435ServiceExitCode		: 0x00000000CheckPoint		: 0x00000000WaitHint		: 0x00000000
Link to comment

DisplayName: Abiosdsk

ServiceName: Abiosdsk

ServiceType: 0x00000001

CurrentState: 0x00000001

ControlsAccepted: 0x00000000

Win32ExitCode: 0x00000435

SpecificExitCode: 0x00000000

CheckPoint: 0x00000000

WaitHint: 0x00000000

Fixed with update binary...

 

Also, I have something wrong with (CloseServiceHandle(hManager))

LastError ERROR_NEGATIVE_SEEK (00000083) when the application tried to close the opened handle...

from -->> if(!CloseServiceHandle(hManager))

ErrorDescription(GetLastError());

to -->> CloseServiceHandle(hManager);

ErrorDescription(GetLastError());

To reproduce the behavior change the line above to catch the error!

EAX 00000001

ECX 77DB6CF5 ADVAPI32.77DB6CF5

EDX 00010001

EBX 003F3BA0

ESP 0022FEC4

EBP 0022FF48

ESI 002563B0

EDI 00000122

EIP 00401442 enumserv.00401442

C 0 ES 0023 32bit 0(FFFFFFFF)

P 0 CS 001B 32bit 0(FFFFFFFF)

A 0 SS 0023 32bit 0(FFFFFFFF)

Z 0 DS 0023 32bit 0(FFFFFFFF)

S 0 FS 003B 32bit 7FFDF000(FFF)

T 0 GS 0000 NULL

D 0

O 0 LastErr ERROR_NEGATIVE_SEEK (00000083)

Edited by Insid3Code
Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...