The MASM Forum

General => The Campus => Topic started by: Zen on August 01, 2014, 05:32:23 AM

Title: Embarrassingly Simple Problem
Post by: Zen on August 01, 2014, 05:32:23 AM
...This has GOT TO BE one of those "Check Line 42" situations,...but, I've tried a number of what I considered,...obvious,...solutions to the code syntax,...and, every one of them FAILS.
What I'm trying to do is obtain a Pointer to a structure member (that resides at a location in memory allocated by a Win32 API), but, is not in the DATA section of my app.
Basically, I'm reading and printing the details of all the ACEs (Access Control Entry) (http://msdn.microsoft.com/en-us/library/windows/desktop/aa374912(v=vs.85).aspx) in a Security Descriptor. Most of it is quite simple.
I have a valid pointer to the WMI Namespace Security Descriptor, and I have called GetSecurityDescriptorDacl (http://msdn.microsoft.com/en-us/library/windows/desktop/aa446648(v=vs.85).aspx), and, then, GetAclInformation (http://msdn.microsoft.com/en-us/library/windows/desktop/aa446635(v=vs.85).aspx). This works correctly.
Then I want to iterate through the ACEs, and print out the relevant data to file, as a check. So, I'm invoking GetAce (http://msdn.microsoft.com/en-us/library/windows/desktop/aa446634(v=vs.85).aspx) (in a loop),...and, using the pointer to the ACE (which is returned from GetAce), to retrieve information about the ACE and print this info to file. It all works great (I've already used the ACE pointer to retrieve data from the ACE_HEADER structure (http://msdn.microsoft.com/en-us/library/windows/desktop/aa374919(v=vs.85).aspx)), until I get to the point where I'm trying to retrieve a pointer to the SID that is embedded in an ACCESS_ALLOWED_ACE structure (http://msdn.microsoft.com/en-us/library/windows/desktop/aa374847(v=vs.85).aspx), and use it in a call to: LookupAccountSid (http://msdn.microsoft.com/en-us/library/windows/desktop/aa379166(v=vs.85).aspx). The concept is simple, really,...but, then when I try to use the obtained SID pointer in a call to IsValidSid (http://msdn.microsoft.com/en-us/library/windows/desktop/aa379151(v=vs.85).aspx), the function FAILS.
Here is what I've tried,...

        mov ecx, dwptrACE    ;    dwptrACE is a valid pointer to the ACE returned from GetAce.   
        ASSUME ecx: PTR ACCESS_ALLOWED_ACE   
        mov edx, OFFSET [ecx].SidStart    ;    Internal Assembly Error.     
        ASSUME ecx: NOTHING
        mov dwptrAceSID, edx    ;    dwptrAceSID is a pointer to the SID enclosed in an ACE.   
        invoke IsValidSid, dwptrAceSID


        mov ecx, dwptrACE    ;    dwptrACE is a valid pointer to the ACE returned from GetAce.   
        ASSUME ecx: PTR ACCESS_ALLOWED_ACE   
        mov edx, [ecx].SidStart    ;    Compiles, but, IsValidSid FAILS.     
        ASSUME ecx: NOTHING
        mov dwptrAceSID, edx    ;    dwptrAceSID is a pointer to the SID enclosed in an ACE.   
        invoke IsValidSid, dwptrAceSID


        mov ecx, dwptrACE    ;    dwptrACE is a pointer to the ACE returned from GetAce.   
        ASSUME ecx: PTR ACCESS_ALLOWED_ACE   
        mov edx, DWORD PTR [ecx+8]    ;    IsValidSid FAILED.
        ASSUME ecx: NOTHING
        mov dwptrAceSID, edx    ;    dwptrAceSID is a pointer to the SID enclosed in an ACE.   
        invoke IsValidSid, dwptrAceSID


        mov ecx, dwptrACE    ;    dwptrACE is a valid pointer to the ACE returned from GetAce.   
        mov ebx, SIZEOF ACE_HEADER    ;    DWORD
        mov eax, SIZEOF ACCESS_MASK    ;    DWORD
        ADD ebx, eax
        ADD ecx, ebx
        mov dwptrAceSID, ecx    ;    Program malfunctioned.   
        invoke IsValidSid, dwptrAceSID


In the ACCESS_ALLOWED_ACE structure, the member StartSid is the first DWORD of the SID, it's NOT a pointer to the SID. What I need is a pointer to that SID. I need the address of ACCESS_ALLOWED_ACE.StartSid.
Thanks for any ideas,... :biggrin:
Title: Re: Embarrassingly Simple Problem
Post by: qWord on August 01, 2014, 06:40:09 AM
        mov ecx, dwptrACE    ;    pointer to the ACE   
        lea edx,[ecx].ACCESS_ALLOWED_ACE.SidStart
        mov dwptrAceSID, edx    ;    dwptrAceSID is a pointer to the SID   
        invoke IsValidSid, edx
Title: Re: Embarrassingly Simple Problem
Post by: Zen on August 01, 2014, 06:46:50 AM
QWORD,
Thanks you. I tried something similar in my code (it seems so simple),...but the app malfunctioned (it just stopped working, although it compiled).
When I commented out that block, it compiled, functioned OK,...except that the info returned from LookupAccountSid wasn't written to the file.
Title: Re: Embarrassingly Simple Problem
Post by: dedndave on August 01, 2014, 07:35:57 AM
let's say you are using a WIN32_FIND_DATAW structure
wfd WIN32_FIND_DATAW <>
; dwFileAttributes   DWORD    ?
; ftCreationTime     FILETIME <>
; ftLastAccessTime   FILETIME <>
; ftLastWriteTime    FILETIME <>
; nFileSizeHigh      DWORD    ?
; nFileSizeLow       DWORD    ?
; dwReserved0        DWORD    ?
; dwReserved1        DWORD    ?
; cFileName          WORD     MAX_PATH dup (?)  ;MAX_PATH = 260
; cAlternateFileName WORD     14 dup (?)


the offset of any member can be found with StructName.MemberName
    add     eax,WIN32_FIND_DATAW.ftCreationTime

because ftCreationTime is at offset 4 of the WIN32_FIND_DATAW structure, that code adds 4 to EAX

you can do the same using LEA
    lea     edx,[eax].WIN32_FIND_DATAW.ftCreationTime
Title: Re: Embarrassingly Simple Problem
Post by: jj2007 on August 01, 2014, 07:37:29 AM
Hi Zen,

lea is the way to go - it IS so simple. Difficult to say why your app crashes, but Olly could surely tell you a story ;-)

P.S.: Dave's solution may work, too - why don't you post your code, so that we can play around a little bit?
Title: Re: Embarrassingly Simple Problem
Post by: Zen on August 01, 2014, 09:09:38 AM
QWORD, DAVE, and, JOCHEN,
Yeah,...on further inspection of my code, something else is going wrong (and, at this point, I'm not sure what). :dazzled:
EDIT: I found and fixed the error,...it is unrelated to the SID Address problem.
I'm certain that you guys are correct. Everything you said makes perfect sense. Like I said, it's a simple operation.
THANKS FOR YOUR HELP !!!
I'll mess with my code and see if I can't figure out (what is NO DOUBT and incredibly dumb mistake), and, get back to your with the solution.

...By the way, I found some source code in the Windows SDK for Windows Seven that demonstrates how to access the Security Descriptor for the WMI Namesapce (it's written in C++),...and, this is what I'm trying to translate into MASM assembly, so that I can access WMI data,...
Title: Re: Embarrassingly Simple Problem
Post by: Zen on August 03, 2014, 04:20:37 AM
Well, I figured out what the problem is: it's a name collision.  :dazzled:
What the heck is MASK ??? It's either a directive or an operative.
This is the definition of the ACCESS_ALLOWED_ACE (http://msdn.microsoft.com/en-us/library/windows/desktop/aa374847(v=vs.85).aspx) in MASM's windows.inc

ACCESS_ALLOWED_ACE STRUCT
  Header    ACE_HEADER <>
  imask     DWORD      ?     ;    Should be Mask     DWORD      ?
  SidStart  DWORD      ?
ACCESS_ALLOWED_ACE ENDS

...For some odd reason, the MASM compiler chokes on this definition, when using the LEA instruction to return the address of StartSid,...

This code compiles and works (but, accesses a member of the ACE_HEADER structure):
        mov ecx, dwptrACE    ;    dwptrACE is a pointer to the ACE returned from GetAce.   
        ASSUME ecx: PTR ACE_HEADER
        LEA edx, [ecx].AceSize   
        ASSUME ecx: NOTHING

...Of course, this is not the correct address of the SID,...but, it demostrates that QWORD's approach (using LEA) works correctly,...

...This code compiles,...but the app hangs and fails at line containing the LEA instruction,...
mov ecx, dwptrACE    ;    dwptrACE is a pointer to the ACE returned from GetAce.   
        ASSUME ecx: PTR ACCESS_ALLOWED_ACE
        LEA edx, [ecx].ACCESS_ALLOWED_ACE.SidStart 
        ASSUME ecx: NOTHING
Title: Re: Embarrassingly Simple Problem
Post by: jj2007 on August 03, 2014, 04:28:20 AM
Quote from: Zen on August 03, 2014, 04:20:37 AM
Well, I figured out what the problem is: it's a name collision.  :dazzled:
What the heck is MASK ???

See http://masm32.com/board/index.php?topic=3275.msg34434#msg34434 and http://www.masmforum.com/board/index.php?topic=17452.msg146925#msg146925
Title: Re: Embarrassingly Simple Problem
Post by: Zen on August 03, 2014, 04:31:51 AM
JOCHEN,
AHhhhhhhhhhhhh,...HAH,...of course,...the MASK operator,... :dazzled:
...So, the problem NOW is how to correctly define the ACCESS_ALLOWED_ACE structure,...
...Or,...to find an incredibly complicated, but, foolproof method of obtaining the SID pointer for the specified ACE,...:icon_mrgreen:
One thing that I tried, was to write a fake structure definition that contains 3 DWORDs (using LEA with the last DWORD would give me the correct offset to the SID). This compiles, but the program hangs at the LEA instruction.

Thanks,...by the way,...:biggrin:
...And, seriously,...why is QWORD always at the center of these weirdly esoteric, nearly incomprehensible MASM mysteries ???

EDIT: I tried a TEXTEQU, but it didn't work:
imask TEXTEQU <Mask>
Title: Re: Embarrassingly Simple Problem
Post by: dedndave on August 03, 2014, 05:03:58 AM
ACE_HEADER STRUCT
  AceType  BYTE ?
  AceFlags BYTE ?
  AceSize  WORD ?
ACE_HEADER ENDS

ACCESS_ALLOWED_ACE STRUCT
  Header   ACE_HEADER <>
  dwMask   DWORD ?
  SidStart DWORD ?
ACCESS_ALLOWED_ACE ENDS

    .DATA?

aaas ACCESS_ALLOWED_ACE <>
Title: Re: Embarrassingly Simple Problem
Post by: Zen on August 03, 2014, 05:05:49 AM
DAVE !!!
I don't think it will work, for the same reason that (the ACCESS_ALLOWED_ACE member name) iMask didn't work,...
...But, at this point,...I WILL TRY ANYTHING,...

ACCESS_ALLOWED_ACE_REDEF STRUCT
  Header    ACE_HEADER <>
  dwMask     DWORD      ?    ;    was Mask, name collision, MASK is a MASM operator.   
  SidStart  DWORD      ?
ACCESS_ALLOWED_ACE_REDEF ENDS


...Sorry,...it didn't work,...I will redefine in windows.inc,...no,...that didn't work, either,...:dazzled:
...This is evolving into Mission Impossible,...

...I may have to just skip this section (it's unnecessary for the program functionality,...it's just a nice to have the information),...
Title: Re: Embarrassingly Simple Problem
Post by: dedndave on August 03, 2014, 08:27:49 AM
didn't know they were already defined in windows.inc   :P

all you need is
        .DATA?

aaas ACCESS_ALLOWED_ACE <>
Title: Re: Embarrassingly Simple Problem
Post by: Zen on August 03, 2014, 08:48:56 AM
Ha,...Ha,...Ha,...
Jesus, DAVE,...:dazzled:

...I know,...it doesn't make alot of sense to you guys, since I have not given you the code,...
Hell,...it doesn't really make sense to me,...I'm basically guessing,...
QWORD's original suggestion of using the LEA insrtruction is correct,...but, because of the name collision, LEA FAILS in this instance,...
...I'm very certain of this, because I've tried a number of syntax variations,...and, they all work, except, when I try to call LEA for a member of the ACCESS_ALLOWED_ACE structure,...(the ACE_HEADER structure is a member of the  ACCESS_ALLOWED_ACE structure),...
Look Up, to this message: MASK (http://masm32.com/board/index.php?topic=3464.msg36527#msg36527)

Microsoft defines the ACCESS_ALLOWED_ACE structure like this:
C++

typedef struct _ACCESS_ALLOWED_ACE {
  ACE_HEADER  Header;
  ACCESS_MASK Mask;
  DWORD       SidStart;
} ACCESS_ALLOWED_ACE, *PACCESS_ALLOWED_ACE;


The structure ACCESS_ALLOWED_ACE as defined in MASM's windows.inc, is slightly different (because MASK is a MASM keyword),...
Really, all I need is the SID that is included in the ACE,...it can be done in other, less convenient ways,...as, I said, I want to call LookupAccountSid (http://msdn.microsoft.com/en-us/library/windows/desktop/aa379166(v=vs.85).aspx), which requires a pointer to a SID,...returning the Account Name and Domain Name,...that the ACE either allows access to or denies access to (the WMI namespace).

This program contains a HUMONGEOUS amount of code,...it's incredibly bloated, and has an awful lot of extraneous (but, useful) data,...and, crap that didn't work that I commented out,...it's an ugly mess,...but, most of it works quite well,...when compiled,...
I'm basically trying to save you the trouble of reading through all of it (the vast majority of the code is not relevant to the current problem),...
I wanted to get the whole thing working correctly, and, then, revise it so that it is readable,...and, easily modified,...
I'll work on it some more (I still have some ideas),...and. then,...I'll release the whole thing in all it's way-too-complex COM glory,...

...And, of course,...I'll expect DEATH THREATS,...lots of Death Threats,...:dazzled:
Title: Re: Embarrassingly Simple Problem
Post by: dedndave on August 03, 2014, 09:46:33 AM
i have no problem assembling this
        INCLUDE    \Masm32\Include\Masm32rt.inc

;###############################################################################################

        .DATA?

aaas ACCESS_ALLOWED_ACE <>

;###############################################################################################

        .CODE

;***********************************************************************************************

_main   PROC

        lea     edx,aaas

        print   chr$(13,10)
        inkey
        INVOKE  ExitProcess,0

_main   ENDP

;###############################################################################################

        END     _main
Title: Re: Embarrassingly Simple Problem
Post by: dedndave on August 03, 2014, 09:49:38 AM
so - start with a small file like that and add to it to discover what the issue is

one thing to remember is that INVOKE xxxx,ADDR yyyy uses EAX to LEA the address
so, if you have
    lea     eax,aaas
    INVOKE  SomeFunc,eax,addr Something

you will get an error

that's because the assembler uses EAX in the INVOKE code
    lea     eax,Something

this will work ok
    lea     edx,aaas
    INVOKE  SomeFunc,edx,addr Something
Title: Re: Embarrassingly Simple Problem
Post by: dedndave on August 03, 2014, 09:54:34 AM
i sometimes see this....
    INVOKE  Proc1,something   ;returns a result in EAX
    mov     edx,eax
    INVOKE  Proc2,edx,addr somethingelse


that's silly - well, you don't notice it until you disassemble it   :biggrin:

this would be a better solution
    INVOKE  Proc1,something
    lea     edx,somethingelse
    INVOKE  Proc2,eax,edx
Title: Re: Embarrassingly Simple Problem
Post by: Zen on August 05, 2014, 05:04:33 AM
DAVE !!!
Yeah,...good stuff, thanks. And, I didn't use the eax register with LEA,...
And,...LEA edx, [ecx],...with ecx being the address to the ACCESS_ALLOWED_ACE structure, works fine,...as does the LEA instruction with any of the structure members of the ACE_HEADER structure,...
Every ACE structure begins with an ACE_HEADER structure,...so this is where you begin. You access the AceType member of the ACE_HEADER structure,...so you can determine what format the rest of the data has,...this works correctly in my program (I have four Access Allowed ACEs, I have verified that the pointers are valid, and correspond with the size, in bytes of the ACE,...)
Something else is interfering with my project. I've had alot of simple code sequences fail for no apparent reason,...stuff that doesn't even make sense,...even, to my deranged mentality,...:dazzled:
My thinking is that I'm running a 32-bit app on Windows Seven, 64-bit version, and the computer uses an Intel 64-bit processor,...
...Also,...I'm using a public terminal at a public Library,...and, who the hell knows what kind of software they're running,...

What amazes me is that this FAILS:
        mov ecx, dwptrACE    ;    dwptrACE is a pointer to the ACE returned from GetAce.   
        ASSUME ecx: PTR ACCESS_ALLOWED_ACE       
        LEA edx, [ecx]   ;    This works, but is not the correct address of the SID.   
        ADD edx, 8    ;    8 bytes is the offset to the SidStart member of the ACCESS_ALLOWED_ACE structure.
        ASSUME ecx: NOTHING
        mov dwptrAceSID, edx    ;    dwptrAceSID is a pointer to the SID enclosed in an ACE.   
        invoke IsValidSid, dwptrAceSID


The above code block compiles but, the App hangs (for no apparent reason),... :dazzled:
...If I comment out the, ADD edx, 8 line,...it compiles and works perfectly,...except, of course, that edx is not the correct address of the SID,...And, yes,...it is an ACCESS ALLOWED ACE (there are 13 different types of ACEs (http://msdn.microsoft.com/en-us/library/windows/desktop/aa374912(v=vs.85).aspx), and each different variety uses a different structure to access its data),...
Have you EVER seen an ADD instruction FAIL ???
Title: Re: Embarrassingly Simple Problem
Post by: dedndave on August 05, 2014, 05:32:58 AM
you realize that
LEA edx, [ecx]

is the same as
mov edx,ecx
Title: Re: Embarrassingly Simple Problem
Post by: dedndave on August 05, 2014, 05:35:35 AM
IsValidSid requires a pointer to an SID structure - not an SID

you can combine these lines
        LEA edx, [ecx]   ;    This works, but is not the correct address of the SID.   
        ADD edx, 8    ;    8 bytes is the offset to the SidStart member of the ACCESS_ALLOWED_ACE structure.


lea edx,[ecx+8]
Title: Re: Embarrassingly Simple Problem
Post by: Zen on August 05, 2014, 05:36:37 AM
Yeah,...I know,...
In fact,...I used that EXACT line of code (lea edx,[ecx+8]), as my first attempt (it's in the very first post of this thread),...
This COULD be a DARK MATTER problem,...I haven't explored that one yet,...
And, thanks,...DAVE,...you guys have just confirmed what I already thought,...
At this point, I'm giving up, and proceeding to more exciting scenarios,...
THANKS AGAIN FOR YOUR HELP,...
Title: Re: Embarrassingly Simple Problem
Post by: dedndave on August 05, 2014, 05:44:57 AM
http://technet.microsoft.com/en-us/library/cc962011.aspx (http://technet.microsoft.com/en-us/library/cc962011.aspx)
Title: Re: Embarrassingly Simple Problem
Post by: Zen on August 05, 2014, 06:00:12 AM
DAVE !!!
You will LOVE this one:
There is actually a function named,...ConvertSecurityDescriptorToStringSecurityDescriptor (http://msdn.microsoft.com/en-us/library/windows/desktop/aa376397(v=vs.85).aspx),...
Here is a Raymond Chen blog entry: What Is the Default Security Descriptor?, Mar 2004 (http://blogs.msdn.com/b/oldnewthing/archive/2004/03/12/88572.aspx)
...I've already got this one invoked in my code (is this exciting, or what ???)
Here is what my Log File reports (about the DACL):
QuoteConvertSecurityDescriptorToStringSecurityDescriptor SUCCEEDED.
The size, in TCHARs, of the security descriptor string is: 97