mirror of
https://github.com/hakril/PythonForWindows
synced 2026-06-08 14:31:45 +00:00
utils.create_process now use CreateProcessW for simpler py3 usage + fix code in WinProcess.read_[w]string + associated tests
This commit is contained in:
+21
-6
@@ -81,6 +81,20 @@ class TestProcessWithCheckGarbage(object):
|
||||
def test_process_ppid(self, proc32_64):
|
||||
assert proc32_64.ppid == windows.current_process.pid
|
||||
|
||||
def test_create_process_unicode(self):
|
||||
p = windows.utils.create_process(u"c:\\windows\\system32\\notepad.exe", [u"--", u"yolo.txt"])
|
||||
try:
|
||||
assert p.name == "notepad.exe"
|
||||
finally:
|
||||
p.exit()
|
||||
|
||||
def test_create_process_bytes(self):
|
||||
p = windows.utils.create_process(b"c:\\windows\\system32\\notepad.exe", [b"--", b"yolo.txt"])
|
||||
try:
|
||||
assert p.name == "notepad.exe"
|
||||
finally:
|
||||
p.exit()
|
||||
|
||||
# Test process read/write
|
||||
|
||||
def test_read_memory(self, proc32_64):
|
||||
@@ -106,12 +120,12 @@ class TestProcessWithCheckGarbage(object):
|
||||
with proc32_64.allocated_memory(0x1000) as addr:
|
||||
waddr = addr + 0x1000 - len(string_to_write)
|
||||
proc32_64.write_memory(waddr, string_to_write)
|
||||
with pytest.raises(windows.winproxy.WinproxyError):
|
||||
with pytest.raises(WindowsError):
|
||||
proc32_64.read_memory(waddr, 0x20) # Check that Reading dumbly fails
|
||||
assert proc32_64.read_string(waddr) == test_string
|
||||
|
||||
|
||||
def test_wread_string(self, proc32_64):
|
||||
def test_read_wstring(self, proc32_64):
|
||||
test_string = u"TEST_STRING"
|
||||
string_to_write = test_string + "\x00"
|
||||
with proc32_64.allocated_memory(0x1000) as addr:
|
||||
@@ -125,15 +139,14 @@ class TestProcessWithCheckGarbage(object):
|
||||
with proc32_64.allocated_memory(0x1000) as addr:
|
||||
waddr = addr + 0x1000 - len(string_to_write)
|
||||
proc32_64.write_memory(waddr, string_to_write)
|
||||
with pytest.raises(windows.winproxy.WinproxyError):
|
||||
with pytest.raises(WindowsError):
|
||||
proc32_64.read_memory(waddr, 0x20) # Check that Reading dumbly fails
|
||||
assert proc32_64.read_wstring(waddr) == test_string
|
||||
|
||||
|
||||
def test_read_string_end_page_current_process(self):
|
||||
current_proc = windows.current_process
|
||||
test_string = "TEST_STRING"
|
||||
string_to_write = test_string + "\x00"
|
||||
test_string = b"TEST_STRING"
|
||||
string_to_write = test_string + b"\x00"
|
||||
with current_proc.allocated_memory(0x1000) as addr:
|
||||
waddr = addr + 0x1000 - len(string_to_write)
|
||||
current_proc.write_memory(waddr, string_to_write)
|
||||
@@ -482,3 +495,5 @@ class TestProcessWithCheckGarbage(object):
|
||||
proc32_64.security_descriptor = SSDL_GR_EVERYONE
|
||||
# Via SD obj
|
||||
proc32_64.security_descriptor = SD_GR_EVERYONE
|
||||
|
||||
|
||||
|
||||
@@ -91,16 +91,23 @@ def create_process(path, args=None, dwCreationFlags=0, show_windows=True):
|
||||
proc_info = PROCESS_INFORMATION()
|
||||
lpStartupInfo = None
|
||||
if show_windows:
|
||||
StartupInfo = STARTUPINFOA()
|
||||
StartupInfo = STARTUPINFOW()
|
||||
StartupInfo.cb = ctypes.sizeof(StartupInfo)
|
||||
StartupInfo.dwFlags = 0
|
||||
lpStartupInfo = ctypes.byref(StartupInfo)
|
||||
lpCommandLine = None
|
||||
if isinstance(path, bytes):
|
||||
path = path.decode()
|
||||
if args:
|
||||
lpCommandLine = (b" ".join([a for a in args]))
|
||||
windows.winproxy.CreateProcessA(path, lpCommandLine=lpCommandLine, dwCreationFlags=dwCreationFlags, lpProcessInformation=ctypes.byref(proc_info), lpStartupInfo=lpStartupInfo)
|
||||
dbgprint("CreateProcessA new process handle {:#x}".format(proc_info.hProcess), "HANDLE")
|
||||
dbgprint("CreateProcessA new thread handle {:#x}".format(proc_info.hThread), "HANDLE")
|
||||
unicode_args = []
|
||||
for arg in args:
|
||||
if isinstance(arg, bytes):
|
||||
arg = arg.decode()
|
||||
unicode_args.append(arg)
|
||||
lpCommandLine = (" ".join(unicode_args))
|
||||
windows.winproxy.CreateProcessW(path, lpCommandLine=lpCommandLine, dwCreationFlags=dwCreationFlags, lpProcessInformation=ctypes.byref(proc_info), lpStartupInfo=lpStartupInfo)
|
||||
dbgprint("CreateProcessW new process handle {:#x}".format(proc_info.hProcess), "HANDLE")
|
||||
dbgprint("CreateProcessW new thread handle {:#x}".format(proc_info.hThread), "HANDLE")
|
||||
dbgprint("Automatic close of thread handle {:#x}".format(proc_info.hThread), "HANDLE")
|
||||
windows.winproxy.CloseHandle(proc_info.hThread) # Give access to a WinThread in addition of the WinProcess ?
|
||||
return windows.winobject.process.WinProcess(pid=proc_info.dwProcessId, handle=proc_info.hProcess)
|
||||
|
||||
@@ -348,13 +348,13 @@ class Process(utils.AutoHandle):
|
||||
for i in itertools.count():
|
||||
try:
|
||||
x = self.read_memory(addr + readden, read_size)
|
||||
except winproxy.WinproxyError as e:
|
||||
except WindowsError as e:
|
||||
if read_size == 2:
|
||||
raise
|
||||
# handle read_wstring at end of page
|
||||
# Of read failed: read only the half of size
|
||||
# read_size must remain a multiple of 2
|
||||
read_size = read_size / 2
|
||||
read_size = read_size // 2
|
||||
continue
|
||||
readden += read_size
|
||||
if b"\x00" in x:
|
||||
@@ -372,13 +372,13 @@ class Process(utils.AutoHandle):
|
||||
while True:
|
||||
try:
|
||||
x = self.read_memory(addr + readden, read_size)
|
||||
except winproxy.WinproxyError as e:
|
||||
except WindowsError as e:
|
||||
if read_size == 2:
|
||||
raise
|
||||
# handle read_wstring at end of page
|
||||
# Of read failed: read only the half of size
|
||||
# read_size must remain a multiple of 2
|
||||
read_size = int(read_size / 2)
|
||||
read_size = read_size // 2
|
||||
continue
|
||||
readden += read_size
|
||||
# Bytearray will work on py2 & py3
|
||||
@@ -387,10 +387,10 @@ class Process(utils.AutoHandle):
|
||||
utf16_chars = [bytearray(c) for c in zip(*[iter(x)] * 2)]
|
||||
if b"\x00\x00" in utf16_chars:
|
||||
# Translate bytearray to str/bytes for both py2 & py3
|
||||
res.extend(bytes(x) for x in utf16_chars[:utf16_chars.index(b"\x00\x00")])
|
||||
res.extend(x[:utf16_chars.index(b"\x00\x00") * 2])
|
||||
break
|
||||
res.extend(x)
|
||||
return b"".join(res).decode('utf16')
|
||||
return bytearray(res).decode("utf-16")
|
||||
|
||||
def write_byte(self, addr, byte):
|
||||
"""write a byte at ``addr``"""
|
||||
|
||||
Reference in New Issue
Block a user