From 80c6a747da718d39b459371f19c49a8cbb0b3f61 Mon Sep 17 00:00:00 2001 From: hakril Date: Thu, 13 Feb 2020 22:12:40 +0100 Subject: [PATCH] Updated test for py3 --- tests/conftest.py | 10 +++---- tests/pfwtest.py | 13 +++++++-- tests/test_alpc.py | 17 +++++++---- tests/test_apisetmap.py | 11 +++---- tests/test_crypto.py | 33 ++++++++++----------- tests/test_evtlog.py | 20 +++++++------ tests/test_generated_def.py | 54 +++++++++++++++++++++++++++++++++-- tests/test_hook.py | 34 +++++++++++++++------- tests/test_improved_buffer.py | 10 +++---- tests/test_native_utils.py | 23 ++++++++------- tests/test_object_manager.py | 2 +- tests/test_pipe.py | 2 +- tests/test_process.py | 35 +++++++++++++++++------ tests/test_registry.py | 33 +++++++++++++-------- tests/test_rpc.py | 2 +- tests/test_security.py | 18 ++++++------ tests/test_service.py | 6 ++-- tests/test_system.py | 8 ++++-- tests/test_syswow.py | 4 +-- tests/test_token.py | 20 ++++++++----- tests/test_winproxy.py | 10 +++++-- tests/test_wintrust.py | 19 ++++++++---- tests/test_winutils.py | 23 ++++++++------- tests/test_wmi.py | 3 +- 24 files changed, 271 insertions(+), 139 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index bea605f..92c599c 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -6,26 +6,26 @@ import collections import windows import windows.generated_def as gdef -from pfwtest import is_windows_32_bits, is_process_32_bits, test_binary_name, DEFAULT_CREATION_FLAGS +from .pfwtest import is_windows_32_bits, is_process_32_bits, test_binary_name, DEFAULT_CREATION_FLAGS if is_windows_32_bits: def pop_proc_32(dwCreationFlags=DEFAULT_CREATION_FLAGS): - return windows.utils.create_process(r"C:\Windows\system32\{0}".format(test_binary_name), dwCreationFlags=dwCreationFlags, show_windows=True) + return windows.utils.create_process(r"C:\Windows\system32\{0}".format(test_binary_name).encode("ascii"), dwCreationFlags=dwCreationFlags, show_windows=True) def pop_proc_64(dwCreationFlags=DEFAULT_CREATION_FLAGS): raise WindowsError("Cannot create calc64 in 32bits system") else: def pop_proc_32(dwCreationFlags=DEFAULT_CREATION_FLAGS): - return windows.utils.create_process(r"C:\Windows\syswow64\{0}".format(test_binary_name), dwCreationFlags=dwCreationFlags, show_windows=True) + return windows.utils.create_process(r"C:\Windows\syswow64\{0}".format(test_binary_name).encode("ascii"), dwCreationFlags=dwCreationFlags, show_windows=True) if is_process_32_bits: def pop_proc_64(dwCreationFlags=DEFAULT_CREATION_FLAGS): with windows.utils.DisableWow64FsRedirection(): - return windows.utils.create_process(r"C:\Windows\system32\{0}".format(test_binary_name), dwCreationFlags=dwCreationFlags, show_windows=True) + return windows.utils.create_process(r"C:\Windows\system32\{0}".format(test_binary_name).encode("ascii"), dwCreationFlags=dwCreationFlags, show_windows=True) else: def pop_proc_64(dwCreationFlags=DEFAULT_CREATION_FLAGS): - return windows.utils.create_process(r"C:\Windows\system32\{0}".format(test_binary_name), dwCreationFlags=dwCreationFlags, show_windows=True) + return windows.utils.create_process(r"C:\Windows\system32\{0}".format(test_binary_name).encode("ascii"), dwCreationFlags=dwCreationFlags, show_windows=True) import sys diff --git a/tests/pfwtest.py b/tests/pfwtest.py index 4fa95e9..92023b3 100644 --- a/tests/pfwtest.py +++ b/tests/pfwtest.py @@ -1,5 +1,6 @@ import os.path import pytest +import base64 import windows import windows.generated_def as gdef @@ -47,7 +48,7 @@ if windows.current_process.bitness == 64: @pytest.fixture def check_injected_python_installed(request): # Find the process parameter - procparams = [argname for argname in request.funcargnames if argname.startswith("proc")] + procparams = [argname for argname in request.fixturenames if argname.startswith("proc")] if len(procparams) != 1: raise ValueError("Could not find the fixture name of the injected python") procparam = procparams[0] @@ -57,4 +58,12 @@ def check_injected_python_installed(request): return None -python_injection = pytest.mark.usefixtures("check_injected_python_installed") \ No newline at end of file +python_injection = pytest.mark.usefixtures("check_injected_python_installed") + + +## P2 VS PY3 + +if windows.pycompat.is_py3: + b64decode = base64.decodebytes +else: + b64decode = base64.decodestring \ No newline at end of file diff --git a/tests/test_alpc.py b/tests/test_alpc.py index 5f53bea..d52a783 100644 --- a/tests/test_alpc.py +++ b/tests/test_alpc.py @@ -5,7 +5,7 @@ import time import windows.alpc import windows.generated_def as gdef -from pfwtest import * +from .pfwtest import * def generate_client_server_test(client_function, server_function): @@ -19,8 +19,12 @@ def generate_client_server_test(client_function, server_function): return generated_test PORT_NAME = r"\RPC Control\PythonForWindowsTestPort" -CLIENT_MESSAGE = "Message 1\x00\xffABCD" -SERVER_MESSAGE = "Message 2-" + "".join(chr(i) for i in range(256)) +CLIENT_MESSAGE = b"Message 1\x00\xffABCD" + +if windows.pycompat.is_py3: + SERVER_MESSAGE = b"Message 2-" + bytes(range(256)) +else: + SERVER_MESSAGE = "Message 2-" + "".join(chr(i) for i in range(256)) def alpc_simple_test_server(): server = windows.alpc.AlpcServer(PORT_NAME) @@ -58,8 +62,11 @@ def send_message_with_view(client, message_data, view_data): return client.send_receive(msg) -CLIENT_VIEW_MESSAGE = "Message 1\x00\xffABCD" -CLIENT_VIEW_DATA = "Message Data-view" + "".join(chr(i) for i in range(256)) +CLIENT_VIEW_MESSAGE = b"Message 1\x00\xffABCD" +if windows.pycompat.is_py3: + CLIENT_VIEW_DATA = b"Message Data-view" + bytes(range(256)) +else: + CLIENT_VIEW_DATA = "Message Data-view" + "".join(chr(i) for i in range(256)) def alpc_view_test_server(): diff --git a/tests/test_apisetmap.py b/tests/test_apisetmap.py index 40608b8..d9e4a5e 100644 --- a/tests/test_apisetmap.py +++ b/tests/test_apisetmap.py @@ -5,7 +5,8 @@ import pytest import windows.generated_def as gdef from windows.winobject.apisetmap import get_api_set_map_for_current_process -from pfwtest import * +from .pfwtest import * + # Late getattr param si these can be at the end od the file @pytest.fixture(params=[ @@ -15,7 +16,7 @@ from pfwtest import * ],ids=["Version6", "Version4","Version2"]) def dumped_apisetmap_base_and_version(request): variable_name, version = request.param - data = getattr(sys.modules[__name__],variable_name ).decode("base64") + data = b64decode(getattr(sys.modules[__name__], variable_name)) ctypes_data = ctypes.c_buffer(data) yield ctypes.addressof(ctypes_data), version @@ -44,7 +45,7 @@ def test_apisetmap_parsing_current_process(): def test_apisetmap_parsing_from_dump(dumped_apisetmap_base_and_version): return verify_apisetmap_parsing(*dumped_apisetmap_base_and_version) -APISETMAP_V2 = """ +APISETMAP_V2 = b""" AgAAACMAAACsAQAANAAAAOABAAAMAgAANgAAAEQCAABYAgAAMAAAAIgCAAC4AgAAOAAAAPACAAAE AwAAQAAAAEQDAABoAwAAMgAAAJwDAACwAwAALgAAAOADAAAEBAAAMgAAADgEAABcBAAALgAAAIwE AACgBAAAPAAAANwEAADwBAAAKgAAABwFAABABQAAQAAAAIAFAACUBQAAPgAAANQFAADoBQAAQAAA @@ -119,7 +120,7 @@ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA== """ -APISETMAP_V4 = """ +APISETMAP_V4 = b""" BAAAAKzlAAAAAAAA9gEAAAMAAACMlQAANgAAAIyVAAAuAAAAxJUAAAMAAADglQAASAAAAOCVAABA AAAAKJYAAAMAAABElgAAUgAAAESWAABKAAAAmJYAAAMAAAC0lgAAPgAAALSWAAA2AAAA9JYAAAMA AAAQlwAAPgAAABCXAAA2AAAAUJcAAAMAAABslwAANAAAAGyXAAAsAAAAoJcAAAMAAAC8lwAANAAA @@ -1200,7 +1201,7 @@ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA """ -APISETMAP_V6 = """ +APISETMAP_V6 = b""" BgAAAKxdAQAAAAAAswIAABwAAAAUSAEAHwAAAAEAAADkQAAASgAAAEYAAAAwQQAAAQAAAAEAAABw QQAAVgAAAFIAAADIQQAAAQAAAAEAAAAEQgAARgAAAEIAAABMQgAAAQAAAAEAAACEQgAAVgAAAFIA AADcQgAAAQAAAAEAAADwQgAARAAAAEAAAAA0QwAAAQAAAAEAAABIQwAAQAAAADwAAACIQwAAAQAA diff --git a/tests/test_crypto.py b/tests/test_crypto.py index 75dbf33..037c538 100644 --- a/tests/test_crypto.py +++ b/tests/test_crypto.py @@ -4,11 +4,11 @@ import windows.crypto import windows.generated_def as gdef import windows.crypto.generation -from pfwtest import * +from .pfwtest import * pytestmark = pytest.mark.usefixtures('check_for_gc_garbage') -TEST_CERT = """ +TEST_CERT = b""" MIIBwTCCASqgAwIBAgIQG46Uyws+67ZBOfPJCbFrRjANBgkqhkiG9w0BAQsFADAfMR0wGwYDVQQD ExRQeXRob25Gb3JXaW5kb3dzVGVzdDAeFw0xNzA0MTIxNDM5MjNaFw0xODA0MTIyMDM5MjNaMB8x HTAbBgNVBAMTFFB5dGhvbkZvcldpbmRvd3NUZXN0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB @@ -24,7 +24,7 @@ gy+ApYDdSwTtWFARSrMqk7rRHUveYEfMw72yaOWDxCzcopEuADKrrYEute4CzZuXF9PbbgK6""" TEST_PFX_PASSWORD = "TestPassword" -TEST_PFX = """ +TEST_PFX = b""" MIIGMwIBAzCCBe8GCSqGSIb3DQEHAaCCBeAEggXcMIIF2DCCA7AGCSqGSIb3DQEHAaCCA6EEggOd MIIDmTCCA5UGCyqGSIb3DQEMCgECoIICtjCCArIwHAYKKoZIhvcNAQwBAzAOBAhoE8r3qUJeTQIC B9AEggKQT7jm7ppgH64scyJ3cFW50BurqpMPtxgYyYCCtjdmHMlLPbUoujXOZVYi3seAEERE51BS @@ -57,20 +57,20 @@ DgMCGgQU70h/rEXLQOberGvgJenggoWU5poEFCfdE1wNK1M38Yp3+qfjEqNIJGCPAgIH0A== @pytest.fixture() def rawcert(): - return TEST_CERT.decode("base64") + return b64decode(TEST_CERT) @pytest.fixture() def rawpfx(): - return TEST_PFX.decode("base64") + return b64decode(TEST_PFX) PFW_TEST_TMP_KEY_CONTAINER = "PythonForWindowsTMPContainerTest" -RANDOM_CERTIF_NAME = "PythonForWindowsGeneratedRandomCertifTest" +RANDOM_CERTIF_NAME = b"PythonForWindowsGeneratedRandomCertifTest" RANDOM_PFX_PASSWORD = "PythonForWindowsGeneratedRandomPFXPassword" @pytest.fixture() def randomkeypair(keysize=1024): - """Generate a cert / pfx. Based on samples\crypto\encryption_demo.py""" + r"""Generate a cert / pfx. Based on samples\crypto\encryption_demo.py""" cert_store = windows.crypto.CertificateStore.new_in_memory() # Create a TMP context that will hold our newly generated key-pair with windows.crypto.CryptContext(PFW_TEST_TMP_KEY_CONTAINER, None, gdef.PROV_RSA_FULL, 0, retrycreate=True) as ctx: @@ -95,9 +95,10 @@ def randomkeypair(keysize=1024): KeyProvInfo.dwKeySpec = gdef.AT_KEYEXCHANGE crypt_algo = gdef.CRYPT_ALGORITHM_IDENTIFIER() - crypt_algo.pszObjId = gdef.szOID_RSA_SHA256RSA + crypt_algo.pszObjId = gdef.szOID_RSA_SHA256RSA.encode("ascii") # do something else (bytes in generated ctypes ?) - certif_name = "CN={0}".format(RANDOM_CERTIF_NAME) + # This is fucking dumb, there is no .format on bytes object... + certif_name = b"".join((b"CN=", RANDOM_CERTIF_NAME)) # Generate a self-signed certificate based on the given key-container and signature algorithme certif = windows.crypto.generation.generate_selfsigned_certificate(certif_name, key_info=KeyProvInfo, signature_algo=crypt_algo) # Add the newly created certificate to our TMP cert-store @@ -114,8 +115,8 @@ def randomkeypair(keysize=1024): def test_certificate(rawcert): cert = windows.crypto.Certificate.from_buffer(rawcert) assert cert.serial == '1b 8e 94 cb 0b 3e eb b6 41 39 f3 c9 09 b1 6b 46' - assert cert.name == 'PythonForWindowsTest' - assert cert.issuer == 'PythonForWindowsTest' + assert cert.name == b'PythonForWindowsTest' + assert cert.issuer == b'PythonForWindowsTest' assert cert.thumbprint == 'EF 0C A8 C9 F9 E0 96 AF 74 18 56 8B C1 C9 57 27 A0 89 29 6A' assert cert.encoded == rawcert assert cert.version == 2 @@ -141,7 +142,7 @@ def test_open_pfx_bad_password(rawpfx): def test_encrypt_decrypt(rawcert, rawpfx): - message_to_encrypt = "Testing message \xff\x01" + message_to_encrypt = b"Testing message \xff\x01" cert = windows.crypto.Certificate.from_buffer(rawcert) # encrypt should accept a cert or iterable of cert res = windows.crypto.encrypt(cert, message_to_encrypt) @@ -166,7 +167,7 @@ def test_randomkeypair(randomkeypair): def test_encrypt_decrypt_multiple_receivers(rawcert, rawpfx, randomkeypair): - message_to_encrypt = "\xff\x00 Testing message \xff\x01" + message_to_encrypt = b"\xff\x00 Testing message \xff\x01" # Receiver 1: random key pair randcert, randrawpfx = randomkeypair randpfx = windows.crypto.import_pfx(randrawpfx, RANDOM_PFX_PASSWORD) @@ -197,7 +198,7 @@ def test_certificate_from_store(): def test_sign_verify(rawcert, rawpfx): - message_to_sign = "Testing message \xff\x01" + message_to_sign = b"Testing message \xff\x01" # Load PFX (priv+pub key) & certif (pubkey only) pfx = windows.crypto.import_pfx(rawpfx, TEST_PFX_PASSWORD) cert = windows.crypto.Certificate.from_buffer(rawcert) @@ -208,14 +209,14 @@ def test_sign_verify(rawcert, rawpfx): def test_sign_verify_fail(rawcert, rawpfx): - message_to_sign = "Testing message \xff\x01" + message_to_sign = b"Testing message \xff\x01" # Load PFX (priv+pub key) & certif (pubkey only) pfx = windows.crypto.import_pfx(rawpfx, TEST_PFX_PASSWORD) cert = windows.crypto.Certificate.from_buffer(rawcert) signed_blob = windows.crypto.sign(pfx.certs[0], message_to_sign) assert message_to_sign in signed_blob # Tamper the signed mesasge content - signed_blob = signed_blob.replace("message", "massage") + signed_blob = signed_blob.replace(b"message", b"massage") with pytest.raises(windows.winproxy.WinproxyError) as excinfo: decoded_blob = windows.crypto.verify_signature(cert, signed_blob) assert excinfo.value.winerror == gdef.STATUS_INVALID_SIGNATURE diff --git a/tests/test_evtlog.py b/tests/test_evtlog.py index 1eb1ab7..ed36ec7 100644 --- a/tests/test_evtlog.py +++ b/tests/test_evtlog.py @@ -9,7 +9,7 @@ import windows.winobject.event_log as evtl CHANNEL_NAME = "Microsoft-Windows-Windows Firewall With Advanced Security/Firewall" PUBLISHER_NAME = "Microsoft-Windows-Windows Firewall With Advanced Security" -ALL_FIREWALL_CHAN = ["Microsoft-Windows-Windows Firewall With Advanced Security/Firewall", +SOME_FIREWALL_CHAN = ["Microsoft-Windows-Windows Firewall With Advanced Security/Firewall", "Microsoft-Windows-Windows Firewall With Advanced Security/ConnectionSecurity", "Microsoft-Windows-Windows Firewall With Advanced Security/FirewallVerbose", "Microsoft-Windows-Windows Firewall With Advanced Security/ConnectionSecurityVerbose", @@ -39,25 +39,27 @@ def test_event_channel_query(name, eventid): event_data_names = chan.get_event_metadata(eventid).event_data # Check all event data match event metadata description for evt in all_id_events: - assert set(evt.data.keys()) == set(event_data_names) + # assert set(evt.data.keys()) == set(event_data_names) + assert set(evt.data.keys()) == set(x["name"] for x in event_data_names) -@pytest.mark.parametrize("name, chans, eventid", [(PUBLISHER_NAME, ALL_FIREWALL_CHAN, 2004)]) +@pytest.mark.parametrize("name, chans, eventid", [(PUBLISHER_NAME, SOME_FIREWALL_CHAN, 2004)]) def test_event_publisher(name, chans, eventid): publisher = windows.system.event_log[name] assert isinstance(publisher, evtl.EvtPublisher) assert publisher.name == name pmetadata = publisher.metadata - assert set(chan.name for chan in pmetadata.channels) == set(chans) + # Pourquoi on a "System" dedans ? + assert set(chan.name for chan in pmetadata.channels) >= set(chans) assert eventid in [evtmedata.id for evtmedata in pmetadata.events_metadata] -POWERSHELL_PATH = r"C:\Windows\System32\WindowsPowershell\v1.0\powershell.exe" -POWERSHELL_ARG = "PFW_TEST_STRING.NOTEXISTS" +POWERSHELL_PATH = br"C:\Windows\System32\WindowsPowershell\v1.0\powershell.exe" +POWERSHELL_ARG = [b"-NonInteractive]", b"PFW_TEST_STRING.NOTEXISTS"] def test_new_event(): chan = windows.system.event_log["Microsoft-Windows-PowerShell/Operational"] pre_events = chan.events - p = windows.utils.create_process(POWERSHELL_PATH, ["PFW_TEST_STRING.NOTEXISTS"], show_windows=False) + p = windows.utils.create_process(POWERSHELL_PATH, POWERSHELL_ARG, show_windows=False) p.wait() import time; time.sleep(1) # It seems to take some time to log the event post_events = chan.events @@ -82,7 +84,7 @@ def test_event_close(): memory_usage_in_ko = (post_usage - start_usage) / 1024 # With auto-evtclose of evt there should not be too much memory used when # Variable are not accessible anymore - assert memory_usage_in_mo == 0 + assert memory_usage_in_mo <= 0.5 def test_evthandle_close(): start_usage = windows.current_process.memory_info.PrivateUsage @@ -94,4 +96,4 @@ def test_evthandle_close(): # windows.winproxy.EvtClose(chan) post_usage = windows.current_process.memory_info.PrivateUsage memory_usage_in_mo = (post_usage - start_usage) / 1024 / 1024 - assert memory_usage_in_mo == 0 + assert memory_usage_in_mo <= 0.5 diff --git a/tests/test_generated_def.py b/tests/test_generated_def.py index 1c851e4..c059c62 100644 --- a/tests/test_generated_def.py +++ b/tests/test_generated_def.py @@ -1,8 +1,10 @@ import pytest import windows import windows.remotectypes as rctypes +import ctypes +import json -from pfwtest import * +from .pfwtest import * def assert_struct_offset(struct, field, offset): assert getattr(struct, field).offset == offset @@ -45,4 +47,52 @@ def test_peb64_fields(): assert_peb_offset("PostProcessInitRoutine", 0x230) # Field just after 'GdiHandleBuffer' allow to also check the 'GdiHandleBuffer' size hack assert_peb_offset("SessionId", 0x2c0) assert_peb_offset("CSDVersion", 0x02E8) - assert_peb_offset("MinimumStackCommit", 0x0318) \ No newline at end of file + assert_peb_offset("MinimumStackCommit", 0x0318) + +def test_cs_custom_define(): + assert windows.generated_def.CS_USER_32B == 0x23 + assert windows.generated_def.CS_USER_64B == 0x33 + +# typedef struct _DnsRecordFlags +# { +# DWORD Section : 2; +# DWORD Delete : 1; +# DWORD CharSet : 2; +# DWORD Unused : 3; +# DWORD Reserved : 24; +# } +# DNS_RECORD_FLAGS; + +# Size should be 4 bytes (2+1+2+3+24) == 32 == 4 bytes +def test_dns_record_flags_size(): + assert ctypes.sizeof(gdef.DNS_RECORD_FLAGS) == 4 + + +def test_str_json_serialization(): + # Until dec2019 the __str__ of Flags were that same as __repr__ + # Flag being a int subclasse it would break json encoding as str(x) is used for int & subclasses + # I do not find this acceptable anymore + # __str__ of generated_def will now be really different from __repr__ and try to keep good level of compatility + # with expected output of __str__ by the stdlib + + data = {"code": gdef.CREATE_SUSPENDED, "other": [gdef.ALPC_MESSAGE_VIEW_ATTRIBUTE, gdef.szOID_RSA_RC4]} + json_data = json.dumps(data) + newdata = json.loads(json_data) # Will fail if bad Flag.__str__ + assert "CREATE_SUSPENDED" not in json_data + assert newdata == {"code": gdef.CREATE_SUSPENDED, "other": [gdef.ALPC_MESSAGE_VIEW_ATTRIBUTE, gdef.szOID_RSA_RC4]} + assert type(newdata["code"]) is int + + +def test_psid_compare(): + msid = gdef.PSID.from_string + # Do not reuse the same object as we do not want to fallback on compare based on address + assert msid("S-1-5-12345") == msid("S-1-5-12345") + assert msid("S-1-5-123") != msid("S-1-5-42") + assert not (msid("S-1-5-12345") != msid("S-1-5-12345")) + assert not (msid("S-1-5-12345") == msid("S-1-5-42")) + +def test_psid_from_to_string(): + initial_str = "S-1-5-12345" + sid = gdef.PSID.from_string(initial_str) + assert str(sid) == initial_str + assert gdef.PSID.from_string(str(sid)) == sid diff --git a/tests/test_hook.py b/tests/test_hook.py index 1d83801..4aada2c 100644 --- a/tests/test_hook.py +++ b/tests/test_hook.py @@ -7,29 +7,41 @@ import windows.generated_def as gdef import windows.native_exec.simple_x86 as x86 import windows.native_exec.simple_x64 as x64 +try: + import _winreg as winreg +except ImportError as e: + import winreg -from pfwtest import * + +from .pfwtest import * pytestmark = pytest.mark.usefixtures('check_for_gc_garbage') +if windows.pycompat.is_py3: + function_to_hook = "RegOpenKeyExW" + callback_type = windows.hooks.RegOpenKeyExWCallback +else: + function_to_hook = "RegOpenKeyExA" + callback_type = windows.hooks.RegOpenKeyExACallback + def test_self_iat_hook_success(): """Test hook success in single(self) thread""" pythondll_mod = [m for m in windows.current_process.peb.modules if m.name.startswith("python") and m.name.endswith(".dll")][0] - RegOpenKeyExA = [n for n in pythondll_mod.pe.imports['advapi32.dll'] if n.name == "RegOpenKeyExA"][0] + RegOpenKeyEx = [n for n in pythondll_mod.pe.imports['advapi32.dll'] if n.name == function_to_hook][0] hook_value = [] - @windows.hooks.RegOpenKeyExACallback + @callback_type def open_reg_hook(hKey, lpSubKey, ulOptions, samDesired, phkResult, real_function): hook_value.append((hKey, lpSubKey.value)) phkResult[0] = 12345678 return 0 - x = RegOpenKeyExA.set_hook(open_reg_hook) - import _winreg + x = RegOpenKeyEx.set_hook(open_reg_hook) + open_args = (0x12345678, "MY_KEY_VALUE") - k = _winreg.OpenKey(*open_args) + k = winreg.OpenKey(*open_args) assert k.handle == 12345678 assert hook_value[0] == open_args # Remove the hook @@ -38,17 +50,16 @@ def test_self_iat_hook_success(): def test_self_iat_hook_fail_return(): """Test hook fail in single(self) thread""" pythondll_mod = [m for m in windows.current_process.peb.modules if m.name.startswith("python") and m.name.endswith(".dll")][0] - RegOpenKeyExA = [n for n in pythondll_mod.pe.imports['advapi32.dll'] if n.name == "RegOpenKeyExA"][0] + RegOpenKeyEx = [n for n in pythondll_mod.pe.imports['advapi32.dll'] if n.name == function_to_hook][0] - @windows.hooks.RegOpenKeyExACallback + @callback_type def open_reg_hook_fail(hKey, lpSubKey, ulOptions, samDesired, phkResult, real_function): return 0x11223344 - x = RegOpenKeyExA.set_hook(open_reg_hook_fail) - import _winreg + x = RegOpenKeyEx.set_hook(open_reg_hook_fail) open_args = (0x12345678, "MY_KEY_VALUE") with pytest.raises(WindowsError) as ar: - _winreg.OpenKey(*open_args) + winreg.OpenKey(*open_args) assert ar.value.winerror == 0x11223344 x.disable() @@ -73,6 +84,7 @@ def test_self_iat_hook_multithread(): # Trigger from another thread k32 = [m for m in cp.peb.modules if m.name == "kernel32.dll"][0] load_libraryA = k32.pe.exports["LoadLibraryA"] + with cp.allocated_memory(0x1000) as addr: cp.write_memory(addr, "DLLNOTFOUND.NOT_A_REAL_DLL" + "\x00") t = cp.create_thread(load_libraryA, addr) diff --git a/tests/test_improved_buffer.py b/tests/test_improved_buffer.py index 5829af9..ab06b9b 100644 --- a/tests/test_improved_buffer.py +++ b/tests/test_improved_buffer.py @@ -3,7 +3,7 @@ import ctypes import windows.utils as utils import windows.generated_def as gdef -from pfwtest import * +from .pfwtest import * @pytest.mark.parametrize("type, size", [ @@ -27,11 +27,11 @@ def test_improved_buffer(params, expected_type, expected_size): assert len(x) == expected_size @pytest.mark.parametrize("c_type, buffer, expected_size", [ -(gdef.CHAR, "12345", 5), -(gdef.WCHAR, "\x001\x002\x003\x004\x005", 5), -(gdef.DWORD, "1111222233334444", 4), +(gdef.CHAR, b"12345", 5), +(gdef.WCHAR, b"\x001\x002\x003\x004\x005", 5), +(gdef.DWORD, b"1111222233334444", 4), ]) -def test_parial_buffer_size_guess(c_type, buffer, expected_size): +def test_partial_buffer_size_guess(c_type, buffer, expected_size): buf = windows.utils.BUFFER(c_type).from_buffer_copy(buffer) assert len(buf) == expected_size diff --git a/tests/test_native_utils.py b/tests/test_native_utils.py index a448520..d20a275 100644 --- a/tests/test_native_utils.py +++ b/tests/test_native_utils.py @@ -4,8 +4,9 @@ import windows import windows.generated_def as gdef from windows.native_exec import nativeutils +from windows.pycompat import basestring, int_types -from pfwtest import * +from .pfwtest import * @check_for_gc_garbage class TestNativeUtils(object): @@ -18,14 +19,14 @@ class TestNativeUtils(object): @process_64bit_only def test_strlena64(self): strlena64 = windows.native_exec.create_function(nativeutils.StrlenA64.get_code(), [gdef.UINT, gdef.LPCSTR]) - assert strlena64("YOLO") == 4 - assert strlena64("") == 0 + assert strlena64(b"YOLO") == 4 + assert strlena64(b"") == 0 @process_64bit_only def test_getprocaddr64(self): getprocaddr64 = windows.native_exec.create_function(nativeutils.GetProcAddress64.get_code(), [gdef.ULONG64, gdef.LPCWSTR, gdef.LPCSTR]) k32 = [mod for mod in windows.current_process.peb.modules if mod.name == "kernel32.dll"][0] - exports = [(x,y) for x,y in k32.pe.exports.items() if isinstance(x, basestring)] + exports = [(x,y) for x,y in k32.pe.exports.items() if isinstance(x, basestring) and isinstance(y, int_types)] for name, addr in exports: name = name.encode() @@ -33,8 +34,8 @@ class TestNativeUtils(object): # Put name in test to know which function caused the assert fails assert (name, hex(addr)) == (name, hex(compute_addr)) - assert getprocaddr64("YOLO.DLL", "whatever") == 0xfffffffffffffffe - assert getprocaddr64("KERNEL32.DLL", "YOLOAPI") == 0xffffffffffffffff + assert getprocaddr64("YOLO.DLL", b"whatever") == 0xfffffffffffffffe + assert getprocaddr64("KERNEL32.DLL", b"YOLOAPI") == 0xffffffffffffffff @process_32bit_only def test_strlenw32(self): @@ -45,14 +46,14 @@ class TestNativeUtils(object): @process_32bit_only def test_strlena32(self): strlena32 = windows.native_exec.create_function(nativeutils.StrlenA32.get_code(), [gdef.UINT, gdef.LPCSTR]) - assert strlena32("YOLO") == 4 - assert strlena32("") == 0 + assert strlena32(b"YOLO") == 4 + assert strlena32(b"") == 0 @process_32bit_only def test_getprocaddr32(self): getprocaddr32 = windows.native_exec.create_function(nativeutils.GetProcAddress32.get_code(), [gdef.UINT, gdef.LPCWSTR, gdef.LPCSTR]) k32 = [mod for mod in windows.current_process.peb.modules if mod.name == "kernel32.dll"][0] - exports = [(x,y) for x,y in k32.pe.exports.items() if isinstance(x, basestring)] + exports = [(x,y) for x,y in k32.pe.exports.items() if isinstance(x, basestring) and isinstance(y, int_types)] for name, addr in exports: name = name.encode() @@ -60,5 +61,5 @@ class TestNativeUtils(object): # Put name in test to know which function caused the assert fails assert (name, hex(addr)) == (name, hex(compute_addr)) - assert getprocaddr32("YOLO.DLL", "whatever") == 0xfffffffe - assert getprocaddr32("KERNEL32.DLL", "YOLOAPI") == 0xffffffff \ No newline at end of file + assert getprocaddr32("YOLO.DLL", b"whatever") == 0xfffffffe + assert getprocaddr32("KERNEL32.DLL", b"YOLOAPI") == 0xffffffff \ No newline at end of file diff --git a/tests/test_object_manager.py b/tests/test_object_manager.py index c55b098..6cc14ed 100644 --- a/tests/test_object_manager.py +++ b/tests/test_object_manager.py @@ -1,7 +1,7 @@ import pytest import windows -from pfwtest import * +from .pfwtest import * KNOWN_DIRECTORY_OBJECT = ("KnownDLLs", "\\KnownDLLs") diff --git a/tests/test_pipe.py b/tests/test_pipe.py index c18f7f2..25af0a4 100644 --- a/tests/test_pipe.py +++ b/tests/test_pipe.py @@ -1,5 +1,5 @@ import windows.pipe -from pfwtest import * +from .pfwtest import * import time diff --git a/tests/test_process.py b/tests/test_process.py index adc84d6..fbfb21a 100644 --- a/tests/test_process.py +++ b/tests/test_process.py @@ -38,16 +38,16 @@ class TestCurrentProcessWithCheckGarbage(object): imp = python_module.pe.imports assert "kernel32.dll" in imp.keys(), 'Kernel32.dll not in python imports' current_proc_id_iat = [f for f in imp["kernel32.dll"] if f.name == "GetCurrentProcessId"][0] - k32_base = windows.winproxy.LoadLibraryA("kernel32.dll") - assert windows.winproxy.GetProcAddress(k32_base, "GetCurrentProcessId") == current_proc_id_iat.value + k32_base = windows.winproxy.LoadLibraryA(b"kernel32.dll") + assert windows.winproxy.GetProcAddress(k32_base, b"GetCurrentProcessId") == current_proc_id_iat.value def test_current_process_pe_exports(self): mods = [m for m in windows.current_process.peb.modules if m.name == "kernel32.dll"] assert mods, 'Could not find "kernel32.dll" in current process modules' k32 = mods[0] get_current_proc_id = k32.pe.exports['GetCurrentProcessId'] - k32_base = windows.winproxy.LoadLibraryA("kernel32.dll") - assert windows.winproxy.GetProcAddress(k32_base, "GetCurrentProcessId") == get_current_proc_id + k32_base = windows.winproxy.LoadLibraryA(b"kernel32.dll") + assert windows.winproxy.GetProcAddress(k32_base, b"GetCurrentProcessId") == get_current_proc_id def test_local_process_pe_sections(self): mods = [m for m in windows.current_process.peb.modules if m.name == "kernel32.dll"] @@ -84,13 +84,13 @@ class TestProcessWithCheckGarbage(object): def test_read_memory(self, proc32_64): k32 = [m for m in proc32_64.peb.modules if m.name == "kernel32.dll"][0] - assert proc32_64.read_memory(k32.baseaddr, 2), "MZ" + assert proc32_64.read_memory(k32.baseaddr, 2), b"MZ" def test_write_memory(self, proc32_64): k32 = [m for m in proc32_64.peb.modules if m.name == "kernel32.dll"][0] with proc32_64.virtual_protected(k32.baseaddr, 2, gdef.PAGE_EXECUTE_READWRITE): - proc32_64.write_memory(k32.baseaddr, "XD") - assert proc32_64.read_memory(k32.baseaddr, 2) == "XD" + proc32_64.write_memory(k32.baseaddr, b"XD") + assert proc32_64.read_memory(k32.baseaddr, 2) == b"XD" def test_read_string(self, proc32_64): test_string = "TEST_STRING" @@ -112,7 +112,8 @@ class TestProcessWithCheckGarbage(object): test_string = "TEST_STRING" string_to_write = test_string + "\x00" with proc32_64.allocated_memory(0x1000) as addr: - proc32_64.write_memory(addr, "\x00".join(string_to_write)) + # Just check based on previous 'encoding' method + proc32_64.write_memory(addr, test_string.encode("utf-16")) assert proc32_64.read_wstring(addr) == test_string def test_read_wstring_end_page(self, proc32_64): @@ -166,6 +167,17 @@ class TestProcessWithCheckGarbage(object): dword = proc32_64.read_dword(addr) assert dword == 0x42424242 + def test_execute_python_good_version(self, proc32_64): + PIPE_NAME = "PFW_TEST_Pipe" + rcode = r"""import sys; import windows; windows.pipe.send_object("{pipe}", list(sys.version_info))""" + + with windows.pipe.create(PIPE_NAME) as np: + proc32_64.execute_python(rcode.format(pipe=PIPE_NAME)) + version = np.recv() + # Check only major/minor + assert version[:2] == list(sys.version_info[:2]) + + @python_injection def test_execute_python_suspended(self, proc32_64_suspended): proc = proc32_64_suspended @@ -230,7 +242,12 @@ class TestProcessWithCheckGarbage(object): res = proc32_64.execute_python("import time;time.sleep(0.1); 2") assert res == True with pytest.raises(windows.injection.RemotePythonError) as ar: - t = proc32_64.execute_python("import time;time.sleep(0.1); raise ValueError('BYE')") + t = proc32_64.execute_python("import time;time.sleep(0.1); raise ValueError('EXCEPTION_MESSAGE')") + # Check the RemotePythonError contains the remote exception text + assert b"ValueError: EXCEPTION_MESSAGE" in ar.value.args[0] + + def test_execute_python_create_console(self, proc32_64): + res = proc32_64.execute_python("import windows; windows.utils.create_console()") def test_thread_start_address(self, proc32_64): t = proc32_64.threads[0] diff --git a/tests/test_registry.py b/tests/test_registry.py index 62c1714..42196a5 100644 --- a/tests/test_registry.py +++ b/tests/test_registry.py @@ -1,7 +1,7 @@ import datetime import pytest -from pfwtest import * +from .pfwtest import * import windows @@ -12,6 +12,11 @@ basekeytest = windows.system.registry(testbasekeypath, gdef.KEY_WOW64_64KEY | gd if not basekeytest.exists: basekeytest.create() +if windows.pycompat.is_py3: + REG_TEST_BINARY_DATA = b"BIN_DATA\x01\x02\x03\x00" + bytes(range(256)) +else: + REG_TEST_BINARY_DATA = "BIN_DATA\x01\x02\x03\x00" + "".join(chr(i) for i in range(256)) + @pytest.fixture() def empty_test_base_key(): assert basekeytest.exists @@ -27,6 +32,7 @@ def test_registry_set_get_simple_values(value): basekeytest["tst1"] = value assert basekeytest["tst1"].value == value + # TODO: test with other registry type (the stranges ones) @pytest.mark.parametrize("value, type", [ (0x11223344, gdef.REG_DWORD), # same as gdef.REG_DWORD_LITTLE_ENDIAN @@ -37,12 +43,12 @@ def test_registry_set_get_simple_values(value): ("Hello world %path%", gdef.REG_EXPAND_SZ), (["AAAA", "BBBB", "CCCC"], gdef.REG_MULTI_SZ), # Binary format and associated - ("123\x00123" + "".join(chr(c) for c in range(256)), gdef.REG_BINARY), - ("Hello world", gdef.REG_LINK), - ("", gdef.REG_NONE), - ("Not really None :)\x11\x22\x00ABCD", gdef.REG_NONE), - ("Test-Unknown-format", 0x11223344), # Unknown registry type - ("Test-Unknown-format\x00\x01\xff\xfe Lol", 0xffffffff), # Unknown registry type + (REG_TEST_BINARY_DATA, gdef.REG_BINARY), + (b"Hello-world", gdef.REG_LINK), + (b"", gdef.REG_NONE), + (b"Not really None :)\x11\x22\x00ABCD", gdef.REG_NONE), + (b"Test-Unknown-format", 0x11223344), # Unknown registry type + (b"Test-Unknown-format\x00\x01\xff\xfe Lol", 0xffffffff), # Unknown registry type ]) def test_registry_set_get_simple_values_with_types(value, type): basekeytest["tst2"] = (value, type) @@ -51,12 +57,12 @@ def test_registry_set_get_simple_values_with_types(value, type): @pytest.mark.parametrize("value, type", [ # "\xff\xd8".decode("utf-16") -> UnicodeDecodeError - ("\xff\xd8", gdef.REG_MULTI_SZ), + (b"\xff\xd8", gdef.REG_MULTI_SZ), # Is NOT valid UTF-16 (len == 33) - ("Hello\x00World\x00This is not unicode\x00\x00", gdef.REG_MULTI_SZ), + (b"Hello\x00World\x00This is not unicode\x00\x00", gdef.REG_MULTI_SZ), # Is valid UTF-16 (len == 40) # Should the decoding be completly different ? - ("Hello\x00World\x00This is not really unicode\x00\x00", gdef.REG_MULTI_SZ), + (b"Hello\x00World\x00This is not really unicode\x00\x00", gdef.REG_MULTI_SZ), ]) def test_registry_badly_encoded_values(value, type): # Bypass any encoding logic to setup bad key @@ -136,7 +142,7 @@ def test_registry_get_key_info(): other_info = subkey.info assert other_info[0] == 0 # Nb subkeys assert other_info[1] == 2 # Nb values - assert isinstance(other_info[2], (int, long)) # Last write + assert isinstance(other_info[2], windows.pycompat.int_types) # Last write def test_registry_key_empty(): subname = "MyTestKeyEmpty" @@ -208,7 +214,10 @@ def test_registry_unicode_value_name_enumerate_with_race_condition(monkeypatch): subkey.delete() def test_registry_unicode_subkeys_create_delete(): - subname = UNICODE_RU_STRING + unicode(datetime.datetime.now()) + if windows.pycompat.is_py3: + subname = UNICODE_RU_STRING + str(datetime.datetime.now()) + else: + subname = UNICODE_RU_STRING + unicode(datetime.datetime.now()) subkey = basekeytest(subname) assert not subkey.exists subkey.create() diff --git a/tests/test_rpc.py b/tests/test_rpc.py index 80924a3..9cb3d1b 100644 --- a/tests/test_rpc.py +++ b/tests/test_rpc.py @@ -6,7 +6,7 @@ import windows.rpc as rpc from windows.rpc import ndr import windows.generated_def as gdef -from pfwtest import * +from .pfwtest import * diff --git a/tests/test_security.py b/tests/test_security.py index 4bed5f1..73ed0dc 100644 --- a/tests/test_security.py +++ b/tests/test_security.py @@ -1,8 +1,10 @@ import windows.security from windows.security import SecurityDescriptor -from pfwtest import * +from .pfwtest import * import ctypes + + # CC -> Create-Child -> 1 # GR -> Generic read -> 0x80000000L # AN -> Anonymous -> S-1-5-7 @@ -88,7 +90,6 @@ COMPLEXE_SDDL_GUID = [ @pytest.mark.parametrize("sddl, obj_guid, inherited_object_guid", COMPLEXE_SDDL_GUID) def test_complex_ace_guid_sid(sddl, obj_guid, inherited_object_guid): - print(sddl) sd = SecurityDescriptor.from_string(sddl) assert sd.dacl is not None ace = sd.dacl[0] @@ -165,7 +166,7 @@ RESOURCE_ATTRIBUTES_SDDLS = [ gdef.PSID.from_string("S-1-2-3-4-5-6-7-8-9"))), ("""S:(RA;;;;;WD; ("TestName",TX,0, 42000042, 0123456789abcdef))""", - ("B\x00\x00B", "\x01\x23\x45\x67\x89\xab\xcd\xef")), + (b"B\x00\x00B", b"\x01\x23\x45\x67\x89\xab\xcd\xef")), ("""S:(RA;;;;;WD; ("TestName",TB,0, 0, 1, 0, 0, 1))""", (False, True, False, False, True)), @@ -176,15 +177,14 @@ def test_ace_resource_attribute(sddl, expected_values): sd = SecurityDescriptor.from_string(sddl) ra = sd.sacl[0] assert ra.Header.AceType == gdef.SYSTEM_RESOURCE_ATTRIBUTE_ACE_TYPE - attr = ra.attribute assert attr.name == "TestName" assert attr.values == expected_values CONDITIONAL_SDDLS = [ - ("D:AI(XA;;GR;;;WD;(ATTR1))", "ATTR1"), - ("D:AI(XD;;GR;;;WD;(ATTR2))", "ATTR2"), - ("S:AI(XU;;GR;;;WD;(ATTR3))", "ATTR3") + ("D:AI(XA;;GR;;;WD;(ATTR1))", b"ATTR1"), + ("D:AI(XD;;GR;;;WD;(ATTR2))", b"ATTR2"), + ("S:AI(XU;;GR;;;WD;(ATTR3))", b"ATTR3") ] @pytest.mark.parametrize("sddl, expected_value", CONDITIONAL_SDDLS) @@ -196,8 +196,8 @@ def test_conditional_ace_applicationdata(sddl, expected_value): ace = acl[0] appdata = ace.application_data # https://msdn.microsoft.com/en-us/library/hh877860.aspx - assert appdata.startswith("artx") - assert expected_value in appdata.replace("\x00", "") + assert appdata.startswith(b"artx") + assert expected_value in appdata.replace(b"\x00", b"") diff --git a/tests/test_service.py b/tests/test_service.py index 0676ce1..de45a98 100644 --- a/tests/test_service.py +++ b/tests/test_service.py @@ -12,10 +12,10 @@ def test_services_process(): def test_service_appinfo(): - appinfos = [x for x in windows.system.services if x.name == "Appinfo"] + appinfos = [x for x in windows.system.services if x.name == b"Appinfo"] assert len(appinfos) == 1 appinfo = appinfos[0] assert appinfo.status.type & gdef.SERVICE_WIN32_OWN_PROCESS # Check other fields - assert appinfo.name == "Appinfo" - assert appinfo.description == "Application Information" \ No newline at end of file + assert appinfo.name == b"Appinfo" + assert appinfo.description == b"Application Information" \ No newline at end of file diff --git a/tests/test_system.py b/tests/test_system.py index 60c8a98..0fbef90 100644 --- a/tests/test_system.py +++ b/tests/test_system.py @@ -1,7 +1,7 @@ import pytest import windows -from pfwtest import * +from .pfwtest import * @check_for_gc_garbage class TestSystemWithCheckGarbage(object): @@ -22,7 +22,9 @@ class TestSystemWithCheckGarbage(object): def test_computer_name(self): - return windows.system.computer_name + computer_name = windows.system.computer_name + assert computer_name + assert isinstance(computer_name, str) def test_services(self): return windows.system.services @@ -49,7 +51,7 @@ class TestSystemWithCheckGarbage(object): return windows.system.object_manager def test_system_modules_ntosk(self): - assert windows.system.modules[0].name.endswith("ntoskrnl.exe") + assert windows.system.modules[0].name.endswith(b"ntoskrnl.exe") @check_for_gc_garbage diff --git a/tests/test_syswow.py b/tests/test_syswow.py index 2db66ef..32ff65d 100644 --- a/tests/test_syswow.py +++ b/tests/test_syswow.py @@ -6,7 +6,7 @@ import windows.generated_def as gdef import windows.native_exec.simple_x86 as x86 import windows.native_exec.simple_x64 as x64 -from pfwtest import * +from .pfwtest import * pytestmark = pytest.mark.usefixtures('check_for_gc_garbage') @@ -44,10 +44,8 @@ class TestSyswowRemoteProcess(object): remote_python_code = """ import windows import windows.native_exec.simple_x64 as x64 - windows.utils.create_console() x64_code = x64.assemble("mov r11, 0x1122334455667788; mov rax, 0x8877665544332211; mov [{0}], rax ;label :loop; jmp :loop; nop; nop; ret") res = windows.syswow64.execute_64bits_code_from_syswow(x64_code) - print("res = {{0}}".format(hex(res))) windows.current_process.write_qword({0}, res) """.format(addr) diff --git a/tests/test_token.py b/tests/test_token.py index 1156a1b..3961204 100644 --- a/tests/test_token.py +++ b/tests/test_token.py @@ -13,10 +13,16 @@ def curtok(): def newtok(): return windows.current_process.token.duplicate() + +if windows.pycompat.is_py3: + unicode_type = str +else: + unicode_type = unicode + def test_token_info(curtok): - assert isinstance(curtok.computername, basestring) - assert isinstance(curtok.username, basestring) - assert isinstance(curtok.integrity, (int, long)) + assert isinstance(curtok.computername, unicode_type) + assert isinstance(curtok.username, unicode_type) + assert isinstance(curtok.integrity, windows.pycompat.int_types) assert isinstance(curtok.is_elevated, (bool)) def test_lower_integrity(newtok): @@ -38,7 +44,7 @@ def test_token_id(curtok): assert ntok.id != curtok.id mid = ntok.modified_id aid = ntok.authentication_id - ntok.enable_privilege("SeShutDownPrivilege") + ntok.enable_privilege(b"SeShutDownPrivilege") mid2 = ntok.modified_id aid2 = ntok.authentication_id ntok.integrity -= 1 @@ -47,15 +53,15 @@ def test_token_id(curtok): def test_enable_privilege(newtok): - PRIVILEGE_NAME = "SeShutdownPrivilege" + PRIVILEGE_NAME = b"SeShutdownPrivilege" assert not newtok.privileges[PRIVILEGE_NAME] & gdef.SE_PRIVILEGE_ENABLED newtok.enable_privilege(PRIVILEGE_NAME) assert newtok.privileges[PRIVILEGE_NAME] & gdef.SE_PRIVILEGE_ENABLED def test_adjust_privilege(newtok): - PRIVILEGE_NAME = "SeShutdownPrivilege" - PRIVILEGE2_NAME = "SeTimeZonePrivilege" + PRIVILEGE_NAME = b"SeShutdownPrivilege" + PRIVILEGE2_NAME = b"SeTimeZonePrivilege" tok_dup = newtok.duplicate() assert not tok_dup.privileges[PRIVILEGE_NAME] & gdef.SE_PRIVILEGE_ENABLED assert not tok_dup.privileges[PRIVILEGE2_NAME] & gdef.SE_PRIVILEGE_ENABLED diff --git a/tests/test_winproxy.py b/tests/test_winproxy.py index ada46fb..9d1cdf8 100644 --- a/tests/test_winproxy.py +++ b/tests/test_winproxy.py @@ -10,12 +10,12 @@ pytestmark = pytest.mark.usefixtures('check_for_gc_garbage') def test_createfileA_fail(): with pytest.raises(WindowsError) as ar: - windows.winproxy.CreateFileA("NONEXISTFILE.FILE") + windows.winproxy.CreateFileA(b"NONEXISTFILE.FILE") def test_lstrcmpa(): - assert windows.winproxy.lstrcmpA("LOL", "NO-LOL") - assert not windows.winproxy.lstrcmpA("LOL", "LOL") + assert windows.winproxy.lstrcmpA(b"LOL", b"NO-LOL") + assert not windows.winproxy.lstrcmpA(b"LOL", b"LOL") def test_getsystemmetrics(): """Test nothing is raised when GetSystemMetrics() returns 0""" @@ -29,6 +29,10 @@ def test_getsystemmetrics(): windows.winproxy.GetSystemMetrics(gdef.SM_TABLETPC) +def test_NtStatusException_winerror(): + assert gdef.NtStatusException(2).winerror == 2 + assert gdef.NtStatusException(1234).winerror == 1234 + def test_resolve(): ntdll = windows.current_process.peb.modules[1] assert ntdll.name == "ntdll.dll" diff --git a/tests/test_wintrust.py b/tests/test_wintrust.py index 58a67c1..9ae7b1f 100644 --- a/tests/test_wintrust.py +++ b/tests/test_wintrust.py @@ -4,7 +4,8 @@ import pytest import windows import windows.generated_def as gdef -from pfwtest import * +from .pfwtest import * +from windows.pycompat import is_py3 pytestmark = pytest.mark.usefixtures('check_for_gc_garbage') @@ -12,10 +13,18 @@ def test_script_file_not_signed(): assert not windows.wintrust.is_signed(__file__) assert windows.wintrust.check_signature(__file__) == gdef.TRUST_E_SUBJECT_FORM_UNKNOWN -def test_python_not_signed(): - python_path = sys.executable - assert not windows.wintrust.is_signed(python_path) - assert windows.wintrust.check_signature(python_path) == gdef.TRUST_E_NOSIGNATURE +if is_py3: + # Py3 binaries are signed + def test_python_signature(): + python_path = sys.executable + assert windows.wintrust.is_signed(python_path) + assert windows.wintrust.check_signature(python_path) == 0 +else: + # Py2 binaries are NOT signed + def test_python_signature(): + python_path = sys.executable + assert not windows.wintrust.is_signed(python_path) + assert windows.wintrust.check_signature(python_path) == gdef.TRUST_E_NOSIGNATURE def test_kernel32_signed(): k32_path = r"C:\windows\system32\kernel32.dll" diff --git a/tests/test_winutils.py b/tests/test_winutils.py index 69538c6..0f56e51 100644 --- a/tests/test_winutils.py +++ b/tests/test_winutils.py @@ -1,3 +1,4 @@ +import sys import pytest import os import tempfile @@ -5,11 +6,13 @@ import tempfile from datetime import datetime, timedelta import windows.utils import windows.generated_def as gdef -from pfwtest import * +from .pfwtest import * + +if sys.version_info.major >= 3: + unicode = str pytestmark = pytest.mark.usefixtures('check_for_gc_garbage') - ntqueryinformationfile_info_structs = { gdef.FileAccessInformation: gdef.FILE_ACCESS_INFORMATION, gdef.FileAlignmentInformation: gdef.FILE_ALIGNMENT_INFORMATION, @@ -116,21 +119,21 @@ def test_unix_timestamp_from_filetime(): assert datetime.utcfromtimestamp(1504765968.072731) == datetime(2017, 9, 7, 6, 32, 48, 72731) assert windows.utils.unix_timestamp_from_filetime(131492395680727309) == 1504765968.072731 + # Well py3 will round it to 1504765968.07273 + # Because round(0.5) == 0 (vs 1 in py2) assert windows.utils.unix_timestamp_from_filetime(131492395680727305) == 1504765968.072731 -@pytest.mark.parametrize("prefix,prefixtype", [ - ("long_ascii_prefix", str), - (u'\u4e2d\u56fd\u94f6\u884c\u7f51\u94f6\u52a9\u624b', unicode), +@pytest.mark.parametrize("prefix", [ + ("long_ascii_prefix"), + (u'\u4e2d\u56fd\u94f6\u884c\u7f51\u94f6\u52a9\u624b'), ]) -def test_long_short_path_str_unicode(prefix, prefixtype): +def test_long_short_path_str_unicode(prefix): """Test that get_short_path/get_long_path works with str/unicode path and preserve path type""" - assert isinstance(prefix, prefixtype) with tempfile.NamedTemporaryFile(prefix=prefix) as f: basename = f.name.lower() - assert isinstance(basename, prefixtype) short_name = windows.utils.get_short_path(basename).lower() - assert isinstance(short_name, prefixtype) + assert isinstance(short_name, unicode) assert short_name != basename full_name = windows.utils.get_long_path(short_name).lower() - assert isinstance(full_name, prefixtype) + assert isinstance(full_name, unicode) assert full_name == basename \ No newline at end of file diff --git a/tests/test_wmi.py b/tests/test_wmi.py index 4878bea..aca003f 100644 --- a/tests/test_wmi.py +++ b/tests/test_wmi.py @@ -2,8 +2,9 @@ import pytest import windows import windows.generated_def as gdef +from windows.pycompat import basestring -from pfwtest import * +from .pfwtest import * ## This comment was in test_system.py: still revelant ? # Well, pytest initialize COM with its own parameters