mirror of
https://github.com/hakril/PythonForWindows
synced 2026-06-08 14:31:45 +00:00
Some fixes in code/samples/test
This commit is contained in:
@@ -247,6 +247,7 @@ class CtypesGenerator(object):
|
||||
|
||||
def generate_into(self, filename):
|
||||
self.generate()
|
||||
print("Writing generated code into {0}".format(filename))
|
||||
with open(filename, "w") as f:
|
||||
f.write(self.result.getvalue())
|
||||
|
||||
@@ -592,7 +593,7 @@ class ModuleGenerator(object):
|
||||
|
||||
self.after_ctypes_generator_init(ctypesgen)
|
||||
finalfilename = "{0}.py".format(self.name)
|
||||
ctypesgen.generate_into(to_dest(finalfilename))
|
||||
ctypesgen.generate_into(to_dest(finalfilename)) # Need to handle dest != PythonForWindows
|
||||
|
||||
def generate_doc(self, filename):
|
||||
nodelist = self.nodes
|
||||
|
||||
@@ -40,6 +40,8 @@ def full_alpc_server():
|
||||
windows.utils.print_ctypes_struct(msg.view_attribute, " - VIEW", hexa=True)
|
||||
view_data = windows.current_process.read_string(msg.view_attribute.ViewBase)
|
||||
print(" * Reading view content: <{0}>".format(view_data))
|
||||
# Needed in Win7 - TODO: why is there a different behavior ?
|
||||
msg.attributes.ValidAttributes -= gdef.ALPC_MESSAGE_VIEW_ATTRIBUTE
|
||||
print(" * security_is_valid <{0}>".format(msg.security_is_valid))
|
||||
print(" * handle_is_valid <{0}>".format(msg.handle_is_valid))
|
||||
if msg.handle_is_valid:
|
||||
|
||||
@@ -21,9 +21,6 @@ class MySink(windows.com.COMImplementation):
|
||||
IMPLEMENT = gdef.ICallFrameEvents
|
||||
|
||||
def OnCall(self, this, frame):
|
||||
import pdb;pdb.set_trace()
|
||||
# this = gdef.ICallFrameEvents(this) # TODO: auto-translate this ?
|
||||
# frame = gdef.ICallFrame(frame)
|
||||
ifname = gdef.PWSTR()
|
||||
methodname = gdef.PWSTR()
|
||||
print("Hello from python sink !")
|
||||
|
||||
@@ -41,6 +41,9 @@ RegOpenKeyExA_iat = [n for n in adv_imports if n.name == "RegOpenKeyExA"][0]
|
||||
# Setup our hook
|
||||
RegOpenKeyExA_iat.set_hook(open_reg_hook)
|
||||
|
||||
### !!!! You must keep the iat_entry alive !!!!
|
||||
### If the hook is garbage collected while active -> python will crash
|
||||
|
||||
# Use python native module _winreg that call 'RegOpenKeyExA'
|
||||
print("Asking for <MY_SECRET_KEY>")
|
||||
v = _winreg.OpenKey(1234567, "MY_SECRET_KEY")
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import gc
|
||||
import time
|
||||
import pytest
|
||||
import collections
|
||||
|
||||
@@ -35,6 +36,7 @@ def generate_pop_and_exit_fixtures(proc_popers, ids=[], dwCreationFlags=DEFAULT_
|
||||
def pop_and_exit_process(request):
|
||||
proc_poper = request.param
|
||||
proc = proc_poper(dwCreationFlags=dwCreationFlags)
|
||||
time.sleep(0.1) # Give time to the process to load :)
|
||||
yield weakref.proxy(proc) # provide the fixture value
|
||||
try:
|
||||
proc.exit(0)
|
||||
|
||||
@@ -71,6 +71,7 @@ def alpc_view_test_server():
|
||||
assert msg.type & 0xfff == gdef.LPC_REQUEST
|
||||
assert msg.view_is_valid
|
||||
view_data = windows.current_process.read_memory(msg.view_attribute.ViewBase, len(CLIENT_VIEW_DATA))
|
||||
msg.attributes.ValidAttributes -= gdef.ALPC_MESSAGE_VIEW_ATTRIBUTE
|
||||
assert view_data == CLIENT_VIEW_DATA
|
||||
assert msg.data == CLIENT_VIEW_MESSAGE
|
||||
msg.data = SERVER_MESSAGE
|
||||
|
||||
@@ -19,6 +19,8 @@ def dumped_apisetmap_base_and_version(request):
|
||||
ctypes_data = ctypes.c_buffer(data)
|
||||
yield ctypes.addressof(ctypes_data), version
|
||||
|
||||
KNOWN_APISETMAP_PREFIX = ["api-", "ext-", "MS-Win-"]
|
||||
|
||||
def verify_apisetmap_parsing(apisetmap_base, version=None):
|
||||
if version is not None:
|
||||
assert windows.current_process.read_dword(apisetmap_base) == version
|
||||
@@ -29,12 +31,12 @@ def verify_apisetmap_parsing(apisetmap_base, version=None):
|
||||
# Verify that at least one entry resolve to kernel32.dll
|
||||
# This ensure that the ApiSetMap parsing works at least a little
|
||||
assert "kernel32.dll" in apisetmap_dict.values()
|
||||
assert all(dll.startswith("api-") or dll.startswith("ext-") for dll in apisetmap_dict)
|
||||
# This key was found in all current tested version by hand
|
||||
# Might need to change that if I add another APISET dump
|
||||
# But as it was in Windows7 to Windows10 there are big chance it will be in others APISET.
|
||||
# We do as MS code and ignore everything after the last '-'
|
||||
assert 'api-ms-win-core-com-l2-1-' in apisetmap_dict
|
||||
assert all(any(dll.startswith(pref) for pref in KNOWN_APISETMAP_PREFIX) for dll in apisetmap_dict)
|
||||
# This first key was found in most of the tested version by hand
|
||||
# MS-Win found on: 6.1.7600 (Win7)
|
||||
assert 'api-ms-win-core-com-l2-1-' in apisetmap_dict or "MS-Win-Core-ProcessThreads-L1-1-" in apisetmap_dict
|
||||
|
||||
|
||||
|
||||
def test_apisetmap_parsing_current_process():
|
||||
return verify_apisetmap_parsing(windows.current_process.peb.ApiSetMap)
|
||||
|
||||
+14
-1
@@ -1,6 +1,7 @@
|
||||
import pytest
|
||||
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
import struct
|
||||
import textwrap
|
||||
@@ -23,7 +24,8 @@ class TestCurrentProcessWithCheckGarbage(object):
|
||||
return windows.current_process.peb
|
||||
|
||||
def test_get_current_process_modules(self):
|
||||
assert "python" in windows.current_process.peb.modules[0].name
|
||||
# Use sys.executable because executable can be a PyInstaller exe
|
||||
assert os.path.basename(sys.executable) in windows.current_process.peb.modules[0].name
|
||||
|
||||
def test_get_current_process_exe(self):
|
||||
exe = windows.current_process.peb.exe
|
||||
@@ -151,7 +153,16 @@ class TestProcessWithCheckGarbage(object):
|
||||
|
||||
# Python execution
|
||||
|
||||
def _skip_if_injection_dll_not_found(self, target):
|
||||
if windows.current_process.bitness == target.bitness:
|
||||
return # Should never fail if we have the same bitness
|
||||
try:
|
||||
windows.injection.validate_python_dll_presence_on_disk(target)
|
||||
except IOError as e:
|
||||
pytest.skip("Python DLL to inject not installed")
|
||||
|
||||
def test_execute_python(self, proc32_64):
|
||||
self._skip_if_injection_dll_not_found(proc32_64)
|
||||
with proc32_64.allocated_memory(0x1000) as addr:
|
||||
proc32_64.execute_python('import ctypes; ctypes.c_uint.from_address({0}).value = 0x42424242'.format(addr))
|
||||
dword = proc32_64.read_dword(addr)
|
||||
@@ -159,6 +170,7 @@ class TestProcessWithCheckGarbage(object):
|
||||
|
||||
|
||||
def test_execute_python_suspended(self, proc32_64_suspended):
|
||||
self._skip_if_injection_dll_not_found(proc32_64_suspended)
|
||||
proc = proc32_64_suspended
|
||||
with proc.allocated_memory(0x1000) as addr:
|
||||
proc.execute_python('import ctypes; ctypes.c_uint.from_address({0}).value = 0x42424242'.format(addr))
|
||||
@@ -217,6 +229,7 @@ class TestProcessWithCheckGarbage(object):
|
||||
assert exe.bitness == exe_by_module.bitness
|
||||
|
||||
def test_execute_python_raises(self, proc32_64):
|
||||
self._skip_if_injection_dll_not_found(proc32_64)
|
||||
res = proc32_64.execute_python("import time;time.sleep(0.1); 2")
|
||||
assert res == True
|
||||
with pytest.raises(windows.injection.RemotePythonError) as ar:
|
||||
|
||||
+53
-10
@@ -16,8 +16,17 @@ from windows.dbgprint import dbgprint
|
||||
class InjectionFailedError(WindowsError):
|
||||
pass
|
||||
|
||||
def get_kernel32_dll_name():
|
||||
# Our injected shellcode search for 'kernel32.dll' with a strcmp
|
||||
# The BaseDllName of k32 might be 'KERNEL32.DLL' or 'kernel32.dll' on different system32
|
||||
# We base the name on our own loaded kernel32
|
||||
k32 = [m for m in windows.current_process.peb.modules if m.name == "kernel32.dll"]
|
||||
assert len(k32) == 1
|
||||
k32name = k32[0].BaseDllName.str
|
||||
return (k32name + "\x00").encode("utf-16-le")
|
||||
|
||||
def perform_manual_getproc_loadlib_32(target, dll_name):
|
||||
dll = "KERNEL32.DLL\x00".encode("utf-16-le")
|
||||
dll = get_kernel32_dll_name()
|
||||
api = "LoadLibraryA\x00"
|
||||
dll_to_load = dll_name + "\x00"
|
||||
|
||||
@@ -54,7 +63,7 @@ def perform_manual_getproc_loadlib_32(target, dll_name):
|
||||
return True
|
||||
|
||||
def perform_manual_getproc_loadlib_64(target, dll_name):
|
||||
dll = "KERNEL32.DLL\x00".encode("utf-16-le")
|
||||
dll = get_kernel32_dll_name()
|
||||
api = "LoadLibraryA\x00"
|
||||
dll_to_load = dll_name + "\x00"
|
||||
|
||||
@@ -94,6 +103,19 @@ def perform_manual_getproc_loadlib_64(target, dll_name):
|
||||
raise InjectionFailedError("Injection of <{0}> failed".format(dll_name))
|
||||
return True
|
||||
|
||||
def generate_simple_LoadLibraryW_64(load_libraryW, remote_store):
|
||||
code = RemoteLoadLibrayStub = x64.MultipleInstr()
|
||||
# code += x64.Int3()
|
||||
code += x64.Mov("RAX", load_libraryW)
|
||||
code += (x64.Push("RDI") * 5) # Prepare stack
|
||||
code += x64.Call("RAX")
|
||||
code += (x64.Pop("RDI") * 5) # Clean stack
|
||||
code += x64.Mov(x64.deref(remote_store), "RAX")
|
||||
code += x64.Ret()
|
||||
return RemoteLoadLibrayStub.get_code()
|
||||
|
||||
|
||||
|
||||
def perform_manual_getproc_loadlib(target, *args, **kwargs):
|
||||
if target.bitness == 32:
|
||||
return perform_manual_getproc_loadlib_32(target, *args, **kwargs)
|
||||
@@ -101,6 +123,8 @@ def perform_manual_getproc_loadlib(target, *args, **kwargs):
|
||||
|
||||
|
||||
def load_dll_in_remote_process(target, dll_name):
|
||||
# if target.bitness == 64:
|
||||
# import pdb;pdb.set_trace()
|
||||
rpeb = target.peb
|
||||
if rpeb.Ldr:
|
||||
# LDR est parcourable, ca va etre deja plus simple..
|
||||
@@ -119,14 +143,33 @@ def load_dll_in_remote_process(target, dll_name):
|
||||
raise ValueError("Kernel32 have no export <LoadLibraryA> (wtf)")
|
||||
|
||||
with target.allocated_memory(0x1000) as addr:
|
||||
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(u"Injection of <{0}> failed".format(dll_name))
|
||||
if target.bitness == 32:
|
||||
target.write_memory(addr, (dll_name + "\x00").encode('utf-16le'))
|
||||
t = target.create_thread(load_libraryW, addr)
|
||||
t.wait()
|
||||
module_baseaddr = t.exit_code
|
||||
else:
|
||||
# For 64b target we need a special stub as the return value of
|
||||
# load_libraryW does not fit in t.exit_code (DWORD)
|
||||
retval_addr = addr
|
||||
target.write_ptr(retval_addr, 0)
|
||||
addr += ctypes.sizeof(ctypes.c_ulonglong)
|
||||
full_dll_name = (dll_name + "\x00").encode('utf-16le')
|
||||
target.write_memory(addr, full_dll_name)
|
||||
param_addr = addr
|
||||
addr += len(full_dll_name)
|
||||
shellcode_addr = addr
|
||||
shellcode = generate_simple_LoadLibraryW_64(load_libraryW, retval_addr)
|
||||
target.write_memory(shellcode_addr, shellcode)
|
||||
t = target.create_thread(shellcode_addr, param_addr)
|
||||
t.wait()
|
||||
module_baseaddr = target.read_ptr(retval_addr)
|
||||
|
||||
if not module_baseaddr:
|
||||
raise InjectionFailedError(u"Injection of <{0}> failed".format(dll_name))
|
||||
dbgprint("DLL Injected via LoadLibray", "DLLINJECT")
|
||||
# Cannot return the full return value of load_libraryW in 64b target.. (exit_code is a DWORD)
|
||||
return t.exit_code
|
||||
return module_baseaddr
|
||||
# Hardcore mode
|
||||
# We don't have k32 or PEB->Ldr
|
||||
# Go inject a GetProcAddress(LoadLib) + LoadLib shellcode :D
|
||||
@@ -287,11 +330,11 @@ def validate_python_dll_presence_on_disk(process):
|
||||
if windows.current_process.bitness == 32 and process.bitness == 64:
|
||||
with windows.utils.DisableWow64FsRedirection():
|
||||
if not os.path.exists(r"C:\Windows\system32\python27.dll"):
|
||||
raise ValueError("Could not find Python DLL to inject")
|
||||
raise IOError("Could not find Python DLL to inject")
|
||||
return True
|
||||
if windows.current_process.bitness == 64 and process.bitness == 32:
|
||||
if not os.path.exists(r"C:\Windows\SysWOW64\python27.dll"):
|
||||
raise ValueError("Could not find Python DLL to inject")
|
||||
raise IOError("Could not find Python DLL to inject")
|
||||
return True
|
||||
raise NotImplementedError("Unknown bitness")
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import collections
|
||||
import struct
|
||||
from windows.dbgprint import dbgprint
|
||||
|
||||
DEBUG = False
|
||||
|
||||
@@ -740,7 +739,6 @@ class Instruction(object):
|
||||
default_rex = BitArray.from_int(8, 0x40)
|
||||
|
||||
def __init__(self, *initial_args):
|
||||
dbgprint("Assembling {0}{1}".format(type(self).__name__, initial_args), "X64")
|
||||
for type_encoding in self.encoding:
|
||||
args = list(initial_args)
|
||||
res = []
|
||||
@@ -759,7 +757,6 @@ class Instruction(object):
|
||||
else: # if no break
|
||||
if args: # if still args: fail
|
||||
continue
|
||||
dbgprint("Valid encoding found: REX={0:#x}".format(ord(full_rex.dump())), "X64")
|
||||
self.prefix = prefix
|
||||
self.value = sum(res, BitArray(0, ""))
|
||||
if str(full_rex.dump()) != "\x40":
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
"""utils fonctions non windows-related"""
|
||||
import sys
|
||||
import ctypes
|
||||
import _ctypes
|
||||
from windows.generated_def import Flag, LPCSTR, LPWSTR
|
||||
from windows.generated_def import Flag, LPCSTR, LPWSTR, INFINITE
|
||||
|
||||
from windows.dbgprint import dbgprint
|
||||
from windows import winproxy
|
||||
|
||||
|
||||
def buffer(size): # Test
|
||||
@@ -24,6 +28,26 @@ def buffer(size): # Test
|
||||
return ImprovedCtypesBufferImpl()
|
||||
|
||||
|
||||
def wbuffer(size): # Test
|
||||
buf = ctypes.create_string_buffer(size)
|
||||
buf.size = size
|
||||
buf.address = ctypes.addressof(buf)
|
||||
|
||||
class ImprovedCtypesBufferImpl(ctypes.Array):
|
||||
_length_ = size
|
||||
_type_ = ctypes.c_wchar
|
||||
def lol(self):
|
||||
return "lol"
|
||||
|
||||
def as_string(self):
|
||||
return ctypes.cast(self, LPCSTR).value
|
||||
|
||||
def as_wstring(self):
|
||||
return ctypes.cast(self, LPWSTR).value
|
||||
|
||||
return ImprovedCtypesBufferImpl()
|
||||
|
||||
|
||||
def fixedpropety(f):
|
||||
cache_name = "_" + f.__name__
|
||||
|
||||
@@ -75,4 +99,38 @@ def print_ctypes_struct(struct, name="", ident=0, hexa=False):
|
||||
|
||||
def sprint(struct, name="struct", hexa=True):
|
||||
"""Print recursively the content of a :mod:`ctypes` structure"""
|
||||
return print_ctypes_struct(struct, name=name, hexa=hexa)
|
||||
return print_ctypes_struct(struct, name=name, hexa=hexa)
|
||||
|
||||
|
||||
class AutoHandle(object):
|
||||
"""An abstract class that allow easy handle creation/destruction/wait"""
|
||||
# Big bypass to prevent missing reference at programm exit..
|
||||
_close_function = ctypes.WinDLL("kernel32").CloseHandle
|
||||
def _get_handle(self):
|
||||
raise NotImplementedError("{0} is abstract".format(type(self).__name__))
|
||||
|
||||
@property
|
||||
def handle(self):
|
||||
"""An handle on the object
|
||||
|
||||
:type: HANDLE
|
||||
|
||||
.. note::
|
||||
The handle is automaticaly closed when the object is destroyed
|
||||
"""
|
||||
if hasattr(self, "_handle"):
|
||||
return self._handle
|
||||
self._handle = self._get_handle()
|
||||
dbgprint("Open handle {0} for {1}".format(hex(self._handle), self), "HANDLE")
|
||||
return self._handle
|
||||
|
||||
def wait(self, timeout=INFINITE):
|
||||
"""Wait for the object"""
|
||||
return winproxy.WaitForSingleObject(self.handle, timeout)
|
||||
|
||||
def __del__(self):
|
||||
# sys.path is not None -> check if python shutdown
|
||||
if hasattr(sys, "path") and sys.path is not None and hasattr(self, "_handle") and self._handle:
|
||||
# Prevent some bug where dbgprint might be None when __del__ is called in a closing process
|
||||
dbgprint("Closing Handle {0} for {1}".format(hex(self._handle), self), "HANDLE") if dbgprint is not None else None
|
||||
self._close_function(self._handle)
|
||||
@@ -1,3 +1,5 @@
|
||||
import ctypes
|
||||
|
||||
import windows
|
||||
import windows.generated_def as gdef
|
||||
|
||||
|
||||
@@ -33,44 +33,7 @@ TimeInfo = namedtuple("TimeInfo", ["creation", "exit", "kernel", "user"])
|
||||
"""Time information about a process"""
|
||||
|
||||
|
||||
class AutoHandle(object):
|
||||
"""An abstract class that allow easy handle creation/destruction/wait"""
|
||||
# Big bypass to prevent missing reference at programm close..
|
||||
_close_function = ctypes.WinDLL("kernel32").CloseHandle
|
||||
def _get_handle(self):
|
||||
raise NotImplementedError("{0} is abstract".format(type(self).__name__))
|
||||
|
||||
@property
|
||||
def handle(self):
|
||||
"""An handle on the object
|
||||
|
||||
:type: HANDLE
|
||||
|
||||
.. note::
|
||||
The handle is automaticaly closed when the object is destroyed
|
||||
"""
|
||||
if hasattr(self, "_handle"):
|
||||
return self._handle
|
||||
self._handle = self._get_handle()
|
||||
dbgprint("Open handle {0} for {1}".format(hex(self._handle), self), "HANDLE")
|
||||
#if "DEAD" in str(self):
|
||||
# print("OPEN FOR THE DEADS")
|
||||
# import pdb;pdb.set_trace()
|
||||
return self._handle
|
||||
|
||||
def wait(self, timeout=INFINITE):
|
||||
"""Wait for the object"""
|
||||
return winproxy.WaitForSingleObject(self.handle, timeout)
|
||||
|
||||
def __del__(self):
|
||||
# sys.path is not None -> check if python shutdown
|
||||
if hasattr(sys, "path") and sys.path is not None and hasattr(self, "_handle") and self._handle:
|
||||
# Prevent some bug where dbgprint might be None when __del__ is called in a closing process
|
||||
dbgprint("Closing Handle {0} for {1}".format(hex(self._handle), self), "HANDLE") if dbgprint is not None else None
|
||||
self._close_function(self._handle)
|
||||
|
||||
|
||||
class WinThread(AutoHandle):
|
||||
class WinThread(utils.AutoHandle):
|
||||
"""Represent a thread """
|
||||
|
||||
def __init__(self, tid=None, handle=None, owner_pid=None, owner=None):
|
||||
@@ -297,7 +260,7 @@ class WinThread(AutoHandle):
|
||||
# return Token(token_handle.value)
|
||||
|
||||
|
||||
class DeadThread(AutoHandle):
|
||||
class DeadThread(utils.AutoHandle):
|
||||
"""An already dead thread (returned only by API returning a new thread if thread die before being returned)"""
|
||||
def __init__(self, handle, tid=None):
|
||||
if tid is None:
|
||||
@@ -325,7 +288,7 @@ class DeadThread(AutoHandle):
|
||||
return res.value
|
||||
|
||||
|
||||
class Process(AutoHandle):
|
||||
class Process(utils.AutoHandle):
|
||||
@utils.fixedpropety
|
||||
def is_wow_64(self):
|
||||
"""``True`` if the process is a SysWow64 process (32bit process on 64bits system).
|
||||
@@ -666,6 +629,12 @@ class Process(AutoHandle):
|
||||
"""write a qword at ``addr``"""
|
||||
return self.write_memory(addr, struct.pack("<Q", qword))
|
||||
|
||||
def write_ptr(self, addr, value):
|
||||
"""Write a ``PTR`` at ``addr``"""
|
||||
if self.bitness == 32:
|
||||
return self.write_dword(addr, value)
|
||||
return self.write_qword(addr, value)
|
||||
|
||||
@property
|
||||
def time_info(self):
|
||||
"""The time information of the process (creation, kernel/user time, exit time)
|
||||
@@ -739,7 +708,7 @@ class Process(AutoHandle):
|
||||
# winproxy.OpenProcessToken(self.handle, TOKEN_QUERY, byref(token_handle))
|
||||
# return Token(token_handle.value)
|
||||
|
||||
class CurrentThread(AutoHandle):
|
||||
class CurrentThread(utils.AutoHandle):
|
||||
"""The current thread"""
|
||||
@property #It's not a fixedpropety because executing thread might change
|
||||
def tid(self):
|
||||
@@ -874,8 +843,12 @@ class CurrentProcess(Process):
|
||||
return WinThread._from_handle(handle)
|
||||
|
||||
def load_library(self, dll_path):
|
||||
"""Load the library in current process"""
|
||||
return winproxy.LoadLibraryA(dll_path)
|
||||
"""Load the library in current process
|
||||
|
||||
:rtype: :class:`LoadedModule`
|
||||
"""
|
||||
dllbase = winproxy.LoadLibraryA(dll_path)
|
||||
return [m for m in self.peb.modules if m.baseaddr == dllbase][0]
|
||||
|
||||
def execute(self, code, parameter=0):
|
||||
"""Execute native code ``code`` in the current thread.
|
||||
@@ -908,6 +881,8 @@ class CurrentProcess(Process):
|
||||
winproxy.OpenProcessToken(self.handle, flags, byref(token_handle))
|
||||
return Token(token_handle.value)
|
||||
|
||||
# TODO: use ctypes.string_ad / ctypes.wstring_at for read_string / read_wstring ?
|
||||
|
||||
|
||||
token = property(open_token)
|
||||
|
||||
@@ -947,7 +922,7 @@ class WinProcess(Process):
|
||||
:type: :class:`str`
|
||||
"""
|
||||
buffer = ctypes.c_buffer(0x1024)
|
||||
rsize = winproxy.GetProcessImageFileNameA(self.handle, buffer)
|
||||
rsize = winproxy.GetProcessImageFileNameA(self.limited_handle, buffer)
|
||||
# GetProcessImageFileNameA returns the fullpath
|
||||
return buffer[:rsize].decode().split("\\")[-1]
|
||||
|
||||
@@ -1052,8 +1027,12 @@ class WinProcess(Process):
|
||||
return WinThread._from_handle(winproxy.CreateRemoteThread(hProcess=self.handle, lpStartAddress=addr, lpParameter=param))
|
||||
|
||||
def load_library(self, dll_path):
|
||||
"""Load the library in remote process"""
|
||||
return windows.injection.load_dll_in_remote_process(self, dll_path)
|
||||
"""Load the library in remote process
|
||||
|
||||
:rtype: :class:`RemoteLoadedModule`
|
||||
"""
|
||||
dllbase = windows.injection.load_dll_in_remote_process(self, dll_path)
|
||||
return [m for m in self.peb.modules if m.baseaddr == dllbase][0]
|
||||
|
||||
def execute_python(self, pycode):
|
||||
"""Execute Python code into the remote process.
|
||||
@@ -1161,7 +1140,8 @@ SECURITY_MANDATORY_PROTECTED_PROCESS_RID]
|
||||
know_integrity_level_mapper = gdef.FlagMapper(*KNOW_INTEGRITY_LEVEL)
|
||||
|
||||
# Create ProcessToken and Thread Token objects ?
|
||||
class Token(AutoHandle):
|
||||
# token.py ?
|
||||
class Token(utils.AutoHandle):
|
||||
"""The token of a process"""
|
||||
def __init__(self, handle):
|
||||
self._handle = handle
|
||||
@@ -1215,6 +1195,12 @@ class Token(AutoHandle):
|
||||
"""The username of the token"""
|
||||
return self._user_and_computer_name()[0]
|
||||
|
||||
def duplicate(self, access_rigth=0, attributes=None, impersonation_level=gdef.SecurityImpersonation, toktype=gdef.TokenPrimary):
|
||||
newtoken = gdef.HANDLE()
|
||||
winproxy.DuplicateTokenEx(self.handle, access_rigth, attributes, impersonation_level, toktype, newtoken)
|
||||
return type(self)(newtoken.value)
|
||||
|
||||
|
||||
def _user_and_computer_name(self):
|
||||
tok_usr = self.token_user
|
||||
sid = tok_usr.User.Sid
|
||||
|
||||
Reference in New Issue
Block a user