2 test robustness improvements, helpful message on interpreter sandbox error

This commit is contained in:
Darius Houle
2025-01-20 12:53:27 -07:00
parent 217da0d6b1
commit 6715b08ed7
2 changed files with 23 additions and 7 deletions
+16 -7
View File
@@ -4,9 +4,11 @@ import pytest
import os
import sys
import time
import struct
import ctypes
import textwrap
import shutil
import re
import windows
import windows.pipe
@@ -26,8 +28,12 @@ class TestCurrentProcessWithCheckGarbage(object):
return windows.current_process.peb
def test_get_current_process_modules(self):
# Use sys.executable because executable can be a PyInstaller exe
assert os.path.basename(sys.executable) in windows.current_process.peb.modules[0].name
# Use module filename because this executable can be:
# 1. A PyInstaller exe
# 2. A Windows App execution alias (Microsoft Store builds)
current_proc_filename = ctypes.create_string_buffer(1000)
windows.winproxy.GetModuleFileNameA(None, current_proc_filename, 1000)
assert os.path.basename(current_proc_filename.value.decode()) in windows.current_process.peb.modules[0].name
def test_get_current_process_exe(self):
exe = windows.current_process.peb.exe
@@ -38,10 +44,13 @@ class TestCurrentProcessWithCheckGarbage(object):
def test_current_process_pe_imports(self):
python_module = windows.current_process.peb.modules[0]
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(b"kernel32.dll")
assert windows.winproxy.GetProcAddress(k32_base, b"GetCurrentProcessId") == current_proc_id_iat.value
python_dll_regex = re.compile(r'python[0-9.]+dll', re.IGNORECASE)
python_dll_imp = next((i for i in imp.keys() if python_dll_regex.match(i)), None)
assert python_dll_imp is not None, 'Python dll not in python imports'
imp_id_iat = imp[python_dll_imp][0]
mod_base = windows.winproxy.LoadLibraryA(python_dll_imp.encode())
assert windows.winproxy.GetProcAddress(mod_base, imp_id_iat.name.encode()) == imp_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"]
+7
View File
@@ -389,6 +389,13 @@ def execute_python_code(process, code):
# Cache the value ?
py_dll_name = get_dll_name_from_python_version()
pydll_path = find_python_dll_to_inject(process.bitness)
# NB: Sandboxing on Windows Store apps prevents remote loading DLLs stored under "C:\Program Files*\WindowsApps\*"
# This is relevant for remote python execution, as the sandboxed python process is the _only_ one that can
# access its CRT and shared libraries.
if '\\windowsapps\\' in pydll_path.lower():
raise ValueError('Cannot execute remote python code from a sandboxed python interpreter. Install python outside of the Microsoft Store to resolve.')
if sys.version_info.major == 3:
# FOr py3, we may have a per-user install.
# Meaning that the vcruntime140.dll will not be in the injected process path