Hello all
I am trying to make a program to shutdown my computer. I want to use ExitWindowsEx and I understand I will require certain privileges for that which can be obtained via tokens. This is the current code I have done now :
.486
option casemap:none
include \masm32\include\masm32rt.inc
include \masm32\include\dialogs.inc
include \masm32\macros\macros.asm
include \masm32\include\msvcrt.inc
include \masm32\include\advapi32.inc
includelib \masm32\lib\masm32.lib
includelib \masm32\lib\gdi32.lib
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\Comctl32.lib
includelib \masm32\lib\comdlg32.lib
includelib \masm32\lib\shell32.lib
includelib \masm32\lib\oleaut32.lib
includelib \masm32\lib\msvcrt.lib
includelib \masm32\lib\advapi32.lib
SetPrivilegeInfo proto
.data
PrivilegeName db "SeShutdownPrivilege",0
.data?
hToken dword ?
.code
Start:
xor ebx, ebx
invoke GetCurrentProcess
invoke OpenProcessToken, eax, 28h, addr hToken
invoke SetPrivilegeInfo
invoke CloseHandle, hToken
invoke ExitProcess, ebx
SetPrivilegeInfo proc
LOCAL tkp:TOKEN_PRIVILEGES
LOCAL laa:LUID_AND_ATTRIBUTES
invoke LookupPrivilegeValue, ebx, addr PrivilegeName, addr laa.Luid
mov laa.Attributes, SE_PRIVILEGE_ENABLED
mov tkp.PrivilegeCount, 1
lea eax, laa
mov tkp.Privileges, eax
invoke AdjustTokenPrivileges, hToken, ebx, addr tkp, ebx, ebx, ebx
ret
SetPrivilegeInfo endp
end Start
I am having problems filling in the second part of the TOKEN_PRIVILEGES structure. I assumed at first that it wants a pointer to an array of structures so I have tried doing that but MASM tells me the instruction operand sizes are wrong (mov tkp.Privileges, eax) which means that member is not a dword. Can anyone shed any light ?
QuoteSpecifies an array of LUID_AND_ATTRIBUTES structures. Each structure contains the LUID and attributes of a privilege. To get the name of the privilege associated with a LUID, call the LookupPrivilegeName function, passing the address of the LUID as the value of the lpLuid parameter. The attributes of a privilege can be a combination of the following values.
The problem is that after the dword(PrivilegeCount) come the LUID_AND_ATTRIBUTES structures themselves (not a pointer reference).
Try this:
SetPrivilegeInfo proc
LOCAL tkp:TOKEN_PRIVILEGES ;contains one LUID_AND_ATTRIBUTESĀ member by default.
mov tkp.PrivilegeCount,1
mov tkp.Privileges[0].Attributes, SE_PRIVILEGE_ENABLED
invoke LookupPrivilegeValue, NULL, addr PrivilegeName, addr tkp.Privileges[0].Luid
invoke AdjustTokenPrivileges, hToken, FALSE, addr tkp, 0, NULL, NULL
ret
SetPrivilegeInfo endp
Notice that this code only works when the privileges count is 1. To add more Privileges to the array, add more LUID_AND_ATTRIBUTES locals(or use the data section).
Thanks, works perfectly. Only thing I changed was to let MASM use its own prologue/epilogue. Instead of pop ebp myself and having to clean stack as well, etc.
one line:
invoke RtlAdjustPrivilege,SE_SHUTDOWN_PRIVILEGE,SE_PRIVILEGE_ENABLED,FALSE,addr bEnabled
let ntdll do the work
I tend not to use native APIs due to their poor documentation. It's almost as if Microsoft does not want us to know about them..
Slugsnack,
Also, remember, anything not documented can disappear at a moments notice leaving you with busted code. Stick to your method and try, always, not to get too fancy.
-- Paul
You might also want to take a look here...
http://www.masm32.com/board/index.php?topic=6299.0
Quote from: drizz on August 29, 2008, 01:13:14 AM
one line:
invoke RtlAdjustPrivilege,SE_SHUTDOWN_PRIVILEGE,SE_PRIVILEGE_ENABLED,FALSE,addr bEnabled
let ntdll do the work
Thank you very much.Your tips to solve the proplem that has been toubling me for a long time.