[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
} RPC_HEADER_EXT_Flags;
typedef [public] struct {
uint16 Version;
RPC_HEADER_EXT_Flags Flags;
uint16 Size;
uint16 SizeActual;
} RPC_HEADER_EXT;
typedef [public, bitmap32bit] bitmap {
pulFlags_NoCompression = 0x00000001,
pulFlags_NoXorMagic = 0x00000002,
pulFlags_Chain = 0x00000004
} pulFlags;
typedef [public] struct {
RPC_HEADER_EXT header;
[flag(NDR_NOALIGN|NDR_REMAINING)] DATA_BLOB data;
} mapi2k3_rgbIn;
MAPISTATUS EcDoRpcExt2(
[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
compression(NDR_COMPRESSION_XPRESS)).
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.
Conclusion:
1. I plan to implement this similarly to what was done for
EcDoRpc:
- 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
IDL.
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:
MAPISTATUS EcDoRpcExt2(
[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