Updated test for py3

This commit is contained in:
hakril
2020-02-13 22:12:40 +01:00
parent f403856e26
commit 80c6a747da
24 changed files with 271 additions and 139 deletions
+5 -5
View File
@@ -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
+11 -2
View File
@@ -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")
python_injection = pytest.mark.usefixtures("check_injected_python_installed")
## P2 VS PY3
if windows.pycompat.is_py3:
b64decode = base64.decodebytes
else:
b64decode = base64.decodestring
+12 -5
View File
@@ -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():
+6 -5
View File
@@ -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
+17 -16
View File
@@ -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
+11 -9
View File
@@ -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
+52 -2
View File
@@ -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)
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
+23 -11
View File
@@ -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)
+5 -5
View File
@@ -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
+12 -11
View File
@@ -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
assert getprocaddr32("YOLO.DLL", b"whatever") == 0xfffffffe
assert getprocaddr32("KERNEL32.DLL", b"YOLOAPI") == 0xffffffff
+1 -1
View File
@@ -1,7 +1,7 @@
import pytest
import windows
from pfwtest import *
from .pfwtest import *
KNOWN_DIRECTORY_OBJECT = ("KnownDLLs", "\\KnownDLLs")
+1 -1
View File
@@ -1,5 +1,5 @@
import windows.pipe
from pfwtest import *
from .pfwtest import *
import time
+26 -9
View File
@@ -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]
+21 -12
View File
@@ -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()
+1 -1
View File
@@ -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 *
+9 -9
View File
@@ -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"")
+3 -3
View File
@@ -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"
assert appinfo.name == b"Appinfo"
assert appinfo.description == b"Application Information"
+5 -3
View File
@@ -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
+1 -3
View File
@@ -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)
+13 -7
View File
@@ -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
+7 -3
View File
@@ -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"
+14 -5
View File
@@ -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"
+13 -10
View File
@@ -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
+2 -1
View File
@@ -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