def __init__(self, os_name=None): """ :param str os_name: The name of the Windows operating system for which to resolve syscall names to numbers. """ if process_is_wow64(): raise RuntimeError('python running in WOW64 is not supported') self._syscall_db_con = None if os_name is None: os_name = self.__name_map.get(platform.platform()) if os_name is not None: self._syscall_db_con = sqlite3.connect(self._syscall_db_path, check_same_thread=False) if not self._syscall_db_con.execute( 'SELECT COUNT(os_name) FROM syscalls WHERE arch = ? AND os_name = ?', ( self._syscall_arch, os_name, )).fetchone()[0]: raise ValueError( 'no syscall numbers available in the database for ' + os_name) self.os_name = os_name process_h = WindowsProcess(pid=-1) shellcode_sz = mayhem.utilities.align_up(len(self._syscall_stub), 1024) self.address = process_h.allocate(size=shellcode_sz) process_h.write_memory(self.address, self._syscall_stub) process_h.protect(self.address, size=shellcode_sz, permissions='PAGE_EXECUTE_READ') self._syscall = self._syscall_prototype(self.address)
def find_driver_base(driver=None): """ Get the base address of the specified driver or the NT Kernel if none is specified. :param str driver: The name of the driver to get the base address of. :return: The base address and the driver name. :rtype: tuple """ if platform.architecture()[0] == '64bit': lpImageBase = (ctypes.c_ulonglong * 1024)() lpcbNeeded = ctypes.c_longlong() ctypes.windll.psapi.GetDeviceDriverBaseNameA.argtypes = [ctypes.c_longlong, ctypes.POINTER(ctypes.c_char), ctypes.c_uint32] else: if process_is_wow64(): raise RuntimeError('python running in WOW64 is not supported') lpImageBase = (ctypes.c_ulong * 1024)() lpcbNeeded = ctypes.c_long() driver_name_size = ctypes.c_long() driver_name_size.value = 48 ctypes.windll.psapi.EnumDeviceDrivers(ctypes.byref(lpImageBase), ctypes.c_int(1024), ctypes.byref(lpcbNeeded)) for base_addr in lpImageBase: driver_name = ctypes.c_char_p(b'\x00' * driver_name_size.value) if base_addr: ctypes.windll.psapi.GetDeviceDriverBaseNameA(base_addr, driver_name, driver_name_size.value) driver_name_value = driver_name.value.decode('utf-8') if driver is None and driver_name_value.lower().find("krnl") != -1: return base_addr, driver_name_value elif driver_name_value.lower() == driver: return base_addr, driver_name_value return None
def get_system_handle_info(): """ Get the SystemHandleInformation class. :rtype: list """ if process_is_wow64(): raise RuntimeError('python running in WOW64 is not supported') if mayhem.utilities.architecture_is_64bit: header = 'Lxxxx' layout = 'HHBBHPLxxxx' else: raise NotImplemented( 'this function is not implemented for this architecture') space_size = 0x1000 status = 0xc0000004 length = wintypes.ULONG() while _NTSTATUS_CODES[status].name == 'STATUS_INFO_LENGTH_MISMATCH': space_size *= 2 space = (ctypes.c_byte * space_size)() status = m_ntdll.NtQuerySystemInformation( m_ntdll.SystemInformationClass.SystemHandleInformation, space, space_size, length) if _NTSTATUS_CODES[status].name != 'STATUS_SUCCESS': raise RuntimeError( "NtQuerySystemInformation failed with NTSTATUS: 0x{0:08x}".format( status)) space = mayhem.utilities.ctarray_to_bytes(space) count = struct.unpack(header, space[:struct.calcsize(header)])[0] space = space[struct.calcsize(header):] for entry in boltons.iterutils.chunked(space, struct.calcsize(layout), count=count): yield _SystemHandleTableEntryInfo(*struct.unpack(layout, entry))
def __init__(self, stub=None): if process_is_wow64(): raise RuntimeError('python running in WOW64 is not supported') asm_function_stub = stub or self._asm_function_stub process_h = WindowsProcess(pid=-1) shellcode_sz = mayhem.utilities.align_up(len(asm_function_stub), 1024) self.address = process_h.allocate(size=shellcode_sz) process_h.write_memory(self.address, asm_function_stub) process_h.protect(self.address, size=shellcode_sz, permissions='PAGE_EXECUTE_READ') self._asm_function = self._asm_function_prototype(self.address)
def get_haldispatchtable(): """ Get the address of the halDispatchTable. :return: The address of the halDispatchTable. :rtype: int """ if process_is_wow64(): raise RuntimeError('python running in WOW64 is not supported') (krnlbase, kernelver) = find_driver_base() hKernel = m_k32.LoadLibraryExA(kernelver, 0, 1) halDispatchTable = m_k32.GetProcAddress(hKernel, 'HalDispatchTable') halDispatchTable -= hKernel halDispatchTable += krnlbase return halDispatchTable
def get_haldispatchtable(): """ Get the address of the halDispatchTable. :return: The address of the halDispatchTable. :rtype: int """ if platform.architecture()[0] == '64bit': ctypes.windll.kernel32.LoadLibraryExA.restype = ctypes.c_uint64 ctypes.windll.kernel32.GetProcAddress.argtypes = [ctypes.c_uint64, ctypes.POINTER(ctypes.c_char)] ctypes.windll.kernel32.GetProcAddress.restype = ctypes.c_uint64 elif process_is_wow64(): raise RuntimeError('python running in WOW64 is not supported') (krnlbase, kernelver) = find_driver_base() hKernel = ctypes.windll.kernel32.LoadLibraryExA(kernelver, 0, 1) halDispatchTable = ctypes.windll.kernel32.GetProcAddress(hKernel, 'HalDispatchTable') halDispatchTable -= hKernel halDispatchTable += krnlbase return halDispatchTable
def __init__(self, os_name=None): """ :param str os_name: The name of the Windows operating system for which to resolve syscall names to numbers. """ if process_is_wow64(): raise RuntimeError('python running in WOW64 is not supported') self._syscall_db_con = None if os_name is not None: self._syscall_db_con = sqlite3.connect(self._syscall_db_path, check_same_thread=False) if not self._syscall_db_con.execute('SELECT COUNT(os_name) FROM syscalls WHERE arch = ? AND os_name = ?', (self._syscall_arch, os_name,)).fetchone()[0]: raise ValueError('no syscall numbers available in the database for ' + os_name) self.os_name = os_name process_h = WindowsProcess(pid=-1) shellcode_sz = align_up(len(self._syscall_stub), 1024) self.address = process_h.allocate(size=shellcode_sz) process_h.write_memory(self.address, self._syscall_stub) process_h.protect(self.address, size=shellcode_sz, permissions='PAGE_EXECUTE_READ') self._syscall = self._syscall_prototype(self.address)
def get_haldispatchtable(): """ Get the address of the halDispatchTable. :return: The address of the halDispatchTable. :rtype: int """ if platform.architecture()[0] == '64bit': ctypes.windll.kernel32.LoadLibraryExA.restype = ctypes.c_uint64 ctypes.windll.kernel32.GetProcAddress.argtypes = [ ctypes.c_uint64, ctypes.POINTER(ctypes.c_char) ] ctypes.windll.kernel32.GetProcAddress.restype = ctypes.c_uint64 elif process_is_wow64(): raise RuntimeError('python running in WOW64 is not supported') (krnlbase, kernelver) = find_driver_base() hKernel = ctypes.windll.kernel32.LoadLibraryExA(kernelver, 0, 1) halDispatchTable = ctypes.windll.kernel32.GetProcAddress( hKernel, 'HalDispatchTable') halDispatchTable -= hKernel halDispatchTable += krnlbase return halDispatchTable
def find_driver_base(driver=None): """ Get the base address of the specified driver or the NT Kernel if none is specified. :param str driver: The name of the driver to get the base address of. :return: The base address and the driver name. :rtype: tuple """ if platform.architecture()[0] == '64bit': lpImageBase = (ctypes.c_ulonglong * 1024)() lpcbNeeded = ctypes.c_longlong() ctypes.windll.psapi.GetDeviceDriverBaseNameA.argtypes = [ ctypes.c_longlong, ctypes.POINTER(ctypes.c_char), ctypes.c_uint32 ] else: if process_is_wow64(): raise RuntimeError('python running in WOW64 is not supported') lpImageBase = (ctypes.c_ulong * 1024)() lpcbNeeded = ctypes.c_long() driver_name_size = ctypes.c_long() driver_name_size.value = 48 ctypes.windll.psapi.EnumDeviceDrivers(ctypes.byref(lpImageBase), ctypes.c_int(1024), ctypes.byref(lpcbNeeded)) for base_addr in lpImageBase: driver_name = ctypes.c_char_p(b'\x00' * driver_name_size.value) if base_addr: ctypes.windll.psapi.GetDeviceDriverBaseNameA( base_addr, driver_name, driver_name_size.value) driver_name_value = driver_name.value.decode('utf-8') if driver is None and driver_name_value.lower().find("krnl") != -1: return base_addr, driver_name_value elif driver_name_value.lower() == driver: return base_addr, driver_name_value return None