diff --git a/tests/test_apisetmap.py b/tests/test_apisetmap.py index d9e4a5e7..c1528cb0 100644 --- a/tests/test_apisetmap.py +++ b/tests/test_apisetmap.py @@ -20,7 +20,7 @@ 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-"] +KNOWN_APISETMAP_PREFIX = ["api-", "ext-", "MS-Win-", "SchemaExt-"] def verify_apisetmap_parsing(apisetmap_base, version=None): if version is not None: diff --git a/tests/test_ndr.py b/tests/test_ndr.py index 64f34fef..37d93fb6 100644 --- a/tests/test_ndr.py +++ b/tests/test_ndr.py @@ -58,6 +58,11 @@ class ComplexAlignementStructure(ndr.NdrStructure): NDR_PACK_TEST_CASE = [ # Simple case (ndr.make_structure([ndr.NdrLong, ndr.NdrLong]), (2, 2), b"\x02\x00\x00\x00\x02\x00\x00\x00"), + # String case, test packing works + \x00 is added if not present in string + (ndr.NdrCString, "Hello", b"\x06\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00Hello\x00PP"), + (ndr.NdrCString, "Hello\x00", b"\x06\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00Hello\x00PP"), + (ndr.NdrWString, "Hello", b"\x06\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00H\x00e\x00l\x00l\x00o\x00\x00\x00"), + (ndr.NdrWString, "Hello\x00", b"\x06\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00H\x00e\x00l\x00l\x00o\x00\x00\x00"), # Test GUID packing (ndr.NdrGuid, gdef.GUID.from_string("42424242-42424242-4242-4242-424242424242"), b"BBBBBBBBBBBBBBBB"), # Test CtxHandle packing diff --git a/windows/rpc/ndr.py b/windows/rpc/ndr.py index 88af1431..065447b8 100644 --- a/windows/rpc/ndr.py +++ b/windows/rpc/ndr.py @@ -160,6 +160,9 @@ def pack(cls, data): return None if not data.endswith('\x00'): data += '\x00' + # Technically windows NDR seems to accept any bitstream that ends with '\x00\x00' here + # And not limited to valid utf-16 + # Exemple: b'\x41\x00\x00\xD8' data = data.encode("utf-16-le") l = (len(data) // 2) result = struct.pack("<3I", l, 0, l) @@ -179,7 +182,7 @@ def unpack(cls, stream): @classmethod def get_alignment(self): - # Not sur, but size is on 4 bytes so... + # Not sure, but size is on 4 bytes so... return 4 class NdrCString(object): @@ -190,6 +193,10 @@ def pack(cls, data): return None if not data.endswith('\x00'): data += '\x00' + # Windows NDR seems to accept any bitstream in a FC_C_CSTRING + # I was able to send range(1, 256) + b"\x00" + # For now play safe for user and only accept encoded with always keep the same number of bytes + data = data.encode("ascii") l = len(data) result = struct.pack("<3I", l, 0, l) result += data