flat assembler
Message board for the users of flat assembler.

Index > Windows > [solved] PROPVARIANT structure

Author
Thread Post new topic Reply to topic
Overclick



Joined: 11 Jul 2020
Posts: 670
Location: Ukraine
Overclick 27 Mar 2021, 01:11
Hi
Is it correct for 64bit?
Code:
        struct          BLOB
                cbSize          dd ?
                pBlobData       dq ?
        ends
        struct          PROPVARIANT
                vt              dw ?
                wRes1           db ?
                wRes2           db ?
                wRes3           dd ?
                blob            BLOB
        end    


Last edited by Overclick on 27 Mar 2021, 11:44; edited 1 time in total
Post 27 Mar 2021, 01:11
View user's profile Send private message Visit poster's website Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20487
Location: In your JS exploiting you and your system
revolution 27 Mar 2021, 06:42
I think you need to change end to ends.
Post 27 Mar 2021, 06:42
View user's profile Send private message Visit poster's website Reply with quote
bitRAKE



Joined: 21 Jul 2003
Posts: 4121
Location: vpcmpistri
bitRAKE 27 Mar 2021, 06:55
Currently MS defines it in PropIdBase.h as
Code:
struct tag_inner_PROPVARIANT
    {
    VARTYPE vt;
    PROPVAR_PAD1 wReserved1;
    PROPVAR_PAD2 wReserved2;
    PROPVAR_PAD3 wReserved3;
    /* [switch_is] */ /* [switch_type] */ union 
        {
        /* [case()] */  /* Empty union arm */ 
        /* [case()] */ CHAR cVal;
        /* [case()] */ UCHAR bVal;
        /* [case()] */ SHORT iVal;
        /* [case()] */ USHORT uiVal;
        /* [case()] */ LONG lVal;
        /* [case()] */ ULONG ulVal;
        /* [case()] */ INT intVal;
        /* [case()] */ UINT uintVal;
        /* [case()] */ LARGE_INTEGER hVal;
        /* [case()] */ ULARGE_INTEGER uhVal;
        /* [case()] */ FLOAT fltVal;
        /* [case()] */ DOUBLE dblVal;
        /* [case()] */ VARIANT_BOOL boolVal;
        /* [case()] */ VARIANT_BOOL __OBSOLETE__VARIANT_BOOL;
        /* [case()] */ SCODE scode;
        /* [case()] */ CY cyVal;
        /* [case()] */ DATE date;
        /* [case()] */ FILETIME filetime;
        /* [case()] */ CLSID *puuid;
        /* [case()] */ CLIPDATA *pclipdata;
        /* [case()] */ BSTR bstrVal;
        /* [case()] */ BSTRBLOB bstrblobVal;
        /* [case()] */ BLOB blob;
        /* [case()] */ LPSTR pszVal;
        /* [case()] */ LPWSTR pwszVal;
        /* [case()] */ IUnknown *punkVal;
        /* [case()] */ IDispatch *pdispVal;
        /* [case()] */ IStream *pStream;
        /* [case()] */ IStorage *pStorage;
        /* [case()] */ LPVERSIONEDSTREAM pVersionedStream;
        /* [case()] */ LPSAFEARRAY parray;
        /* [case()] */ CAC cac;
        /* [case()] */ CAUB caub;
        /* [case()] */ CAI cai;
        /* [case()] */ CAUI caui;
        /* [case()] */ CAL cal;
        /* [case()] */ CAUL caul;
        /* [case()] */ CAH cah;
        /* [case()] */ CAUH cauh;
        /* [case()] */ CAFLT caflt;
        /* [case()] */ CADBL cadbl;
        /* [case()] */ CABOOL cabool;
        /* [case()] */ CASCODE cascode;
        /* [case()] */ CACY cacy;
        /* [case()] */ CADATE cadate;
        /* [case()] */ CAFILETIME cafiletime;
        /* [case()] */ CACLSID cauuid;
        /* [case()] */ CACLIPDATA caclipdata;
        /* [case()] */ CABSTR cabstr;
        /* [case()] */ CABSTRBLOB cabstrblob;
        /* [case()] */ CALPSTR calpstr;
        /* [case()] */ CALPWSTR calpwstr;
        /* [case()] */ CAPROPVARIANT capropvar;
        /* [case()] */ CHAR *pcVal;
        /* [case()] */ UCHAR *pbVal;
        /* [case()] */ SHORT *piVal;
        /* [case()] */ USHORT *puiVal;
        /* [case()] */ LONG *plVal;
        /* [case()] */ ULONG *pulVal;
        /* [case()] */ INT *pintVal;
        /* [case()] */ UINT *puintVal;
        /* [case()] */ FLOAT *pfltVal;
        /* [case()] */ DOUBLE *pdblVal;
        /* [case()] */ VARIANT_BOOL *pboolVal;
        /* [case()] */ DECIMAL *pdecVal;
        /* [case()] */ SCODE *pscode;
        /* [case()] */ CY *pcyVal;
        /* [case()] */ DATE *pdate;
        /* [case()] */ BSTR *pbstrVal;
        /* [case()] */ IUnknown **ppunkVal;
        /* [case()] */ IDispatch **ppdispVal;
        /* [case()] */ LPSAFEARRAY *pparray;
        /* [case()] */ PROPVARIANT *pvarVal;
        }       ;
    } ;
