def _wait_for_handles(handles, timeout=-1):
"""
Waits for multiple handles. (Similar to 'select') Returns the handle which is ready.
Returns `None` on timeout.
http://msdn.microsoft.com/en-us/library/windows/desktop/ms687025(v=vs.85).aspx
"""
arrtype = HANDLE * len(handles)
handle_array = arrtype(*handles)
ret = windll.kernel32.WaitForMultipleObjects(
len(handle_array), handle_array, BOOL(False), DWORD(timeout))
if ret == WAIT_TIMEOUT:
return None
else:
h = handle_array[ret]
return h
python类HANDLE的实例源码
def __init__(self, console_handle, fileno, stream_name, encoding):
super(WinUnicodeConsoleOutput, self).__init__(
fileno, '<Unicode console %s>' % stream_name, encoding)
# Handle to use for WriteConsoleW
self._console_handle = console_handle
# Loads the necessary function.
# These types are available on linux but not Mac.
# pylint: disable=no-name-in-module,F0401
from ctypes import byref, GetLastError, POINTER, windll, WINFUNCTYPE
from ctypes.wintypes import BOOL, DWORD, HANDLE, LPWSTR
from ctypes.wintypes import LPVOID # pylint: disable=no-name-in-module
self._DWORD = DWORD
self._byref = byref
# <http://msdn.microsoft.com/en-us/library/ms687401.aspx>
self._WriteConsoleW = WINFUNCTYPE(
BOOL, HANDLE, LPWSTR, DWORD, POINTER(DWORD), LPVOID)(
('WriteConsoleW', windll.kernel32))
self._GetLastError = GetLastError
def WlanOpenHandle():
"""
The WlanOpenHandle function opens a connection to the server.
DWORD WINAPI WlanOpenHandle(
_In_ DWORD dwClientVersion,
_Reserved_ PVOID pReserved,
_Out_ PDWORD pdwNegotiatedVersion,
_Out_ PHANDLE phClientHandle
);
"""
func_ref = wlanapi.WlanOpenHandle
func_ref.argtypes = [DWORD, c_void_p, POINTER(DWORD), POINTER(HANDLE)]
func_ref.restype = DWORD
negotiated_version = DWORD()
client_handle = HANDLE()
result = func_ref(2, None, byref(negotiated_version), byref(client_handle))
if result != ERROR_SUCCESS:
raise Exception("WlanOpenHandle failed.")
return client_handle
def WlanCloseHandle(hClientHandle):
"""
The WlanCloseHandle function closes a connection to the server.
DWORD WINAPI WlanCloseHandle(
_In_ HANDLE hClientHandle,
_Reserved_ PVOID pReserved
);
"""
func_ref = wlanapi.WlanCloseHandle
func_ref.argtypes = [HANDLE, c_void_p]
func_ref.restype = DWORD
result = func_ref(hClientHandle, None)
if result != ERROR_SUCCESS:
raise Exception("WlanCloseHandle failed.")
return result
def WlanEnumInterfaces(hClientHandle):
"""
The WlanEnumInterfaces function enumerates all of the wireless LAN
interfaces currently enabled on the local computer.
DWORD WINAPI WlanEnumInterfaces(
_In_ HANDLE hClientHandle,
_Reserved_ PVOID pReserved,
_Out_ PWLAN_INTERFACE_INFO_LIST *ppInterfaceList
);
"""
func_ref = wlanapi.WlanEnumInterfaces
func_ref.argtypes = [HANDLE,
c_void_p,
POINTER(POINTER(WLAN_INTERFACE_INFO_LIST))]
func_ref.restype = DWORD
wlan_ifaces = pointer(WLAN_INTERFACE_INFO_LIST())
result = func_ref(hClientHandle, None, byref(wlan_ifaces))
if result != ERROR_SUCCESS:
raise Exception("WlanEnumInterfaces failed.")
return wlan_ifaces
def WlanDeleteProfile(hClientHandle, pInterfaceGuid, profileName):
"""
DWORD WINAPI WlanDeleteProfile(
_In_ HANDLE hClientHandle,
_In_ const GUID *pInterfaceGuid,
_In_ LPCWSTR strProfileName,
_Reserved_ PVOID pReserved
);
"""
func_ref = wlanapi.WlanDeleteProfile
func_ref.argtypes = [HANDLE,
POINTER(GUID),
LPCWSTR,
c_void_p]
func_ref.restype = DWORD
result = func_ref(hClientHandle,
byref(pInterfaceGuid),
profileName,
None)
if result != ERROR_SUCCESS:
raise Exception("WlanDeleteProfile failed. error %d" % result, result)
return result
def WlanConnect(hClientHandle, pInterfaceGuid, pConnectionParameters):
"""
The WlanConnect function attempts to connect to a specific network.
DWORD WINAPI WlanConnect(
_In_ HANDLE hClientHandle,
_In_ const GUID *pInterfaceGuid,
_In_ const PWLAN_CONNECTION_PARAMETERS pConnectionParameters,
_Reserved_ PVOID pReserved
);
"""
func_ref = wlanapi.WlanConnect
func_ref.argtypes = [HANDLE,
POINTER(GUID),
POINTER(WLAN_CONNECTION_PARAMETERS),
c_void_p]
func_ref.restype = DWORD
result = func_ref(hClientHandle,
pointer(pInterfaceGuid),
pointer(pConnectionParameters),
None)
if result != ERROR_SUCCESS:
raise Exception("".join(["WlanConnect failed with error ", str(result)]))
return result
def areAdminRightsElevated():
'''
Tells you whether current script already has Administrative rights.
'''
pid = GetCurrentProcess()
processToken = HANDLE()
if not OpenProcessToken(pid, TOKEN_READ, ctypes.byref(processToken)):
raise ctypes.WinError()
try:
elevated, elevatedSize = DWORD(), DWORD()
if not GetTokenInformation(processToken, TokenElevation, ctypes.byref(elevated),
ctypes.sizeof(elevated), ctypes.byref(elevatedSize)):
raise ctypes.WinError()
return bool(elevated)
finally:
CloseHandle(processToken)
def areAdminRightsElevated():
'''
Tells you whether current script already has Administrative rights.
'''
pid = GetCurrentProcess()
processToken = HANDLE()
if not OpenProcessToken(pid, TOKEN_READ, ctypes.byref(processToken)):
raise ctypes.WinError()
try:
elevated, elevatedSize = DWORD(), DWORD()
if not GetTokenInformation(processToken, TokenElevation, ctypes.byref(elevated),
ctypes.sizeof(elevated), ctypes.byref(elevatedSize)):
raise ctypes.WinError()
return bool(elevated)
finally:
CloseHandle(processToken)
def _wait_for_handles(handles, timeout=-1):
"""
Waits for multiple handles. (Similar to 'select') Returns the handle which is ready.
Returns `None` on timeout.
http://msdn.microsoft.com/en-us/library/windows/desktop/ms687025(v=vs.85).aspx
"""
arrtype = HANDLE * len(handles)
handle_array = arrtype(*handles)
ret = windll.kernel32.WaitForMultipleObjects(
len(handle_array), handle_array, BOOL(False), DWORD(timeout))
if ret == WAIT_TIMEOUT:
return None
else:
h = handle_array[ret]
return h
def CreateFile(path, access=GENERIC_READ | GENERIC_WRITE, mode=0, security_attributes=NULL, creation=OPEN_EXISTING, flags=FILE_ATTRIBUTE_NORMAL, template_file = NULL):
"""See: CreateFile function
http://msdn.microsoft.com/en-us/library/windows/desktop/aa363858(v=vs.85).aspx
"""
CreateFile_Fn = windll.kernel32.CreateFileA
CreateFile_Fn.argtypes = [
wintypes.LPCSTR, # _In_ LPCTSTR lpFileName
wintypes.DWORD, # _In_ DWORD dwDesiredAccess
wintypes.DWORD, # _In_ DWORD dwShareMode
LPSECURITY_ATTRIBUTES, # _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes
wintypes.DWORD, # _In_ DWORD dwCreationDisposition
wintypes.DWORD, # _In_ DWORD dwFlagsAndAttributes
wintypes.HANDLE] # _In_opt_ HANDLE hTemplateFile
CreateFile_Fn.restype = wintypes.HANDLE
handle = wintypes.HANDLE(CreateFile_Fn(path,
access,
mode,
security_attributes,
creation,
flags,
template_file))
return handle
def WriteFile(file, buffer, number_of_bytes_to_write, number_of_bytes_written, overlapped):
"""See: WriteFile function
https://msdn.microsoft.com/en-us/library/windows/desktop/aa365747(v=vs.85).aspx
"""
WriteFile_Fn = windll.kernel32.WriteFile
WriteFile_Fn.argtypes = [
wintypes.HANDLE, # _In_ HANDLE hFile,
wintypes.LPCVOID, # _In_ LPCVOID lpBuffer,
wintypes.DWORD, # _In_ DWORD nNumberOfBytesToWrite,
LPDWORD, # _Out_opt_ LPDWORD lpNumberOfBytesWritten,
LPOVERLAPPED # _Inout_opt_ LPOVERLAPPED lpOverlapped
]
WriteFile_Fn.restype = wintypes.BOOL
ret = wintypes.BOOL(WriteFile_Fn(
file,
buffer,
number_of_bytes_to_write,
number_of_bytes_written,
overlapped
))
return ret
def open_service(service_manager_handle, service_name, desired_access):
""" See: OpenService function
https://msdn.microsoft.com/en-us/library/windows/desktop/ms684330(v=vs.85).aspx
"""
OpenService_Fn = windll.Advapi32.OpenServiceA #SC_HANDLE WINAPI OpenService(
OpenService_Fn.argtypes = [ #
wintypes.HANDLE, # _In_ SC_HANDLE hSCManager,
LPCTSTR, # _In_ LPCTSTR lpServiceName,
wintypes.DWORD # _In_ DWORD dwDesiredAccess
]
OpenService_Fn.restype = wintypes.SC_HANDLE
handle = OpenService_Fn(
service_manager_handle,
service_name,
desired_access
)
return handle
def rename_regkey(skey, ssubkey, dsubkey):
"""Rename an entire tree of values in the registry.
Function by Thorsten Sick."""
res_handle = HANDLE()
options = DWORD(0)
res = RegOpenKeyExW(
skey, ssubkey, options, _winreg.KEY_ALL_ACCESS, byref(res_handle)
)
if not res:
bsize = c_ushort(len(dsubkey) * 2)
us = UNICODE_STRING()
us.Buffer = c_wchar_p(dsubkey)
us.Length = bsize
us.MaximumLength = bsize
res = NtRenameKey(res_handle, pointer(us))
if res:
log.warning("Error renaming %s\\%s to %s (0x%x)",
skey, ssubkey, dsubkey, res % 2**32)
if res_handle:
RegCloseKey(res_handle)
def set_regkey(rootkey, subkey, name, type_, value):
if type_ == _winreg.REG_SZ:
value = unicode(value)
length = len(value) * 2 + 2
elif type_ == _winreg.REG_MULTI_SZ:
value = u"\u0000".join(value) + u"\u0000\u0000"
length = len(value) * 2 + 2
elif type_ == _winreg.REG_DWORD:
value = struct.pack("I", value)
length = 4
else:
length = len(value)
res_handle = HANDLE()
res = RegCreateKeyExW(
rootkey, subkey, 0, None, 0, _winreg.KEY_ALL_ACCESS,
0, byref(res_handle), None
)
if not res:
RegSetValueExW(res_handle, name, 0, type_, value, length)
RegCloseKey(res_handle)
def query_value(rootkey, subkey, name):
res_handle = HANDLE()
type_ = DWORD()
value = create_string_buffer(1024 * 1024)
length = DWORD(1024 * 1024)
res = RegOpenKeyExW(
rootkey, subkey, 0, _winreg.KEY_QUERY_VALUE, byref(res_handle)
)
if not res:
res = RegQueryValueExW(
res_handle, name, None, byref(type_), value, byref(length)
)
RegCloseKey(res_handle)
if not res:
if type_.value == _winreg.REG_SZ:
return value.raw[:length.value].decode("utf16").rstrip("\x00")
if type_.value == _winreg.REG_MULTI_SZ:
value = value.raw[:length.value].decode("utf16")
return value.rstrip(u"\u0000").split(u"\u0000")
if type_.value == _winreg.REG_DWORD:
return struct.unpack("I", value.raw[:length.value])[0]
return value.raw[:length.value]
def wait_for_handles(handles, timeout=INFINITE):
"""
Waits for multiple handles. (Similar to 'select') Returns the handle which is ready.
Returns `None` on timeout.
http://msdn.microsoft.com/en-us/library/windows/desktop/ms687025(v=vs.85).aspx
"""
assert isinstance(handles, list)
assert isinstance(timeout, int)
arrtype = HANDLE * len(handles)
handle_array = arrtype(*handles)
ret = windll.kernel32.WaitForMultipleObjects(
len(handle_array), handle_array, BOOL(False), DWORD(timeout))
if ret == WAIT_TIMEOUT:
return None
else:
h = handle_array[ret]
return h
def _make_non_blocking(file_obj):
"""make file object non-blocking
Windows doesn't have the fcntl module, but someone on
stack overflow supplied this code as an answer, and it works
http://stackoverflow.com/a/34504971/2893090"""
if USING_WINDOWS:
LPDWORD = POINTER(DWORD)
PIPE_NOWAIT = wintypes.DWORD(0x00000001)
SetNamedPipeHandleState = windll.kernel32.SetNamedPipeHandleState
SetNamedPipeHandleState.argtypes = [HANDLE, LPDWORD, LPDWORD, LPDWORD]
SetNamedPipeHandleState.restype = BOOL
h = msvcrt.get_osfhandle(file_obj.fileno())
res = windll.kernel32.SetNamedPipeHandleState(h, byref(PIPE_NOWAIT), None, None)
if res == 0:
raise ValueError(WinError())
else:
# Set the file status flag (F_SETFL) on the pipes to be non-blocking
# so we can attempt to read from a pipe with no new data without locking
# the program up
fcntl.fcntl(file_obj, fcntl.F_SETFL, os.O_NONBLOCK)
def check_aslr():
# first check for a potentially rebased user32.dll
from ctypes import windll
from ctypes import wintypes
check_dlls = ["user32.dll", "kernel32.dll", "ntdll.dll"]
offsets = []
is_aslr = False
windll.kernel32.GetModuleHandleW.restype = wintypes.HMODULE
windll.kernel32.GetModuleHandleW.argtypes = [wintypes.LPCWSTR]
windll.kernel32.GetModuleFileNameW.restype = wintypes.DWORD
windll.kernel32.GetModuleFileNameW.argtypes = [wintypes.HANDLE, wintypes.LPWSTR, wintypes.DWORD]
for dll_name in check_dlls:
h_module_base = windll.kernel32.GetModuleHandleW(dll_name)
# next get the module's file path
module_path = wintypes.create_unicode_buffer(255)
windll.kernel32.GetModuleFileNameW(h_module_base, module_path, 255)
# then the ImageBase from python.exe file
pe = pefile.PE(module_path.value)
pe_header_base_addr = pe.OPTIONAL_HEADER.ImageBase
offsets.append(pe_header_base_addr - h_module_base)
for dll_name, offset in zip(check_dlls, offsets):
LOG.debug("Memory vs. File ImageBase offset (%s): 0x%x", dll_name, offset)
is_aslr |= offset != 0
return is_aslr
def areAdminRightsElevated():
'''
Tells you whether current script already has Administrative rights.
'''
pid = GetCurrentProcess()
processToken = HANDLE()
if not OpenProcessToken(pid, TOKEN_READ, ctypes.byref(processToken)):
raise ctypes.WinError()
try:
elevated, elevatedSize = DWORD(), DWORD()
if not GetTokenInformation(processToken, TokenElevation, ctypes.byref(elevated),
ctypes.sizeof(elevated), ctypes.byref(elevatedSize)):
raise ctypes.WinError()
return bool(elevated)
finally:
CloseHandle(processToken)
def _wait_for_handles(handles, timeout=-1):
"""
Waits for multiple handles. (Similar to 'select') Returns the handle which is ready.
Returns `None` on timeout.
http://msdn.microsoft.com/en-us/library/windows/desktop/ms687025(v=vs.85).aspx
"""
arrtype = HANDLE * len(handles)
handle_array = arrtype(*handles)
ret = windll.kernel32.WaitForMultipleObjects(
len(handle_array), handle_array, BOOL(False), DWORD(timeout))
if ret == WAIT_TIMEOUT:
return None
else:
h = handle_array[ret]
return h
def __init__(self, console_handle, fileno, stream_name, encoding):
super(WinUnicodeConsoleOutput, self).__init__(
fileno, '<Unicode console %s>' % stream_name, encoding)
# Handle to use for WriteConsoleW
self._console_handle = console_handle
# Loads the necessary function.
# These types are available on linux but not Mac.
# pylint: disable=no-name-in-module,F0401
from ctypes import byref, GetLastError, POINTER, windll, WINFUNCTYPE
from ctypes.wintypes import BOOL, DWORD, HANDLE, LPWSTR
from ctypes.wintypes import LPVOID # pylint: disable=no-name-in-module
self._DWORD = DWORD
self._byref = byref
# <http://msdn.microsoft.com/en-us/library/ms687401.aspx>
self._WriteConsoleW = WINFUNCTYPE(
BOOL, HANDLE, LPWSTR, DWORD, POINTER(DWORD), LPVOID)(
('WriteConsoleW', windll.kernel32))
self._GetLastError = GetLastError
def win_handle_is_a_console(handle):
"""Returns True if a Windows file handle is a handle to a console."""
# These types are available on linux but not Mac.
# pylint: disable=no-name-in-module,F0401
from ctypes import byref, POINTER, windll, WINFUNCTYPE
from ctypes.wintypes import BOOL, DWORD, HANDLE
FILE_TYPE_CHAR = 0x0002
FILE_TYPE_REMOTE = 0x8000
INVALID_HANDLE_VALUE = DWORD(-1).value
# <http://msdn.microsoft.com/en-us/library/ms683167.aspx>
GetConsoleMode = WINFUNCTYPE(BOOL, HANDLE, POINTER(DWORD))(
('GetConsoleMode', windll.kernel32))
# <http://msdn.microsoft.com/en-us/library/aa364960.aspx>
GetFileType = WINFUNCTYPE(DWORD, DWORD)(('GetFileType', windll.kernel32))
# GetStdHandle returns INVALID_HANDLE_VALUE, NULL, or a valid handle.
if handle == INVALID_HANDLE_VALUE or handle is None:
return False
return (
(GetFileType(handle) & ~FILE_TYPE_REMOTE) == FILE_TYPE_CHAR and
GetConsoleMode(handle, byref(DWORD())))
def __init__(self, console_handle, fileno, stream_name, encoding):
super(WinUnicodeConsoleOutput, self).__init__(
fileno, '<Unicode console %s>' % stream_name, encoding)
# Handle to use for WriteConsoleW
self._console_handle = console_handle
# Loads the necessary function.
# These types are available on linux but not Mac.
# pylint: disable=no-name-in-module,F0401
from ctypes import byref, GetLastError, POINTER, windll, WINFUNCTYPE
from ctypes.wintypes import BOOL, DWORD, HANDLE, LPWSTR
from ctypes.wintypes import LPVOID # pylint: disable=no-name-in-module
self._DWORD = DWORD
self._byref = byref
# <http://msdn.microsoft.com/en-us/library/ms687401.aspx>
self._WriteConsoleW = WINFUNCTYPE(
BOOL, HANDLE, LPWSTR, DWORD, POINTER(DWORD), LPVOID)(
('WriteConsoleW', windll.kernel32))
self._GetLastError = GetLastError
def win_handle_is_a_console(handle):
"""Returns True if a Windows file handle is a handle to a console."""
# These types are available on linux but not Mac.
# pylint: disable=no-name-in-module,F0401
from ctypes import byref, POINTER, windll, WINFUNCTYPE
from ctypes.wintypes import BOOL, DWORD, HANDLE
FILE_TYPE_CHAR = 0x0002
FILE_TYPE_REMOTE = 0x8000
INVALID_HANDLE_VALUE = DWORD(-1).value
# <http://msdn.microsoft.com/en-us/library/ms683167.aspx>
GetConsoleMode = WINFUNCTYPE(BOOL, HANDLE, POINTER(DWORD))(
('GetConsoleMode', windll.kernel32))
# <http://msdn.microsoft.com/en-us/library/aa364960.aspx>
GetFileType = WINFUNCTYPE(DWORD, DWORD)(('GetFileType', windll.kernel32))
# GetStdHandle returns INVALID_HANDLE_VALUE, NULL, or a valid handle.
if handle == INVALID_HANDLE_VALUE or handle is None:
return False
return (
(GetFileType(handle) & ~FILE_TYPE_REMOTE) == FILE_TYPE_CHAR and
GetConsoleMode(handle, byref(DWORD())))
def open_device(self, access=GENERIC_READ | GENERIC_WRITE, mode=0, creation=OPEN_EXISTING, flags=FILE_ATTRIBUTE_NORMAL):
"""See: CreateFile function
http://msdn.microsoft.com/en-us/library/windows/desktop/aa363858(v=vs.85).aspx
"""
CreateFile_Fn = windll.kernel32.CreateFileA
CreateFile_Fn.argtypes = [
wintypes.LPCSTR, # _In_ LPCTSTR lpFileName
wintypes.DWORD, # _In_ DWORD dwDesiredAccess
wintypes.DWORD, # _In_ DWORD dwShareMode
LPSECURITY_ATTRIBUTES, # _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes
wintypes.DWORD, # _In_ DWORD dwCreationDisposition
wintypes.DWORD, # _In_ DWORD dwFlagsAndAttributes
wintypes.HANDLE] # _In_opt_ HANDLE hTemplateFile
CreateFile_Fn.restype = wintypes.HANDLE
self.handle = wintypes.HANDLE(CreateFile_Fn('\\\\.\\' + self.name,
access,
mode,
NULL,
creation,
flags,
NULL))
def open_service(service_manager_handle, service_name, desired_access):
""" See: OpenService function
https://msdn.microsoft.com/en-us/library/windows/desktop/ms684330(v=vs.85).aspx
"""
OpenService_Fn = windll.Advapi32.OpenServiceA #SC_HANDLE WINAPI OpenService(
OpenService_Fn.argtypes = [ #
wintypes.HANDLE, # _In_ SC_HANDLE hSCManager,
LPCTSTR, # _In_ LPCTSTR lpServiceName,
wintypes.DWORD # _In_ DWORD dwDesiredAccess
]
OpenService_Fn.restype = wintypes.SC_HANDLE
handle = OpenService_Fn(
service_manager_handle,
service_name,
desired_access
)
return handle
def create_spora_mutex():
"""
Creates a mutex just like the notorious Spora ransomware
This prevents the execution of known Spora variants
Based on Minerva's blog post:
https://www.minerva-labs.com/post/vaccinating-against-spora-ransomware-a-proof-of-concept-tool-by-minerva
"""
try:
vol_serial = int(subprocess.check_output(['cmd', '/c', 'vol'])[-11:-2].replace("-", ""), 16)
spora_mutex = 'm' + str(vol_serial)
_CreateMutex = ctypes.windll.kernel32.CreateMutexA
_CreateMutex.argtypes = [wintypes.LPCVOID, wintypes.BOOL, wintypes.LPCSTR]
_CreateMutex.restype = wintypes.HANDLE
ret = _CreateMutex(None, False, spora_mutex)
except Exception as e:
print "Got exception {0} while creating {1}".format(e, "Spora mutex")
def __init__ (self):
import ctypes.wintypes
if sys.platform[:3] != 'win':
raise SystemError('Windows is required')
self.__winmm = ctypes.windll.LoadLibrary('winmm.dll')
self.__mciSendStringW = self.__winmm.mciSendStringW
self.__mciGetErrorStringW = self.__winmm.mciGetErrorStringW
wintypes = ctypes.wintypes
LPCWSTR, HANDLE = wintypes.LPCWSTR, wintypes.HANDLE
args = [LPCWSTR, ctypes.c_char_p, wintypes.UINT, HANDLE]
self.__mciSendStringW.argtypes = args
self.__mciSendStringW.restype = wintypes.DWORD
args = [wintypes.DWORD, ctypes.c_void_p, wintypes.UINT]
self.__mciGetErrorStringW.argtypes = args
self.__mciGetErrorStringW.restype = wintypes.BOOL
self.__buffer = ctypes.create_string_buffer('?' * 4098)
self.__alias_index = 0
def areAdminRightsElevated():
'''
Tells you whether current script already has Administrative rights.
'''
pid = GetCurrentProcess()
processToken = HANDLE()
if not OpenProcessToken(pid, TOKEN_READ, ctypes.byref(processToken)):
raise ctypes.WinError()
try:
elevated, elevatedSize = DWORD(), DWORD()
if not GetTokenInformation(processToken, TokenElevation, ctypes.byref(elevated),
ctypes.sizeof(elevated), ctypes.byref(elevatedSize)):
raise ctypes.WinError()
return bool(elevated)
finally:
CloseHandle(processToken)