Added new service API allowing to find service by name easily

This commit is contained in:
hakril
2019-11-14 13:31:20 +01:00
parent 0ed859b95e
commit 7638080ee4
11 changed files with 987 additions and 139 deletions
@@ -1,4 +1,73 @@
#define SYMSEARCH_MASKOBJS 0x01 // used internally to implement other APIs
#define SYMSEARCH_RECURSE 0X02 // recurse scopes
#define SYMSEARCH_GLOBALSONLY 0X04 // search only for global symbols
#define SYMSEARCH_ALLITEMS 0X08 // search for everything in the pdb, not just normal scoped symbols
#define SYMSEARCH_ALLITEMS 0X08 // search for everything in the pdb, not just normal scoped symbols
//
// data structures used for registered symbol callbacks
//
#define CBA_DEFERRED_SYMBOL_LOAD_START 0x00000001
#define CBA_DEFERRED_SYMBOL_LOAD_COMPLETE 0x00000002
#define CBA_DEFERRED_SYMBOL_LOAD_FAILURE 0x00000003
#define CBA_SYMBOLS_UNLOADED 0x00000004
#define CBA_DUPLICATE_SYMBOL 0x00000005
#define CBA_READ_MEMORY 0x00000006
#define CBA_DEFERRED_SYMBOL_LOAD_CANCEL 0x00000007
#define CBA_SET_OPTIONS 0x00000008
#define CBA_EVENT 0x00000010
#define CBA_DEFERRED_SYMBOL_LOAD_PARTIAL 0x00000020
#define CBA_DEBUG_INFO 0x10000000
#define CBA_SRCSRV_INFO 0x20000000
#define CBA_SRCSRV_EVENT 0x40000000
#define CBA_UPDATE_STATUS_BAR 0x50000000
#define CBA_ENGINE_PRESENT 0x60000000
#define CBA_CHECK_ENGOPT_DISALLOW_NETWORK_PATHS 0x70000000
#define EVENT_SRCSPEW_START 100
#define EVENT_SRCSPEW 100
#define EVENT_SRCSPEW_END 199
#define DSLFLAG_MISMATCHED_PDB 0x1
#define DSLFLAG_MISMATCHED_DBG 0x2
#define FLAG_ENGINE_PRESENT 0x4
#define FLAG_ENGOPT_DISALLOW_NETWORK_PATHS 0x8
//
// options that are set/returned by SymSetOptions() & SymGetOptions()
// these are used as a mask
//
#define SYMOPT_CASE_INSENSITIVE 0x00000001
#define SYMOPT_UNDNAME 0x00000002
#define SYMOPT_DEFERRED_LOADS 0x00000004
#define SYMOPT_NO_CPP 0x00000008
#define SYMOPT_LOAD_LINES 0x00000010
#define SYMOPT_OMAP_FIND_NEAREST 0x00000020
#define SYMOPT_LOAD_ANYTHING 0x00000040
#define SYMOPT_IGNORE_CVREC 0x00000080
#define SYMOPT_NO_UNQUALIFIED_LOADS 0x00000100
#define SYMOPT_FAIL_CRITICAL_ERRORS 0x00000200
#define SYMOPT_EXACT_SYMBOLS 0x00000400
#define SYMOPT_ALLOW_ABSOLUTE_SYMBOLS 0x00000800
#define SYMOPT_IGNORE_NT_SYMPATH 0x00001000
#define SYMOPT_INCLUDE_32BIT_MODULES 0x00002000
#define SYMOPT_PUBLICS_ONLY 0x00004000
#define SYMOPT_NO_PUBLICS 0x00008000
#define SYMOPT_AUTO_PUBLICS 0x00010000
#define SYMOPT_NO_IMAGE_SEARCH 0x00020000
#define SYMOPT_SECURE 0x00040000
#define SYMOPT_NO_PROMPTS 0x00080000
#define SYMOPT_OVERWRITE 0x00100000
#define SYMOPT_IGNORE_IMAGEDIR 0x00200000
#define SYMOPT_FLAT_DIRECTORY 0x00400000
#define SYMOPT_FAVOR_COMPRESSED 0x00800000
#define SYMOPT_ALLOW_ZERO_ADDRESS 0x01000000
#define SYMOPT_DISABLE_SYMSRV_AUTODETECT 0x02000000
#define SYMOPT_READONLY_CACHE 0x04000000
#define SYMOPT_SYMPATH_LAST 0x08000000
#define SYMOPT_DISABLE_FAST_SYMBOLS 0x10000000
#define SYMOPT_DISABLE_SYMSRV_TIMEOUT 0x20000000
#define SYMOPT_DISABLE_SRVSTAR_ON_STARTUP 0x40000000
#define SYMOPT_DEBUG 0x80000000
@@ -0,0 +1,5 @@
LPVOID HeapAlloc(
HANDLE hHeap,
DWORD dwFlags,
SIZE_T dwBytes
);
@@ -71,4 +71,197 @@ BOOL ControlService(
SC_HANDLE hService,
DWORD dwControl,
LPSERVICE_STATUS lpServiceStatus
);
BOOL QueryServiceStatus(
SC_HANDLE hService,
LPSERVICE_STATUS lpServiceStatus
);
BOOL QueryServiceStatusEx(
SC_HANDLE hService,
SC_STATUS_TYPE InfoLevel,
LPBYTE lpBuffer,
DWORD cbBufSize,
LPDWORD pcbBytesNeeded
);
BOOL ChangeServiceConfig2A(
SC_HANDLE hService,
DWORD dwInfoLevel,
LPVOID lpInfo
);
BOOL ChangeServiceConfig2W(
SC_HANDLE hService,
DWORD dwInfoLevel,
LPVOID lpInfo
);
BOOL ChangeServiceConfigA(
SC_HANDLE hService,
DWORD dwServiceType,
DWORD dwStartType,
DWORD dwErrorControl,
LPCSTR lpBinaryPathName,
LPCSTR lpLoadOrderGroup,
LPDWORD lpdwTagId,
LPCSTR lpDependencies,
LPCSTR lpServiceStartName,
LPCSTR lpPassword,
LPCSTR lpDisplayName
);
BOOL ChangeServiceConfigW(
SC_HANDLE hService,
DWORD dwServiceType,
DWORD dwStartType,
DWORD dwErrorControl,
LPCWSTR lpBinaryPathName,
LPCWSTR lpLoadOrderGroup,
LPDWORD lpdwTagId,
LPCWSTR lpDependencies,
LPCWSTR lpServiceStartName,
LPCWSTR lpPassword,
LPCWSTR lpDisplayName
);
BOOL QueryServiceConfig2A(
SC_HANDLE hService,
DWORD dwInfoLevel,
LPBYTE lpBuffer,
DWORD cbBufSize,
LPDWORD pcbBytesNeeded
);
BOOL QueryServiceConfig2W(
SC_HANDLE hService,
DWORD dwInfoLevel,
LPBYTE lpBuffer,
DWORD cbBufSize,
LPDWORD pcbBytesNeeded
);
BOOL QueryServiceConfigA(
SC_HANDLE hService,
LPQUERY_SERVICE_CONFIGA lpServiceConfig,
DWORD cbBufSize,
LPDWORD pcbBytesNeeded
);
BOOL QueryServiceConfigW(
SC_HANDLE hService,
LPQUERY_SERVICE_CONFIGW lpServiceConfig,
DWORD cbBufSize,
LPDWORD pcbBytesNeeded
);
BOOL QueryServiceDynamicInformation(
SERVICE_STATUS_HANDLE hServiceStatus,
DWORD dwInfoLevel,
PVOID *ppDynamicInfo
);
BOOL GetServiceDisplayNameA(
SC_HANDLE hSCManager,
LPCSTR lpServiceName,
LPSTR lpDisplayName,
LPDWORD lpcchBuffer
);
BOOL GetServiceDisplayNameW(
SC_HANDLE hSCManager,
LPCWSTR lpServiceName,
LPWSTR lpDisplayName,
LPDWORD lpcchBuffer
);
BOOL GetServiceKeyNameA(
SC_HANDLE hSCManager,
LPCSTR lpDisplayName,
LPSTR lpServiceName,
LPDWORD lpcchBuffer
);
BOOL GetServiceKeyNameW(
SC_HANDLE hSCManager,
LPCWSTR lpDisplayName,
LPWSTR lpServiceName,
LPDWORD lpcchBuffer
);
BOOL EnumDependentServicesA(
SC_HANDLE hService,
DWORD dwServiceState,
LPENUM_SERVICE_STATUSA lpServices,
DWORD cbBufSize,
LPDWORD pcbBytesNeeded,
LPDWORD lpServicesReturned
);
BOOL EnumDependentServicesW(
SC_HANDLE hService,
DWORD dwServiceState,
LPENUM_SERVICE_STATUSW lpServices,
DWORD cbBufSize,
LPDWORD pcbBytesNeeded,
LPDWORD lpServicesReturned
);
BOOL ControlService(
SC_HANDLE hService,
DWORD dwControl,
LPSERVICE_STATUS lpServiceStatus
);
BOOL ControlServiceExA(
SC_HANDLE hService,
DWORD dwControl,
DWORD dwInfoLevel,
PVOID pControlParams
);
BOOL ControlServiceExW(
SC_HANDLE hService,
DWORD dwControl,
DWORD dwInfoLevel,
PVOID pControlParams
);
SC_HANDLE CreateServiceA(
SC_HANDLE hSCManager,
LPCSTR lpServiceName,
LPCSTR lpDisplayName,
DWORD dwDesiredAccess,
DWORD dwServiceType,
DWORD dwStartType,
DWORD dwErrorControl,
LPCSTR lpBinaryPathName,
LPCSTR lpLoadOrderGroup,
LPDWORD lpdwTagId,
LPCSTR lpDependencies,
LPCSTR lpServiceStartName,
LPCSTR lpPassword
);
SC_HANDLE CreateServiceW(
SC_HANDLE hSCManager,
LPCWSTR lpServiceName,
LPCWSTR lpDisplayName,
DWORD dwDesiredAccess,
DWORD dwServiceType,
DWORD dwStartType,
DWORD dwErrorControl,
LPCWSTR lpBinaryPathName,
LPCWSTR lpLoadOrderGroup,
LPDWORD lpdwTagId,
LPCWSTR lpDependencies,
LPCWSTR lpServiceStartName,
LPCWSTR lpPassword
);
BOOL DeleteService(
SC_HANDLE hService
);
@@ -105,6 +105,148 @@ BOOL WINAPI SymEnumerateModules64(
_In_ PVOID UserContext
);
BOOL SymNext(
HANDLE hProcess,
PSYMBOL_INFO si
);
BOOL SymNextW(
HANDLE hProcess,
PSYMBOL_INFOW siw
);
BOOL SymPrev(
HANDLE hProcess,
PSYMBOL_INFO si
);
BOOL SymPrevW(
HANDLE hProcess,
PSYMBOL_INFOW siw
);
BOOL SymSetContext(
HANDLE hProcess,
PIMAGEHLP_STACK_FRAME StackFrame,
PIMAGEHLP_CONTEXT Context
);
BOOL SymSetExtendedOption(
IMAGEHLP_EXTENDED_OPTIONS option,
BOOL value
);
BOOL SymSrvGetFileIndexes(
PCSTR File,
GUID *Id,
PDWORD Val1,
PDWORD Val2,
DWORD Flags
);
BOOL SymSrvGetFileIndexesW(
PCWSTR File,
GUID *Id,
PDWORD Val1,
PDWORD Val2,
DWORD Flags
);
BOOL SymSrvGetFileIndexInfo(
PCSTR File,
PSYMSRV_INDEX_INFO Info,
DWORD Flags
);
BOOL SymSrvGetFileIndexInfoW(
PCWSTR File,
PSYMSRV_INDEX_INFOW Info,
DWORD Flags
);
BOOL SymSrvGetFileIndexString(
HANDLE hProcess,
PCSTR SrvPath,
PCSTR File,
PSTR Index,
SIZE_T Size,
DWORD Flags
);
BOOL SymSrvGetFileIndexStringW(
HANDLE hProcess,
PCWSTR SrvPath,
PCWSTR File,
PWSTR Index,
SIZE_T Size,
DWORD Flags
);
BOOL SymUnDName(
PIMAGEHLP_SYMBOL sym,
PSTR UnDecName,
DWORD UnDecNameLength
);
BOOL SymUnDName64(
PIMAGEHLP_SYMBOL64 sym,
PSTR UnDecName,
DWORD UnDecNameLength
);
BOOL SymUnloadModule(
HANDLE hProcess,
DWORD BaseOfDll
);
BOOL SymUnloadModule64(
HANDLE hProcess,
DWORD64 BaseOfDll
);
DWORD UnDecorateSymbolName(
PCSTR name,
PSTR outputString,
DWORD maxStringLength,
DWORD flags
);
DWORD UnDecorateSymbolNameW(
PCWSTR name,
PWSTR outputString,
DWORD maxStringLength,
DWORD flags
);
BOOL SymCleanup(
HANDLE hProcess
);
BOOL SymEnumProcesses(
PSYM_ENUMPROCESSES_CALLBACK EnumProcessesCallback,
PVOID UserContext
);
BOOL SymEnumSymbolsForAddr(
HANDLE hProcess,
DWORD64 Address,
PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback,
PVOID UserContext
);
BOOL SymEnumSymbolsForAddrW(
HANDLE hProcess,
DWORD64 Address,
PSYM_ENUMERATESYMBOLS_CALLBACKW EnumSymbolsCallback,
PVOID UserContext
);
BOOL WINAPI SymGetTypeFromName(
_In_ HANDLE hProcess,
@@ -146,4 +288,77 @@ BOOL SymSearchW(
PSYM_ENUMERATESYMBOLS_CALLBACKW EnumSymbolsCallback,
PVOID UserContext,
DWORD Options
);
PVOID SymFunctionTableAccess(
HANDLE hProcess,
DWORD AddrBase
);
DWORD SymGetModuleBase(
HANDLE hProcess,
DWORD dwAddr
);
BOOL SymRefreshModuleList(
HANDLE hProcess
);
BOOL SymRegisterCallback(
HANDLE hProcess,
PSYMBOL_REGISTERED_CALLBACK CallbackFunction,
PVOID UserContext
);
BOOL SymRegisterCallback64(
HANDLE hProcess,
PSYMBOL_REGISTERED_CALLBACK64 CallbackFunction,
ULONG64 UserContext
);
BOOL SymRegisterCallbackW64(
HANDLE hProcess,
PSYMBOL_REGISTERED_CALLBACK64 CallbackFunction,
ULONG64 UserContext
);
/* Stack walking */
BOOL StackWalk64(
DWORD MachineType,
HANDLE hProcess,
HANDLE hThread,
LPSTACKFRAME64 StackFrame,
PVOID ContextRecord,
PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemoryRoutine,
PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine,
PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine,
PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress
);
BOOL StackWalkEx(
DWORD MachineType,
HANDLE hProcess,
HANDLE hThread,
LPSTACKFRAME_EX StackFrame,
PVOID ContextRecord,
PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemoryRoutine,
PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine,
PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine,
PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress,
DWORD Flags
);
BOOL StackWalk(
DWORD MachineType,
HANDLE hProcess,
HANDLE hThread,
LPSTACKFRAME StackFrame,
PVOID ContextRecord,
PREAD_PROCESS_MEMORY_ROUTINE ReadMemoryRoutine,
PFUNCTION_TABLE_ACCESS_ROUTINE FunctionTableAccessRoutine,
PGET_MODULE_BASE_ROUTINE GetModuleBaseRoutine,
PTRANSLATE_ADDRESS_ROUTINE TranslateAddress
);
@@ -21,6 +21,7 @@ DWORD_PTR = ULONG_PTR
KAFFINITY = ULONG_PTR
KPRIORITY = LONG
CHAR = c_char
PCHAR = POINTER(CHAR)
UCHAR = c_char
CSHORT = c_short
VARTYPE = c_ushort
@@ -29,6 +30,7 @@ PBOOL = POINTER(BOOL)
LPBOOL = PBOOL
PSTR = LPSTR
PCSTR = LPSTR
va_list = c_char_p
BSTR = c_wchar_p
OLECHAR = c_wchar
@@ -85,6 +87,15 @@ NCRYPT_SECRET_HANDLE = ULONG_PTR
TRACEHANDLE = ULONG64
PTRACEHANDLE = POINTER(TRACEHANDLE)
/* Symbols stuff */
/* https://docs.microsoft.com/en-us/windows/win32/api/dbghelp/nf-dbghelp-symsetcontext
PIMAGEHLP_CONTEXT Context -> This parameter is ignored. (NOT GIVEN..)
typedef VOID IMAGEHLP_CONTEXT, *PIMAGEHLP_CONTEXT;
*/
PIMAGEHLP_CONTEXT = PVOID
/* INT sized*/
INT8 = c_byte // signed | our BYTE is unsigned
@@ -159,6 +170,17 @@ PEVENT_TRACE_BUFFER_CALLBACKA = PVOID
PEVENT_TRACE_BUFFER_CALLBACKW = PVOID
PEVENT_RECORD_CALLBACK = PVOID
PFN_CRYPT_ENUM_OID_FUNC = PVOID
PGET_MODULE_BASE_ROUTINE64 = PVOID # StackWalk
PGET_MODULE_BASE_ROUTINE = PVOID # StackWalk
PREAD_PROCESS_MEMORY_ROUTINE = PVOID # StackWalk
PREAD_PROCESS_MEMORY_ROUTINE64 = PVOID # StackWalk
PFUNCTION_TABLE_ACCESS_ROUTINE = PVOID # StackWalk
PFUNCTION_TABLE_ACCESS_ROUTINE64 = PVOID # StackWalk
PTRANSLATE_ADDRESS_ROUTINE = PVOID # StackWalk
PTRANSLATE_ADDRESS_ROUTINE64 = PVOID # StackWalk
PSYMBOL_REGISTERED_CALLBACK64 = PVOID # Symbols
PSYMBOL_REGISTERED_CALLBACK = PVOID # Symbols
PSYM_ENUMPROCESSES_CALLBACK = PVOID # Symbols
// Will be changed at import time
@@ -0,0 +1,85 @@
//
// Info levels for QueryServiceStatusEx
//
typedef enum _SC_STATUS_TYPE {
SC_STATUS_PROCESS_INFO = 0
} SC_STATUS_TYPE;
//
// Info levels for EnumServicesStatusEx
//
typedef enum _SC_ENUM_TYPE {
SC_ENUM_PROCESS_INFO = 0
} SC_ENUM_TYPE;
typedef struct _SERVICE_STATUS {
DWORD dwServiceType;
DWORD dwCurrentState;
DWORD dwControlsAccepted;
DWORD dwWin32ExitCode;
DWORD dwServiceSpecificExitCode;
DWORD dwCheckPoint;
DWORD dwWaitHint;
} SERVICE_STATUS, *LPSERVICE_STATUS;
typedef struct _SERVICE_STATUS_PROCESS {
DWORD dwServiceType;
DWORD dwCurrentState;
DWORD dwControlsAccepted;
DWORD dwWin32ExitCode;
DWORD dwServiceSpecificExitCode;
DWORD dwCheckPoint;
DWORD dwWaitHint;
DWORD dwProcessId;
DWORD dwServiceFlags;
} SERVICE_STATUS_PROCESS, *LPSERVICE_STATUS_PROCESS;
typedef struct _ENUM_SERVICE_STATUS_PROCESSA {
LPSTR lpServiceName;
LPSTR lpDisplayName;
SERVICE_STATUS_PROCESS ServiceStatusProcess;
} ENUM_SERVICE_STATUS_PROCESSA, *LPENUM_SERVICE_STATUS_PROCESSA;
typedef struct _ENUM_SERVICE_STATUS_PROCESSW {
LPWSTR lpServiceName;
LPWSTR lpDisplayName;
SERVICE_STATUS_PROCESS ServiceStatusProcess;
} ENUM_SERVICE_STATUS_PROCESSW, *LPENUM_SERVICE_STATUS_PROCESSW;
typedef struct _ENUM_SERVICE_STATUSA {
LPSTR lpServiceName;
LPSTR lpDisplayName;
SERVICE_STATUS ServiceStatus;
} ENUM_SERVICE_STATUSA, *LPENUM_SERVICE_STATUSA;
typedef struct _ENUM_SERVICE_STATUSW {
LPWSTR lpServiceName;
LPWSTR lpDisplayName;
SERVICE_STATUS ServiceStatus;
} ENUM_SERVICE_STATUSW, *LPENUM_SERVICE_STATUSW;
typedef struct _QUERY_SERVICE_CONFIGA {
DWORD dwServiceType;
DWORD dwStartType;
DWORD dwErrorControl;
LPSTR lpBinaryPathName;
LPSTR lpLoadOrderGroup;
DWORD dwTagId;
LPSTR lpDependencies;
LPSTR lpServiceStartName;
LPSTR lpDisplayName;
} QUERY_SERVICE_CONFIGA, *LPQUERY_SERVICE_CONFIGA;
typedef struct _QUERY_SERVICE_CONFIGW {
DWORD dwServiceType;
DWORD dwStartType;
DWORD dwErrorControl;
LPWSTR lpBinaryPathName;
LPWSTR lpLoadOrderGroup;
DWORD dwTagId;
LPWSTR lpDependencies;
LPWSTR lpServiceStartName;
LPWSTR lpDisplayName;
} QUERY_SERVICE_CONFIGW, *LPQUERY_SERVICE_CONFIGW;
@@ -85,6 +85,12 @@ typedef enum _SymTagEnum {
SymTagDimension
}SymTagEnum;
typedef enum _IMAGEHLP_EXTENDED_OPTIONS {
SYMOPT_EX_DISABLEACCESSTIMEUPDATE,
SYMOPT_EX_MAX,
SYMOPT_EX_LASTVALIDDEBUGDIRECTORY
} IMAGEHLP_EXTENDED_OPTIONS;
typedef struct _IMAGEHLP_MODULE64 {
DWORD SizeOfStruct;
DWORD64 BaseOfImage;
@@ -165,4 +171,270 @@ typedef struct _SYMBOL_INFO {
ULONG NameLen;
ULONG MaxNameLen;
CHAR Name[1];
} SYMBOL_INFO, *PSYMBOL_INFO;
} SYMBOL_INFO, *PSYMBOL_INFO;
typedef struct _SYMBOL_INFOW {
ULONG SizeOfStruct;
ULONG TypeIndex;
ULONG64 Reserved[2];
ULONG Index;
ULONG Size;
ULONG64 ModBase;
ULONG Flags;
ULONG64 Value;
ULONG64 Address;
ULONG Register;
ULONG Scope;
ULONG Tag;
ULONG NameLen;
ULONG MaxNameLen;
WCHAR Name[1];
} SYMBOL_INFOW, *PSYMBOL_INFOW;
typedef struct {
DWORD sizeofstruct;
WCHAR file[MAX_PATH + 1];
BOOL stripped;
DWORD timestamp;
DWORD size;
WCHAR dbgfile[MAX_PATH + 1];
WCHAR pdbfile[MAX_PATH + 1];
GUID guid;
DWORD sig;
DWORD age;
} SYMSRV_INDEX_INFOW, *PSYMSRV_INDEX_INFOW;
typedef struct {
DWORD sizeofstruct;
CHAR file[MAX_PATH + 1];
BOOL stripped;
DWORD timestamp;
DWORD size;
CHAR dbgfile[MAX_PATH + 1];
CHAR pdbfile[MAX_PATH + 1];
GUID guid;
DWORD sig;
DWORD age;
} SYMSRV_INDEX_INFO, *PSYMSRV_INDEX_INFO;
typedef struct _IMAGEHLP_SYMBOL {
DWORD SizeOfStruct;
DWORD Address;
DWORD Size;
DWORD Flags;
DWORD MaxNameLength;
CHAR Name[1];
} IMAGEHLP_SYMBOL, *PIMAGEHLP_SYMBOL;
typedef struct _IMAGEHLP_SYMBOL64 {
DWORD SizeOfStruct;
DWORD64 Address;
DWORD Size;
DWORD Flags;
DWORD MaxNameLength;
CHAR Name[1];
} IMAGEHLP_SYMBOL64, *PIMAGEHLP_SYMBOL64;
typedef struct _IMAGEHLP_SYMBOLW64 {
DWORD SizeOfStruct;
DWORD64 Address;
DWORD Size;
DWORD Flags;
DWORD MaxNameLength;
WCHAR Name[1];
} IMAGEHLP_SYMBOLW64, *PIMAGEHLP_SYMBOLW64;
typedef struct _IMAGEHLP_STACK_FRAME {
ULONG64 InstructionOffset;
ULONG64 ReturnOffset;
ULONG64 FrameOffset;
ULONG64 StackOffset;
ULONG64 BackingStoreOffset;
ULONG64 FuncTableEntry;
ULONG64 Params[4];
ULONG64 Reserved[5];
BOOL Virtual;
ULONG Reserved2;
} IMAGEHLP_STACK_FRAME, *PIMAGEHLP_STACK_FRAME;
/* SymRegisterCallbackProc* related */
// Anonyme in DbgHelp.h
enum _CBA_EVENT_SEVERITY {
sevInfo = 0,
sevProblem,
sevAttn,
sevFatal,
sevMax // unused
} CBA_EVENT_SEVERITY;
typedef struct _IMAGEHLP_CBA_EVENT {
CBA_EVENT_SEVERITY severity; // values from sevInfo to sevFatal
DWORD code; // numerical code IDs the error
PCHAR desc; // may contain a text description of the error
PVOID object; // value dependant upon the error code
} IMAGEHLP_CBA_EVENT, *PIMAGEHLP_CBA_EVENT;
typedef struct _IMAGEHLP_CBA_EVENTW {
CBA_EVENT_SEVERITY severity; // values from sevInfo to sevFatal
DWORD code; // numerical code IDs the error
PCWSTR desc; // may contain a text description of the error
PVOID object; // value dependant upon the error code
} IMAGEHLP_CBA_EVENTW, *PIMAGEHLP_CBA_EVENTW;
typedef struct _IMAGEHLP_CBA_READ_MEMORY {
DWORD64 addr; // address to read from
PVOID buf; // buffer to read to
DWORD bytes; // amount of bytes to read
DWORD *bytesread; // pointer to store amount of bytes read
} IMAGEHLP_CBA_READ_MEMORY, *PIMAGEHLP_CBA_READ_MEMORY;
typedef struct _IMAGEHLP_DEFERRED_SYMBOL_LOAD {
DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_DEFERRED_SYMBOL_LOAD)
DWORD BaseOfImage; // base load address of module
DWORD CheckSum; // checksum from the pe header
DWORD TimeDateStamp; // date/time stamp from pe header
CHAR FileName[MAX_PATH]; // symbols file or image name
BOOLEAN Reparse; // load failure reparse
HANDLE hFile; // file handle, if passed
} IMAGEHLP_DEFERRED_SYMBOL_LOAD, *PIMAGEHLP_DEFERRED_SYMBOL_LOAD;
typedef struct _IMAGEHLP_DEFERRED_SYMBOL_LOAD64 {
DWORD SizeOfStruct;
DWORD64 BaseOfImage;
DWORD CheckSum;
DWORD TimeDateStamp;
CHAR FileName[MAX_PATH];
BOOLEAN Reparse;
HANDLE hFile;
DWORD Flags;
} IMAGEHLP_DEFERRED_SYMBOL_LOAD64, *PIMAGEHLP_DEFERRED_SYMBOL_LOAD64;
typedef struct _IMAGEHLP_DEFERRED_SYMBOL_LOADW64 {
DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_DEFERRED_SYMBOL_LOADW64)
DWORD64 BaseOfImage; // base load address of module
DWORD CheckSum; // checksum from the pe header
DWORD TimeDateStamp; // date/time stamp from pe header
WCHAR FileName[MAX_PATH + 1]; // symbols file or image name
BOOLEAN Reparse; // load failure reparse
HANDLE hFile; // file handle, if passed
DWORD Flags; //
} IMAGEHLP_DEFERRED_SYMBOL_LOADW64, *PIMAGEHLP_DEFERRED_SYMBOL_LOADW64;
typedef struct _IMAGEHLP_DUPLICATE_SYMBOL64 {
DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_DUPLICATE_SYMBOL64)
DWORD NumberOfDups; // number of duplicates in the Symbol array
PIMAGEHLP_SYMBOL64 Symbol; // array of duplicate symbols
DWORD SelectedSymbol; // symbol selected (-1 to start)
} IMAGEHLP_DUPLICATE_SYMBOL64, *PIMAGEHLP_DUPLICATE_SYMBOL64;
typedef struct _IMAGEHLP_DUPLICATE_SYMBOL {
DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_DUPLICATE_SYMBOL)
DWORD NumberOfDups; // number of duplicates in the Symbol array
PIMAGEHLP_SYMBOL Symbol; // array of duplicate symbols
DWORD SelectedSymbol; // symbol selected (-1 to start)
} IMAGEHLP_DUPLICATE_SYMBOL, *PIMAGEHLP_DUPLICATE_SYMBOL;
/* StackWalk related structs */
typedef enum {
AddrMode1616,
AddrMode1632,
AddrModeReal,
AddrModeFlat
} ADDRESS_MODE;
typedef struct _tagADDRESS {
DWORD Offset;
WORD Segment;
ADDRESS_MODE Mode;
} ADDRESS, *LPADDRESS;
typedef struct _tagADDRESS64 {
DWORD64 Offset;
WORD Segment;
ADDRESS_MODE Mode;
} ADDRESS64, *LPADDRESS64;
typedef struct _KDHELP {
DWORD Thread;
DWORD ThCallbackStack;
DWORD NextCallback;
DWORD FramePointer;
DWORD KiCallUserMode;
DWORD KeUserCallbackDispatcher;
DWORD SystemRangeStart;
DWORD ThCallbackBStore;
DWORD KiUserExceptionDispatcher;
DWORD StackBase;
DWORD StackLimit;
DWORD Reserved[5];
} KDHELP, *PKDHELP;
typedef struct _KDHELP64 {
DWORD64 Thread;
DWORD ThCallbackStack;
DWORD ThCallbackBStore;
DWORD NextCallback;
DWORD FramePointer;
DWORD64 KiCallUserMode;
DWORD64 KeUserCallbackDispatcher;
DWORD64 SystemRangeStart;
DWORD64 KiUserExceptionDispatcher;
DWORD64 StackBase;
DWORD64 StackLimit;
DWORD BuildVersion;
DWORD RetpolineStubFunctionTableSize;
DWORD64 RetpolineStubFunctionTable;
DWORD RetpolineStubOffset;
DWORD RetpolineStubSize;
DWORD64 Reserved0[2];
} KDHELP64, *PKDHELP64;
typedef struct _tagSTACKFRAME {
ADDRESS AddrPC;
ADDRESS AddrReturn;
ADDRESS AddrFrame;
ADDRESS AddrStack;
PVOID FuncTableEntry;
DWORD Params[4];
BOOL Far;
BOOL Virtual;
DWORD Reserved[3];
KDHELP KdHelp;
ADDRESS AddrBStore;
} STACKFRAME, *LPSTACKFRAME;
typedef struct _tagSTACKFRAME64 {
ADDRESS64 AddrPC;
ADDRESS64 AddrReturn;
ADDRESS64 AddrFrame;
ADDRESS64 AddrStack;
ADDRESS64 AddrBStore;
PVOID FuncTableEntry;
DWORD64 Params[4];
BOOL Far;
BOOL Virtual;
DWORD64 Reserved[3];
KDHELP64 KdHelp;
} STACKFRAME64, *LPSTACKFRAME64;
typedef struct _tagSTACKFRAME_EX {
ADDRESS64 AddrPC;
ADDRESS64 AddrReturn;
ADDRESS64 AddrFrame;
ADDRESS64 AddrStack;
ADDRESS64 AddrBStore;
PVOID FuncTableEntry;
DWORD64 Params[4];
BOOL Far;
BOOL Virtual;
DWORD64 Reserved[3];
KDHELP64 KdHelp;
DWORD StackFrameSize;
DWORD InlineFrameContext;
} STACKFRAME_EX, *LPSTACKFRAME_EX;
@@ -627,15 +627,6 @@ typedef enum _SECURITY_IMPERSONATION_LEVEL {
SecurityDelegation
} SECURITY_IMPERSONATION_LEVEL, * PSECURITY_IMPERSONATION_LEVEL;
typedef enum _SC_ENUM_TYPE {
SC_ENUM_PROCESS_INFO = 0
} SC_ENUM_TYPE;
typedef enum _SC_STATUS_TYPE {
SC_STATUS_PROCESS_INFO = 0
} SC_STATUS_TYPE;
typedef enum _OBJECT_INFORMATION_CLASS {
ObjectBasicInformation = 0,
ObjectNameInformation = 1, /*NOT DOC*/
@@ -1836,42 +1827,6 @@ typedef struct _SECURITY_QUALITY_OF_SERVICE {
} SECURITY_QUALITY_OF_SERVICE, * PSECURITY_QUALITY_OF_SERVICE;
typedef struct _SERVICE_STATUS {
DWORD dwServiceType;
DWORD dwCurrentState;
DWORD dwControlsAccepted;
DWORD dwWin32ExitCode;
DWORD dwServiceSpecificExitCode;
DWORD dwCheckPoint;
DWORD dwWaitHint;
} SERVICE_STATUS, *LPSERVICE_STATUS;
typedef struct _SERVICE_STATUS_PROCESS {
DWORD dwServiceType;
DWORD dwCurrentState;
DWORD dwControlsAccepted;
DWORD dwWin32ExitCode;
DWORD dwServiceSpecificExitCode;
DWORD dwCheckPoint;
DWORD dwWaitHint;
DWORD dwProcessId;
DWORD dwServiceFlags;
} SERVICE_STATUS_PROCESS, *LPSERVICE_STATUS_PROCESS;
typedef struct _ENUM_SERVICE_STATUS_PROCESSA {
LPSTR lpServiceName;
LPSTR lpDisplayName;
SERVICE_STATUS_PROCESS ServiceStatusProcess;
} ENUM_SERVICE_STATUS_PROCESSA, *LPENUM_SERVICE_STATUS_PROCESSA;
typedef struct _ENUM_SERVICE_STATUS_PROCESSW {
LPWSTR lpServiceName;
LPWSTR lpDisplayName;
SERVICE_STATUS_PROCESS ServiceStatusProcess;
} ENUM_SERVICE_STATUS_PROCESSW, *LPENUM_SERVICE_STATUS_PROCESSW;
typedef struct CATALOG_INFO_
{
DWORD cbStruct;
+102 -90
View File
@@ -7,14 +7,9 @@ from contextlib import contextmanager
from windows import utils
import windows.generated_def as gdef
from windows.generated_def import *
from windows import security
SERVICE_TYPE = gdef.FlagMapper(SERVICE_KERNEL_DRIVER, SERVICE_FILE_SYSTEM_DRIVER, SERVICE_WIN32_OWN_PROCESS, SERVICE_WIN32_SHARE_PROCESS, SERVICE_INTERACTIVE_PROCESS)
SERVICE_STATE = gdef.FlagMapper(SERVICE_STOPPED, SERVICE_START_PENDING, SERVICE_STOP_PENDING, SERVICE_RUNNING, SERVICE_CONTINUE_PENDING, SERVICE_PAUSE_PENDING, SERVICE_PAUSED)
SERVICE_CONTROLE_ACCEPTED = gdef.FlagMapper()
SERVICE_FLAGS = gdef.FlagMapper(SERVICE_RUNS_IN_SYSTEM_PROCESS)
# TODO: RM :)
ServiceStatus = namedtuple("ServiceStatus", ["type", "state", "control_accepted", "flags"])
"""
``type`` might be one of:
@@ -42,94 +37,37 @@ ServiceStatus = namedtuple("ServiceStatus", ["type", "state", "control_accepted"
"""
class Service(object):
handle = None
def __repr__(self):
return '<{0} "{1}" {2}>'.format(type(self).__name__, self.name, self.status.state)
class ServiceManager(utils.AutoHandle):
_close_function = staticmethod(windows.winproxy.CloseServiceHandle)
@utils.fixedpropety
def name(self):
"""The name of the service
def _get_handle(self):
return windows.winproxy.OpenSCManagerA(dwDesiredAccess=gdef.MAXIMUM_ALLOWED)
:type: :class:`str`
"""
return self.lpServiceName
def open_service(self, name, access=gdef.MAXIMUM_ALLOWED):
return windows.winproxy.OpenServiceA(self.handle, name, access) # Check service exists :)
@utils.fixedpropety
def description(self):
"""The description of the service
def get_service(self, name, access=gdef.MAXIMUM_ALLOWED):
handle = self.open_service(name, access)
return NewService(name=name, handle=handle)
:type: :class:`str`
"""
return self.lpDisplayName
__getitem__ = get_service
@property
def status(self):
"""The status of the service
def get_service_display_name(self, name):
# This API is strange..
# Why can't we retrieve the display name for a service handle ?
BUFFER_SIZE = 0x1000
result = (CHAR * BUFFER_SIZE)()
size_needed = gdef.DWORD(BUFFER_SIZE)
windows.winproxy.GetServiceDisplayNameA(self.handle, name, result, size_needed)
return result.value
:type: :class:`ServiceStatus`
"""
status = self.ServiceStatusProcess
stype = SERVICE_TYPE[status.dwServiceType]
sstate = SERVICE_STATE[status.dwCurrentState]
scontrol = status.dwControlsAccepted
sflags = SERVICE_FLAGS[status.dwServiceFlags]
return ServiceStatus(stype, sstate, scontrol, sflags)
@utils.fixedpropety
def process(self):
"""The process running the service (if any)
:type: :class:`WinProcess <windows.winobject.process.WinProcess>` or ``None``
"""
pid = self.ServiceStatusProcess.dwProcessId
if not pid:
return None
l = windows.WinProcess(pid=pid)
return l
class ServiceA(Service, ENUM_SERVICE_STATUS_PROCESSA):
"""A Service object with ascii data"""
def start(self, args=None):
nbelt = 0
if args is not None:
if isinstance(args, basestring):
args = [args]
nbelt = len(args)
args = (gdef.LPCSTR * (nbelt))(*args)
with scmanagera(SC_MANAGER_CONNECT) as scm:
servh = windows.winproxy.OpenServiceA(scm, self.name, SERVICE_START)
windows.winproxy.StartServiceA(servh, nbelt, args)
windows.winproxy.CloseServiceHandle(servh)
def stop(self):
status = SERVICE_STATUS()
with scmanagera(SC_MANAGER_CONNECT) as scm:
servh = windows.winproxy.OpenServiceA(scm, self.name, SERVICE_STOP)
windows.winproxy.ControlService(servh, SERVICE_CONTROL_STOP, status)
windows.winproxy.CloseServiceHandle(servh)
return status
@contextmanager
def scmanagera(access):
# scmanager = windows.winproxy.OpenSCManagerA(dwDesiredAccess=SC_MANAGER_ENUMERATE_SERVICE)
scmanager = windows.winproxy.OpenSCManagerA(dwDesiredAccess=access)
try:
yield scmanager
finally:
windows.winproxy.CloseServiceHandle(scmanager)
def enumerate_services():
with scmanagera(SC_MANAGER_ENUMERATE_SERVICE) as scm:
size_needed = DWORD()
nb_services = DWORD()
counter = DWORD()
def _enumerate_services_generator(self):
size_needed = gdef.DWORD()
nb_services = gdef.DWORD()
counter = gdef.DWORD()
try:
windows.winproxy.EnumServicesStatusExA(scm, SC_ENUM_PROCESS_INFO, SERVICE_TYPE_ALL, SERVICE_STATE_ALL, None, 0, ctypes.byref(size_needed), ctypes.byref(nb_services), byref(counter), None)
windows.winproxy.EnumServicesStatusExA(self.handle, SC_ENUM_PROCESS_INFO, SERVICE_TYPE_ALL, SERVICE_STATE_ALL, None, 0, ctypes.byref(size_needed), ctypes.byref(nb_services), byref(counter), None)
except WindowsError:
pass
@@ -137,8 +75,82 @@ def enumerate_services():
size = size_needed.value
buffer = (BYTE * size)()
try:
windows.winproxy.EnumServicesStatusExA(scm, SC_ENUM_PROCESS_INFO, SERVICE_TYPE_ALL, SERVICE_STATE_ALL, buffer, size, ctypes.byref(size_needed), ctypes.byref(nb_services), byref(counter), None)
windows.winproxy.EnumServicesStatusExA(self.handle, SC_ENUM_PROCESS_INFO, SERVICE_TYPE_ALL, SERVICE_STATE_ALL, buffer, size, ctypes.byref(size_needed), ctypes.byref(nb_services), byref(counter), None)
except WindowsError as e:
continue
return_type = (ServiceA * nb_services.value)
return list(return_type.from_buffer(buffer))
break
services_array = (gdef.ENUM_SERVICE_STATUS_PROCESSA * nb_services.value).from_buffer(buffer)
for service_info in services_array:
shandle = self.open_service(service_info.lpServiceName)
yield NewService(handle=shandle, name=service_info.lpServiceName, description=service_info.lpDisplayName)
return
__iter__ = _enumerate_services_generator
def enumerate_services(self):
return list(self._enumerate_services_generator())
class NewService(gdef.SC_HANDLE):
# close_function = windows.winproxy.CloseServiceHandle
def __init__(self, handle, name, description=None):
super(NewService, self).__init__(handle)
self.name = name
"""The name of the service
:type: :class:`str`
"""
if description is not None:
self._description = description # Setup fixedpropety
@property
def description(self):
"""The description of the service
:type: :class:`str`
"""
return ServiceManager().get_service_display_name(self.name)
@property
def status(self):
buffer = windows.utils.BUFFER(gdef.SERVICE_STATUS_PROCESS)()
size_needed = gdef.DWORD()
windows.winproxy.QueryServiceStatusEx(self, gdef.SC_STATUS_PROCESS_INFO, buffer.cast(gdef.LPBYTE), ctypes.sizeof(buffer), size_needed)
return buffer[0]
@utils.fixedpropety
def process(self):
"""The process running the service (if any)
:type: :class:`WinProcess <windows.winobject.process.WinProcess>` or ``None``
"""
pid = self.status.dwProcessId
if not pid:
return None
l = windows.WinProcess(pid=pid)
return l
@property
def security_descriptor(self):
return security.SecurityDescriptor.from_service(self.name)
def start(self, args=None):
nbelt = 0
if args is not None:
if isinstance(args, basestring):
args = [args]
nbelt = len(args)
args = (gdef.LPCSTR * (nbelt))(*args)
return windows.winproxy.StartServiceA(self, nbelt, args)
def stop(self):
status = SERVICE_STATUS()
windows.winproxy.ControlService(self, gdef.SERVICE_CONTROL_STOP, status)
return status
def __repr__(self):
return """<{0} "{1}" {2}>""".format(type(self).__name__, self.name, self.status.state)
def __del__(self):
return windows.winproxy.CloseServiceHandle(self)
+2 -2
View File
@@ -61,12 +61,12 @@ class System(object):
"""
return volume.enum_logical_drive()
@property
@utils.fixedpropety
def services(self):
"""The list of services
:type: [:class:`~windows.winobject.service.ServiceA`] -- A list of Service"""
return service.enumerate_services()
return service.ServiceManager()
@property
def handles(self):
+20
View File
@@ -395,6 +395,26 @@ def ControlService(hService, dwControl, lpServiceStatus):
def CloseServiceHandle(hSCObject):
return CloseServiceHandle.ctypes_function(hSCObject)
@Advapi32Proxy()
def QueryServiceStatus(hService, lpServiceStatus):
return QueryServiceStatus.ctypes_function(hService, lpServiceStatus)
@Advapi32Proxy()
def QueryServiceStatusEx(hService, InfoLevel, lpBuffer, cbBufSize, pcbBytesNeeded):
return QueryServiceStatusEx.ctypes_function(hService, InfoLevel, lpBuffer, cbBufSize, pcbBytesNeeded)
@Advapi32Proxy()
def DeleteService(hService):
return DeleteService.ctypes_function(hService)
@Advapi32Proxy()
def GetServiceDisplayNameA(hSCManager, lpServiceName, lpDisplayName, lpcchBuffer):
return GetServiceDisplayNameA.ctypes_function(hSCManager, lpServiceName, lpDisplayName, lpcchBuffer)
@Advapi32Proxy()
def GetServiceDisplayNameW(hSCManager, lpServiceName, lpDisplayName, lpcchBuffer):
return GetServiceDisplayNameW.ctypes_function(hSCManager, lpServiceName, lpDisplayName, lpcchBuffer)
# Event log
@Advapi32Proxy()