...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:
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
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.
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
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?
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,...
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
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
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>
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 <>
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),...
didn't know they were already defined in windows.inc :P
all you need is
.DATA?
aaas ACCESS_ALLOWED_ACE <>
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:
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
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
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
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 ???
you realize that
LEA edx, [ecx]
is the same as
mov edx,ecx
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]
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,...
http://technet.microsoft.com/en-us/library/cc962011.aspx (http://technet.microsoft.com/en-us/library/cc962011.aspx)
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