[openchange][devel] Parsing array and its size in EcDoRpcExt2

Julien Kerihuel j.kerihuel at openchange.org
Tue Apr 28 09:16:33 GMT 2009

On Mon, 2009-04-27 at 15:38 -0700, Harsha wrote:
> Hi all,
> I am writing a dissector for Wireshark for MAPI protocol and was
> trying to parse a DCERPC message. The code comments in Wireshark
> mentioned that the Samba folks maintain the DCERPC part, so I figured
> that this would be the best place to post my question.
> I was trying to parse this MSRPC function in Wireshark-
> long __stdcall EcDoRpcExt2(
> [in, out, ref] CXH * pcxh, [in, out] unsigned long *pulFlags,
> [in, size_is(cbIn)] unsigned char rgbIn[],
> [in] unsigned long cbIn, <br/>
> [out, length_is(*pcbOut), size_is(*pcbOut)] unsigned char rgbOut[],
> [in, out] BIG_RANGE_ULONG *pcbOut, <br/>
> [in, size_is(cbAuxIn)] unsigned char rgbAuxIn[],
> [in] unsigned long cbAuxIn, [out, length_is(*pcbAuxOut),
> size_is(*pcbAuxOut)] unsigned char rgbAuxOut[],
> [in, out] SMALL_RANGE_ULONG *pcbAuxOut,
> [out] unsigned long *pulTransTime
> );
> I'm stuck trying to parse
> [in, size_is(cbIn)] unsigned char rgbIn[],
> [in] unsigned long cbIn,

Hi Harsha,

You'll find below a *very* preliminary IDL and remarks:

	typedef [public, bitmap16bit] bitmap {
		RHEF_Compressed		= 0x0001,
		RHEF_XorMagic		= 0x0002,
		RHEF_Last		= 0x0004

	typedef [public] struct {
		uint16			Version;
		RPC_HEADER_EXT_Flags	Flags;
		uint16			Size;
		uint16			SizeActual;

	typedef [public, bitmap32bit] bitmap {
		pulFlags_NoCompression	= 0x00000001,
		pulFlags_NoXorMagic	= 0x00000002,
		pulFlags_Chain		= 0x00000004
	} pulFlags;

	typedef [public] struct {
		RPC_HEADER_EXT					header;
	} mapi2k3_rgbIn;

		[in,out]						policy_handle	*handle,
		[in,out]						pulFlags	*pulFlags,
		[in, subcontext(4),flag(NDR_REMAINING|NDR_NOALIGN)]	mapi2k3_rgbIn	*rgbIn,
		[in]							uint32		cbIn,
		[out]							uint32		size,
		[out]							uint32		offset,
		[out,subcontext(4),flag(NDR_REMAINING|NDR_NOALIGN)]	DATA_BLOB	rgbOut,
		[in,out][range(0,262144)]				uint32		*pcbOut,
		[in, subcontext(4),flag(NDR_REMAINING|NDR_NOALIGN)]	DATA_BLOB	rgbAuxIn,
		[in]							uint32		cbAuxIn,
		[out,subcontext(4),flag(NDR_REMAINING|NDR_NOALIGN)]	DATA_BLOB	rgbAuxOut,
		[in,out][range(0,4104)]					uint32		*pcbAuxOut,
		[out]							uint32		*pulTransTime

        -  I replaced the SMALL_RANGE_ULONG and BIG_RANGE_ULONG typedefs
        with their associated values
        - rgbAuxIn and rgbAuxOut while having their size defined after
        in the IDL (cbAuxIn, pcbAuxOut) also have their array size
        prefixing the blob when you look at the NDR blob.
        - rgbOut is prefixed with
        [size=4bytes][offset=4bytes][length=4bytes], so I turned it into
        a subcontext(4) handling length and explicitly added size and
        offset field for padding purposes.
        - In this IDL I have only started to hack rgbIn which I changed
        from DATA_BLOB to mapi2k3_rgbIn (not definitive names).

The reason why I turned the initial uint8 array into subcontexts is that
the blob processing - using samba4 NDR layer - needs to be done manually
(see ndr_mapi.c in openchange trunk) - and dealing with DATA_BLOB is
easier IMHO than uint8 array when it comes to use this blob as a ndr
context - for boundaries etc.

About the decoding routines internals (will focus on rgbIn as it
shouldn't be different for other blobs):

        - the mapi2k3_rgbIn can be either a single request or multiple
        requests (depending if the Last flag is enabled). Note that
        using NDR_REMAINING for the mapi2k3_rgbIn.data is incorrect
        since it doesn't consider the Last flag at all.
        - secondly it can either be Xor'ed (already used for EcDoRpc) or
        Compressed (see samba4/librpc/idl/drsuapi.idl and
        The point is that as far I as know, we won't be able to process
        this using a pidl union. While we can easily use
        switch_is(Header.Flags) in mapi2k3_rgbIn, we also need to supply
        the length and actual length so the lxpress decompression can be
        done properly.
        1. I plan to implement this similarly to what was done for
                - Try to write as much EcDoRpcExt2 related structures as
                possible, tag them as public and use NDR_NOALIGN
        2. Only write manually the mapi2k3_rgbIn pull/push/print
        functions and rely as much as possible on generated/existing
PS: TDR is probably the best way to implement this, but that would cost
a lot of extra work and this would probably take quite some time before
we get back to the same level of features/stability.

Note: I have preliminary tried to use the following IDL which turns to
decode the EcDoRpcExt2 blob properly, but which has limitations - mostly
because rgbOut, rgbAuxIn and pcbAuxOut are not NDR encoded (see the
NDR_NOALIGN hack) and I try to avoid as much as possible non-pidl
generated code:

		[in,out]			policy_handle		*handle,
		[in,out]			pulFlags		*pulFlags,
		[in,size_is(cbIn)]		uint8			rgbIn[],
		[in]				uint32			cbIn,
		[out, length_is(*pcbOut), size_is(*pcbOut)] uint8	rgbOut[],
		[in,out][range(0,262144)]	uint32			*pcbOut,
		[in,size_is(cbAuxIn)]		uint8			rgbAuxIn[],
		[in]				uint32			cbAuxIn,
		[out, length_is(*pcbAuxOut), size_is(*pcbAuxOut)] uint8	rgbAuxOut[],
		[in,out][range(0,4104)]		uint32			*pcbAuxOut,
		[out]				uint32			*pulTransTime

> The problem I see is that we first have the array and then it length.
> I did a quick read of the relevant part of DCE RPC specs, but in all
> the cases I saw it always had the size and then the array. In those
> cases it is trivial to first extract the size and use the size to
> extract the array contents.
> I'm sure it is not a typo in the spec, so clearly I'm missing
> something. Can someone please clarify how to parse the array field ?
> Any pointers/ suggestions/ hints welcome.
> Many thanks,
> Harsha
> _______________________________________________
> devel mailing list
> devel at lists.openchange.org
> http://mailman.openchange.org/listinfo/devel
Julien Kerihuel
j.kerihuel at openchange.org
OpenChange Project Manager

GPG Fingerprint: 0B55 783D A781 6329 108A  B609 7EF6 FE11 A35F 1F79

-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 197 bytes
Desc: This is a digitally signed message part
Url : http://lists.samba.org/archive/samba-technical/attachments/20090428/fd5d1785/attachment.bin

More information about the samba-technical mailing list