mirror of
https://github.com/hakril/PythonForWindows
synced 2026-06-08 14:31:45 +00:00
Remote load library now use LoadLibraryW and get_mapped_filename use GetMappedFileNameW: return unicode str in every case
This commit is contained in:
@@ -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 <WinProcess "notepad.exe" pid 16724 at 0x63455d0>
|
||||
# <PipeConnection name="\\.\pipe\PFW_Pipe" server=True>
|
||||
# Remote Address = 0x6fa0000
|
||||
# <MEMORY_BASIC_INFORMATION32 BaseAddress=0x6fa0000 RegionSize=0x001000 State=MEM_COMMIT(0x1000L) Type=MEM_MAPPED(0x40000L) Protect=PAGE_READWRITE(0x4L)>
|
||||
# \Device\HarddiskVolume2\Users\hakril\Documents\projets\PythonForWindows\tst.txt
|
||||
@@ -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):
|
||||
|
||||
@@ -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 <LoadLibraryA> (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
|
||||
|
||||
@@ -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``"""
|
||||
|
||||
Reference in New Issue
Block a user