diff --git a/tests/test_process.py b/tests/test_process.py index 79924c2..16b94ae 100644 --- a/tests/test_process.py +++ b/tests/test_process.py @@ -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 + + diff --git a/windows/utils/winutils.py b/windows/utils/winutils.py index b6be48d..8ca42a5 100644 --- a/windows/utils/winutils.py +++ b/windows/utils/winutils.py @@ -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) diff --git a/windows/winobject/process.py b/windows/winobject/process.py index 9900e1e..88d0e8b 100644 --- a/windows/winobject/process.py +++ b/windows/winobject/process.py @@ -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``"""