From 3cb8cc6f9e198d030a0150471cfda6526616d470 Mon Sep 17 00:00:00 2001 From: Clement Rouault Date: Wed, 23 Mar 2016 13:42:54 +0100 Subject: [PATCH] Refactor: new winobject directory --- ctypes_generation/winstruct.txt | 22 +- setup.py | 2 +- windows/__init__.py | 15 +- windows/debug.py | 23 +- windows/generated_def/winstructs.py | 25 +- windows/syswow64.py | 4 +- windows/test/__init__.py | 4 +- windows/test/mytest.py | 32 ++- windows/utils/winutils.py | 2 +- windows/winobject/__init__.py | 0 windows/{ => winobject}/exception.py | 0 windows/{ => winobject}/network.py | 0 .../{winobject.py => winobject/process.py} | 219 +----------------- windows/{ => winobject}/registry.py | 0 windows/{ => winobject}/service.py | 2 - windows/winobject/system.py | 191 +++++++++++++++ windows/{volumes.py => winobject/volume.py} | 0 windows/winobject/wingui.py | 51 ++++ windows/{ => winobject}/wmi.py | 0 19 files changed, 355 insertions(+), 237 deletions(-) create mode 100644 windows/winobject/__init__.py rename windows/{ => winobject}/exception.py (100%) rename windows/{ => winobject}/network.py (100%) rename windows/{winobject.py => winobject/process.py} (82%) rename windows/{ => winobject}/registry.py (100%) rename windows/{ => winobject}/service.py (98%) create mode 100644 windows/winobject/system.py rename windows/{volumes.py => winobject/volume.py} (100%) create mode 100644 windows/winobject/wingui.py rename windows/{ => winobject}/wmi.py (100%) diff --git a/ctypes_generation/winstruct.txt b/ctypes_generation/winstruct.txt index 0646d0b..c45408c 100644 --- a/ctypes_generation/winstruct.txt +++ b/ctypes_generation/winstruct.txt @@ -1777,4 +1777,24 @@ typedef struct _PUBLIC_OBJECT_BASIC_INFORMATION { ULONG HandleCount; ULONG PointerCount; ULONG Reserved[10]; - } PUBLIC_OBJECT_BASIC_INFORMATION, *PPUBLIC_OBJECT_BASIC_INFORMATION; \ No newline at end of file + } PUBLIC_OBJECT_BASIC_INFORMATION, *PPUBLIC_OBJECT_BASIC_INFORMATION; + + + typedef struct _EVENTLOGRECORD { + DWORD Length; + DWORD Reserved; + DWORD RecordNumber; + DWORD TimeGenerated; + DWORD TimeWritten; + DWORD EventID; + WORD EventType; + WORD NumStrings; + WORD EventCategory; + WORD ReservedFlags; + DWORD ClosingRecordNumber; + DWORD StringOffset; + DWORD UserSidLength; + DWORD UserSidOffset; + DWORD DataLength; + DWORD DataOffset; +} EVENTLOGRECORD, *PEVENTLOGRECORD; \ No newline at end of file diff --git a/setup.py b/setup.py index 80344e9..d56e159 100644 --- a/setup.py +++ b/setup.py @@ -14,5 +14,5 @@ setup( license = 'BSD', keywords = 'windows python', url = '', - packages = ['windows', 'windows.generated_def', 'windows.native_exec', 'windows.utils'], + packages = ['windows', 'windows.generated_def', 'windows.native_exec', 'windows.utils', 'windows.winobject'], ) \ No newline at end of file diff --git a/windows/__init__.py b/windows/__init__.py index 4e99e39..074ecb5 100644 --- a/windows/__init__.py +++ b/windows/__init__.py @@ -11,9 +11,12 @@ Exported: current_thread : :class:`windows.winobject.CurrentThread` """ -from . import winproxy -from .utils import VirtualProtected -from .winobject import System, CurrentProcess, CurrentThread +from windows import winproxy +from windows import winobject + +from winobject.system import System +from winobject.process import CurrentProcess, CurrentThread + system = System() current_process = CurrentProcess() @@ -26,18 +29,14 @@ del CurrentThread # Late import: other imports should go here # Do not move it: risk of circular import -import windows.exception -import windows.wmi import windows.utils import windows.debug -import windows.service import windows.wintrust -import windows.volumes +import windows.syswow64 __all__ = ["system", 'current_process', 'current_thread'] import os - if bool(os.environ.get("SPHINX_BUILD", 0)): # I know it's shameful # But it's the only way I can think of right now to get a full class diff --git a/windows/debug.py b/windows/debug.py index 068cb77..35da3e4 100644 --- a/windows/debug.py +++ b/windows/debug.py @@ -2,15 +2,18 @@ import os.path from collections import defaultdict import windows +import windows.winobject.exception as winexception import windows.native_exec.simple_x86 as x86 import windows.native_exec.simple_x64 as x64 -from windows.winobject import WinProcess, WinThread +from windows.winobject.process import WinProcess, WinThread from windows.dbgprint import dbgprint from windows import winproxy from windows.generated_def.winstructs import * from .generated_def import windef -from windows.exception import VectoredException + + +from windows.winobject.exception import VectoredException @@ -245,9 +248,9 @@ class Debugger(object): self._update_debugger_state(debug_event) if windows.current_process.bitness == 32: - exception.__class__ = windows.exception.EEXCEPTION_DEBUG_INFO32 + exception.__class__ = winexception.EEXCEPTION_DEBUG_INFO32 else: - exception.__class__ = windows.exception.EEXCEPTION_DEBUG_INFO64 + exception.__class__ = winexception.EEXCEPTION_DEBUG_INFO64 excp_code = exception.ExceptionRecord.ExceptionCode excp_addr = exception.ExceptionRecord.ExceptionAddress @@ -428,7 +431,7 @@ class Debugger(object): The default behaviour is to return ``DBG_CONTINUE`` for the known exception code and ``DBG_EXCEPTION_NOT_HANDLED`` else """ - if not exception.ExceptionRecord.ExceptionCode in windows.exception.exception_name_by_value: + if not exception.ExceptionRecord.ExceptionCode in winexception.exception_name_by_value: return DBG_EXCEPTION_NOT_HANDLED return DBG_CONTINUE @@ -510,9 +513,9 @@ class LocalDebugger(object): self._reput_breakpoint = {} self._hxbp_breakpoint = defaultdict(dict) - self.callback_vectored = VectoredException(self.callback) + self.callback_vectored = winexception.VectoredException(self.callback) winproxy.AddVectoredExceptionHandler(0, self.callback_vectored) - self.setup_hxbp_callback_vectored = VectoredException(self.setup_hxbp_callback) + self.setup_hxbp_callback_vectored = winexception.VectoredException(self.setup_hxbp_callback) self.hxbp_info = None self.code = windows.native_exec.create_function("\xcc\xc3", [PVOID]) self.veh_depth = 0 @@ -590,7 +593,7 @@ class LocalDebugger(object): """Called on exception""" print(self.get_exception_code()) windows.current_process.exit() - if not self.get_exception_code() in windows.exception.exception_name_by_value: + if not self.get_exception_code() in winexception.exception_name_by_value: return windef.EXCEPTION_CONTINUE_SEARCH return windef.EXCEPTION_CONTINUE_EXECUTION @@ -710,7 +713,7 @@ class LocalDebugger(object): return self.data = addr - with windows.exception.VectoredExceptionHandler(1, self.setup_hxbp_callback): + with winexception.VectoredExceptionHandler(1, self.setup_hxbp_callback): x = self.code() if x is None: raise ValueError("Could not setup HXBP") @@ -733,7 +736,7 @@ class LocalDebugger(object): raise ValueError("Could not setup HXBP") return self.data = addr - with windows.exception.VectoredExceptionHandler(1, self.remove_hxbp_callback): + with winexception.VectoredExceptionHandler(1, self.remove_hxbp_callback): x = self.code() if x is None: raise ValueError("Could not remove HXBP") diff --git a/windows/generated_def/winstructs.py b/windows/generated_def/winstructs.py index 969e88c..f6a63b4 100644 --- a/windows/generated_def/winstructs.py +++ b/windows/generated_def/winstructs.py @@ -51,7 +51,7 @@ HCRYPTMSG = PVOID PALPC_PORT_ATTRIBUTES = PVOID VOID = DWORD -structs = ['_LIST_ENTRY', '_PEB_LDR_DATA', '_LSA_UNICODE_STRING', '_RTL_USER_PROCESS_PARAMETERS', '_PEB', '_SECURITY_ATTRIBUTES', '_SYSTEM_VERIFIER_INFORMATION', '_LDR_DATA_TABLE_ENTRY', '_IMAGE_FILE_HEADER', '_IMAGE_DATA_DIRECTORY', '_IMAGE_SECTION_HEADER', '_IMAGE_OPTIONAL_HEADER64', '_IMAGE_OPTIONAL_HEADER', '_IMAGE_NT_HEADERS64', '_IMAGE_NT_HEADERS', '_IMAGE_IMPORT_DESCRIPTOR', '_IMAGE_IMPORT_BY_NAME', '_IMAGE_EXPORT_DIRECTORY', '_MEMORY_BASIC_INFORMATION', '_MEMORY_BASIC_INFORMATION32', '_MEMORY_BASIC_INFORMATION64', '_STARTUPINFOA', '_STARTUPINFOW', '_PROCESS_INFORMATION', '_FLOATING_SAVE_AREA', '_CONTEXT32', '_WOW64_FLOATING_SAVE_AREA', '_WOW64_CONTEXT', '_M128A', '_CONTEXT64', 'tagPROCESSENTRY32W', 'tagPROCESSENTRY32', 'tagTHREADENTRY32', '_LUID', '_LUID_AND_ATTRIBUTES', '_TOKEN_PRIVILEGES', '_TOKEN_ELEVATION', '_SID_AND_ATTRIBUTES', '_TOKEN_MANDATORY_LABEL', '_TOKEN_USER', '_OSVERSIONINFOA', '_OSVERSIONINFOW', '_OSVERSIONINFOEXA', '_OSVERSIONINFOEXW', '_OVERLAPPED', '_MIB_TCPROW_OWNER_PID', '_MIB_TCPTABLE_OWNER_PID', '_MIB_UDPROW_OWNER_PID', '_MIB_UDPTABLE_OWNER_PID', '_MIB_UDP6ROW_OWNER_PID', '_MIB_UDP6TABLE_OWNER_PID', '_MIB_TCP6ROW_OWNER_PID', '_MIB_TCP6TABLE_OWNER_PID', '_MIB_TCPROW', '_EXCEPTION_RECORD', '_EXCEPTION_RECORD32', '_EXCEPTION_RECORD64', '_EXCEPTION_POINTERS64', '_EXCEPTION_POINTERS32', '_DEBUG_PROCESSOR_IDENTIFICATION_ALPHA', '_DEBUG_PROCESSOR_IDENTIFICATION_AMD64', '_DEBUG_PROCESSOR_IDENTIFICATION_IA64', '_DEBUG_PROCESSOR_IDENTIFICATION_X86', '_DEBUG_PROCESSOR_IDENTIFICATION_ARM', '_DEBUG_PROCESSOR_IDENTIFICATION_ALL', '_SYMBOL_INFO', '_MODLOAD_DATA', '_SYSTEM_MODULE32', '_SYSTEM_MODULE64', '_SYSTEM_MODULE_INFORMATION32', '_SYSTEM_MODULE_INFORMATION64', 'tagSAFEARRAYBOUND', 'tagSAFEARRAY', '_DEBUG_BREAKPOINT_PARAMETERS', '_DEBUG_REGISTER_DESCRIPTION', '_DEBUG_STACK_FRAME', '_DEBUG_LAST_EVENT_INFO_BREAKPOINT', '_DEBUG_LAST_EVENT_INFO_EXCEPTION', '_DEBUG_LAST_EVENT_INFO_EXIT_THREAD', '_DEBUG_LAST_EVENT_INFO_EXIT_PROCESS', '_DEBUG_LAST_EVENT_INFO_LOAD_MODULE', '_DEBUG_LAST_EVENT_INFO_UNLOAD_MODULE', '_DEBUG_LAST_EVENT_INFO_SYSTEM_ERROR', '_DEBUG_SPECIFIC_FILTER_PARAMETERS', '_DEBUG_EXCEPTION_FILTER_PARAMETERS', '_GUID', '_CRYPTOAPI_BLOB', 'WINTRUST_FILE_INFO_', '_CRYPT_ATTRIBUTE', '_CTL_ENTRY', '_CRYPT_ATTRIBUTE', '_CRYPT_ATTRIBUTES', '_CRYPT_ALGORITHM_IDENTIFIER', '_CMSG_SIGNER_INFO', '_CERT_EXTENSION', '_CTL_USAGE', '_CTL_INFO', '_CTL_CONTEXT', 'WINTRUST_CATALOG_INFO_', 'WINTRUST_BLOB_INFO_', '_CRYPT_BIT_BLOB', '_CERT_PUBLIC_KEY_INFO', '_CERT_INFO', '_CERT_CONTEXT', 'WINTRUST_SGNR_INFO_', '_FILETIME', 'WINTRUST_CERT_INFO_', '_TMP_WINTRUST_UNION_TYPE', '_WINTRUST_DATA', '_PROCESS_BASIC_INFORMATION', '_JIT_DEBUG_INFO', '_SID_IDENTIFIER_AUTHORITY', '_EXCEPTION_DEBUG_INFO', '_CREATE_THREAD_DEBUG_INFO', '_CREATE_PROCESS_DEBUG_INFO', '_EXIT_THREAD_DEBUG_INFO', '_EXIT_PROCESS_DEBUG_INFO', '_LOAD_DLL_DEBUG_INFO', '_UNLOAD_DLL_DEBUG_INFO', '_OUTPUT_DEBUG_STRING_INFO', '_RIP_INFO', '_TMP_UNION_DEBUG_INFO', '_DEBUG_EVENT', '_STRING', '_OBJECT_ATTRIBUTES', '_SECURITY_QUALITY_OF_SERVICE', '_ALPC_PORT_ATTRIBUTES32', '_ALPC_PORT_ATTRIBUTES64', '_ALPC_MESSAGE_ATTRIBUTES', '_PORT_MESSAGE_TMP_UNION', '_PORT_MESSAGE_TMP_SUBSTRUCT_S1', '_PORT_MESSAGE_TMP_UNION_U1', '_PORT_MESSAGE_TMP_SUBSTRUCT_S2', '_PORT_MESSAGE_TMP_UNION_U2', '_PORT_MESSAGE', '_SERVICE_STATUS', '_SERVICE_STATUS_PROCESS', '_ENUM_SERVICE_STATUS_PROCESSA', '_ENUM_SERVICE_STATUS_PROCESSW', 'CATALOG_INFO_', '_SYSTEM_HANDLE', '_SYSTEM_HANDLE_INFORMATION', '__PUBLIC_OBJECT_TYPE_INFORMATION', '_PUBLIC_OBJECT_BASIC_INFORMATION'] +structs = ['_LIST_ENTRY', '_PEB_LDR_DATA', '_LSA_UNICODE_STRING', '_RTL_USER_PROCESS_PARAMETERS', '_PEB', '_SECURITY_ATTRIBUTES', '_SYSTEM_VERIFIER_INFORMATION', '_LDR_DATA_TABLE_ENTRY', '_IMAGE_FILE_HEADER', '_IMAGE_DATA_DIRECTORY', '_IMAGE_SECTION_HEADER', '_IMAGE_OPTIONAL_HEADER64', '_IMAGE_OPTIONAL_HEADER', '_IMAGE_NT_HEADERS64', '_IMAGE_NT_HEADERS', '_IMAGE_IMPORT_DESCRIPTOR', '_IMAGE_IMPORT_BY_NAME', '_IMAGE_EXPORT_DIRECTORY', '_MEMORY_BASIC_INFORMATION', '_MEMORY_BASIC_INFORMATION32', '_MEMORY_BASIC_INFORMATION64', '_STARTUPINFOA', '_STARTUPINFOW', '_PROCESS_INFORMATION', '_FLOATING_SAVE_AREA', '_CONTEXT32', '_WOW64_FLOATING_SAVE_AREA', '_WOW64_CONTEXT', '_M128A', '_CONTEXT64', 'tagPROCESSENTRY32W', 'tagPROCESSENTRY32', 'tagTHREADENTRY32', '_LUID', '_LUID_AND_ATTRIBUTES', '_TOKEN_PRIVILEGES', '_TOKEN_ELEVATION', '_SID_AND_ATTRIBUTES', '_TOKEN_MANDATORY_LABEL', '_TOKEN_USER', '_OSVERSIONINFOA', '_OSVERSIONINFOW', '_OSVERSIONINFOEXA', '_OSVERSIONINFOEXW', '_OVERLAPPED', '_MIB_TCPROW_OWNER_PID', '_MIB_TCPTABLE_OWNER_PID', '_MIB_UDPROW_OWNER_PID', '_MIB_UDPTABLE_OWNER_PID', '_MIB_UDP6ROW_OWNER_PID', '_MIB_UDP6TABLE_OWNER_PID', '_MIB_TCP6ROW_OWNER_PID', '_MIB_TCP6TABLE_OWNER_PID', '_MIB_TCPROW', '_EXCEPTION_RECORD', '_EXCEPTION_RECORD32', '_EXCEPTION_RECORD64', '_EXCEPTION_POINTERS64', '_EXCEPTION_POINTERS32', '_DEBUG_PROCESSOR_IDENTIFICATION_ALPHA', '_DEBUG_PROCESSOR_IDENTIFICATION_AMD64', '_DEBUG_PROCESSOR_IDENTIFICATION_IA64', '_DEBUG_PROCESSOR_IDENTIFICATION_X86', '_DEBUG_PROCESSOR_IDENTIFICATION_ARM', '_DEBUG_PROCESSOR_IDENTIFICATION_ALL', '_SYMBOL_INFO', '_MODLOAD_DATA', '_SYSTEM_MODULE32', '_SYSTEM_MODULE64', '_SYSTEM_MODULE_INFORMATION32', '_SYSTEM_MODULE_INFORMATION64', 'tagSAFEARRAYBOUND', 'tagSAFEARRAY', '_DEBUG_BREAKPOINT_PARAMETERS', '_DEBUG_REGISTER_DESCRIPTION', '_DEBUG_STACK_FRAME', '_DEBUG_LAST_EVENT_INFO_BREAKPOINT', '_DEBUG_LAST_EVENT_INFO_EXCEPTION', '_DEBUG_LAST_EVENT_INFO_EXIT_THREAD', '_DEBUG_LAST_EVENT_INFO_EXIT_PROCESS', '_DEBUG_LAST_EVENT_INFO_LOAD_MODULE', '_DEBUG_LAST_EVENT_INFO_UNLOAD_MODULE', '_DEBUG_LAST_EVENT_INFO_SYSTEM_ERROR', '_DEBUG_SPECIFIC_FILTER_PARAMETERS', '_DEBUG_EXCEPTION_FILTER_PARAMETERS', '_GUID', '_CRYPTOAPI_BLOB', 'WINTRUST_FILE_INFO_', '_CRYPT_ATTRIBUTE', '_CTL_ENTRY', '_CRYPT_ATTRIBUTE', '_CRYPT_ATTRIBUTES', '_CRYPT_ALGORITHM_IDENTIFIER', '_CMSG_SIGNER_INFO', '_CERT_EXTENSION', '_CTL_USAGE', '_CTL_INFO', '_CTL_CONTEXT', 'WINTRUST_CATALOG_INFO_', 'WINTRUST_BLOB_INFO_', '_CRYPT_BIT_BLOB', '_CERT_PUBLIC_KEY_INFO', '_CERT_INFO', '_CERT_CONTEXT', 'WINTRUST_SGNR_INFO_', '_FILETIME', 'WINTRUST_CERT_INFO_', '_TMP_WINTRUST_UNION_TYPE', '_WINTRUST_DATA', '_PROCESS_BASIC_INFORMATION', '_JIT_DEBUG_INFO', '_SID_IDENTIFIER_AUTHORITY', '_EXCEPTION_DEBUG_INFO', '_CREATE_THREAD_DEBUG_INFO', '_CREATE_PROCESS_DEBUG_INFO', '_EXIT_THREAD_DEBUG_INFO', '_EXIT_PROCESS_DEBUG_INFO', '_LOAD_DLL_DEBUG_INFO', '_UNLOAD_DLL_DEBUG_INFO', '_OUTPUT_DEBUG_STRING_INFO', '_RIP_INFO', '_TMP_UNION_DEBUG_INFO', '_DEBUG_EVENT', '_STRING', '_OBJECT_ATTRIBUTES', '_SECURITY_QUALITY_OF_SERVICE', '_ALPC_PORT_ATTRIBUTES32', '_ALPC_PORT_ATTRIBUTES64', '_ALPC_MESSAGE_ATTRIBUTES', '_PORT_MESSAGE_TMP_UNION', '_PORT_MESSAGE_TMP_SUBSTRUCT_S1', '_PORT_MESSAGE_TMP_UNION_U1', '_PORT_MESSAGE_TMP_SUBSTRUCT_S2', '_PORT_MESSAGE_TMP_UNION_U2', '_PORT_MESSAGE', '_SERVICE_STATUS', '_SERVICE_STATUS_PROCESS', '_ENUM_SERVICE_STATUS_PROCESSA', '_ENUM_SERVICE_STATUS_PROCESSW', 'CATALOG_INFO_', '_SYSTEM_HANDLE', '_SYSTEM_HANDLE_INFORMATION', '__PUBLIC_OBJECT_TYPE_INFORMATION', '_PUBLIC_OBJECT_BASIC_INFORMATION', '_EVENTLOGRECORD'] enums = ['_SYSTEM_INFORMATION_CLASS', '_MEMORY_INFORMATION_CLASS', '_THREAD_INFORMATION_CLASS', '_TCP_TABLE_CLASS', '_VARENUM', '_UDP_TABLE_CLASS', '_MIB_TCP_STATE', '_TOKEN_INFORMATION_CLASS', '_SECURITY_IMPERSONATION_LEVEL', '_SC_ENUM_TYPE', '_SC_STATUS_TYPE', '_OBJECT_INFORMATION_CLASS', '_SID_NAME_USE', '_IMAGEHLP_SYMBOL_TYPE_INFO', '_PROCESSINFOCLASS'] @@ -2337,3 +2337,26 @@ class _PUBLIC_OBJECT_BASIC_INFORMATION(Structure): PUBLIC_OBJECT_BASIC_INFORMATION = _PUBLIC_OBJECT_BASIC_INFORMATION PPUBLIC_OBJECT_BASIC_INFORMATION = POINTER(_PUBLIC_OBJECT_BASIC_INFORMATION) +# Struct _EVENTLOGRECORD definitions +class _EVENTLOGRECORD(Structure): + _fields_ = [ + ("Length", DWORD), + ("Reserved", DWORD), + ("RecordNumber", DWORD), + ("TimeGenerated", DWORD), + ("TimeWritten", DWORD), + ("EventID", DWORD), + ("EventType", WORD), + ("NumStrings", WORD), + ("EventCategory", WORD), + ("ReservedFlags", WORD), + ("ClosingRecordNumber", DWORD), + ("StringOffset", DWORD), + ("UserSidLength", DWORD), + ("UserSidOffset", DWORD), + ("DataLength", DWORD), + ("DataOffset", DWORD), + ] +PEVENTLOGRECORD = POINTER(_EVENTLOGRECORD) +EVENTLOGRECORD = _EVENTLOGRECORD + diff --git a/windows/syswow64.py b/windows/syswow64.py index cf90f5d..4044225 100644 --- a/windows/syswow64.py +++ b/windows/syswow64.py @@ -185,7 +185,7 @@ def get_current_process_syswow_peb(): winproxy.NtWow64ReadVirtualMemory64(current_process.handle, addr, buffer_addr, size) return buffer_addr[:] peb_addr = get_current_process_syswow_peb_addr() - return windows.winobject.RemotePEB64(peb_addr, CurrentProcessReadSyswow()) + return windows.winobject.process.RemotePEB64(peb_addr, CurrentProcessReadSyswow()) class ReadSyswow64Process(object): @@ -285,7 +285,7 @@ def NtQueryVirtualMemory_32_to_64(ProcessHandle, BaseAddress, MemoryInformationC @Syswow64ApiProxy(winproxy.NtGetContextThread) def NtGetContextThread_32_to_64(hThread, lpContext): - if type(lpContext) == windows.exception.ECONTEXT64: + if type(lpContext) == windows.winobject.exception.ECONTEXT64: lpContext = byref(lpContext) return NtGetContextThread_32_to_64.ctypes_function(hThread, lpContext) diff --git a/windows/test/__init__.py b/windows/test/__init__.py index 8937c54..83ef26d 100644 --- a/windows/test/__init__.py +++ b/windows/test/__init__.py @@ -1,3 +1,3 @@ -from mytest import WindowsTestCase, WindowsAPITestCase, DebuggerTestCase, NativeUtilsTestCase, pop_calc_32, pop_calc_64, Calc32, Calc64 +from mytest import WindowsTestCase, WindowsAPITestCase, DebuggerTestCase, NativeUtilsTestCase, SystemTestCase, pop_calc_32, pop_calc_64, Calc32, Calc64 -__all__ = ["WindowsTestCase", "WindowsAPITestCase", "DebuggerTestCase", "NativeUtilsTestCase"] +__all__ = ["SystemTestCase", "WindowsTestCase", "WindowsAPITestCase", "DebuggerTestCase", "NativeUtilsTestCase"] diff --git a/windows/test/mytest.py b/windows/test/mytest.py index 4dda20a..68df352 100644 --- a/windows/test/mytest.py +++ b/windows/test/mytest.py @@ -57,7 +57,8 @@ def Calc64(dwCreationFlags=0, exit_code=0): calc = pop_calc_64(dwCreationFlags) yield calc finally: - calc.exit(exit_code) + if "calc" in locals(): + calc.exit(exit_code) @contextmanager def Calc32(dwCreationFlags=0, exit_code=0): @@ -65,7 +66,33 @@ def Calc32(dwCreationFlags=0, exit_code=0): calc = pop_calc_32(dwCreationFlags) yield calc finally: - calc.exit(exit_code) + if "calc" in locals(): + calc.exit(exit_code) + +class SystemTestCase(unittest.TestCase): + def test_version(self): + return windows.system.version + + def test_version_name(self): + return windows.system.version_name + + def test_computer_name(self): + return windows.system.computer_name + + def test_services(self): + return windows.system.services + + def test_logicaldrives(self): + return windows.system.logicaldrives + + def test_processes(self): + return windows.system.processes + + def test_threads(self): + return windows.system.threads + + def test_wmi(self): + return windows.system.wmi.select("Win32_Process", "*") class WindowsTestCase(unittest.TestCase): @@ -732,6 +759,7 @@ class DebuggerTestCase(unittest.TestCase): if __name__ == '__main__': alltests = unittest.TestSuite() + alltests.addTest(unittest.makeSuite(SystemTestCase)) alltests.addTest(unittest.makeSuite(WindowsTestCase)) alltests.addTest(unittest.makeSuite(WindowsAPITestCase)) alltests.addTest(unittest.makeSuite(DebuggerTestCase)) diff --git a/windows/utils/winutils.py b/windows/utils/winutils.py index c224367..10d7e20 100644 --- a/windows/utils/winutils.py +++ b/windows/utils/winutils.py @@ -83,7 +83,7 @@ def create_process(path, args=None, dwCreationFlags=0, show_windows=False): if args: lpCommandLine = (" ".join([str(a) for a in args])) windows.winproxy.CreateProcessA(path, lpCommandLine=lpCommandLine, dwCreationFlags=dwCreationFlags, lpProcessInformation=ctypes.byref(proc_info), lpStartupInfo=lpStartupInfo) - return windows.winobject.WinProcess(pid=proc_info.dwProcessId, handle=proc_info.hProcess) + return windows.winobject.process.WinProcess(pid=proc_info.dwProcessId, handle=proc_info.hProcess) def enable_privilege(lpszPrivilege, bEnablePrivilege): diff --git a/windows/winobject/__init__.py b/windows/winobject/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/windows/exception.py b/windows/winobject/exception.py similarity index 100% rename from windows/exception.py rename to windows/winobject/exception.py diff --git a/windows/network.py b/windows/winobject/network.py similarity index 100% rename from windows/network.py rename to windows/winobject/network.py diff --git a/windows/winobject.py b/windows/winobject/process.py similarity index 82% rename from windows/winobject.py rename to windows/winobject/process.py index ad1df0b..1a4d17b 100644 --- a/windows/winobject.py +++ b/windows/winobject/process.py @@ -8,28 +8,20 @@ import itertools from contextlib import contextmanager import windows -import windows.network -import windows.registry -import windows.syswow64 -import windows.exception -import windows.service -import windows.volumes -import windows.wmi - -import windows.injection as injection -import windows.native_exec as native_exec import windows.native_exec.simple_x86 as x86 import windows.native_exec.simple_x64 as x64 -from windows import winproxy -from . import utils +from windows import injection +from windows import native_exec +from windows import pe_parse +from windows import winproxy +from windows import utils from windows.dbgprint import dbgprint from windows.generated_def.winstructs import * from windows.generated_def.ntstatus import NtStatusException -from .generated_def import windef - -import windows.pe_parse as pe_parse +from windows.generated_def import windef +from windows.winobject import exception class AutoHandle(object): """An abstract class that allow easy handle creation/destruction/wait""" @@ -63,193 +55,6 @@ class AutoHandle(object): self._close_function(self._handle) -class System(object): - """Represent the current ``Windows`` system ``Python`` is running on""" - - network = windows.network.Network() # Object of class :class:`windows.network.Network` - registry = windows.registry.Registry() # Object of class :class:`windows.registry.Registry` - - @property - def processes(self): - """The list of running processes - - :type: [:class:`WinProcess`] -- A list of Process - """ - return self.enumerate_processes() - - @property - def threads(self): - """The list of running threads - - :type: [:class:`WinThread`] -- A list of Thread - """ - return self.enumerate_threads() - - @property - def logicaldrives(self): - return windows.volumes.enum_logical_drive() - - @property - def services(self): - """The list of services (TODO: BETTER DOC)""" - return windows.service.enumerate_services() - - #@property - #def handles(self): - # size_needed = ULONG() - # size = 0x1000 - # buffer = ctypes.c_buffer(size) - # - # try: - # winproxy.NtQuerySystemInformation(16, buffer, size, ReturnLength=ctypes.byref(size_needed)) - # except WindowsError as e: - # pass - # - # size = size_needed.value + 0x1000 - # buffer = ctypes.c_buffer(size) - # winproxy.NtQuerySystemInformation(16, buffer, size, ReturnLength=ctypes.byref(size_needed)) - # - # x = SYSTEM_HANDLE_INFORMATION.from_buffer(buffer) - # - # class _GENERATED_SYSTEM_HANDLE_INFORMATION(ctypes.Structure): - # _fields_ = [ - # ("HandleCount", ULONG), - # ("Handles", SYSTEM_HANDLE * x.HandleCount), - # ] - # return _GENERATED_SYSTEM_HANDLE_INFORMATION.from_buffer_copy(buffer[:size_needed.value]).Handles[:] - - @utils.fixedpropety - def bitness(self): - """The bitness of the system - - :type: :class:`int` -- 32 or 64 - """ - if os.environ["PROCESSOR_ARCHITECTURE"].lower() != "x86": - return 64 - if "PROCESSOR_ARCHITEW6432" in os.environ: - return 64 - return 32 - - @utils.fixedpropety - def wmi(self): - return windows.wmi.WmiRequester() - - @utils.fixedpropety - def computer_name(self): - size = DWORD(0x1000) - buf = ctypes.c_buffer(size.value) - winproxy.GetComputerNameA(buf, ctypes.byref(size)) - return buf[:size.value] - - @staticmethod - def enumerate_processes(): - process_entry = WinProcess() - process_entry.dwSize = ctypes.sizeof(process_entry) - snap = winproxy.CreateToolhelp32Snapshot(windef.TH32CS_SNAPPROCESS, 0) - winproxy.Process32First(snap, process_entry) - res = [] - res.append(utils.swallow_ctypes_copy(process_entry)) - while winproxy.Process32Next(snap, process_entry): - res.append(utils.swallow_ctypes_copy(process_entry)) - return res - - @staticmethod - def enumerate_processes(): - process_entry = PROCESSENTRY32() - process_entry.dwSize = ctypes.sizeof(process_entry) - snap = winproxy.CreateToolhelp32Snapshot(windef.TH32CS_SNAPPROCESS, 0) - winproxy.Process32First(snap, process_entry) - res = [] - res.append(WinProcess._from_PROCESSENTRY32(process_entry)) - while winproxy.Process32Next(snap, process_entry): - res.append(WinProcess._from_PROCESSENTRY32(process_entry)) - return res - - @staticmethod - def enumerate_threads(): - thread_entry = WinThread() - thread_entry.dwSize = ctypes.sizeof(thread_entry) - snap = winproxy.CreateToolhelp32Snapshot(windef.TH32CS_SNAPTHREAD, 0) - threads = [] - winproxy.Thread32First(snap, thread_entry) - threads.append(copy.copy(thread_entry)) - while winproxy.Thread32Next(snap, thread_entry): - threads.append(copy.copy(thread_entry)) - return threads - - @utils.fixedpropety - def version(self): - data = self.get_version() - result = data.dwMajorVersion, data.dwMinorVersion - if result == (6,2): - result_str = self.get_file_version("kernel32") - result_tup = [int(x) for x in result_str.split(".")] - result = tuple(result_tup[:2]) - return result - - @utils.fixedpropety - def version_name(self): - version = self.version - is_workstation = self.product_type == VER_NT_WORKSTATION - if version == (10, 0): - return ["Windows Server 2016, ""Windows 10"][is_workstation] - elif version == (6, 3): - return ["Windows Server 2012 R2", "Windows 8.1"][is_workstation] - elif version == (6, 2): - return ["Windows Server 2012", "Windows 8"][is_workstation] - elif version == (6, 1): - return ["Windows Server 2008 R2", "Windows 7"][is_workstation] - elif version == (6, 0): - return ["Windows Server 2008", "Windows Vista"][is_workstation] - elif version == (5, 2): - metric = winproxy.GetSystemMetrics(SM_SERVERR2) - if is_workstation: - if self.bitness == 64: - return "Windows XP Professional x64 Edition" - else: - return "TODO: version (5.2) + is_workstation + bitness == 32" - elif metric != 0: - return "Windows Server 2003 R2" - else: - return "Windows Server 2003" - elif version == (5, 1): - return "Windows XP" - elif version == (5, 0): - return "Windows 2000" - else: - return "Unknow Windows ".format(version, is_workstation) - - @utils.fixedpropety - def product_type(self): - version_map = {x:x for x in [VER_NT_WORKSTATION, VER_NT_DOMAIN_CONTROLLER, VER_NT_SERVER]} - version = self.get_version() - return version_map.get(version.wProductType, version.wProductType) - - - def get_version(self): - data = windows.generated_def.OSVERSIONINFOEXA() - data.dwOSVersionInfoSize = ctypes.sizeof(data) - windows.winproxy.GetVersionExA(ctypes.cast(ctypes.pointer(data), ctypes.POINTER(windows.generated_def.OSVERSIONINFOA))) - return data - - - def get_file_version(self, name): - size = winproxy.GetFileVersionInfoSizeA(name) - buf = ctypes.c_buffer(size) - winproxy.GetFileVersionInfoA(name, 0, size, buf) - - bufptr = PVOID() - bufsize = UINT() - winproxy.VerQueryValueA(buf, "\\VarFileInfo\\Translation", ctypes.byref(bufptr), ctypes.byref(bufsize)) - bufstr = ctypes.cast(bufptr, LPCSTR) - tup = struct.unpack("".format(version, is_workstation) + + @utils.fixedpropety + def product_type(self): + version_map = {x:x for x in [VER_NT_WORKSTATION, VER_NT_DOMAIN_CONTROLLER, VER_NT_SERVER]} + version = self.get_version() + return version_map.get(version.wProductType, version.wProductType) + + def get_version(self): + data = windows.generated_def.OSVERSIONINFOEXA() + data.dwOSVersionInfoSize = ctypes.sizeof(data) + winproxy.GetVersionExA(ctypes.cast(ctypes.pointer(data), ctypes.POINTER(windows.generated_def.OSVERSIONINFOA))) + return data + + def get_file_version(self, name): + size = winproxy.GetFileVersionInfoSizeA(name) + buf = ctypes.c_buffer(size) + winproxy.GetFileVersionInfoA(name, 0, size, buf) + + bufptr = PVOID() + bufsize = UINT() + winproxy.VerQueryValueA(buf, "\\VarFileInfo\\Translation", ctypes.byref(bufptr), ctypes.byref(bufsize)) + bufstr = ctypes.cast(bufptr, LPCSTR) + tup = struct.unpack(" {1} ".format(i, w.name())) + +raise "YOLO" diff --git a/windows/wmi.py b/windows/winobject/wmi.py similarity index 100% rename from windows/wmi.py rename to windows/winobject/wmi.py