Skip to content

Commit 6715b08

Browse files
committed
2 test robustness improvements, helpful message on interpreter sandbox error
1 parent 217da0d commit 6715b08

2 files changed

Lines changed: 23 additions & 7 deletions

File tree

tests/test_process.py

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@
44
import os
55
import sys
66
import time
7-
import struct
7+
import ctypes
8+
89
import textwrap
910
import shutil
11+
import re
1012

1113
import windows
1214
import windows.pipe
@@ -26,8 +28,12 @@ def test_get_current_process_peb(self):
2628
return windows.current_process.peb
2729

2830
def test_get_current_process_modules(self):
29-
# Use sys.executable because executable can be a PyInstaller exe
30-
assert os.path.basename(sys.executable) in windows.current_process.peb.modules[0].name
31+
# Use module filename because this executable can be:
32+
# 1. A PyInstaller exe
33+
# 2. A Windows App execution alias (Microsoft Store builds)
34+
current_proc_filename = ctypes.create_string_buffer(1000)
35+
windows.winproxy.GetModuleFileNameA(None, current_proc_filename, 1000)
36+
assert os.path.basename(current_proc_filename.value.decode()) in windows.current_process.peb.modules[0].name
3137

3238
def test_get_current_process_exe(self):
3339
exe = windows.current_process.peb.exe
@@ -38,10 +44,13 @@ def test_get_current_process_exe(self):
3844
def test_current_process_pe_imports(self):
3945
python_module = windows.current_process.peb.modules[0]
4046
imp = python_module.pe.imports
41-
assert "kernel32.dll" in imp.keys(), 'Kernel32.dll not in python imports'
42-
current_proc_id_iat = [f for f in imp["kernel32.dll"] if f.name == "GetCurrentProcessId"][0]
43-
k32_base = windows.winproxy.LoadLibraryA(b"kernel32.dll")
44-
assert windows.winproxy.GetProcAddress(k32_base, b"GetCurrentProcessId") == current_proc_id_iat.value
47+
python_dll_regex = re.compile(r'python[0-9.]+dll', re.IGNORECASE)
48+
python_dll_imp = next((i for i in imp.keys() if python_dll_regex.match(i)), None)
49+
assert python_dll_imp is not None, 'Python dll not in python imports'
50+
51+
imp_id_iat = imp[python_dll_imp][0]
52+
mod_base = windows.winproxy.LoadLibraryA(python_dll_imp.encode())
53+
assert windows.winproxy.GetProcAddress(mod_base, imp_id_iat.name.encode()) == imp_id_iat.value
4554

4655
def test_current_process_pe_exports(self):
4756
mods = [m for m in windows.current_process.peb.modules if m.name == "kernel32.dll"]

windows/injection.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,13 @@ def execute_python_code(process, code):
389389
# Cache the value ?
390390
py_dll_name = get_dll_name_from_python_version()
391391
pydll_path = find_python_dll_to_inject(process.bitness)
392+
393+
# NB: Sandboxing on Windows Store apps prevents remote loading DLLs stored under "C:\Program Files*\WindowsApps\*"
394+
# This is relevant for remote python execution, as the sandboxed python process is the _only_ one that can
395+
# access its CRT and shared libraries.
396+
if '\\windowsapps\\' in pydll_path.lower():
397+
raise ValueError('Cannot execute remote python code from a sandboxed python interpreter. Install python outside of the Microsoft Store to resolve.')
398+
392399
if sys.version_info.major == 3:
393400
# FOr py3, we may have a per-user install.
394401
# Meaning that the vcruntime140.dll will not be in the injected process path

0 commit comments

Comments
 (0)