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
> [email protected]
> http://mailman.openchange.org/listinfo/devel
Julien Kerihuel
[email protected]
OpenChange Project Manager
GPG Fingerprint: 0B55 783D A781 6329 108A B609 7EF6 FE11 A35F 1F79
signature.asc
Description: This is a digitally signed message part
_______________________________________________ devel mailing list [email protected] http://mailman.openchange.org/listinfo/devel
