Ethereal-dev: Re: [Ethereal-dev] DCERPC support and improved SAMR

Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.

From: "Ronnie Sahlberg" <sahlberg@xxxxxxxxxxxxxxxx>
Date: Tue, 5 Feb 2002 20:37:24 +1100
----- Original Message -----
From: "Guy Harris"
Sent: Tuesday, February 05, 2002 6:57 PM
Subject: Re: [Ethereal-dev] DCERPC support and improved SAMR


> > The patch also makes each pointer (to structure) be evaluated twice,
> > once with conformant_run==1    and once with conformant_run==0.
> > This is to make the dissection of non-fixed arrays work properly.
> > Currently only unidimensional conformant and unidimensional conformant
and
> > varying arrays are implemented.
> > This is however completely transparent to the dissector in say samr and
only
> > visible in packet-dcerpc.c
> > However, it means that subdissectors can only call dissect_ndr_xxx
> > functions, or other handcrafted functions which are aware
> > of when to dissect scalars and when not to.
> > See dissect_ndr_ucarray()m dissect_ndr_ucvarray() and
> > dissect_deferred_pointers()  for examples on how this interaction
> > works.
>
> This causes the reply to a SAMR_QUERY_DISPINFO call not to be dissected
> completely correctly.
>
> DISPLAY_INFO is defined as
>
>     typedef [switch_type(unsigned short)] union {
>       [case(1)] USER_DISPINFO_1_ARRAY users1;
>       [case(2)] USER_DISPINFO_2_ARRAY users2;
>       [case(3)] GROUP_DISPINFO_ARRAY groups;
>       [case(4)] ASCII_DISPINFO_ARRAY ausers;
>       [case(5)] ASCII_DISPINFO_ARRAY agroups;
>     } DISPLAY_INFO;
>
> The dissector disects the "switch_type" value (as "Level"), and then
> dissects the info.
>
> For level 1, USER_DISPINFO_1_ARRAY is defined as
>
>     typedef struct {
>       long count;
>       [size_is(count), ptr]  USER_DISPINFO_1 *users;
>     } USER_DISPINFO_1_ARRAY;
>
> It dissects the "count" field as "Max Count" (but it's *not* a count
> field for a conformant array, it's just a number called "count"), and
> then dissects the pointer.
>
> Then it dissects the Referent ID.
>
> It *should* then dissect the max_count for the array to which "users"
> points, but it doesn't, because, in "dissect_deferred_pointers()":
>
> the first pass, with "conformant_run" true, passes null as the
> tree pointer, so nothing is put into the protocol tree when
> "dissect_ndr_ucarray()" calls "dissect_ndr_uint32()" to get the
> max_count;
>
> the second pass, with "conformant_run false, doesn't dissect the
> max_count header;
>
> so there's no pass where the max_count header is dissected and the
> "tree" argument is non-null.
>

The example above should be dissected as
[2byte, short : Level] [ 2 padding bytes]
[4byte, long : count ]  [ 4byte referent id]
[4byte : maxcount for conformant array] [first array argument] [second ...

I will look at the dissector to see where the bug is and try to fix it.
Your problem description is detailed enough so I should be able to track the
bug down.