Remove 'WinUnicodeString' and add un extended struct _LSA_UNICODE_STRING: simplify lots of things

This commit is contained in:
Clement Rouault
2017-11-17 15:13:34 +01:00
parent d3ca30b229
commit d12bae6dbb
11 changed files with 389 additions and 65 deletions
+10
View File
@@ -1000,6 +1000,16 @@ NTSTATUS WINAPI NtAlpcQueryInformation(
_Out_opt_ PULONG ReturnLength
);
NTSTATUS WINAPI NtAlpcQueryInformationMessage(
_In_ HANDLE PortHandle,
_In_ PPORT_MESSAGE PortMessage,
_In_ ALPC_MESSAGE_INFORMATION_CLASS MessageInformationClass,
_Out_opt_ PVOID MessageInformation,
_In_ ULONG Length,
_Out_opt_ PULONG ReturnLength
);
NTSTATUS WINAPI NtAlpcConnectPort(
_Out_ PHANDLE PortHandle,
_In_ PUNICODE_STRING PortName,
+49 -6
View File
@@ -14,17 +14,60 @@ typedef struct _PEB_LDR_DATA {
typedef struct _LSA_UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
PVOID Buffer; // PVOID to prevent ctypes to automatically read the content of the buffer till a \0
} LSA_UNICODE_STRING, *PLSA_UNICODE_STRING, UNICODE_STRING, *PUNICODE_STRING;
typedef struct _RTL_USER_PROCESS_PARAMETERS {
BYTE Reserved1[16];
PVOID Reserved2[10];
UNICODE_STRING ImagePathName;
UNICODE_STRING CommandLine;
typedef struct _CURDIR
{
UNICODE_STRING DosPath;
PVOID Handle;
} CURDIR, *PCURDIR;
typedef struct _RTL_DRIVE_LETTER_CURDIR
{
WORD Flags;
WORD Length;
ULONG TimeStamp;
UNICODE_STRING DosPath;
} RTL_DRIVE_LETTER_CURDIR, *PRTL_DRIVE_LETTER_CURDIR;
/* This is the part of RTL_USER_PROCESS_PARAMETERS that works from XP to Windows 10
http://terminus.rewolf.pl/terminus/structures/ntdll/_RTL_USER_PROCESS_PARAMETERS_x86.html
*/
typedef struct _RTL_USER_PROCESS_PARAMETERS
{
ULONG MaximumLength;
ULONG Length;
ULONG Flags;
ULONG DebugFlags;
PVOID ConsoleHandle;
ULONG ConsoleFlags;
PVOID StandardInput;
PVOID StandardOutput;
PVOID StandardError;
CURDIR CurrentDirectory;
UNICODE_STRING DllPath;
UNICODE_STRING ImagePathName;
UNICODE_STRING CommandLine;
PVOID Environment;
ULONG StartingX;
ULONG StartingY;
ULONG CountX;
ULONG CountY;
ULONG CountCharsX;
ULONG CountCharsY;
ULONG FillAttribute;
ULONG WindowFlags;
ULONG ShowWindowFlags;
UNICODE_STRING WindowTitle;
UNICODE_STRING DesktopInfo;
UNICODE_STRING ShellInfo;
UNICODE_STRING RuntimeData;
RTL_DRIVE_LETTER_CURDIR CurrentDirectores[32];
} RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS;
typedef struct _PEB {
BYTE Reserved1[2];
BYTE BeingDebugged;
@@ -16,6 +16,13 @@ typedef enum _ALPC_PORT_INFORMATION_CLASS
MaxAlpcPortInfoClass
} ALPC_PORT_INFORMATION_CLASS;
typedef enum _ALPC_MESSAGE_INFORMATION_CLASS
{
AlpcMessageSidInformation,
AlpcMessageTokenModifiedIdInformation,
MaxAlpcMessageInfoClass,
AlpcMessageHandleInformation,
} ALPC_MESSAGE_INFORMATION_CLASS, *PALPC_MESSAGE_INFORMATION_CLASS;
typedef struct _ALPC_PORT_ATTRIBUTES32
{
+201 -5
View File
@@ -85,7 +85,59 @@ _LSA_UNICODE_STRING
.. attribute:: Buffer
:class:`PWSTR`
:class:`PVOID`
_CURDIR
'''''''
.. class:: PCURDIR
Pointer to :class:`_CURDIR`
.. class:: CURDIR
Alias for :class:`_CURDIR`
.. class:: _CURDIR
.. attribute:: DosPath
:class:`UNICODE_STRING`
.. attribute:: Handle
:class:`PVOID`
_RTL_DRIVE_LETTER_CURDIR
''''''''''''''''''''''''
.. class:: PRTL_DRIVE_LETTER_CURDIR
Pointer to :class:`_RTL_DRIVE_LETTER_CURDIR`
.. class:: RTL_DRIVE_LETTER_CURDIR
Alias for :class:`_RTL_DRIVE_LETTER_CURDIR`
.. class:: _RTL_DRIVE_LETTER_CURDIR
.. attribute:: Flags
:class:`WORD`
.. attribute:: Length
:class:`WORD`
.. attribute:: TimeStamp
:class:`ULONG`
.. attribute:: DosPath
:class:`UNICODE_STRING`
_RTL_USER_PROCESS_PARAMETERS
''''''''''''''''''''''''''''
@@ -99,14 +151,59 @@ _RTL_USER_PROCESS_PARAMETERS
.. class:: _RTL_USER_PROCESS_PARAMETERS
.. attribute:: Reserved1
.. attribute:: MaximumLength
:class:`BYTE` ``[16]``
:class:`ULONG`
.. attribute:: Reserved2
.. attribute:: Length
:class:`PVOID` ``[10]``
:class:`ULONG`
.. attribute:: Flags
:class:`ULONG`
.. attribute:: DebugFlags
:class:`ULONG`
.. attribute:: ConsoleHandle
:class:`PVOID`
.. attribute:: ConsoleFlags
:class:`ULONG`
.. attribute:: StandardInput
:class:`PVOID`
.. attribute:: StandardOutput
:class:`PVOID`
.. attribute:: StandardError
:class:`PVOID`
.. attribute:: CurrentDirectory
:class:`CURDIR`
.. attribute:: DllPath
:class:`UNICODE_STRING`
.. attribute:: ImagePathName
@@ -118,6 +215,81 @@ _RTL_USER_PROCESS_PARAMETERS
:class:`UNICODE_STRING`
.. attribute:: Environment
:class:`PVOID`
.. attribute:: StartingX
:class:`ULONG`
.. attribute:: StartingY
:class:`ULONG`
.. attribute:: CountX
:class:`ULONG`
.. attribute:: CountY
:class:`ULONG`
.. attribute:: CountCharsX
:class:`ULONG`
.. attribute:: CountCharsY
:class:`ULONG`
.. attribute:: FillAttribute
:class:`ULONG`
.. attribute:: WindowFlags
:class:`ULONG`
.. attribute:: ShowWindowFlags
:class:`ULONG`
.. attribute:: WindowTitle
:class:`UNICODE_STRING`
.. attribute:: DesktopInfo
:class:`UNICODE_STRING`
.. attribute:: ShellInfo
:class:`UNICODE_STRING`
.. attribute:: RuntimeData
:class:`UNICODE_STRING`
.. attribute:: CurrentDirectores
:class:`RTL_DRIVE_LETTER_CURDIR` ``[32]``
_PEB
''''
.. class:: PPEB
@@ -13076,3 +13248,27 @@ _ALPC_PORT_INFORMATION_CLASS
.. attribute:: MaxAlpcPortInfoClass(12)
_ALPC_MESSAGE_INFORMATION_CLASS
'''''''''''''''''''''''''''''''
.. class:: ALPC_MESSAGE_INFORMATION_CLASS
Alias for :class:`_ALPC_MESSAGE_INFORMATION_CLASS`
.. class:: PALPC_MESSAGE_INFORMATION_CLASS
Pointer to :class:`_ALPC_MESSAGE_INFORMATION_CLASS`
.. class:: _ALPC_MESSAGE_INFORMATION_CLASS
.. attribute:: AlpcMessageSidInformation(0)
.. attribute:: AlpcMessageTokenModifiedIdInformation(1)
.. attribute:: MaxAlpcMessageInfoClass(2)
.. attribute:: AlpcMessageHandleInformation(3)
+2 -2
View File
@@ -357,7 +357,7 @@ class AlpcClient(AlpcTransportBase):
def _alpc_port_to_unicode_string(self, name):
utf16_len = len(name) * 2
return gdef.UNICODE_STRING(utf16_len, utf16_len, name)
return gdef.UNICODE_STRING(utf16_len, utf16_len, ctypes.cast(gdef.PWSTR(name), gdef.PVOID))
def connect_to_port(self, port_name, connect_message=None,
port_attr=None, port_attr_flags=0x10000, obj_attr=None,
@@ -453,7 +453,7 @@ class AlpcServer(AlpcTransportBase):
def _alpc_port_to_unicode_string(self, name):
utf16_len = len(name) * 2
return gdef.UNICODE_STRING(utf16_len, utf16_len, name)
return gdef.UNICODE_STRING(utf16_len, utf16_len, ctypes.cast(gdef.PWSTR(name), gdef.PVOID))
def create_port(self, port_name, msglen=None, port_attr_flags=0, obj_attr=None, port_attr=None):
"""Create the ALPC port ``port_name``. Most of the parameters have defauls value is ``None`` is passed.
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+97 -3
View File
@@ -1015,6 +1015,17 @@ class _ALPC_PORT_INFORMATION_CLASS(EnumType):
ALPC_PORT_INFORMATION_CLASS = _ALPC_PORT_INFORMATION_CLASS
AlpcMessageSidInformation = EnumValue("_ALPC_MESSAGE_INFORMATION_CLASS", "AlpcMessageSidInformation", 0x0)
AlpcMessageTokenModifiedIdInformation = EnumValue("_ALPC_MESSAGE_INFORMATION_CLASS", "AlpcMessageTokenModifiedIdInformation", 0x1)
MaxAlpcMessageInfoClass = EnumValue("_ALPC_MESSAGE_INFORMATION_CLASS", "MaxAlpcMessageInfoClass", 0x2)
AlpcMessageHandleInformation = EnumValue("_ALPC_MESSAGE_INFORMATION_CLASS", "AlpcMessageHandleInformation", 0x3)
class _ALPC_MESSAGE_INFORMATION_CLASS(EnumType):
values = [AlpcMessageSidInformation, AlpcMessageTokenModifiedIdInformation, MaxAlpcMessageInfoClass, AlpcMessageHandleInformation]
mapper = {x:x for x in values}
ALPC_MESSAGE_INFORMATION_CLASS = _ALPC_MESSAGE_INFORMATION_CLASS
PALPC_MESSAGE_INFORMATION_CLASS = POINTER(_ALPC_MESSAGE_INFORMATION_CLASS)
# Self referencing struct tricks
class _LIST_ENTRY(Structure): pass
PLIST_ENTRY = POINTER(_LIST_ENTRY)
@@ -1038,19 +1049,102 @@ class _LSA_UNICODE_STRING(Structure):
_fields_ = [
("Length", USHORT),
("MaximumLength", USHORT),
("Buffer", PWSTR),
("Buffer", PVOID),
]
PUNICODE_STRING = POINTER(_LSA_UNICODE_STRING)
UNICODE_STRING = _LSA_UNICODE_STRING
LSA_UNICODE_STRING = _LSA_UNICODE_STRING
PLSA_UNICODE_STRING = POINTER(_LSA_UNICODE_STRING)
INITIAL_LSA_UNICODE_STRING = _LSA_UNICODE_STRING
class _LSA_UNICODE_STRING(INITIAL_LSA_UNICODE_STRING):
@property
def str(self):
"""The python string of the LSA_UNICODE_STRING object
:type: :class:`unicode`
"""
if not self.Length:
return ""
if getattr(self, "_target", None) is not None: # remote ctypes :D -> TRICKS OF THE YEAR
# raw_data = self._target.read_memory(self.Buffer, self.Length)
buffer_ptr = self._target.read_ptr(self._base_addr + type(self).Buffer.offset)
raw_data = self._target.read_memory(buffer_ptr, self.Length)
return raw_data.decode("utf16")
size = self.Length / 2
buffer_ptr = PVOID.from_address(ctypes.addressof(self) + type(self).Buffer.offset).value
return (ctypes.c_wchar * size).from_address(buffer_ptr)[:]
@property
def str(self):
"""The python string of the LSA_UNICODE_STRING object
:type: :class:`unicode`
"""
if not self.Length:
return ""
if getattr(self, "_target", None) is not None: #remote ctypes :D -> TRICKS OF THE YEAR
raw_data = self._target.read_memory(self.Buffer, self.Length)
return raw_data.decode("utf16")
size = self.Length / 2
return (ctypes.c_wchar * size).from_address(self.Buffer)[:]
def __repr__(self):
return """<{0} "{1}" at {2}>""".format(type(self).__name__, self.str, hex(id(self)))
PUNICODE_STRING = POINTER(_LSA_UNICODE_STRING)
UNICODE_STRING = _LSA_UNICODE_STRING
LSA_UNICODE_STRING = _LSA_UNICODE_STRING
PLSA_UNICODE_STRING = POINTER(_LSA_UNICODE_STRING)
class _CURDIR(Structure):
_fields_ = [
("DosPath", UNICODE_STRING),
("Handle", PVOID),
]
PCURDIR = POINTER(_CURDIR)
CURDIR = _CURDIR
class _RTL_DRIVE_LETTER_CURDIR(Structure):
_fields_ = [
("Flags", WORD),
("Length", WORD),
("TimeStamp", ULONG),
("DosPath", UNICODE_STRING),
]
PRTL_DRIVE_LETTER_CURDIR = POINTER(_RTL_DRIVE_LETTER_CURDIR)
RTL_DRIVE_LETTER_CURDIR = _RTL_DRIVE_LETTER_CURDIR
class _RTL_USER_PROCESS_PARAMETERS(Structure):
_fields_ = [
("Reserved1", BYTE * 16),
("Reserved2", PVOID * 10),
("MaximumLength", ULONG),
("Length", ULONG),
("Flags", ULONG),
("DebugFlags", ULONG),
("ConsoleHandle", PVOID),
("ConsoleFlags", ULONG),
("StandardInput", PVOID),
("StandardOutput", PVOID),
("StandardError", PVOID),
("CurrentDirectory", CURDIR),
("DllPath", UNICODE_STRING),
("ImagePathName", UNICODE_STRING),
("CommandLine", UNICODE_STRING),
("Environment", PVOID),
("StartingX", ULONG),
("StartingY", ULONG),
("CountX", ULONG),
("CountY", ULONG),
("CountCharsX", ULONG),
("CountCharsY", ULONG),
("FillAttribute", ULONG),
("WindowFlags", ULONG),
("ShowWindowFlags", ULONG),
("WindowTitle", UNICODE_STRING),
("DesktopInfo", UNICODE_STRING),
("ShellInfo", UNICODE_STRING),
("RuntimeData", UNICODE_STRING),
("CurrentDirectores", RTL_DRIVE_LETTER_CURDIR * 32),
]
PRTL_USER_PROCESS_PARAMETERS = POINTER(_RTL_USER_PROCESS_PARAMETERS)
RTL_USER_PROCESS_PARAMETERS = _RTL_USER_PROCESS_PARAMETERS
+4 -4
View File
@@ -4,11 +4,11 @@ import ctypes
import windows
from windows import winproxy
from windows.generated_def import windef
from windows.winobject.process import WinUnicodeString
from windows.generated_def.winstructs import *
class EPUBLIC_OBJECT_TYPE_INFORMATION(ctypes.Structure):
_fields_ = windows.utils.transform_ctypes_fields(PUBLIC_OBJECT_TYPE_INFORMATION, {"TypeName": windows.winobject.process.WinUnicodeString})
# Remove this ?
class EPUBLIC_OBJECT_TYPE_INFORMATION(PUBLIC_OBJECT_TYPE_INFORMATION):
pass
current_process_pid = os.getpid()
@@ -47,7 +47,7 @@ class Handle(SYSTEM_HANDLE):
size_needed = DWORD()
yyy = ctypes.c_buffer(0x1000)
winproxy.NtQueryObject(lh, ObjectNameInformation, ctypes.byref(yyy), ctypes.sizeof(yyy), ctypes.byref(size_needed))
return WinUnicodeString.from_buffer_copy(yyy[:size_needed.value]).str
return LSA_UNICODE_STRING.from_buffer_copy(yyy[:size_needed.value]).str
def _get_object_type(self):
lh = self.local_handle
+5 -41
View File
@@ -564,7 +564,7 @@ class Process(AutoHandle):
if e.code not in [STATUS_FILE_INVALID, STATUS_INVALID_ADDRESS, STATUS_TRANSACTION_NOT_ACTIVE]:
raise
return None
remote_winstring = rctypes.transform_type_to_remote64bits(WinUnicodeString)
remote_winstring = rctypes.transform_type_to_remote64bits(gdef.LSA_UNICODE_STRING)
mapped_filename = remote_winstring(ctypes.addressof(buffer), windows.current_process)
return mapped_filename.str
@@ -1240,32 +1240,7 @@ def transform_ctypes_fields(struct, replacement):
return [(name, replacement.get(name, type)) for name, type in struct._fields_]
class WinUnicodeString(Structure):
"""LSA_UNICODE_STRING with a nice `__repr__`"""
_fields_ = transform_ctypes_fields(LSA_UNICODE_STRING, {"Buffer": ctypes.c_void_p})
fields = [f[0] for f in _fields_]
"""The fields of the structure"""
@property
def str(self):
"""The python string of the LSA_UNICODE_STRING object
:type: :class:`unicode`
"""
if not self.Length:
return ""
if getattr(self, "_target", None) is not None: #remote ctypes :D -> TRICKS OF THE YEAR
raw_data = self._target.read_memory(self.Buffer, self.Length)
return raw_data.decode("utf16")
size = self.Length / 2
return (ctypes.c_wchar * size).from_address(self.Buffer)[:]
def __repr__(self):
return """<{0} "{1}" at {2}>""".format(type(self).__name__, self.str, hex(id(self)))
class LoadedModule(Structure):
_fields_ = transform_ctypes_fields(LDR_DATA_TABLE_ENTRY, {"BaseDllName": WinUnicodeString, "FullDllName": WinUnicodeString})
class LoadedModule(LDR_DATA_TABLE_ENTRY):
"""An entry in the PEB Ldr list"""
@property
def baseaddr(self):
@@ -1308,18 +1283,8 @@ class LIST_ENTRY_PTR(PVOID):
return LDR_DATA_TABLE_ENTRY.from_address(self.value - sizeof(PVOID) * 2)
class RTL_USER_PROCESS_PARAMETERS(Structure):
_fields_ = transform_ctypes_fields(RTL_USER_PROCESS_PARAMETERS, # The one in generated_def
{"ImagePathName": WinUnicodeString,
"CommandLine": WinUnicodeString}
)
class PEB(Structure):
class PEB(gdef.PEB):
"""The PEB (Process Environment Block) of the current process"""
_fields_ = transform_ctypes_fields(PEB, # The one in generated_def
{"ProcessParameters": POINTER(RTL_USER_PROCESS_PARAMETERS)}
)
@property
def exe(self):
@@ -1333,7 +1298,7 @@ class PEB(Structure):
def imagepath(self):
"""The ImagePathName of the PEB
:type: :class:`WinUnicodeString`
:type: :class:`~windows.generated_def.LSA_UNICODE_STRING`
"""
return self.ProcessParameters.contents.ImagePathName
@@ -1341,9 +1306,8 @@ class PEB(Structure):
def commandline(self):
"""The CommandLine of the PEB
:type: :class:`WinUnicodeString`
:type: :class:`~windows.generated_def.LSA_UNICODE_STRING`
"""
# This or changing the __repr__ of LSA_UNICODE_STRING
return self.ProcessParameters.contents.CommandLine
@property
+5
View File
@@ -919,6 +919,11 @@ def NtAlpcDeleteSectionView(PortHandle, Flags, ViewBase):
return NtAlpcDeleteSectionView.ctypes_function(PortHandle, Flags, ViewBase)
@NtdllProxy("NtAlpcQueryInformationMessage", error_ntstatus)
def NtAlpcQueryInformationMessage(PortHandle, PortMessage, MessageInformationClass, MessageInformation, Length, ReturnLength):
return NtAlpcQueryInformationMessage.ctypes_function(PortHandle, PortMessage, MessageInformationClass, MessageInformation, Length, ReturnLength)
@NtdllProxy("NtOpenDirectoryObject", error_ntstatus)
def NtOpenDirectoryObject(DirectoryHandle, DesiredAccess, ObjectAttributes):
return NtOpenDirectoryObject.ctypes_function(DirectoryHandle, DesiredAccess, ObjectAttributes)