#ifndef MIDL_PASS
    DECIMAL decVal;
  };
};
#endif    
It's a catch all for all these types - only a few of them change under 64-bit - otherwise it's the same regardless of system.

Here is a map for VARTYPE vt (in wtypes.h):
Code:
typedef unsigned short VARTYPE;

/*
 * VARENUM usage key,
 *
 * * [V] - may appear in a VARIANT
 * * [T] - may appear in a TYPEDESC
 * * [P] - may appear in an OLE property set
 * * [S] - may appear in a Safe Array
 *
 *
 *  VT_EMPTY            [V]   [P]     nothing
 *  VT_NULL             [V]   [P]     SQL style Null
 *  VT_I2               [V][T][P][S]  2 byte signed int
 *  VT_I4               [V][T][P][S]  4 byte signed int
 *  VT_R4               [V][T][P][S]  4 byte real
 *  VT_R8               [V][T][P][S]  8 byte real
 *  VT_CY               [V][T][P][S]  currency
 *  VT_DATE             [V][T][P][S]  date
 *  VT_BSTR             [V][T][P][S]  OLE Automation string
 *  VT_DISPATCH         [V][T]   [S]  IDispatch *
 *  VT_ERROR            [V][T][P][S]  SCODE
 *  VT_BOOL             [V][T][P][S]  True=-1, False=0
 *  VT_VARIANT          [V][T][P][S]  VARIANT *
 *  VT_UNKNOWN          [V][T]   [S]  IUnknown *
 *  VT_DECIMAL          [V][T]   [S]  16 byte fixed point
 *  VT_RECORD           [V]   [P][S]  user defined type
 *  VT_I1               [V][T][P][s]  signed char
 *  VT_UI1              [V][T][P][S]  unsigned char
 *  VT_UI2              [V][T][P][S]  unsigned short
 *  VT_UI4              [V][T][P][S]  ULONG
 *  VT_I8                  [T][P]     signed 64-bit int
 *  VT_UI8                 [T][P]     unsigned 64-bit int
 *  VT_INT              [V][T][P][S]  signed machine int
 *  VT_UINT             [V][T]   [S]  unsigned machine int
 *  VT_INT_PTR             [T]        signed machine register size width
 *  VT_UINT_PTR            [T]        unsigned machine register size width
 *  VT_VOID                [T]        C style void
 *  VT_HRESULT             [T]        Standard return type
 *  VT_PTR                 [T]        pointer type
 *  VT_SAFEARRAY           [T]        (use VT_ARRAY in VARIANT)
 *  VT_CARRAY              [T]        C style array
 *  VT_USERDEFINED         [T]        user defined type
 *  VT_LPSTR               [T][P]     null terminated string
 *  VT_LPWSTR              [T][P]     wide null terminated string
 *  VT_FILETIME               [P]     FILETIME
 *  VT_BLOB                   [P]     Length prefixed bytes
 *  VT_STREAM                 [P]     Name of the stream follows
 *  VT_STORAGE                [P]     Name of the storage follows
 *  VT_STREAMED_OBJECT        [P]     Stream contains an object
 *  VT_STORED_OBJECT          [P]     Storage contains an object
 *  VT_VERSIONED_STREAM       [P]     Stream with a GUID version
 *  VT_BLOB_OBJECT            [P]     Blob contains an object 
 *  VT_CF                     [P]     Clipboard format
 *  VT_CLSID                  [P]     A Class ID
 *  VT_VECTOR                 [P]     simple counted array
 *  VT_ARRAY            [V]           SAFEARRAY*
 *  VT_BYREF            [V]           void* for local use
 *  VT_BSTR_BLOB                      Reserved for system use
 */

