diff --git a/samples/pipe/child_send_object.py b/samples/pipe/child_send_object.py new file mode 100644 index 0000000..bdf0f76 --- /dev/null +++ b/samples/pipe/child_send_object.py @@ -0,0 +1,36 @@ +import windows +import windows.test + +p = windows.test.pop_proc_32() +print("Child is {0}".format(p)) + +PIPE_NAME = "PFW_Pipe" + +rcode = """ +import windows + +f = open('tst.txt', "w+") +fh = windows.utils.get_handle_from_file(f) +hm = windows.winproxy.CreateFileMappingA(fh, dwMaximumSizeLow=0x1000, lpName=None) +addr = windows.winproxy.MapViewOfFile(hm, dwNumberOfBytesToMap=0x1000) + +windows.pipe.send_object("{pipe}", addr) +""" + +with windows.pipe.create(PIPE_NAME) as np: + print(np) + p.execute_python(rcode.format(pipe=PIPE_NAME)) + addr = np.recv() + +print("Remote Address = {0:#x}".format(addr)) +print(p.query_memory(addr)) +print(p.get_mapped_filename(addr)) +p.exit() + + +# python samples\pipe\child_send_object.py +# Child is +# +# Remote Address = 0x6fa0000 +# +# \Device\HarddiskVolume2\Users\hakril\Documents\projets\PythonForWindows\tst.txt \ No newline at end of file diff --git a/tests/test_process.py b/tests/test_process.py index 602fe7c..cc52e05 100644 --- a/tests/test_process.py +++ b/tests/test_process.py @@ -4,6 +4,7 @@ import os import time import struct import textwrap +import shutil import windows import windows.generated_def as gdef @@ -300,6 +301,41 @@ class TestProcessWithCheckGarbage(object): proc32_64.load_library(DLL) assert DLL in [m.name for m in proc32_64.peb.modules] + def test_load_library_unicode_name(self, proc32_64, tmpdir): + mybitness = windows.current_process.bitness + UNICODE_FILENAME = u'\u4e2d\u56fd\u94f6\u884c\u7f51\u94f6\u52a9\u624b.dll' + + if proc32_64.bitness == mybitness: + DLLPATH = r"c:\windows\system32\wintrust.dll" + elif mybitness == 64: # target is 32 + DLLPATH = r"c:\windows\syswow64\wintrust.dll" + elif mybitness == 32: # target is 64 + DLLPATH = r"c:\windows\sysnative\wintrust.dll" + else: + raise Value("WTF ARE THE BITNESS ?") + targetname = os.path.join(str(tmpdir), UNICODE_FILENAME) + shutil.copy(DLLPATH, targetname) + proc32_64.load_library(targetname) + dlls = [m for m in proc32_64.peb.modules if m.name == UNICODE_FILENAME] + assert len(dlls) == 1 + injecteddll = dlls[0] + # Check that the DLL is the one we asked to load + assert injecteddll.fullname == targetname + +# UNICODE_PATH_NAME = u'\u4e2d\u56fd\u94f6\u884c\u7f51\u94f6\u52a9\u624b' + +# def test_unicode_path_module(tmpdir, proc32_64): + # assert windows.current_process.bitness == 32 + # if proc32_64.bitness == 64: + # wintrust_native_path = r'c:\windows\sysnative\wintrust.dll' + # else: + # wintrust_native_path = r'c:\windows\system32\wintrust.dll' + + # full_dirpath = os.path.join(tmpdir, UNICODE_PATH_NAME) + # full_dllpath = os.path.join(full_dirpath, "wintrust.dll") + # os.mkdir(full_dirpath) + # shutil.copy(wintrust_native_path, full_dllpath) + # wintrust_sha256 = hashlib.sha256(open(wintrust_native_path, "rb").read()).hexdigest() def test_get_working_set(self, proc32_64): @@ -355,6 +391,9 @@ class TestProcessWithCheckGarbage(object): k32 = [m for m in proc32_64.peb.modules if m.name == "kernel32.dll"][0] mapped_filname = proc32_64.get_mapped_filename(k32.baseaddr) assert mapped_filname.endswith("kernel32.dll") + # Test on non-commit & non file-mapped addresses + assert proc32_64.get_mapped_filename(0) == None + assert proc32_64.get_mapped_filename(id(object())) == None def test_thread_teb_base(self, proc32_64): diff --git a/windows/injection.py b/windows/injection.py index c459bdc..274bff8 100644 --- a/windows/injection.py +++ b/windows/injection.py @@ -114,16 +114,17 @@ def load_dll_in_remote_process(target, dll_name): # We have kernel32 \o/ k32 = k32[0] try: - load_libraryA = k32.pe.exports["LoadLibraryA"] + load_libraryW = k32.pe.exports["LoadLibraryW"] except KeyError: raise ValueError("Kernel32 have no export (wtf)") with target.allocated_memory(0x1000) as addr: - target.write_memory(addr, dll_name + "\x00") - t = target.create_thread(load_libraryA, addr) + # target.write_memory(addr, dll_name + "\x00") + target.write_memory(addr, (dll_name + "\x00").encode('utf-16le')) + t = target.create_thread(load_libraryW, addr) t.wait() if not t.exit_code: - raise InjectionFailedError("Injection of <{0}> failed".format(dll_name)) + raise InjectionFailedError(u"Injection of <{0}> failed".format(dll_name)) dbgprint("DLL Injected via LoadLibray", "DLLINJECT") return t.exit_code # Hardcore mode diff --git a/windows/winobject/process.py b/windows/winobject/process.py index 0df85c7..5c61741 100644 --- a/windows/winobject/process.py +++ b/windows/winobject/process.py @@ -551,7 +551,7 @@ class Process(AutoHandle): def get_mapped_filename(self, addr): """The filename mapped at address ``addr`` or ``None`` - :rtype: :class:`str` or ``None`` + :rtype: :class:`unicode` or ``None`` """ buffer_size = 0x1000 buffer = ctypes.c_buffer(buffer_size) @@ -561,7 +561,7 @@ class Process(AutoHandle): try: windows.syswow64.NtQueryVirtualMemory_32_to_64(self.handle, addr, MemorySectionName, buffer, buffer_size, target_size) except NtStatusException as e: - if e.code not in [STATUS_FILE_INVALID, STATUS_INVALID_ADDRESS, STATUS_TRANSACTION_NOT_ACTIVE]: + if e.code not in (STATUS_FILE_INVALID, STATUS_INVALID_ADDRESS): raise return None remote_winstring = rctypes.transform_type_to_remote64bits(gdef.LSA_UNICODE_STRING) @@ -569,12 +569,12 @@ class Process(AutoHandle): return mapped_filename.str try: - size = winproxy.GetMappedFileNameA(self.handle, addr, buffer, buffer_size) + size = winproxy.GetMappedFileNameW(self.handle, addr, buffer, buffer_size) except winproxy.Kernel32Error as e: - if e.winerror != gdef.ERROR_UNEXP_NET_ERR: + if e.winerror not in (gdef.ERROR_UNEXP_NET_ERR, gdef.ERROR_FILE_INVALID): raise # Raise if error type is not expected: detect mapped aborted transaction return None - return buffer[:size] + return buffer[: size * 2].decode("utf16") def read_byte(self, addr): """Read a ``CHAR`` at ``addr``"""