diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index c09018a..f4707d7 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -125,4 +125,4 @@ jobs: run: py -${{ matrix.python-version}}-${{ matrix.python-bitness-to-test}} -c "import windows; print(windows)" - name: Arm64 pytests - run: py -${{ matrix.python-version}}-${{ matrix.python-bitness-to-test}} -m pytest tests -k "not test_debugger" -v -s + run: py -${{ matrix.python-version}}-${{ matrix.python-bitness-to-test}} -m pytest tests -k "not test_debugger" -v -s -r fEsx diff --git a/tests/conftest.py b/tests/conftest.py index 7dfb520..34e5e07 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -159,11 +159,9 @@ def pytest_configure(config): @pytest.hookimpl(hookwrapper=True, trylast=True) def pytest_runtest_makereport(item, call): outcome = yield - # print("Make report {0} | {1}".format(item, call)) if call.when == "teardown" and call.excinfo and type(call.excinfo.value) == NoLeakAssert: x = outcome.get_result() x.outcome = "failed" - # import pdb;pdb.set_trace() x.LEAK = call.excinfo.value.args[0] diff --git a/tests/pfwtest.py b/tests/pfwtest.py index 473a3f2..578faac 100644 --- a/tests/pfwtest.py +++ b/tests/pfwtest.py @@ -73,13 +73,24 @@ def check_injected_python_installed(request): proc = request.getfixturevalue(procparam) if not windows.injection.find_python_dll_to_inject(proc.bitness): pytest.skip("Python {0}b not installed -> skipping test with python injection into {0}b process".format(proc.bitness)) + return None + +@pytest.fixture +def check_dll_injection_target_architecture(request): + # Find the process parameter + 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] + proc = request.getfixturevalue(procparam) # xfail ARM64 injection as its not implemented if proc.architecture == gdef.IMAGE_FILE_MACHINE_ARM64: request.applymarker("xfail") - return None -python_injection = pytest.mark.usefixtures("check_injected_python_installed") + +dll_injection = pytest.mark.usefixtures("check_dll_injection_target_architecture") +python_injection = pytest.mark.usefixtures("check_dll_injection_target_architecture", "check_injected_python_installed") ## P2 VS PY3 diff --git a/tests/test_handle.py b/tests/test_handle.py index 8008d7c..c39c1d0 100644 --- a/tests/test_handle.py +++ b/tests/test_handle.py @@ -1,6 +1,8 @@ import windows import windows.pipe +from .pfwtest import * + def test_handle_process_id(): handle_with_process = [h for h in windows.system.handles if h.dwProcessId] handle = handle_with_process[-1] @@ -19,8 +21,8 @@ def test_local_handle_type(): PIPE_NAME = "PFW_Test_handle_Pipe" TEST_FILE_FOR_HANDLE = r"C:\Windows\explorer.exe" +@python_injection def test_remote_handle_type_and_name(proc32_64): - # tmpfile proc32_64.execute_python("import windows; import windows.pipe") # A filename that a normal process should not have a handle on (to be sur) proc32_64.execute_python(r"""f = open(r"{filename}")""".format(filename=TEST_FILE_FOR_HANDLE)) diff --git a/tests/test_injection.py b/tests/test_injection.py index 7008e07..bbf99b4 100644 --- a/tests/test_injection.py +++ b/tests/test_injection.py @@ -10,7 +10,7 @@ import windows import windows.generated_def as gdef from .conftest import pop_proc_32, pop_proc_64 -from .pfwtest import DEFAULT_CREATION_FLAGS +from .pfwtest import DEFAULT_CREATION_FLAGS, dll_injection @pytest.fixture(params= [(pop_proc_32, DEFAULT_CREATION_FLAGS), @@ -34,17 +34,20 @@ def proc_3264_runsus(request): del proc # Its really the same test as test_process.test_load_library but with suspended process as well +@dll_injection def test_dll_injection(proc_3264_runsus): assert (not proc_3264_runsus.peb.Ldr) or ("wintrust.dll" not in [mod.name for mod in proc_3264_runsus.peb.modules]) modaddr = windows.injection.load_dll_in_remote_process(proc_3264_runsus, "wintrust.dll") wintrustmod = [mod for mod in proc_3264_runsus.peb.modules if mod.name == "wintrust.dll"][0] assert wintrustmod.baseaddr == modaddr +@dll_injection def test_dll_injection_error_reporting(proc_3264_runsus): with pytest.raises(windows.injection.InjectionFailedError) as excinfo: windows.injection.load_dll_in_remote_process(proc_3264_runsus, "NO_A_DLL.dll") assert excinfo.value.__cause__.winerror == gdef.ERROR_MOD_NOT_FOUND +@dll_injection def test_dll_injection_access_denied(proc_3264_runsus, tmpdir): """Emulate injection of MsStore python, were its DLL are not executable by any other append See: https://github.com/hakril/PythonForWindows/issues/72 diff --git a/tests/test_process.py b/tests/test_process.py index db8b001..0ffe322 100644 --- a/tests/test_process.py +++ b/tests/test_process.py @@ -214,6 +214,7 @@ class TestProcessWithCheckGarbage(object): dword = proc32_64.read_dword(addr) assert dword == 0x42424242 + @python_injection def test_execute_python_good_version(self, proc32_64): PIPE_NAME = "PFW_TEST_Pipe" rcode = r"""import sys; import windows; import windows.pipe; windows.pipe.send_object("{pipe}", list(sys.version_info))""" @@ -293,6 +294,7 @@ class TestProcessWithCheckGarbage(object): # Check the RemotePythonError contains the remote exception text assert b"ValueError: EXCEPTION_MESSAGE" in ar.value.args[0] + @python_injection def test_execute_python_create_console(self, proc32_64): res = proc32_64.execute_python("import windows; windows.utils.create_console()") @@ -370,17 +372,19 @@ class TestProcessWithCheckGarbage(object): time.sleep(0.1) assert t.exit_code == 0x11223344 - + @dll_injection def test_load_library(self, proc32_64): DLL = "wintrust.dll" proc32_64.load_library(DLL) assert DLL in [m.name for m in proc32_64.peb.modules] + @dll_injection def test_load_library_suspended(self, proc32_64_suspended): DLL = "wintrust.dll" proc32_64_suspended.load_library(DLL) assert DLL in [m.name for m in proc32_64_suspended.peb.modules] + @dll_injection def test_load_library_unicode_name(self, proc32_64, tmpdir): mybitness = windows.current_process.bitness UNICODE_FILENAME = u'\u4e2d\u56fd\u94f6\u884c\u7f51\u94f6\u52a9\u624b.dll'