Remote load library now use LoadLibraryW and get_mapped_filename use GetMappedFileNameW: return unicode str in every case

This commit is contained in:
hakril
2018-02-07 13:14:25 +01:00
parent b2a72f11cc
commit 4499080a77
4 changed files with 85 additions and 9 deletions
+36
View File
@@ -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
+39
View File
@@ -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):
+5 -4
View File
@@ -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
+5 -5
View File
@@ -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``"""