enum VARENUM
    {
        VT_EMPTY        = 0,
        VT_NULL = 1,
        VT_I2   = 2,
        VT_I4   = 3,
        VT_R4   = 4,
        VT_R8   = 5,
        VT_CY   = 6,
        VT_DATE = 7,
        VT_BSTR = 8,
        VT_DISPATCH     = 9,
        VT_ERROR        = 10,
        VT_BOOL = 11,
        VT_VARIANT      = 12,
        VT_UNKNOWN      = 13,
        VT_DECIMAL      = 14,
        VT_I1   = 16,
        VT_UI1  = 17,
        VT_UI2  = 18,
        VT_UI4  = 19,
        VT_I8   = 20,
        VT_UI8  = 21,
        VT_INT  = 22,
        VT_UINT = 23,
        VT_VOID = 24,
        VT_HRESULT      = 25,
        VT_PTR  = 26,
        VT_SAFEARRAY    = 27,
        VT_CARRAY       = 28,
        VT_USERDEFINED  = 29,
        VT_LPSTR        = 30,
        VT_LPWSTR       = 31,
        VT_RECORD       = 36,
        VT_INT_PTR      = 37,
        VT_UINT_PTR     = 38,
        VT_FILETIME     = 64,
        VT_BLOB = 65,
        VT_STREAM       = 66,
        VT_STORAGE      = 67,
        VT_STREAMED_OBJECT      = 68,
        VT_STORED_OBJECT        = 69,
        VT_BLOB_OBJECT  = 70,
        VT_CF   = 71,
        VT_CLSID        = 72,
        VT_VERSIONED_STREAM     = 73,
        VT_BSTR_BLOB    = 0xfff,
        VT_VECTOR       = 0x1000,
        VT_ARRAY        = 0x2000,
        VT_BYREF        = 0x4000,
        VT_RESERVED     = 0x8000,
        VT_ILLEGAL      = 0xffff,
        VT_ILLEGALMASKED        = 0xfff,
        VT_TYPEMASK     = 0xfff
    } ;    
As long as the structure is 24 bytes and vt is used to decode the data you should be fine, imho. (seems like you're 4 bytes shy)

Maybe,
Code:
struct PROPVARIANT
  vt dw ?,?,?,? ; padding
  _data: db 16
end struct    
... if I were to rewrite history. Very Happy

_________________
¯\(°_o)/¯ “languages are not safe - uses can be” Bjarne Stroustrup


Last edited by bitRAKE on 27 Mar 2021, 07:05; edited 1 time in total
Post 27 Mar 2021, 06:55
View user's profile Send private message Visit poster's website Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20487
Location: In your JS exploiting you and your system
revolution 27 Mar 2021, 07:04
So it needs 4 bytes of padding after cbSize to align the dq?
Post 27 Mar 2021, 07:04
View user's profile Send private message Visit poster's website Reply with quote
bitRAKE



Joined: 21 Jul 2003
Posts: 4121
Location: vpcmpistri
bitRAKE 27 Mar 2021, 07:07
Nice catch - yes, that would be the reason.
Post 27 Mar 2021, 07:07
View user's profile Send private message Visit poster's website Reply with quote
ProMiNick



Joined: 24 Mar 2012
Posts: 816
Location: Russian Federation, Sochi
ProMiNick 27 Mar 2021, 07:12
Code:
struct          BLOB
                cbSize          dd ?,? ; qword must be aligned on 8 bytes boundary ; in HLL it goes via such words as pragmapack 8 or aligment hidden in compiler another way
                pBlobData       dq ?
        ends    
Post 27 Mar 2021, 07:12
View user's profile Send private message Send e-mail Reply with quote
Overclick



Joined: 11 Jul 2020
Posts: 670
Location: Ukraine
Overclick 27 Mar 2021, 11:42
Quote:

/* [switch_is] */ /* [switch_type] */ union

Seems like it's not a full list of variables. I'm looking for WAVEFORMATEX structure on it.

It's finally works! Thanks for extra padding mates Very Happy
Post 27 Mar 2021, 11:42
View user's profile Send private message Visit poster's website Reply with quote
Overclick



Joined: 11 Jul 2020
Posts: 670
Location: Ukraine
Overclick 27 Mar 2021, 14:25
p.s. I just add some union for different purposes I need
Code:
struct          BLOB
        cbSize          dd ?,?
        pBlobData       dq ?
ends
struct          PROPVARIANT
        vt              dw ?
        wRes1           db ?
        wRes2           db ?
        wRes3           dd ?
        union
                blob            BLOB
                pFriendlyName   dq ?
        ends
ends
    
Post 27 Mar 2021, 14:25
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.