From 37d5e9089e07213c8e88e68956649695abb2f4c7 Mon Sep 17 00:00:00 2001 From: hakril Date: Thu, 15 May 2025 09:00:59 +0200 Subject: [PATCH] Add use_memoryview param to NdrStream() for speed. Default=False as it currently require special handling in response. --- windows/rpc/client.py | 5 +++++ windows/rpc/ndr.py | 12 +++++++++--- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/windows/rpc/client.py b/windows/rpc/client.py index 03e1741..087ac86 100644 --- a/windows/rpc/client.py +++ b/windows/rpc/client.py @@ -225,6 +225,11 @@ class RPCClient(object): viewattr = response.view_attribute assert viewattr.ViewSize >= rpcdatasize data = windows.current_process.read_memory(viewattr.ViewBase, rpcdatasize) + # We have copied the data from the view: free it + # It looks like: + # windows.winproxy.NtAlpcDeleteSectionView(self.alpc_client.handle, 0, viewattr.ViewBase) + # Will ne be enough, as it will wait for the message to be reused to unmap the section.. + # And the current architecture encourage creating new message every time if response_header.request_id == self.REQUEST_IDENTIFIER_ORPC: # Parse & remove ORPC headers (orpcthat + LocalThat) data = self._pass_orpc_response_structures(data) diff --git a/windows/rpc/ndr.py b/windows/rpc/ndr.py index ebf8c81..88af143 100644 --- a/windows/rpc/ndr.py +++ b/windows/rpc/ndr.py @@ -173,6 +173,8 @@ class NdrWString(object): assert size1 == size2 assert zero == 0 s = stream.read(size1 * 2) + if stream.use_memoryview: + return bytearray(s).decode("utf-16-le") return s.decode("utf-16-le") @classmethod @@ -551,10 +553,14 @@ class NdrGuidConformantArray(NdrConformantArray): class NdrStream(object): """A stream of bytes used for NDR unpacking""" - def __init__(self, data): + def __init__(self, data, use_memoryview=False): + """""" self.fulldata = data - self.data = data - # self.data = memoryview(data) # FAST but need some code rewrite at some places + self.use_memoryview = use_memoryview + if use_memoryview: + self.data = memoryview(data) # FAST but need some code rewrite at some places + else: + self.data = data def partial_unpack(self, format): size = struct.calcsize(format)