diff --git a/tests/test_process.py b/tests/test_process.py index 16b94ae..06808a1 100644 --- a/tests/test_process.py +++ b/tests/test_process.py @@ -82,16 +82,16 @@ class TestProcessWithCheckGarbage(object): 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"]) + p = windows.utils.create_process(u"c:\\windows\\system32\\winver.exe", [u"--", u"yolo.txt"]) try: - assert p.name == "notepad.exe" + assert p.name == "winver.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"]) + p = windows.utils.create_process(b"c:\\windows\\system32\\winver.exe", [b"--", b"yolo.txt"]) try: - assert p.name == "notepad.exe" + assert p.name == "winver.exe" finally: p.exit() @@ -468,6 +468,14 @@ class TestProcessWithCheckGarbage(object): t = proc32_64.threads[0] assert t.teb_base != 0 + @windows_64bit_only + def test_thread_teb_syswow_base(self, proc32): + t = proc32.threads[0] + assert t.teb_base != 0 + assert t.teb_syswow_base != 0 + assert t.teb_base == t.teb_syswow_base + 0x2000 + + def test_thread_owner_from_tid(self, proc32_64): thread = proc32_64.threads[0] @@ -496,4 +504,23 @@ class TestProcessWithCheckGarbage(object): # Via SD obj proc32_64.security_descriptor = SD_GR_EVERYONE + def test_process_name_with_unicode_name(self, tmpdir): + # Cmd.exe can be started from anywhere with any name + # This is not the case of notepad.exe + source_programme = r"c:\windows\system32\cmd.exe" + UNICODE_PATH_NAME = u'\u4e2d\u56fd\u94f6\u884c\u7f51\u94f6\u52a9\u624b.exe' + target_programe = tmpdir.join(UNICODE_PATH_NAME) + if sys.version_info.major == 2: + target_programe = unicode(target_programe) + else: + target_programe = str(target_programe) + shutil.copy(source_programme, target_programe) + p = windows.utils.create_process(target_programe, dwCreationFlags=gdef.CREATE_NEW_CONSOLE) + try: + assert windows.system.processes + print(windows.system.processes) # Check for encoding error in __repr__ of WinProcess + finally: + p.exit() + p.wait() + os.unlink(target_programe) diff --git a/windows/winobject/process.py b/windows/winobject/process.py index 7ecab97..e9b66a3 100644 --- a/windows/winobject/process.py +++ b/windows/winobject/process.py @@ -865,13 +865,15 @@ class WinThread(Thread): winproxy.NtQueryInformationThread(self.handle, ThreadQuerySetWin32StartAddress, byref(res), ctypes.sizeof(res)) return res.value - @property - def teb_base(self): - """The address of the thread's TEB + def _get_principal_teb_addr(self): + # Returns the 64bits TEB on a 64bits computer (syswow process or not) + # Returns the 32bits TEB on a 32bits computer - :type: :class:`int` - """ - if windows.current_process.bitness == 32 and self.owner.bitness == 64: + # If we are wow64 process its means we either + # - Want the TEB of a 64b process + # - Want the TEB64 of a Wowprocess + # It's the same code for both + if windows.current_process.is_wow_64: restype = rctypes.transform_type_to_remote64bits(THREAD_BASIC_INFORMATION) ressize = (ctypes.sizeof(restype)) # Manual aligned allocation :DDDD @@ -887,6 +889,33 @@ class WinThread(Thread): windows.winproxy.NtQueryInformationThread(self.handle, ThreadBasicInformation, byref(res), ctypes.sizeof(res)) return res.TebBaseAddress + @property + def teb_base(self): + """The address of the thread's TEB. If the owner is a SysWow64 process, return the TEB32. + + :type: :class:`int` + """ + main_teb_addr = self._get_principal_teb_addr() + if not self.owner.is_wow_64: + return main_teb_addr + # import pdb; pdb.set_trace() + # TEB32 is pointed at the begining of the TEB64 + return self.owner.read_dword(main_teb_addr) + + + + @property + def teb_syswow_base(self): + """The address of the thread's TEB64 for a SysWow64 process + + :type: :class:`int` + """ + if not self.owner.is_wow_64: + raise ValueError("Not a syswow process") + # just return the main TEB + return self._get_principal_teb_addr() + + def exit(self, code=0): """Exit the thread""" return winproxy.TerminateThread(self.handle, code) @@ -1115,6 +1144,9 @@ class WinProcess(Process): """ return injection.execute_python_code(self, pycode) + + + @utils.fixedpropety def peb_addr(self): """The address of the PEB