Wireshark-dev: Re: [Wireshark-dev] [openchange][devel] Parsing array and its size in EcDoRpcExt
From: Julien Kerihuel <j.kerihuel@xxxxxxxxxxxxxx>
Date: Tue, 28 Apr 2009 11:16:33 +0200
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@xxxxxxxxxxxxxxxxxxxx > http://mailman.openchange.org/listinfo/devel Julien Kerihuel j.kerihuel@xxxxxxxxxxxxxx OpenChange Project Manager GPG Fingerprint: 0B55 783D A781 6329 108A B609 7EF6 FE11 A35F 1F79
Attachment:
signature.asc
Description: This is a digitally signed message part
- Follow-Ups:
- Re: [Wireshark-dev] [openchange][devel] Parsing array and its size in EcDoRpcExt2
- From: Julien Kerihuel
- Re: [Wireshark-dev] [openchange][devel] Parsing array and its size in EcDoRpcExt2
- References:
- Prev by Date: Re: [Wireshark-dev] IEC dissectors
- Next by Date: Re: [Wireshark-dev] IEC dissectors
- Previous by thread: Re: [Wireshark-dev] Parsing array and its size in EcDoRpcExt2
- Next by thread: Re: [Wireshark-dev] [openchange][devel] Parsing array and its size in EcDoRpcExt2
- Index(es):