diff --git a/ctypes_generation/definitions/defines/symbols.txt b/ctypes_generation/definitions/defines/symbols.txt index 8d5d0e7..f6356ae 100644 --- a/ctypes_generation/definitions/defines/symbols.txt +++ b/ctypes_generation/definitions/defines/symbols.txt @@ -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 \ No newline at end of file +#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 \ No newline at end of file diff --git a/ctypes_generation/definitions/functions/heap.txt b/ctypes_generation/definitions/functions/heap.txt new file mode 100644 index 0000000..58b3b4f --- /dev/null +++ b/ctypes_generation/definitions/functions/heap.txt @@ -0,0 +1,5 @@ +LPVOID HeapAlloc( + HANDLE hHeap, + DWORD dwFlags, + SIZE_T dwBytes +); diff --git a/ctypes_generation/definitions/functions/service.txt b/ctypes_generation/definitions/functions/service.txt index 33d97fe..643d66a 100644 --- a/ctypes_generation/definitions/functions/service.txt +++ b/ctypes_generation/definitions/functions/service.txt @@ -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 ); \ No newline at end of file diff --git a/ctypes_generation/definitions/functions/symbols.txt b/ctypes_generation/definitions/functions/symbols.txt index b841200..6d6cf13 100644 --- a/ctypes_generation/definitions/functions/symbols.txt +++ b/ctypes_generation/definitions/functions/symbols.txt @@ -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 ); \ No newline at end of file diff --git a/ctypes_generation/definitions/simple_types.txt b/ctypes_generation/definitions/simple_types.txt index 254f1d7..933536c 100644 --- a/ctypes_generation/definitions/simple_types.txt +++ b/ctypes_generation/definitions/simple_types.txt @@ -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 diff --git a/ctypes_generation/definitions/structures/service.txt b/ctypes_generation/definitions/structures/service.txt new file mode 100644 index 0000000..a0d1c99 --- /dev/null +++ b/ctypes_generation/definitions/structures/service.txt @@ -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; \ No newline at end of file diff --git a/ctypes_generation/definitions/structures/symbols.txt b/ctypes_generation/definitions/structures/symbols.txt index 669fb94..7c9cb81 100644 --- a/ctypes_generation/definitions/structures/symbols.txt +++ b/ctypes_generation/definitions/structures/symbols.txt @@ -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; \ No newline at end of file +} 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; \ No newline at end of file diff --git a/ctypes_generation/definitions/structures/winstruct.txt b/ctypes_generation/definitions/structures/winstruct.txt index 3b0fdbd..ad8dd6e 100644 --- a/ctypes_generation/definitions/structures/winstruct.txt +++ b/ctypes_generation/definitions/structures/winstruct.txt @@ -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; diff --git a/windows/winobject/service.py b/windows/winobject/service.py index ca97cfd..83246ab 100644 --- a/windows/winobject/service.py +++ b/windows/winobject/service.py @@ -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 ` 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)) \ No newline at end of file + 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 ` 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) diff --git a/windows/winobject/system.py b/windows/winobject/system.py index 62ef7d5..dbf87ea 100644 --- a/windows/winobject/system.py +++ b/windows/winobject/system.py @@ -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): diff --git a/windows/winproxy/apis/advapi32.py b/windows/winproxy/apis/advapi32.py index 6d5f464..9568663 100644 --- a/windows/winproxy/apis/advapi32.py +++ b/windows/winproxy/apis/advapi32.py @@ -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()