Structures for NT security

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Structures for NT security

Bill Schwab-2
Blair,

I recently had need to reboot windows from within a Dolphin executable.
ExitWindowsEx() will not work until the app authorizes itself to run it.
LUID_AND_ATTRIBUTES and TOKEN_PRIVILEGES present themselves.

TOKEN_PRIVILEGES is particularly fun because it contains an array of size
ANYSIZE_ARRAY - read one element.  I'm assuming that the designer didn't
want to be bothered with a pointer, and reasoned that other elements could
be arrayed behind the one referenced in the structure.  Does that have any
implications for the way one would define the structure in Dolphin?

Having done what I thought was the right thing, I found that nothing worked.
Then I found a sample C++ program and compiled it with MinGW.  Some
debugging revealed that it was doing pretty much everything I was, with one
difference: it worked =:0   A sizeof in the C++ program revealed that the
TOKEN_PRIVILEGES structure had a size that suspiciously matched what one
would predict without packing.  I finally just dumped the correctly sized
elements into a byte array and got it working.  Comments?  It seems weird
that the "Advanced API" would not use the default packing and alignment.

In the past, you've mentioned writing a C program to print structure sizes
and offsets.  I know how to get the size, but how does one get the offsets?

Have a good one,

Bill

--
Wilhelm K. Schwab, Ph.D.
[hidden email]


Reply | Threaded
Open this post in threaded view
|

Re: Structures for NT security

Maxim Fridental
Bill,

"Bill Schwab" <[hidden email]> schrieb im Newsbeitrag
news:bpmlrl$1ocn7r$[hidden email]...
> difference: it worked =:0   A sizeof in the C++ program revealed that the
> TOKEN_PRIVILEGES structure had a size that suspiciously matched what one
> would predict without packing.  I finally just dumped the correctly sized
> elements into a byte array and got it working.  Comments?  It seems weird
> that the "Advanced API" would not use the default packing and alignment.
I've had the very same problem. The catch is that Dolphin default packing
doesn't comply with Advanced API wants to have. Luckily you can set the
alignment  yourself:
!LUID_AND_ATTRIBUTES class methodsFor!

alignment
 ^4!

defineFields
 "
 self compileDefinition
 typedef struct _LUID_AND_ATTRIBUTES {
 LUID Luid;
 DWORD Attributes
 } LUID_AND_ATTRIBUTES, *PLUID_AND_ATTRIBUTES;"

 self
  defineField: #luid type: QWORDField new;
  defineField: #attributes type: DWORDField new! !

and then

!TOKEN_PRIVILEGES class methodsFor!

defineFields
 "
 self compileDefinition

 typedef struct _TOKEN_PRIVILEGES {
 DWORD PrivilegeCount ;
 LUID_AND_ATTRIBUTES Privileges [ANYSIZE_ARRAY];
  } TOKEN_PRIVILEGES, *PTOKEN_PRIVILEGES;"

 self
  defineField: #privilegeCount type: DWORDField new;
  defineField: #privileges
   type: (VariableStructureArrayField type: LUID_AND_ATTRIBUTES length:
#privilegeCount)! !



Best Regards,
Maxim Fridental


Reply | Threaded
Open this post in threaded view
|

Re: Structures for NT security

Chris Uppal-3
In reply to this post by Bill Schwab-2
Bill Schwab wrote:

> In the past, you've mentioned writing a C program to print structure sizes
> and offsets.  I know how to get the size, but how does one get the
> offsets?

An idiom which may help (from memory -- i.e. untested):

    #define OFFSET_OF(type, field)    \
            ( (int)&((type *)0->field) )

E.g, with:

    typedef struct xxx
    {
            char ch;
            int i;
    } XXX;

then:

    printf("%d\n", OFFSET_OF(XXX, i));

    -- chris


Reply | Threaded
Open this post in threaded view
|

Re: Structures for NT security

Blair McGlashan-2
In reply to this post by Bill Schwab-2
"Bill Schwab" <[hidden email]> wrote in message
news:bpmlrl$1ocn7r$[hidden email]...

> Blair,
>
> I recently had need to reboot windows from within a Dolphin executable.
> ExitWindowsEx() will not work until the app authorizes itself to run it.
> LUID_AND_ATTRIBUTES and TOKEN_PRIVILEGES present themselves.
>
> TOKEN_PRIVILEGES is particularly fun because it contains an array of size
> ANYSIZE_ARRAY - read one element.  I'm assuming that the designer didn't
> want to be bothered with a pointer, and reasoned that other elements could
> be arrayed behind the one referenced in the structure.  Does that have any
> implications for the way one would define the structure in Dolphin?

This is a typical assembly language programmers trick. The idea is to define
a variable length structure where the last field is an array that can vary
in size - the array is typically defined as having 1 element in the
structure definition because many C compilers won't allow the definition of
zero length arrays. Another field usually specifies the real length of the
variable length part. The benefit of this approach is that it means only a
single block of memory need be allocated for the structure, which has
various space/performance/management advantages. The dowside is that the
structure is more difficult to represent and use.

This sort of representation does pop up occassionally in the Win32 API, and
the VariableStructureArrayField type can be used to represent such fields in
Dolphin ExternalStructure definitions. See, for example, BITMAPINFO.

>
> Having done what I thought was the right thing, I found that nothing
worked.
> Then I found a sample C++ program and compiled it with MinGW.  Some
> debugging revealed that it was doing pretty much everything I was, with
one
> difference: it worked =:0   A sizeof in the C++ program revealed that the
> TOKEN_PRIVILEGES structure had a size that suspiciously matched what one
> would predict without packing.  I finally just dumped the correctly sized
> elements into a byte array and got it working.  Comments?  It seems weird
> that the "Advanced API" would not use the default packing and alignment.

If you look at the definition of LUID_AND_ATTRIBUTES in WinNT.h, you'll see
that it is surrounded by a pair of includes as follows:

#include <pshpack4.h>
....

#include <poppack.h>

The first include file does whatever is necessary in the including
environment to switch to 4-byte packing (from the normal natural size
packing that Win32 usually uses). The second pops back to whatever packing
was in force before.
>
> In the past, you've mentioned writing a C program to print structure sizes
> and offsets.  I know how to get the size, but how does one get the
offsets?

The offsetof(struct,field) macro can be used, but these days I never define
ExternalStructures by hand. I always generate them from a type-library, and
then edit the results by hand if needs be. This helps eliminate size and
offset errors, which can otherwise go unnoticed or cause damaging memory
overwrite errors.

Most Win32 structures are already defined in:

http://www.themandelbrotset.com/Technical/Typelib.asp

This is a useful resource, though it does have the disadvantage of being
explicitly targetted at VB, and hence (since VB does not support unsigned
integer types), all the unsigned integers are incorrectly defined as shared.
This is trivial to correct however.

I don't think these NT security structures are defined in that library,
however, so I would just create an IDL definition (by copying and pasting
the relevant definitions from WinNT.h, including the structure packing
includes, into the library block of an IDL file) and run the freely
available MIDL compiler against it. Then I'd use the AX Component Wizard to
load up the resulting type library and create the Dolphin ExternalStructure
defs.

Regards

Blair